diff --git a/qwt/qwt.prf b/qwt/qwt.prf index f91e65d98..a4ebb2e35 100644 --- a/qwt/qwt.prf +++ b/qwt/qwt.prf @@ -1,34 +1,44 @@ -# -*- mode: sh -*- ################################################ +################################################################ # Qwt Widget Library # Copyright (C) 1997 Josef Wilgen # Copyright (C) 2002 Uwe Rathmann # # This library is free software; you can redistribute it and/or # modify it under the terms of the Qwt License, Version 1.0 -################################################################### +################################################################ -QwtBuild = dll -QwtVersion = 5.2.0 +include ( ./qwtconfig.pri ) -unix { - QwtBase = /usr/local/qwt-$${QwtVersion}-svn - LIBS += -L$${QwtBase}/lib -lqwt -} -win32 { - QwtBase = C:/Qwt-$${QwtVersion}-svn +contains(QWT_CONFIG, QwtDll) { - contains(QwtBuild, dll) { - DEFINES += QWT_DLL - - msvc:LIBS += $${QwtBase}/lib/qwt5.lib - msvc.net:LIBS += $${QwtBase}/lib/qwt5.lib - msvc2005:LIBS += $${QwtBase}/lib/qwt5.lib - } else { - win32-msvc:LIBS += $${QwtBase}/lib/qwt.lib - win32-msvc.net:LIBS += $${QwtBase}/lib/qwt.lib - win32-msvc2005:LIBS += $${QwtBase}/lib/qwt.lib - } - g++:LIBS += -L$${QwtBase}/lib -lqwt + DEFINES *= QWT_DLL } -INCLUDEPATH += $${QwtBase}/include +contains(QWT_CONFIG, QwtSvg) { + + QT *= svg +} +else { + + DEFINES *= QWT_NO_SVG +} + +contains(QWT_CONFIG, QwtFramework) { + + INCLUDEPATH *= $${QWT_INSTALL_LIBS}/qwt.framework/Headers + LIBS *= -F$${QWT_INSTALL_LIBS} +} +else { + + INCLUDEPATH *= $${QWT_INSTALL_HEADERS} + LIBS *= -L$${QWT_INSTALL_LIBS} +} + +INCLUDEPATH_QWT = $${INCLUDEPATH} +qtAddLibrary(qwt) + +# we don't want qtAddLibrary to expand the +# include path, with directories, that might +# conflict with other installations of qwt + +INCLUDEPATH = $${INCLUDEPATH_QWT} diff --git a/qwt/qwt.pro b/qwt/qwt.pro index 20543ab37..490df5ce7 100644 --- a/qwt/qwt.pro +++ b/qwt/qwt.pro @@ -1,24 +1,30 @@ -# -*- mode: sh -*- ########################### +################################################################ # Qwt Widget Library # Copyright (C) 1997 Josef Wilgen # Copyright (C) 2002 Uwe Rathmann # # This library is free software; you can redistribute it and/or # modify it under the terms of the Qwt License, Version 1.0 -############################################## +################################################################ include( qwtconfig.pri ) TEMPLATE = subdirs +CONFIG += ordered SUBDIRS = \ src \ textengines -contains(CONFIG, QwtDesigner ) { - SUBDIRS += designer +#contains(QWT_CONFIG, QwtDesigner ) { +# SUBDIRS += designer +#} + +contains(QWT_CONFIG, QwtExamples ) { + SUBDIRS += examples } -contains(CONFIG, QwtExamples ) { - SUBDIRS += examples -} +qwtspec.files = qwtconfig.pri qwt.prf +qwtspec.path = $${QWT_INSTALL_FEATURES} + +INSTALLS += qwtspec diff --git a/qwt/qwt.pro.user b/qwt/qwt.pro.user new file mode 100644 index 000000000..e26a54b43 --- /dev/null +++ b/qwt/qwt.pro.user @@ -0,0 +1,2047 @@ + + + + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + System + false + 4 + true + 1 + true + 0 + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + Qt4ProjectManager.Target.DesktopTarget + 0 + 0 + 0 + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Compiler + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Nettoyer + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Desktop Qt 4.7.4 for GCC (Qt SDK) Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /Users/grauser/Documents/DEV/Qt/qwt-6.0.1 + 12 + false + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Compiler + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Nettoyer + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Desktop Qt 4.7.4 for GCC (Qt SDK) Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /Users/grauser/Documents/DEV/Qt/qwt-6.0.1 + 12 + false + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Compiler + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Nettoyer + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Qt dans le PATH Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /Users/grauser/Documents/DEV/Qt/qwt-6.0.1 + 2 + false + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Compiler + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Nettoyer + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Qt dans le PATH Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /Users/grauser/Documents/DEV/Qt/qwt-6.0.1 + 2 + false + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Compiler + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Nettoyer + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + 4.7.0 Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /Users/grauser/Documents/DEV/Qt/qwt-6.0.1 + 8 + false + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Compiler + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Nettoyer + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + 4.7.0 Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /Users/grauser/Documents/DEV/Qt/qwt-6.0.1 + 8 + false + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Compiler + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Nettoyer + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + 4.6.1 Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /Users/grauser/Documents/DEV/Qt/qwt-6.0.1 + 4 + false + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Compiler + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Nettoyer + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + 4.6.1 Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /Users/grauser/Documents/DEV/Qt/qwt-6.0.1 + 4 + false + + 8 + + + 0 + Déploiement + + ProjectExplorer.BuildSteps.Deploy + + 1 + Pas de déploiement + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + dials + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/dials/dials.pro + false + false + + + 3768 + true + false + false + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + plotmatrix + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/plotmatrix/plotmatrix.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + spectrogram + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/spectrogram/spectrogram.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + navigation + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/navigation/navigation.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + refreshtest + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/refreshtest/refreshtest.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + bode + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/bode/bode.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + curvdemo2 + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/curvdemo2/curvdemo2.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + oscilloscope + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/oscilloscope/oscilloscope.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + rasterview + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/rasterview/rasterview.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + svgmap + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/svgmap/svgmap.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + radio + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/radio/radio.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + sysinfo + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/sysinfo/sysinfo.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + cpuplot + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/cpuplot/cpuplot.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + curvdemo1 + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/curvdemo1/curvdemo1.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + sinusplot + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/sinusplot/sinusplot.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + sliders + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/sliders/sliders.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + event_filter + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/event_filter/event_filter.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + realtime + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/realtime/realtime.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + friedberg + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/friedberg/friedberg.pro + false + false + + + 3768 + true + false + true + + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + tvplot + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + examples/tvplot/tvplot.pro + false + false + + + 3768 + true + false + true + + 20 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.EnvironmentId + {aacf4a18-beff-41d4-a574-373b7bf4e503} + + + ProjectExplorer.Project.Updater.FileVersion + 10 + + diff --git a/qwt/qwtbuild.pri b/qwt/qwtbuild.pri new file mode 100644 index 000000000..a154cd3fe --- /dev/null +++ b/qwt/qwtbuild.pri @@ -0,0 +1,70 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +###################################################################### +# qmake internal options +###################################################################### + +CONFIG += qt +CONFIG += warn_on +CONFIG += no_keywords +CONFIG += silent + +###################################################################### +# release/debug mode +###################################################################### + +win32 { + # On Windows you can't mix release and debug libraries. + # The designer is built in release mode. If you like to use it + # you need a release version. For your own application development you + # might need a debug version. + # Enable debug_and_release + build_all if you want to build both. + + CONFIG += debug_and_release + CONFIG += build_all +} +else { + + # CONFIG += release + CONFIG += debug + + VER_MAJ = $${QWT_VER_MAJ} + VER_MIN = $${QWT_VER_MIN} + VER_PAT = $${QWT_VER_PAT} + VERSION = $${QWT_VERSION} +} + +linux-g++ { + # CONFIG += separate_debug_info +} + +###################################################################### +# paths for building qwt +###################################################################### + +MOC_DIR = moc +RCC_DIR = resources +!debug_and_release { + OBJECTS_DIR = obj +} + +unix { + + exists( $${QMAKE_LIBDIR_QT}/libqwt.* ) { + + # On some Linux distributions the Qwt libraries are installed + # in the same directory as the Qt libraries. Unfortunately + # qmake always adds QMAKE_LIBDIR_QT at the beginning of the + # linker path, so that the installed libraries will be + # used instead of the local ones. + + error( "local build will conflict with $${QMAKE_LIBDIR_QT}/libqwt.*" ) + } +} diff --git a/qwt/src/qwt_point_polar.cpp b/qwt/src/qwt_point_polar.cpp new file mode 100644 index 000000000..8f768f93f --- /dev/null +++ b/qwt/src/qwt_point_polar.cpp @@ -0,0 +1,113 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * QwtPolar Widget Library + * Copyright (C) 2008 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_point_polar.h" +#include "qwt_math.h" + +#if QT_VERSION < 0x040601 +#define qAtan2(y, x) ::atan2(y, x) +#endif + +/*! + Convert and assign values from a point in Cartesian coordinates + + \param p Point in Cartesian coordinates + \sa setPoint(), toPoint() +*/ +QwtPointPolar::QwtPointPolar( const QPointF &p ) +{ + d_radius = qSqrt( qwtSqr( p.x() ) + qwtSqr( p.y() ) ); + d_azimuth = qAtan2( p.y(), p.x() ); +} + +/*! + Convert and assign values from a point in Cartesian coordinates + \param p Point in Cartesian coordinates +*/ +void QwtPointPolar::setPoint( const QPointF &p ) +{ + d_radius = qSqrt( qwtSqr( p.x() ) + qwtSqr( p.y() ) ); + d_azimuth = qAtan2( p.y(), p.x() ); +} + +/*! + Convert and return values in Cartesian coordinates + + \note Invalid or null points will be returned as QPointF(0.0, 0.0) + \sa isValid(), isNull() +*/ +QPointF QwtPointPolar::toPoint() const +{ + if ( d_radius <= 0.0 ) + return QPointF( 0.0, 0.0 ); + + const double x = d_radius * qCos( d_azimuth ); + const double y = d_radius * qSin( d_azimuth ); + + return QPointF( x, y ); +} + +/*! + Returns true if point1 is equal to point2; otherwise returns false. + + Two points are equal to each other if radius and + azimuth-coordinates are the same. Points are not equal, when + the azimuth differs, but other.azimuth() == azimuth() % (2 * PI). + + \sa normalized() +*/ +bool QwtPointPolar::operator==( const QwtPointPolar &other ) const +{ + return d_radius == other.d_radius && d_azimuth == other.d_azimuth; +} + +/*! + Returns true if point1 is not equal to point2; otherwise returns false. + + Two points are equal to each other if radius and + azimuth-coordinates are the same. Points are not equal, when + the azimuth differs, but other.azimuth() == azimuth() % (2 * PI). + + \sa normalized() +*/ +bool QwtPointPolar::operator!=( const QwtPointPolar &other ) const +{ + return d_radius != other.d_radius || d_azimuth != other.d_azimuth; +} + +/*! + Normalize radius and azimuth + + When the radius is < 0.0 it is set to 0.0. The azimuth is + a value >= 0.0 and < 2 * M_PI. +*/ +QwtPointPolar QwtPointPolar::normalized() const +{ + const double radius = qMax( d_radius, 0.0 ); + + double azimuth = d_azimuth; + if ( azimuth < -2.0 * M_PI || azimuth >= 2 * M_PI ) + azimuth = ::fmod( d_azimuth, 2 * M_PI ); + + if ( azimuth < 0.0 ) + azimuth += 2 * M_PI; + + return QwtPointPolar( azimuth, radius ); +} + +#ifndef QT_NO_DEBUG_STREAM + +QDebug operator<<( QDebug debug, const QwtPointPolar &point ) +{ + debug.nospace() << "QwtPointPolar(" + << point.azimuth() << "," << point.radius() << ")"; + + return debug.space(); +} + +#endif diff --git a/qwt/src/qwt_point_polar.h b/qwt/src/qwt_point_polar.h new file mode 100644 index 000000000..d213ae0b7 --- /dev/null +++ b/qwt/src/qwt_point_polar.h @@ -0,0 +1,195 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +/*! \file */ +#ifndef _QWT_POINT_POLAR_H_ +#define _QWT_POINT_POLAR_H_ 1 + +#include "qwt_global.h" +#include "qwt_math.h" +#include +#ifndef QT_NO_DEBUG_STREAM +#include +#endif + +/*! + \brief A point in polar coordinates + + In polar coordinates a point is determined by an angle and a distance. + See http://en.wikipedia.org/wiki/Polar_coordinate_system +*/ + +class QWT_EXPORT QwtPointPolar +{ +public: + QwtPointPolar(); + QwtPointPolar( double azimuth, double radius ); + QwtPointPolar( const QwtPointPolar & ); + QwtPointPolar( const QPointF & ); + + void setPoint( const QPointF & ); + QPointF toPoint() const; + + bool isValid() const; + bool isNull() const; + + double radius() const; + double azimuth() const; + + double &rRadius(); + double &rAzimuth(); + + void setRadius( double ); + void setAzimuth( double ); + + bool operator==( const QwtPointPolar & ) const; + bool operator!=( const QwtPointPolar & ) const; + + QwtPointPolar normalized() const; + +private: + double d_azimuth; + double d_radius; +}; + +/*! + Constructs a null point, with a radius and azimuth set to 0.0. + \sa QPointF::isNull +*/ +inline QwtPointPolar::QwtPointPolar(): + d_azimuth( 0.0 ), + d_radius( 0.0 ) +{ +} + +/*! + Constructs a point with coordinates specified by radius and azimuth. + + \param azimuth Azimuth + \param radius Radius +*/ +inline QwtPointPolar::QwtPointPolar( double azimuth, double radius ): + d_azimuth( azimuth ), + d_radius( radius ) +{ +} + +/*! + Constructs a point using the values of the point specified. + \param other Other point +*/ +inline QwtPointPolar::QwtPointPolar( const QwtPointPolar &other ): + d_azimuth( other.d_azimuth ), + d_radius( other.d_radius ) +{ +} + +//! Returns true if radius() >= 0.0 +inline bool QwtPointPolar::isValid() const +{ + return d_radius >= 0.0; +} + +//! Returns true if radius() >= 0.0 +inline bool QwtPointPolar::isNull() const +{ + return d_radius == 0.0; +} + +//! Returns the radius. +inline double QwtPointPolar::radius() const +{ + return d_radius; +} + +//! Returns the azimuth. +inline double QwtPointPolar::azimuth() const +{ + return d_azimuth; +} + +//! Returns the radius. +inline double &QwtPointPolar::rRadius() +{ + return d_radius; +} + +//! Returns the azimuth. +inline double &QwtPointPolar::rAzimuth() +{ + return d_azimuth; +} + +//! Sets the radius to radius. +inline void QwtPointPolar::setRadius( double radius ) +{ + d_radius = radius; +} + +//! Sets the atimuth to atimuth. +inline void QwtPointPolar::setAzimuth( double azimuth ) +{ + d_azimuth = azimuth; +} + +#ifndef QT_NO_DEBUG_STREAM +QWT_EXPORT QDebug operator<<( QDebug, const QwtPointPolar & ); +#endif + +inline QPoint qwtPolar2Pos( const QPoint &pole, + double radius, double angle ) +{ + const double x = pole.x() + radius * qCos( angle ); + const double y = pole.y() - radius * qSin( angle ); + + return QPoint( qRound( x ), qRound( y ) ); +} + +inline QPoint qwtDegree2Pos( const QPoint &pole, + double radius, double angle ) +{ + return qwtPolar2Pos( pole, radius, angle / 180.0 * M_PI ); +} + +inline QPointF qwtPolar2Pos( const QPointF &pole, + double radius, double angle ) +{ + const double x = pole.x() + radius * qCos( angle ); + const double y = pole.y() - radius * qSin( angle ); + + return QPointF( x, y); +} + +inline QPointF qwtDegree2Pos( const QPointF &pole, + double radius, double angle ) +{ + return qwtPolar2Pos( pole, radius, angle / 180.0 * M_PI ); +} + +inline QPointF qwtFastPolar2Pos( const QPointF &pole, + double radius, double angle ) +{ +#if QT_VERSION < 0x040601 + const double x = pole.x() + radius * ::cos( angle ); + const double y = pole.y() - radius * ::sin( angle ); +#else + const double x = pole.x() + radius * qFastCos( angle ); + const double y = pole.y() - radius * qFastSin( angle ); +#endif + + return QPointF( x, y); +} + +inline QPointF qwtFastDegree2Pos( const QPointF &pole, + double radius, double angle ) +{ + return qwtFastPolar2Pos( pole, radius, angle / 180.0 * M_PI ); +} + +#endif diff --git a/qwt/src/qwt_sampling_thread.cpp b/qwt/src/qwt_sampling_thread.cpp new file mode 100644 index 000000000..4cffb3dee --- /dev/null +++ b/qwt/src/qwt_sampling_thread.cpp @@ -0,0 +1,106 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_sampling_thread.h" +#include "qwt_system_clock.h" + +class QwtSamplingThread::PrivateData +{ +public: + QwtSystemClock clock; + + double interval; + bool isStopped; +}; + + +//! Constructor +QwtSamplingThread::QwtSamplingThread( QObject *parent ): + QThread( parent ) +{ + d_data = new PrivateData; + d_data->interval = 1000; // 1 second + d_data->isStopped = true; +} + +//! Destructor +QwtSamplingThread::~QwtSamplingThread() +{ + delete d_data; +} + +/*! + Change the interval (in ms), when sample() is called. + The default interval is 1000.0 ( = 1s ) + + \param interval Interval + \sa interval() +*/ +void QwtSamplingThread::setInterval( double interval ) +{ + if ( interval < 0.0 ) + interval = 0.0; + + d_data->interval = interval; +} + +/*! + \return Interval (in ms), between 2 calls of sample() + \sa setInterval() +*/ +double QwtSamplingThread::interval() const +{ + return d_data->interval; +} + +/*! + \return Time (in ms) since the thread was started + \sa QThread::start(), run() +*/ +double QwtSamplingThread::elapsed() const +{ + if ( d_data->isStopped ) + return 0.0; + + return d_data->clock.elapsed(); +} + +/*! + Terminate the collecting thread + \sa QThread::start(), run() +*/ +void QwtSamplingThread::stop() +{ + d_data->isStopped = true; +} + +/*! + Loop collecting samples started from QThread::start() + \sa stop() +*/ +void QwtSamplingThread::run() +{ + d_data->clock.start(); + d_data->isStopped = false; + + while ( !d_data->isStopped ) + { + const double elapsed = d_data->clock.elapsed(); + sample( elapsed / 1000.0 ); + + if ( d_data->interval > 0.0 ) + { + const double msecs = + d_data->interval - ( d_data->clock.elapsed() - elapsed ); + + if ( msecs > 0.0 ) + usleep( qRound( 1000.0 * msecs ) ); + } + } +} diff --git a/qwt/src/qwt_sampling_thread.h b/qwt/src/qwt_sampling_thread.h new file mode 100644 index 000000000..85b876e5c --- /dev/null +++ b/qwt/src/qwt_sampling_thread.h @@ -0,0 +1,50 @@ +#ifndef _QWT_SAMPLING_THREAD_H_ +#define _QWT_SAMPLING_THREAD_H_ + +#include "qwt_global.h" +#include + +/*! + \brief A thread collecting samples at regular intervals. + + Contiounous signals are converted into a discrete signal by + collecting samples at regular intervals. A discrete signal + can be displayed by a QwtPlotSeriesItem on a QwtPlot widget. + + QwtSamplingThread starts a thread calling perodically sample(), + to collect and store ( or emit ) a single sample. + + \sa QwtPlotCurve, QwtPlotSeriesItem +*/ +class QWT_EXPORT QwtSamplingThread: public QThread +{ + Q_OBJECT + +public: + virtual ~QwtSamplingThread(); + + double interval() const; + double elapsed() const; + +public Q_SLOTS: + void setInterval( double interval ); + void stop(); + +protected: + explicit QwtSamplingThread( QObject *parent = NULL ); + + virtual void run(); + + /*! + Collect a sample + + \param elapsed Time since the thread was started in miliseconds + */ + virtual void sample( double elapsed ) = 0; + +private: + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/qwt/src/qwt_series_data.cpp b/qwt/src/qwt_series_data.cpp new file mode 100644 index 000000000..b79c26ee2 --- /dev/null +++ b/qwt/src/qwt_series_data.cpp @@ -0,0 +1,586 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_series_data.h" +#include "qwt_math.h" + +static inline QRectF qwtBoundingRect( const QPointF &sample ) +{ + return QRectF( sample.x(), sample.y(), 0.0, 0.0 ); +} + +static inline QRectF qwtBoundingRect( const QwtPoint3D &sample ) +{ + return QRectF( sample.x(), sample.y(), 0.0, 0.0 ); +} + +static inline QRectF qwtBoundingRect( const QwtPointPolar &sample ) +{ + return QRectF( sample.azimuth(), sample.radius(), 0.0, 0.0 ); +} + +static inline QRectF qwtBoundingRect( const QwtIntervalSample &sample ) +{ + return QRectF( sample.interval.minValue(), sample.value, + sample.interval.maxValue() - sample.interval.minValue(), 0.0 ); +} + +static inline QRectF qwtBoundingRect( const QwtSetSample &sample ) +{ + double minX = sample.set[0]; + double maxX = sample.set[0]; + + for ( int i = 1; i < ( int )sample.set.size(); i++ ) + { + if ( sample.set[i] < minX ) + minX = sample.set[i]; + if ( sample.set[i] > maxX ) + maxX = sample.set[i]; + } + + double minY = sample.value; + double maxY = sample.value; + + return QRectF( minX, minY, maxX - minX, maxY - minY ); +} + +/*! + \brief Calculate the bounding rect of a series subset + + Slow implementation, that iterates over the series. + + \param series Series + \param from Index of the first sample, <= 0 means from the beginning + \param to Index of the last sample, < 0 means to the end + + \return Bounding rectangle +*/ + +template +QRectF qwtBoundingRectT( + const QwtSeriesData& series, int from, int to ) +{ + QRectF boundingRect( 1.0, 1.0, -2.0, -2.0 ); // invalid; + + if ( from < 0 ) + from = 0; + + if ( to < 0 ) + to = series.size() - 1; + + if ( to < from ) + return boundingRect; + + int i; + for ( i = from; i <= to; i++ ) + { + const QRectF rect = qwtBoundingRect( series.sample( i ) ); + if ( rect.width() >= 0.0 && rect.height() >= 0.0 ) + { + boundingRect = rect; + i++; + break; + } + } + + for ( ; i <= to; i++ ) + { + const QRectF rect = qwtBoundingRect( series.sample( i ) ); + if ( rect.width() >= 0.0 && rect.height() >= 0.0 ) + { + boundingRect.setLeft( qMin( boundingRect.left(), rect.left() ) ); + boundingRect.setRight( qMax( boundingRect.right(), rect.right() ) ); + boundingRect.setTop( qMin( boundingRect.top(), rect.top() ) ); + boundingRect.setBottom( qMax( boundingRect.bottom(), rect.bottom() ) ); + } + } + + return boundingRect; +} + +/*! + \brief Calculate the bounding rect of a series subset + + Slow implementation, that iterates over the series. + + \param series Series + \param from Index of the first sample, <= 0 means from the beginning + \param to Index of the last sample, < 0 means to the end + + \return Bounding rectangle +*/ +QRectF qwtBoundingRect( + const QwtSeriesData &series, int from, int to ) +{ + return qwtBoundingRectT( series, from, to ); +} + +/*! + \brief Calculate the bounding rect of a series subset + + Slow implementation, that iterates over the series. + + \param series Series + \param from Index of the first sample, <= 0 means from the beginning + \param to Index of the last sample, < 0 means to the end + + \return Bounding rectangle +*/ +QRectF qwtBoundingRect( + const QwtSeriesData &series, int from, int to ) +{ + return qwtBoundingRectT( series, from, to ); +} + +/*! + \brief Calculate the bounding rect of a series subset + + The horizontal coordinates represent the azimuth, the + vertical coordinates the radius. + + Slow implementation, that iterates over the series. + + \param series Series + \param from Index of the first sample, <= 0 means from the beginning + \param to Index of the last sample, < 0 means to the end + + \return Bounding rectangle +*/ +QRectF qwtBoundingRect( + const QwtSeriesData &series, int from, int to ) +{ + return qwtBoundingRectT( series, from, to ); +} + +/*! + \brief Calculate the bounding rect of a series subset + + Slow implementation, that iterates over the series. + + \param series Series + \param from Index of the first sample, <= 0 means from the beginning + \param to Index of the last sample, < 0 means to the end + + \return Bounding rectangle +*/ +QRectF qwtBoundingRect( + const QwtSeriesData& series, int from, int to ) +{ + return qwtBoundingRectT( series, from, to ); +} + +/*! + \brief Calculate the bounding rect of a series subset + + Slow implementation, that iterates over the series. + + \param series Series + \param from Index of the first sample, <= 0 means from the beginning + \param to Index of the last sample, < 0 means to the end + + \return Bounding rectangle +*/ +QRectF qwtBoundingRect( + const QwtSeriesData& series, int from, int to ) +{ + return qwtBoundingRectT( series, from, to ); +} + +/*! + Constructor + \param samples Samples +*/ +QwtPointSeriesData::QwtPointSeriesData( + const QVector &samples ): + QwtArraySeriesData( samples ) +{ +} + +/*! + \brief Calculate the bounding rect + + The bounding rectangle is calculated once by iterating over all + points and is stored for all following requests. + + \return Bounding rectangle +*/ +QRectF QwtPointSeriesData::boundingRect() const +{ + if ( d_boundingRect.width() < 0.0 ) + d_boundingRect = qwtBoundingRect( *this ); + + return d_boundingRect; +} + +/*! + Constructor + \param samples Samples +*/ +QwtPoint3DSeriesData::QwtPoint3DSeriesData( + const QVector &samples ): + QwtArraySeriesData( samples ) +{ +} + +/*! + \brief Calculate the bounding rect + + The bounding rectangle is calculated once by iterating over all + points and is stored for all following requests. + + \return Bounding rectangle +*/ +QRectF QwtPoint3DSeriesData::boundingRect() const +{ + if ( d_boundingRect.width() < 0.0 ) + d_boundingRect = qwtBoundingRect( *this ); + + return d_boundingRect; +} + +/*! + Constructor + \param samples Samples +*/ +QwtIntervalSeriesData::QwtIntervalSeriesData( + const QVector &samples ): + QwtArraySeriesData( samples ) +{ +} + +/*! + \brief Calculate the bounding rect + + The bounding rectangle is calculated once by iterating over all + points and is stored for all following requests. + + \return Bounding rectangle +*/ +QRectF QwtIntervalSeriesData::boundingRect() const +{ + if ( d_boundingRect.width() < 0.0 ) + d_boundingRect = qwtBoundingRect( *this ); + + return d_boundingRect; +} + +/*! + Constructor + \param samples Samples +*/ +QwtSetSeriesData::QwtSetSeriesData( + const QVector &samples ): + QwtArraySeriesData( samples ) +{ +} + +/*! + \brief Calculate the bounding rect + + The bounding rectangle is calculated once by iterating over all + points and is stored for all following requests. + + \return Bounding rectangle +*/ +QRectF QwtSetSeriesData::boundingRect() const +{ + if ( d_boundingRect.width() < 0.0 ) + d_boundingRect = qwtBoundingRect( *this ); + + return d_boundingRect; +} + +/*! + Constructor + + \param x Array of x values + \param y Array of y values + + \sa QwtPlotCurve::setData(), QwtPlotCurve::setSamples() +*/ +QwtPointArrayData::QwtPointArrayData( + const QVector &x, const QVector &y ): + d_x( x ), + d_y( y ) +{ +} + +/*! + Constructor + + \param x Array of x values + \param y Array of y values + \param size Size of the x and y arrays + \sa QwtPlotCurve::setData(), QwtPlotCurve::setSamples() +*/ +QwtPointArrayData::QwtPointArrayData( const double *x, + const double *y, size_t size ) +{ + d_x.resize( size ); + qMemCopy( d_x.data(), x, size * sizeof( double ) ); + + d_y.resize( size ); + qMemCopy( d_y.data(), y, size * sizeof( double ) ); +} + +/*! + \brief Calculate the bounding rect + + The bounding rectangle is calculated once by iterating over all + points and is stored for all following requests. + + \return Bounding rectangle +*/ +QRectF QwtPointArrayData::boundingRect() const +{ + if ( d_boundingRect.width() < 0 ) + d_boundingRect = qwtBoundingRect( *this ); + + return d_boundingRect; +} + +//! \return Size of the data set +size_t QwtPointArrayData::size() const +{ + return qMin( d_x.size(), d_y.size() ); +} + +/*! + Return the sample at position i + + \param i Index + \return Sample at position i +*/ +QPointF QwtPointArrayData::sample( size_t i ) const +{ + return QPointF( d_x[int( i )], d_y[int( i )] ); +} + +//! \return Array of the x-values +const QVector &QwtPointArrayData::xData() const +{ + return d_x; +} + +//! \return Array of the y-values +const QVector &QwtPointArrayData::yData() const +{ + return d_y; +} + +/*! + Constructor + + \param x Array of x values + \param y Array of y values + \param size Size of the x and y arrays + + \warning The programmer must assure that the memory blocks referenced + by the pointers remain valid during the lifetime of the + QwtPlotCPointer object. + + \sa QwtPlotCurve::setData(), QwtPlotCurve::setRawSamples() +*/ +QwtCPointerData::QwtCPointerData( + const double *x, const double *y, size_t size ): + d_x( x ), + d_y( y ), + d_size( size ) +{ +} + +/*! + \brief Calculate the bounding rect + + The bounding rectangle is calculated once by iterating over all + points and is stored for all following requests. + + \return Bounding rectangle +*/ +QRectF QwtCPointerData::boundingRect() const +{ + if ( d_boundingRect.width() < 0 ) + d_boundingRect = qwtBoundingRect( *this ); + + return d_boundingRect; +} + +//! \return Size of the data set +size_t QwtCPointerData::size() const +{ + return d_size; +} + +/*! + Return the sample at position i + + \param i Index + \return Sample at position i +*/ +QPointF QwtCPointerData::sample( size_t i ) const +{ + return QPointF( d_x[int( i )], d_y[int( i )] ); +} + +//! \return Array of the x-values +const double *QwtCPointerData::xData() const +{ + return d_x; +} + +//! \return Array of the y-values +const double *QwtCPointerData::yData() const +{ + return d_y; +} + +/*! + Constructor + + \param size Number of points + \param interval Bounding interval for the points + + \sa setInterval(), setSize() +*/ +QwtSyntheticPointData::QwtSyntheticPointData( + size_t size, const QwtInterval &interval ): + d_size( size ), + d_interval( interval ) +{ +} + +/*! + Change the number of points + + \param size Number of points + \sa size(), setInterval() +*/ +void QwtSyntheticPointData::setSize( size_t size ) +{ + d_size = size; +} + +/*! + \return Number of points + \sa setSize(), interval() +*/ +size_t QwtSyntheticPointData::size() const +{ + return d_size; +} + +/*! + Set the bounding interval + + \param interval Interval + \sa interval(), setSize() +*/ +void QwtSyntheticPointData::setInterval( const QwtInterval &interval ) +{ + d_interval = interval.normalized(); +} + +/*! + \return Bounding interval + \sa setInterval(), size() +*/ +QwtInterval QwtSyntheticPointData::interval() const +{ + return d_interval; +} + +/*! + Set a the "rect of interest" + + QwtPlotSeriesItem defines the current area of the plot canvas + as "rect of interest" ( QwtPlotSeriesItem::updateScaleDiv() ). + + If interval().isValid() == false the x values are calculated + in the interval rect.left() -> rect.right(). + + \sa rectOfInterest() +*/ +void QwtSyntheticPointData::setRectOfInterest( const QRectF &rect ) +{ + d_rectOfInterest = rect; + d_intervalOfInterest = QwtInterval( + rect.left(), rect.right() ).normalized(); +} + +/*! + \return "rect of interest" + \sa setRectOfInterest() +*/ +QRectF QwtSyntheticPointData::rectOfInterest() const +{ + return d_rectOfInterest; +} + +/*! + \brief Calculate the bounding rect + + This implementation iterates over all points, what could often + be implemented much faster using the characteristics of the series. + When there are many points it is recommended to overload and + reimplement this method using the characteristics of the series + ( if possible ). + + \return Bounding rectangle +*/ +QRectF QwtSyntheticPointData::boundingRect() const +{ + if ( d_size == 0 || + !( d_interval.isValid() || d_intervalOfInterest.isValid() ) ) + { + return QRectF(1.0, 1.0, -2.0, -2.0); // something invalid + } + + return qwtBoundingRect( *this ); +} + +/*! + Calculate the point from an index + + \param index Index + \return QPointF(x(index), y(x(index))); + + \warning For invalid indices ( index < 0 || index >= size() ) + (0, 0) is returned. +*/ +QPointF QwtSyntheticPointData::sample( size_t index ) const +{ + if ( index >= d_size ) + return QPointF( 0, 0 ); + + const double xValue = x( index ); + const double yValue = y( xValue ); + + return QPointF( xValue, yValue ); +} + +/*! + Calculate a x-value from an index + + x values are calculated by deviding an interval into + equidistant steps. If !interval().isValid() the + interval is calculated from the "rect of interest". + + \sa interval(), rectOfInterest(), y() +*/ +double QwtSyntheticPointData::x( uint index ) const +{ + const QwtInterval &interval = d_interval.isValid() ? + d_interval : d_intervalOfInterest; + + if ( !interval.isValid() || d_size == 0 || index >= d_size ) + return 0.0; + + const double dx = interval.width() / d_size; + return interval.minValue() + index * dx; +} diff --git a/qwt/src/qwt_series_data.h b/qwt/src/qwt_series_data.h new file mode 100644 index 000000000..22a501769 --- /dev/null +++ b/qwt/src/qwt_series_data.h @@ -0,0 +1,442 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_SERIES_DATA_H +#define QWT_SERIES_DATA_H 1 + +#include "qwt_global.h" +#include "qwt_interval.h" +#include "qwt_point_3d.h" +#include "qwt_point_polar.h" +#include +#include + +//! \brief A sample of the types (x1-x2, y) or (x, y1-y2) +class QWT_EXPORT QwtIntervalSample +{ +public: + QwtIntervalSample(); + QwtIntervalSample( double, const QwtInterval & ); + QwtIntervalSample( double value, double min, double max ); + + bool operator==( const QwtIntervalSample & ) const; + bool operator!=( const QwtIntervalSample & ) const; + + //! Value + double value; + + //! Interval + QwtInterval interval; +}; + +/*! + Constructor + The value is set to 0.0, the interval is invalid +*/ +inline QwtIntervalSample::QwtIntervalSample(): + value( 0.0 ) +{ +} + +//! Constructor +inline QwtIntervalSample::QwtIntervalSample( + double v, const QwtInterval &intv ): + value( v ), + interval( intv ) +{ +} + +//! Constructor +inline QwtIntervalSample::QwtIntervalSample( + double v, double min, double max ): + value( v ), + interval( min, max ) +{ +} + +//! Compare operator +inline bool QwtIntervalSample::operator==( + const QwtIntervalSample &other ) const +{ + return value == other.value && interval == other.interval; +} + +//! Compare operator +inline bool QwtIntervalSample::operator!=( + const QwtIntervalSample &other ) const +{ + return !( *this == other ); +} + +//! \brief A sample of the types (x1...xn, y) or (x, y1..yn) +class QWT_EXPORT QwtSetSample +{ +public: + QwtSetSample(); + bool operator==( const QwtSetSample &other ) const; + bool operator!=( const QwtSetSample &other ) const; + + //! value + double value; + + //! Vector of values associated to value + QVector set; +}; + +/*! + Constructor + The value is set to 0.0 +*/ +inline QwtSetSample::QwtSetSample(): + value( 0.0 ) +{ +} + +//! Compare operator +inline bool QwtSetSample::operator==( const QwtSetSample &other ) const +{ + return value == other.value && set == other.set; +} + +//! Compare operator +inline bool QwtSetSample::operator!=( const QwtSetSample &other ) const +{ + return !( *this == other ); +} + +/*! + \brief Abstract interface for iterating over samples + + Qwt offers several implementations of the QwtSeriesData API, + but in situations, where data of an application specific format + needs to be displayed, without having to copy it, it is recommended + to implement an individual data access. +*/ +template +class QwtSeriesData +{ +public: + QwtSeriesData(); + virtual ~QwtSeriesData(); + + //! \return Number of samples + virtual size_t size() const = 0; + + /*! + Return a sample + \param i Index + \return Sample at position i + */ + virtual T sample( size_t i ) const = 0; + + /*! + Calculate the bounding rect of all samples + + The bounding rect is necessary for autoscaling and can be used + for a couple of painting optimizations. + + qwtBoundingRect(...) offers slow implementations iterating + over the samples. For large sets it is recommended to implement + something faster f.e. by caching the bounding rect. + */ + virtual QRectF boundingRect() const = 0; + + virtual void setRectOfInterest( const QRectF & ); + +protected: + //! Can be used to cache a calculated bounding rectangle + mutable QRectF d_boundingRect; + +private: + QwtSeriesData &operator=( const QwtSeriesData & ); +}; + +//! Constructor +template +QwtSeriesData::QwtSeriesData(): + d_boundingRect( 0.0, 0.0, -1.0, -1.0 ) +{ +} + +//! Destructor +template +QwtSeriesData::~QwtSeriesData() +{ +} + +/*! + Set a the "rect of interest" + + QwtPlotSeriesItem defines the current area of the plot canvas + as "rect of interest" ( QwtPlotSeriesItem::updateScaleDiv() ). + It can be used to implement different levels of details. + + The default implementation does nothing. +*/ +template +void QwtSeriesData::setRectOfInterest( const QRectF & ) +{ +} + +/*! + \brief Template class for data, that is organized as QVector + + QVector uses implicit data sharing and can be + passed around as argument efficiently. +*/ +template +class QwtArraySeriesData: public QwtSeriesData +{ +public: + QwtArraySeriesData(); + QwtArraySeriesData( const QVector & ); + + void setSamples( const QVector & ); + const QVector samples() const; + + virtual size_t size() const; + virtual T sample( size_t ) const; + +protected: + //! Vector of samples + QVector d_samples; +}; + +//! Constructor +template +QwtArraySeriesData::QwtArraySeriesData() +{ +} + +/*! + Constructor + \param samples Array of samples +*/ +template +QwtArraySeriesData::QwtArraySeriesData( const QVector &samples ): + d_samples( samples ) +{ +} + +/*! + Assign an array of samples + \param samples Array of samples +*/ +template +void QwtArraySeriesData::setSamples( const QVector &samples ) +{ + QwtSeriesData::d_boundingRect = QRectF( 0.0, 0.0, -1.0, -1.0 ); + d_samples = samples; +} + +//! \return Array of samples +template +const QVector QwtArraySeriesData::samples() const +{ + return d_samples; +} + +//! \return Number of samples +template +size_t QwtArraySeriesData::size() const +{ + return d_samples.size(); +} + +/*! + Return a sample + \param i Index + \return Sample at position i +*/ +template +T QwtArraySeriesData::sample( size_t i ) const +{ + return d_samples[i]; +} + +//! Interface for iterating over an array of points +class QWT_EXPORT QwtPointSeriesData: public QwtArraySeriesData +{ +public: + QwtPointSeriesData( + const QVector & = QVector() ); + + virtual QRectF boundingRect() const; +}; + +//! Interface for iterating over an array of 3D points +class QWT_EXPORT QwtPoint3DSeriesData: public QwtArraySeriesData +{ +public: + QwtPoint3DSeriesData( + const QVector & = QVector() ); + virtual QRectF boundingRect() const; +}; + +//! Interface for iterating over an array of intervals +class QWT_EXPORT QwtIntervalSeriesData: public QwtArraySeriesData +{ +public: + QwtIntervalSeriesData( + const QVector & = QVector() ); + + virtual QRectF boundingRect() const; +}; + +//! Interface for iterating over an array of samples +class QWT_EXPORT QwtSetSeriesData: public QwtArraySeriesData +{ +public: + QwtSetSeriesData( + const QVector & = QVector() ); + + virtual QRectF boundingRect() const; +}; + +/*! + \brief Interface for iterating over two QVector objects. +*/ +class QWT_EXPORT QwtPointArrayData: public QwtSeriesData +{ +public: + QwtPointArrayData( const QVector &x, const QVector &y ); + QwtPointArrayData( const double *x, const double *y, size_t size ); + + virtual QRectF boundingRect() const; + + virtual size_t size() const; + virtual QPointF sample( size_t i ) const; + + const QVector &xData() const; + const QVector &yData() const; + +private: + QVector d_x; + QVector d_y; +}; + +/*! + \brief Data class containing two pointers to memory blocks of doubles. + */ +class QWT_EXPORT QwtCPointerData: public QwtSeriesData +{ +public: + QwtCPointerData( const double *x, const double *y, size_t size ); + + virtual QRectF boundingRect() const; + virtual size_t size() const; + virtual QPointF sample( size_t i ) const; + + const double *xData() const; + const double *yData() const; + +private: + const double *d_x; + const double *d_y; + size_t d_size; +}; + +/*! + \brief Synthetic point data + + QwtSyntheticPointData provides a fixed number of points for an interval. + The points are calculated in equidistant steps in x-direction. + + If the interval is invalid, the points are calculated for + the "rect of interest", what normally is the displayed area on the + plot canvas. In this mode you get different levels of detail, when + zooming in/out. + + \par Example + + The following example shows how to implement a sinus curve. + + \verbatim +#include +#include +#include +#include +#include + +class SinusData: public QwtSyntheticPointData +{ +public: + SinusData(): + QwtSyntheticPointData(100) + { + } + virtual double y(double x) const + { + return qSin(x); + } +}; + +int main(int argc, char **argv) +{ + QApplication a(argc, argv); + + QwtPlot plot; + plot.setAxisScale(QwtPlot::xBottom, 0.0, 10.0); + plot.setAxisScale(QwtPlot::yLeft, -1.0, 1.0); + + QwtPlotCurve *curve = new QwtPlotCurve("y = sin(x)"); + curve->setData(SinusData()); + curve->attach(&plot); + + plot.show(); + return a.exec(); +} + \endverbatim +*/ +class QWT_EXPORT QwtSyntheticPointData: public QwtSeriesData +{ +public: + QwtSyntheticPointData( size_t size, + const QwtInterval & = QwtInterval() ); + + void setSize( size_t size ); + size_t size() const; + + void setInterval( const QwtInterval& ); + QwtInterval interval() const; + + virtual QRectF boundingRect() const; + virtual QPointF sample( size_t i ) const; + + /*! + Calculate a y value for a x value + + \param x x value + \return Corresponding y value + */ + virtual double y( double x ) const = 0; + virtual double x( uint index ) const; + + virtual void setRectOfInterest( const QRectF & ); + QRectF rectOfInterest() const; + +private: + size_t d_size; + QwtInterval d_interval; + QRectF d_rectOfInterest; + QwtInterval d_intervalOfInterest; +}; + +QWT_EXPORT QRectF qwtBoundingRect( + const QwtSeriesData &, int from = 0, int to = -1 ); +QWT_EXPORT QRectF qwtBoundingRect( + const QwtSeriesData &, int from = 0, int to = -1 ); +QWT_EXPORT QRectF qwtBoundingRect( + const QwtSeriesData &, int from = 0, int to = -1 ); +QWT_EXPORT QRectF qwtBoundingRect( + const QwtSeriesData &, int from = 0, int to = -1 ); +QWT_EXPORT QRectF qwtBoundingRect( + const QwtSeriesData &, int from = 0, int to = -1 ); + +#endif diff --git a/qwt/src/qwt_system_clock.cpp b/qwt/src/qwt_system_clock.cpp new file mode 100644 index 000000000..4816b1226 --- /dev/null +++ b/qwt/src/qwt_system_clock.cpp @@ -0,0 +1,364 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_system_clock.h" +#include + +#if !defined(Q_OS_WIN) +#include +#endif + +#if defined(Q_OS_MAC) +#include +#include +#define QWT_HIGH_RESOLUTION_CLOCK +#elif defined(_POSIX_TIMERS) +#include +#define QWT_HIGH_RESOLUTION_CLOCK +#elif defined(Q_OS_WIN) +#define QWT_HIGH_RESOLUTION_CLOCK +#include +#endif + +#if defined(QWT_HIGH_RESOLUTION_CLOCK) + +class QwtHighResolutionClock +{ +public: + QwtHighResolutionClock(); + + void start(); + double restart(); + double elapsed() const; + + bool isNull() const; + + static double precision(); + +private: + +#if defined(Q_OS_MAC) + static double msecsTo( uint64_t, uint64_t ); + + uint64_t d_timeStamp; +#elif defined(_POSIX_TIMERS) + + static double msecsTo( const struct timespec &, + const struct timespec & ); + + static bool isMonotonic(); + + struct timespec d_timeStamp; + clockid_t d_clockId; + +#elif defined(Q_OS_WIN) + + LARGE_INTEGER d_startTicks; + LARGE_INTEGER d_ticksPerSecond; +#endif +}; + +#if defined(Q_OS_MAC) +QwtHighResolutionClock::QwtHighResolutionClock(): + d_timeStamp( 0 ) +{ +} + +double QwtHighResolutionClock::precision() +{ + return 1e-6; +} + +void QwtHighResolutionClock::start() +{ + d_timeStamp = mach_absolute_time(); +} + +double QwtHighResolutionClock::restart() +{ + const uint64_t timeStamp = mach_absolute_time(); + const double elapsed = msecsTo( d_timeStamp, timeStamp ); + d_timeStamp = timeStamp; + + return elapsed; +} + +double QwtHighResolutionClock::elapsed() const +{ + return msecsTo( d_timeStamp, mach_absolute_time() ); +} + +bool QwtHighResolutionClock::isNull() const +{ + return d_timeStamp == 0; +} + +double QwtHighResolutionClock::msecsTo( + uint64_t from, uint64_t to ) +{ + const uint64_t difference = to - from; + + static double conversion = 0.0; + if ( conversion == 0.0 ) + { + mach_timebase_info_data_t info; + kern_return_t err = mach_timebase_info( &info ); + + //Convert the timebase into ms + if ( err == 0 ) + conversion = 1e-6 * ( double ) info.numer / ( double ) info.denom; + } + + return conversion * ( double ) difference; +} + +#elif defined(_POSIX_TIMERS) + +QwtHighResolutionClock::QwtHighResolutionClock() +{ + d_clockId = isMonotonic() ? CLOCK_MONOTONIC : CLOCK_REALTIME; + d_timeStamp.tv_sec = d_timeStamp.tv_nsec = 0; +} + +double QwtHighResolutionClock::precision() +{ + struct timespec resolution; + + int clockId = isMonotonic() ? CLOCK_MONOTONIC : CLOCK_REALTIME; + ::clock_getres( clockId, &resolution ); + + return resolution.tv_nsec / 1e3; +} + +inline bool QwtHighResolutionClock::isNull() const +{ + return d_timeStamp.tv_sec <= 0 && d_timeStamp.tv_nsec <= 0; +} + +inline void QwtHighResolutionClock::start() +{ + ::clock_gettime( d_clockId, &d_timeStamp ); +} + +double QwtHighResolutionClock::restart() +{ + struct timespec timeStamp; + ::clock_gettime( d_clockId, &timeStamp ); + + const double elapsed = msecsTo( d_timeStamp, timeStamp ); + + d_timeStamp = timeStamp; + return elapsed; +} + +inline double QwtHighResolutionClock::elapsed() const +{ + struct timespec timeStamp; + ::clock_gettime( d_clockId, &timeStamp ); + + return msecsTo( d_timeStamp, timeStamp ); +} + +inline double QwtHighResolutionClock::msecsTo( + const struct timespec &t1, const struct timespec &t2 ) +{ + return ( t2.tv_sec - t1.tv_sec ) * 1e3 + + ( t2.tv_nsec - t1.tv_nsec ) * 1e-6; +} + +bool QwtHighResolutionClock::isMonotonic() +{ + // code copied from qcore_unix.cpp + +#if (_POSIX_MONOTONIC_CLOCK-0 > 0) + return true; +#else + static int returnValue = 0; + + if ( returnValue == 0 ) + { +#if (_POSIX_MONOTONIC_CLOCK-0 < 0) || !defined(_SC_MONOTONIC_CLOCK) + returnValue = -1; +#elif (_POSIX_MONOTONIC_CLOCK == 0) + // detect if the system support monotonic timers + const long x = sysconf( _SC_MONOTONIC_CLOCK ); + returnValue = ( x >= 200112L ) ? 1 : -1; +#endif + } + + return returnValue != -1; +#endif +} + +#elif defined(Q_OS_WIN) + +QwtHighResolutionClock::QwtHighResolutionClock() +{ + d_startTicks.QuadPart = 0; + QueryPerformanceFrequency( &d_ticksPerSecond ); +} + +double QwtHighResolutionClock::precision() +{ + LARGE_INTEGER ticks; + if ( QueryPerformanceFrequency( &ticks ) && ticks.QuadPart > 0 ) + return 1e3 / ticks.QuadPart; + + return 0.0; +} + +inline bool QwtHighResolutionClock::isNull() const +{ + return d_startTicks.QuadPart <= 0; +} + +inline void QwtHighResolutionClock::start() +{ + QueryPerformanceCounter( &d_startTicks ); +} + +inline double QwtHighResolutionClock::restart() +{ + LARGE_INTEGER ticks; + QueryPerformanceCounter( &ticks ); + + const double dt = ticks.QuadPart - d_startTicks.QuadPart; + d_startTicks = ticks; + + return dt / d_ticksPerSecond.QuadPart * 1e3; +} + +inline double QwtHighResolutionClock::elapsed() const +{ + LARGE_INTEGER ticks; + QueryPerformanceCounter( &ticks ); + + const double dt = ticks.QuadPart - d_startTicks.QuadPart; + return dt / d_ticksPerSecond.QuadPart * 1e3; +} + +#endif + +#endif // QWT_HIGH_RESOLUTION_CLOCK + +class QwtSystemClock::PrivateData +{ +public: +#if defined(QWT_HIGH_RESOLUTION_CLOCK) + QwtHighResolutionClock *clock; +#endif + QTime time; +}; + +//! Constructs a null clock object. +QwtSystemClock::QwtSystemClock() +{ + d_data = new PrivateData; + +#if defined(QWT_HIGH_RESOLUTION_CLOCK) + d_data->clock = NULL; + if ( QwtHighResolutionClock::precision() > 0.0 ) + d_data->clock = new QwtHighResolutionClock; +#endif +} + +//! Destructor +QwtSystemClock::~QwtSystemClock() +{ +#if defined(QWT_HIGH_RESOLUTION_CLOCK) + delete d_data->clock; +#endif + delete d_data; +} + +/*! + \return true if the clock has never been started. +*/ +bool QwtSystemClock::isNull() const +{ +#if defined(QWT_HIGH_RESOLUTION_CLOCK) + if ( d_data->clock ) + return d_data->clock->isNull(); +#endif + + return d_data->time.isNull(); +} + +/*! + Sets the start time to the current time. +*/ +void QwtSystemClock::start() +{ +#if defined(QWT_HIGH_RESOLUTION_CLOCK) + if ( d_data->clock ) + { + d_data->clock->start(); + return; + } +#endif + + d_data->time.start(); +} + +/*! + The start time to the current time and + return the time, that is elapsed since the + previous start time. +*/ +double QwtSystemClock::restart() +{ +#if defined(QWT_HIGH_RESOLUTION_CLOCK) + if ( d_data->clock ) + return d_data->clock->restart(); +#endif + + return d_data->time.restart(); +} + +/*! + \return Number of milliseconds that have elapsed since the last time + start() or restart() was called or 0.0 for null clocks. +*/ +double QwtSystemClock::elapsed() const +{ + double elapsed = 0.0; + +#if defined(QWT_HIGH_RESOLUTION_CLOCK) + if ( d_data->clock ) + { + if ( !d_data->clock->isNull() ) + elapsed = d_data->clock->elapsed(); + + return elapsed; + } +#endif + + if ( !d_data->time.isNull() ) + elapsed = d_data->time.elapsed(); + + return elapsed; +} + +/*! + \return Accuracy of the system clock in milliseconds. +*/ +double QwtSystemClock::precision() +{ + static double prec = 0.0; + if ( prec <= 0.0 ) + { +#if defined(QWT_HIGH_RESOLUTION_CLOCK) + prec = QwtHighResolutionClock::precision(); +#endif + if ( prec <= 0.0 ) + prec = 1.0; // QTime offers 1 ms + } + + return prec; +} diff --git a/qwt/src/qwt_system_clock.h b/qwt/src/qwt_system_clock.h new file mode 100644 index 000000000..5ec402647 --- /dev/null +++ b/qwt/src/qwt_system_clock.h @@ -0,0 +1,49 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_SYSTEM_CLOCK_H +#define QWT_SYSTEM_CLOCK_H + +#include "qwt_global.h" + +/*! + \brief QwtSystemClock provides high resolution clock time functions. + + Sometimes the resolution offered by QTime ( millisecond ) is not accurate + enough for implementing time measurements ( f.e. sampling ). + QwtSystemClock offers a subset of the QTime functionality using higher + resolution timers ( if possible ). + + Precision and time intervals are multiples of milliseconds (ms). + + \note The implementation uses high-resolution performance counter on Windows, + mach_absolute_time() on the Mac or POSIX timers on other systems. + If none is available it falls back on QTimer. +*/ + +class QWT_EXPORT QwtSystemClock +{ +public: + QwtSystemClock(); + virtual ~QwtSystemClock(); + + bool isNull() const; + + void start(); + double restart(); + double elapsed() const; + + static double precision(); + +private: + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/qwt/textengines/mathml/qtmmlwidget-license b/qwt/textengines/mathml/qtmmlwidget-license new file mode 100644 index 000000000..9b573c774 --- /dev/null +++ b/qwt/textengines/mathml/qtmmlwidget-license @@ -0,0 +1,44 @@ +qwt_mml_document.h/qwt_mml_document.cpp have been stripped down from +"MML Widget" package of the solutions package, that is distributed under +the following licenses: + +----------------------------------------------------------------- +Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. +Contact: Nokia Corporation (qt-info@nokia.com) + +Commercial Usage +Licensees holding valid Qt Commercial licenses may use this file in +accordance with the Qt Solutions Commercial License Agreement provided +with the Software or, alternatively, in accordance with the terms +contained in a written agreement between you and Nokia. + +GNU Lesser General Public License Usage +Alternatively, this file may be used under the terms of the GNU Lesser +General Public License version 2.1 as published by the Free Software +Foundation and appearing in the file LICENSE.LGPL included in the +packaging of this file. Please review the following information to +ensure the GNU Lesser General Public License version 2.1 requirements +will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. + +In addition, as a special exception, Nokia gives you certain +additional rights. These rights are described in the Nokia Qt LGPL +Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +package. + +GNU General Public License Usage +Alternatively, this file may be used under the terms of the GNU +General Public License version 3.0 as published by the Free Software +Foundation and appearing in the file LICENSE.GPL included in the +packaging of this file. Please review the following information to +ensure the GNU General Public License version 3.0 requirements will be +met: http://www.gnu.org/copyleft/gpl.html. + +Please note Third Party Software included with Qt Solutions may impose +additional restrictions and it is the user's responsibility to ensure +that they have met the licensing requirements of the GPL, LGPL, or Qt +Solutions Commercial license and the relevant license of the Third +Party Software they are using. + +If you are unsure which license is appropriate for your use, please +contact Nokia at qt-info@nokia.com. diff --git a/qwt/textengines/mathml/qwt_mml_document.cpp b/qwt/textengines/mathml/qwt_mml_document.cpp new file mode 100644 index 000000000..0bb36cc1c --- /dev/null +++ b/qwt/textengines/mathml/qwt_mml_document.cpp @@ -0,0 +1,6260 @@ +#include +#include +#include +#include +#include + +#include "qwt_mml_document.h" + +// ******************************************************************* +// Declarations +// ******************************************************************* + +#define ROUND(a) (int)((a)+.5) + +static bool g_draw_frames = false; +static const double g_mfrac_spacing = 0.1; +static const double g_mroot_base_margin = 0.1; +static const double g_script_size_multiplier = 0.7071; // sqrt(1/2) +static const int g_min_font_point_size = 8; +static const QChar g_radical_char = QChar( 0x1A, 0x22 ); +static const unsigned g_oper_spec_rows = 9; + +struct QwtMml +{ + enum NodeType + { + NoNode = 0, MiNode, MnNode, MfracNode, MrowNode, MsqrtNode, + MrootNode, MsupNode, MsubNode, MsubsupNode, MoNode, + MstyleNode, TextNode, MphantomNode, MfencedNode, + MtableNode, MtrNode, MtdNode, MoverNode, MunderNode, + MunderoverNode, MerrorNode, MtextNode, MpaddedNode, + MspaceNode, MalignMarkNode, UnknownNode + }; + + enum MathVariant + { + NormalMV = 0x0000, + BoldMV = 0x0001, + ItalicMV = 0x0002, + DoubleStruckMV = 0x0004, + ScriptMV = 0x0008, + FrakturMV = 0x0010, + SansSerifMV = 0x0020, + MonospaceMV = 0x0040 + }; + + enum FormType { PrefixForm, InfixForm, PostfixForm }; + enum ColAlign { ColAlignLeft, ColAlignCenter, ColAlignRight }; + enum RowAlign { RowAlignTop, RowAlignCenter, RowAlignBottom, + RowAlignAxis, RowAlignBaseline + }; + enum FrameType { FrameNone, FrameSolid, FrameDashed }; + + struct FrameSpacing + { + FrameSpacing( int hor = 0, int ver = 0 ) + : m_hor( hor ), m_ver( ver ) {} + int m_hor, m_ver; + }; +}; + +struct QwtMmlOperSpec +{ + enum StretchDir { NoStretch, HStretch, VStretch, HVStretch }; + + const char *name; + QwtMml::FormType form; + const char *attributes[g_oper_spec_rows]; + StretchDir stretch_dir; +}; + +struct QwtMmlNodeSpec +{ + QwtMml::NodeType type; + const char *tag; + const char *type_str; + int child_spec; + const char *child_types; + const char *attributes; + + enum ChildSpec + { + ChildAny = -1, // any number of children allowed + ChildIgnore = -2, // do not build subexpression of children + ImplicitMrow = -3 // if more than one child, build mrow + }; +}; + +struct QwtMmlEntitySpec +{ + const char *name; + const char *value; +}; + +typedef QMap QwtMmlAttributeMap; +class QwtMmlNode; + +class QwtMmlDocument : public QwtMml +{ +public: + QwtMmlDocument(); + ~QwtMmlDocument(); + void clear(); + + bool setContent( QString text, QString *errorMsg = 0, + int *errorLine = 0, int *errorColumn = 0 ); + void paint( QPainter *p, const QPoint &pos ) const; + void dump() const; + QSize size() const; + void layout(); + + QString fontName( QwtMathMLDocument::MmlFont type ) const; + void setFontName( QwtMathMLDocument::MmlFont type, const QString &name ); + + int baseFontPointSize() const + { return m_base_font_point_size; } + void setBaseFontPointSize( int size ) + { m_base_font_point_size = size; } + QColor foregroundColor() const + { return m_foreground_color; } + void setForegroundColor( const QColor &color ) + { m_foreground_color = color; } + QColor backgroundColor() const + { return m_background_color; } + void setBackgroundColor( const QColor &color ) + { m_background_color = color; } + +private: + void _dump( const QwtMmlNode *node, QString &indent ) const; + bool insertChild( QwtMmlNode *parent, QwtMmlNode *new_node, QString *errorMsg ); + + QwtMmlNode *domToMml( const QDomNode &dom_node, bool *ok, QString *errorMsg ); + QwtMmlNode *createNode( NodeType type, const QwtMmlAttributeMap &mml_attr, + const QString &mml_value, QString *errorMsg ); + QwtMmlNode *createImplicitMrowNode( const QDomNode &dom_node, bool *ok, + QString *errorMsg ); + + void insertOperator( QwtMmlNode *node, const QString &text ); + + QwtMmlNode *m_root_node; + + QString m_normal_font_name; + QString m_fraktur_font_name; + QString m_sans_serif_font_name; + QString m_script_font_name; + QString m_monospace_font_name; + QString m_doublestruck_font_name; + int m_base_font_point_size; + QColor m_foreground_color; + QColor m_background_color; +}; + +class QwtMmlNode : public QwtMml +{ + friend class QwtMmlDocument; + +public: + QwtMmlNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ); + virtual ~QwtMmlNode(); + + // Mml stuff + NodeType nodeType() const + { return m_node_type; } + + virtual QString toStr() const; + + void setRelOrigin( const QPoint &rel_origin ); + QPoint relOrigin() const + { return m_rel_origin; } + void stretchTo( const QRect &rect ); + bool isStretched() const + { return m_stretched; } + QPoint devicePoint( const QPoint &p ) const; + + QRect myRect() const + { return m_my_rect; } + QRect parentRect() const; + virtual QRect deviceRect() const; + void updateMyRect(); + virtual void setMyRect( const QRect &rect ) + { m_my_rect = rect; } + + virtual void stretch(); + virtual void layout(); + virtual void paint( QPainter *p ); + + int basePos() const; + int overlinePos() const; + int underlinePos() const; + int em() const; + int ex() const; + + QString explicitAttribute( const QString &name, const QString &def = QString::null ) const; + QString inheritAttributeFromMrow( const QString &name, const QString &def = QString::null ) const; + + virtual QFont font() const; + virtual QColor color() const; + virtual QColor background() const; + virtual int scriptlevel( const QwtMmlNode *child = 0 ) const; + + + // Node stuff + QwtMmlDocument *document() const + { return m_document; } + QwtMmlNode *parent() const + { return m_parent; } + QwtMmlNode *firstChild() const + { return m_first_child; } + QwtMmlNode *nextSibling() const + { return m_next_sibling; } + QwtMmlNode *previousSibling() const + { return m_previous_sibling; } + QwtMmlNode *lastSibling() const; + QwtMmlNode *firstSibling() const; + bool isLastSibling() const + { return m_next_sibling == 0; } + bool isFirstSibling() const + { return m_previous_sibling == 0; } + bool hasChildNodes() const + { return m_first_child != 0; } + +protected: + virtual void layoutSymbol(); + virtual void paintSymbol( QPainter *p ) const; + virtual QRect symbolRect() const + { return QRect( 0, 0, 0, 0 ); } + + QwtMmlNode *parentWithExplicitAttribute( const QString &name, NodeType type = NoNode ); + int interpretSpacing( const QString &value, bool *ok ) const; + +private: + QwtMmlAttributeMap m_attribute_map; + bool m_stretched; + QRect m_my_rect, m_parent_rect; + QPoint m_rel_origin; + + NodeType m_node_type; + QwtMmlDocument *m_document; + + QwtMmlNode *m_parent, + *m_first_child, + *m_next_sibling, + *m_previous_sibling; +}; + +class QwtMmlTokenNode : public QwtMmlNode +{ +public: + QwtMmlTokenNode( NodeType type, QwtMmlDocument *document, + const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( type, document, attribute_map ) {} + + QString text() const; +}; + +class QwtMmlMphantomNode : public QwtMmlNode +{ +public: + QwtMmlMphantomNode( QwtMmlDocument *document, + const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( MphantomNode, document, attribute_map ) {} + + virtual void paint( QPainter * ) {} +}; + +class QwtMmlUnknownNode : public QwtMmlNode +{ +public: + QwtMmlUnknownNode( QwtMmlDocument *document, + const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( UnknownNode, document, attribute_map ) {} +}; + +class QwtMmlMfencedNode : public QwtMmlNode +{ +public: + QwtMmlMfencedNode( QwtMmlDocument *document, + const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( MfencedNode, document, attribute_map ) {} +}; + +class QwtMmlMalignMarkNode : public QwtMmlNode +{ +public: + QwtMmlMalignMarkNode( QwtMmlDocument *document ) + : QwtMmlNode( MalignMarkNode, document, QwtMmlAttributeMap() ) {} +}; + +class QwtMmlMfracNode : public QwtMmlNode +{ +public: + QwtMmlMfracNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( MfracNode, document, attribute_map ) {} + + QwtMmlNode *numerator() const; + QwtMmlNode *denominator() const; + +protected: + virtual void layoutSymbol(); + virtual void paintSymbol( QPainter *p ) const; + virtual QRect symbolRect() const; +}; + +class QwtMmlMrowNode : public QwtMmlNode +{ +public: + QwtMmlMrowNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( MrowNode, document, attribute_map ) {} +}; + +class QwtMmlRootBaseNode : public QwtMmlNode +{ +public: + QwtMmlRootBaseNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( type, document, attribute_map ) {} + + QwtMmlNode *base() const; + QwtMmlNode *index() const; + + virtual int scriptlevel( const QwtMmlNode *child = 0 ) const; + +protected: + virtual void layoutSymbol(); + virtual void paintSymbol( QPainter *p ) const; + virtual QRect symbolRect() const; + int tailWidth() const; +}; + +class QwtMmlMrootNode : public QwtMmlRootBaseNode +{ +public: + QwtMmlMrootNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlRootBaseNode( MrootNode, document, attribute_map ) {} +}; + +class QwtMmlMsqrtNode : public QwtMmlRootBaseNode +{ +public: + QwtMmlMsqrtNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlRootBaseNode( MsqrtNode, document, attribute_map ) {} + +}; + + +class QwtMmlTextNode : public QwtMmlNode +{ +public: + QwtMmlTextNode( const QString &text, QwtMmlDocument *document ); + + virtual QString toStr() const; + QString text() const + { return m_text; } + + // TextNodes are not xml elements, so they can't have attributes of + // their own. Everything is taken from the parent. + virtual QFont font() const + { return parent()->font(); } + virtual int scriptlevel( const QwtMmlNode* = 0 ) const + { return parent()->scriptlevel( this ); } + virtual QColor color() const + { return parent()->color(); } + virtual QColor background() const + { return parent()->background(); } + +protected: + virtual void paintSymbol( QPainter *p ) const; + virtual QRect symbolRect() const; + + QString m_text; +}; + +class QwtMmlMiNode : public QwtMmlTokenNode +{ +public: + QwtMmlMiNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlTokenNode( MiNode, document, attribute_map ) {} +}; + +class QwtMmlMnNode : public QwtMmlTokenNode +{ +public: + QwtMmlMnNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlTokenNode( MnNode, document, attribute_map ) {} +}; + +class QwtMmlSubsupBaseNode : public QwtMmlNode +{ +public: + QwtMmlSubsupBaseNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( type, document, attribute_map ) {} + + QwtMmlNode *base() const; + QwtMmlNode *sscript() const; + + virtual int scriptlevel( const QwtMmlNode *child = 0 ) const; +}; + +class QwtMmlMsupNode : public QwtMmlSubsupBaseNode +{ +public: + QwtMmlMsupNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlSubsupBaseNode( MsupNode, document, attribute_map ) {} + +protected: + virtual void layoutSymbol(); +}; + +class QwtMmlMsubNode : public QwtMmlSubsupBaseNode +{ +public: + QwtMmlMsubNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlSubsupBaseNode( MsubNode, document, attribute_map ) {} + +protected: + virtual void layoutSymbol(); +}; + +class QwtMmlMsubsupNode : public QwtMmlNode +{ +public: + QwtMmlMsubsupNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( MsubsupNode, document, attribute_map ) {} + + QwtMmlNode *base() const; + QwtMmlNode *superscript() const; + QwtMmlNode *subscript() const; + + virtual int scriptlevel( const QwtMmlNode *child = 0 ) const; + +protected: + virtual void layoutSymbol(); +}; + +class QwtMmlMoNode : public QwtMmlTokenNode +{ +public: + QwtMmlMoNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ); + + QString dictionaryAttribute( const QString &name ) const; + virtual void stretch(); + virtual int lspace() const; + virtual int rspace() const; + + virtual QString toStr() const; + +protected: + virtual void layoutSymbol(); + virtual QRect symbolRect() const; + + virtual FormType form() const; + +private: + const QwtMmlOperSpec *m_oper_spec; +}; + +class QwtMmlMstyleNode : public QwtMmlNode +{ +public: + QwtMmlMstyleNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( MstyleNode, document, attribute_map ) {} +}; + +class QwtMmlTableBaseNode : public QwtMmlNode +{ +public: + QwtMmlTableBaseNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( type, document, attribute_map ) {} +}; + +class QwtMmlMtableNode : public QwtMmlTableBaseNode +{ +public: + QwtMmlMtableNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlTableBaseNode( MtableNode, document, attribute_map ) {} + + int rowspacing() const; + int columnspacing() const; + int framespacing_hor() const; + int framespacing_ver() const; + FrameType frame() const; + FrameType columnlines( int idx ) const; + FrameType rowlines( int idx ) const; + +protected: + virtual void layoutSymbol(); + virtual QRect symbolRect() const; + virtual void paintSymbol( QPainter *p ) const; + +private: + struct CellSizeData + { + void init( const QwtMmlNode *first_row ); + QList col_widths, row_heights; + int numCols() const { return col_widths.count(); } + int numRows() const { return row_heights.count(); } + uint colWidthSum() const; + uint rowHeightSum() const; + }; + + CellSizeData m_cell_size_data; + int m_content_width, m_content_height; +}; + +class QwtMmlMtrNode : public QwtMmlTableBaseNode +{ +public: + QwtMmlMtrNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlTableBaseNode( MtrNode, document, attribute_map ) {} + void layoutCells( const QList &col_widths, int col_spc ); +}; + +class QwtMmlMtdNode : public QwtMmlTableBaseNode +{ +public: + QwtMmlMtdNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlTableBaseNode( MtdNode, document, attribute_map ) + { m_scriptlevel_adjust = 0; } + virtual void setMyRect( const QRect &rect ); + + ColAlign columnalign(); + RowAlign rowalign(); + uint colNum(); + uint rowNum(); + virtual int scriptlevel( const QwtMmlNode *child = 0 ) const; + +private: + int m_scriptlevel_adjust; // added or subtracted to scriptlevel to + // make contents fit the cell +}; + +class QwtMmlMoverNode : public QwtMmlNode +{ +public: + QwtMmlMoverNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( MoverNode, document, attribute_map ) {} + virtual int scriptlevel( const QwtMmlNode *node = 0 ) const; + +protected: + virtual void layoutSymbol(); +}; + +class QwtMmlMunderNode : public QwtMmlNode +{ +public: + QwtMmlMunderNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( MunderNode, document, attribute_map ) {} + virtual int scriptlevel( const QwtMmlNode *node = 0 ) const; + +protected: + virtual void layoutSymbol(); +}; + +class QwtMmlMunderoverNode : public QwtMmlNode +{ +public: + QwtMmlMunderoverNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( MunderoverNode, document, attribute_map ) {} + virtual int scriptlevel( const QwtMmlNode *node = 0 ) const; + +protected: + virtual void layoutSymbol(); +}; + +class QwtMmlMerrorNode : public QwtMmlNode +{ +public: + QwtMmlMerrorNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( MerrorNode, document, attribute_map ) {} +}; + +class QwtMmlMtextNode : public QwtMmlNode +{ +public: + QwtMmlMtextNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( MtextNode, document, attribute_map ) {} +}; + +class QwtMmlMpaddedNode : public QwtMmlNode +{ +public: + QwtMmlMpaddedNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( MpaddedNode, document, attribute_map ) {} + +public: + int lspace() const; + int width() const; + int height() const; + int depth() const; + +protected: + int interpretSpacing( QString value, int base_value, bool *ok ) const; + virtual void layoutSymbol(); + virtual QRect symbolRect() const; +}; + +class QwtMmlMspaceNode : public QwtMmlNode +{ +public: + QwtMmlMspaceNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlNode( MspaceNode, document, attribute_map ) {} +}; + +static const QwtMmlNodeSpec *mmlFindNodeSpec( QwtMml::NodeType type ); +static const QwtMmlNodeSpec *mmlFindNodeSpec( const QString &tag ); +static bool mmlCheckChildType( QwtMml::NodeType parent_type, + QwtMml::NodeType child_type, QString *error_str ); +static bool mmlCheckAttributes( QwtMml::NodeType child_type, + const QwtMmlAttributeMap &attr, QString *error_str ); +static QString mmlDictAttribute( const QString &name, const QwtMmlOperSpec *spec ); +static const QwtMmlOperSpec *mmlFindOperSpec( const QString &name, QwtMml::FormType form ); +static int interpretSpacing( QString name, int em, int ex, bool *ok ); +static int interpretPercentSpacing( QString value, int base, bool *ok ); +static uint interpretMathVariant( const QString &value, bool *ok ); +static QwtMml::FormType interpretForm( const QString &value, bool *ok ); +static QwtMml::FrameType interpretFrameType( const QString &value_list, uint idx, bool *ok ); +static QwtMml::FrameSpacing interpretFrameSpacing( const QString &value_list, int em, int ex, bool *ok ); +static QwtMml::ColAlign interpretColAlign( const QString &value_list, uint colnum, bool *ok ); +static QwtMml::RowAlign interpretRowAlign( const QString &value_list, uint rownum, bool *ok ); +static QwtMml::FrameType interpretFrameType( const QString &value_list, uint idx, bool *ok ); +static QFont interpretDepreciatedFontAttr( const QwtMmlAttributeMap &font_attr, QFont &fn, int em, int ex ); +static QFont interpretMathSize( QString value, QFont &fn, int em, int ex, bool *ok ); +static QString interpretListAttr( const QString &value_list, int idx, const QString &def ); +static QString rectToStr( const QRect &rect ); +static QString entityDeclarations(); + + +#define MML_ATT_COMMON " class style id xref actiontype " +#define MML_ATT_FONTSIZE " fontsize fontweight fontstyle fontfamily color " +#define MML_ATT_MATHVARIANT " mathvariant mathsize mathcolor mathbackground " +#define MML_ATT_FONTINFO MML_ATT_FONTSIZE MML_ATT_MATHVARIANT +#define MML_ATT_OPINFO " form fence separator lspace rspace stretchy symmetric " \ + " maxsize minsize largeop movablelimits accent " +#define MML_ATT_SIZEINFO " width height depth " +#define MML_ATT_TABLEINFO " align rowalign columnalign columnwidth groupalign " \ + " alignmentscope side rowspacing columnspacing rowlines " \ + " columnlines width frame framespacing equalrows " \ + " equalcolumns displaystyle " +#define MML_ATT_MFRAC " bevelled numalign denomalign linethickness " +#define MML_ATT_MSTYLE MML_ATT_FONTINFO MML_ATT_OPINFO \ + " scriptlevel lquote rquote linethickness displaystyle " \ + " scriptsizemultiplier scriptminsize background " \ + " veryverythinmathspace verythinmathspace thinmathspace " \ + " mediummathspace thickmathspace verythickmathspace " \ + " veryverythickmathspace open close separators " \ + " subscriptshift superscriptshift accentunder tableinfo " \ + " rowspan columnspan edge selection bevelled " +#define MML_ATT_MTABLE " align rowalign columnalign groupalign alignmentscope " \ + " columnwidth width rowspacing columnspacing rowlines columnlines " \ + " frame framespacing equalrows equalcolumns displaystyle side " \ + " minlabelspacing " + +static const QwtMmlNodeSpec g_node_spec_data[] = +{ + +// type tag type_str child_spec child_types attributes ""=none, 0=any +// ----------------------- --------------- ------------------- ----------------------- ------------------------ ------------------------------------ + { QwtMml::MiNode, "mi", "MiNode", QwtMmlNodeSpec::ChildAny, " TextNode MalignMark ", MML_ATT_COMMON MML_ATT_FONTINFO }, + { QwtMml::MnNode, "mn", "MnNode", QwtMmlNodeSpec::ChildAny, " TextNode MalignMark ", MML_ATT_COMMON MML_ATT_FONTINFO }, + { QwtMml::MfracNode, "mfrac", "MfracNode", 2, 0, MML_ATT_COMMON MML_ATT_MFRAC }, + { QwtMml::MrowNode, "mrow", "MrowNode", QwtMmlNodeSpec::ChildAny, 0, MML_ATT_COMMON " display mode " }, + { QwtMml::MsqrtNode, "msqrt", "MsqrtNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON }, + { QwtMml::MrootNode, "mroot", "MrootNode", 2, 0, MML_ATT_COMMON }, + { QwtMml::MsupNode, "msup", "MsupNode", 2, 0, MML_ATT_COMMON " subscriptshift " }, + { QwtMml::MsubNode, "msub", "MsubNode", 2, 0, MML_ATT_COMMON " superscriptshift " }, + { QwtMml::MsubsupNode, "msubsup", "MsubsupNode", 3, 0, MML_ATT_COMMON " subscriptshift superscriptshift " }, + { QwtMml::MoNode, "mo", "MoNode", QwtMmlNodeSpec::ChildAny, " TextNode MalignMark ", MML_ATT_COMMON MML_ATT_FONTINFO MML_ATT_OPINFO }, + { QwtMml::MstyleNode, "mstyle", "MstyleNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON MML_ATT_MSTYLE }, + { QwtMml::MphantomNode, "mphantom", "MphantomNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON }, + { QwtMml::MalignMarkNode, "malignmark", "MalignMarkNode", 0, 0, "" }, + { QwtMml::MfencedNode, "mfenced", "MfencedNode", QwtMmlNodeSpec::ChildAny, 0, MML_ATT_COMMON " open close separators " }, + { QwtMml::MtableNode, "mtable", "MtableNode", QwtMmlNodeSpec::ChildAny, " MtrNode ", MML_ATT_COMMON MML_ATT_MTABLE }, + { QwtMml::MtrNode, "mtr", "MtrNode", QwtMmlNodeSpec::ChildAny, " MtdNode ", MML_ATT_COMMON " rowalign columnalign groupalign " }, + { QwtMml::MtdNode, "mtd", "MtdNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON " rowspan columnspan rowalign columnalign groupalign " }, + { QwtMml::MoverNode, "mover", "MoverNode", 2, 0, MML_ATT_COMMON " accent " }, + { QwtMml::MunderNode, "munder", "MunderNode", 2, 0, MML_ATT_COMMON " accentunder " }, + { QwtMml::MunderoverNode, "munderover", "MunderoverNode", 3, 0, MML_ATT_COMMON " accentunder accent " }, + { QwtMml::MerrorNode, "merror", "MerrorNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON }, + { QwtMml::MtextNode, "mtext", "MtextNode", 1, " TextNode ", MML_ATT_COMMON " width height depth linebreak " }, + { QwtMml::MpaddedNode, "mpadded", "MpaddedNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON " width height depth lspace " }, + { QwtMml::MspaceNode, "mspace", "MspaceNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON " width height depth linebreak " }, + { QwtMml::TextNode, 0, "TextNode", QwtMmlNodeSpec::ChildIgnore, 0, "" }, + { QwtMml::UnknownNode, 0, "UnknownNode", QwtMmlNodeSpec::ChildAny, 0, 0 }, + { QwtMml::NoNode, 0, 0, 0, 0, 0 } +}; + +static const char *g_oper_spec_names[g_oper_spec_rows] = { "accent", "fence", "largeop", "lspace", "minsize", "movablelimits", "rspace", "separator", "stretchy" /* stretchdir */ }; +static const QwtMmlOperSpec g_oper_spec_data[] = +{ + + { "!!" , QwtMml::PostfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "!!" + { "!" , QwtMml::PostfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "!" + { "!=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "!=" + { "⩓" , QwtMml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⩓" + { "⁡" , QwtMml::InfixForm, { 0, 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⁡" + { "≔" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≔" + { "∖" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "∖" + { "∵" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∵" + { "˘" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "˘" + { "⋒" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋒" + { "ⅅ" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⅅ" + { "¸" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "¸" + { "·" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "·" + { "⊙" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊙" + { "⊖" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊖" + { "⊕" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊕" + { "⊗" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊗" + { "∲" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, "true"}, QwtMmlOperSpec::VStretch }, // ∲" + { "”" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ”" + { "’" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "’" + { "∷" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∷" + { "≡" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≡" + { "∮" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "∮" + { "∐" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∐" + { "∳", QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // &CounterClockwiseContourInteg + { "⨯" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⨯" + { "⋓" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋓" + { "≍" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≍" + { "∇" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∇" + { "´" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "´" + { "˙" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "˙" + { "˝" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ˝" + { "`" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "`" + { "&DiacriticalLeftArrow;" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &DiacriticalLeftArrow;" + { "&DiacriticalLeftRightArrow;" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &DiacriticalLeftRightArrow;" + { "&DiacriticalLeftRightVector;" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &DiacriticalLeftRightVector;" + { "&DiacriticalLeftVector;" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &DiacriticalLeftVector;" + { "&DiacriticalRightArrow;" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &DiacriticalRightArrow;" + { "&DiacriticalRightVector;" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &DiacriticalRightVector;" + { "˜" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::NoStretch }, // "˜" + { "⋄" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋄" + { "ⅆ" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "ⅆ" + { "≐" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≐" + { "∯" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // ∯" + { "¨" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "¨" + { "⇓" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⇓" + { "⇐" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇐" + { "⇔" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // ⇔" + { "⫤" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⫤" + { "⟸" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⟸" + { "⟺" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // ⟺" + { "⟹" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // ⟹" + { "⇒" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇒" + { "⊨" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊨" + { "⇑" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⇑" + { "⇕" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⇕" + { "∥" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∥" + { "↓" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "↓" + { "⤓" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⤓" + { "⇵" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⇵" + { "̑" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "̑" + { "⥐" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥐" + { "⥞" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥞" + { "↽" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↽" + { "⥖" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥖" + { "⥟" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥟" + { "⇁" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⇁" + { "⥗" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥗" + { "⊤" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊤" + { "↧" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "↧" + { "∈" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∈" + { "⩵" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⩵" + { "≂" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≂" + { "⇌" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇌" + { "∃" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∃" + { "∀" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∀" + { "≥" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≥" + { "⋛" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋛" + { "≧" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≧" + { "⪢" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪢" + { "≷" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≷" + { "⩾" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⩾" + { "≳" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≳" + { "ˇ" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::NoStretch }, // "ˇ" + { "^" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "^" + { "─" , QwtMml::InfixForm, { 0, 0, 0, "0em", "0", 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "─" + { "≎" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≎" + { "≏" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≏" + { "⇒" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇒" + { "∫" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∫" + { "⋂" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⋂" + { "⁣" , QwtMml::InfixForm, { 0, 0, 0, "0em", 0, 0, "0em", "true", 0 }, QwtMmlOperSpec::NoStretch }, // "⁣" + { "⁢" , QwtMml::InfixForm, { 0, 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⁢" + { "⟨" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⟨" + { "←" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "←" + { "⇤" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇤" + { "⇆" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇆" + { "&LeftBracketingBar;" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "&LeftBracketingBar;" + { "⌈" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⌈" + { "⟦" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⟦" + { "&LeftDoubleBracketingBar;" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &LeftDoubleBracketingBar;" + { "⥡" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥡" + { "⇃" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⇃" + { "⥙" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥙" + { "⌊" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⌊" + { "↔" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "↔" + { "⥎" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⥎" + { "&LeftSkeleton;" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "&LeftSkeleton;" + { "⊣" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊣" + { "↤" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "↤" + { "⥚" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⥚" + { "⊲" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊲" + { "⧏" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⧏" + { "⊴" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊴" + { "⥑" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥑" + { "⥠" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥠" + { "↿" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↿" + { "⥘" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥘" + { "↼" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "↼" + { "⥒" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⥒" + { "⋚" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋚" + { "≦" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≦" + { "≶" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≶" + { "⪡" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪡" + { "⩽" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⩽" + { "≲" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≲" + { "⟵" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⟵" + { "⟷" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⟷" + { "⟶" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⟶" + { "↙" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↙" + { "↘" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↘" + { "∓" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "veryverythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∓" + { "≫" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ≫" + { "≪" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≪" + { "⫬" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⫬" + { "≢" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≢" + { "≭" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≭" + { "∦" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ∦" + { "∉" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∉" + { "≠" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≠" + { "≂̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≂̸" + { "∄" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∄" + { "≯" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≯" + { "≱" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≱" + { "≧̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≧̸" + { "≫̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≫̸" + { "≹" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≹" + { "⩾̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⩾̸" + { "≵" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≵" + { "≎̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≎̸" + { "≏̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≏̸" + { "⋪" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋪" + { "⧏̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⧏̸" + { "⋬" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⋬" + { "≮" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≮" + { "≰" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≰" + { "&NotLessFullEqual;" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "&NotLessFullEqual;" + { "≸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≸" + { "≪̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≪̸" + { "⩽̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⩽̸" + { "≴" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≴" + { "⪢̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⪢̸" + { "⪡̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪡̸" + { "⊀" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊀" + { "⪯̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪯̸" + { "⋠" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⋠" + { "&NotPrecedesTilde;" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "&NotPrecedesTilde;" + { "∌" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∌" + { "⋫" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋫" + { "⧐̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⧐̸" + { "⋭" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⋭" + { "⊏̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊏̸" + { "⋢" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⋢" + { "⊐̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊐̸" + { "⋣" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⋣" + { "⊂⃒" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊂⃒" + { "⊈" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊈" + { "⊁" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊁" + { "⪰̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪰̸" + { "⋡" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⋡" + { "≿̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≿̸" + { "⊃⃒" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊃⃒" + { "⊉" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊉" + { "≁" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≁" + { "≄" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≄" + { "≇" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≇" + { "≉" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≉" + { "∤" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∤" + { "“" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // “" + { "‘" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "‘" + { "⩔" , QwtMml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⩔" + { "‾" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "‾" + { "⏞" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⏞" + { "⎴" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⎴" + { "⏜" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⏜" + { "∂" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∂" + { "±" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "veryverythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "±" + { "≺" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≺" + { "⪯" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪯" + { "≼" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≼" + { "≾" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≾" + { "∏" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∏" + { "∷" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∷" + { "∝" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∝" + { "∋" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∋" + { "⇋" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇋" + { "⥯" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // ⥯" + { "⟩" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⟩" + { "→" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "→" + { "⇥" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇥" + { "⇄" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇄" + { "&RightBracketingBar;" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "&RightBracketingBar;" + { "⌉" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⌉" + { "⟧" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⟧" + { "&RightDoubleBracketingBar;" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &RightDoubleBracketingBar;" + { "⥝" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥝" + { "⇂" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⇂" + { "⥕" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥕" + { "⌋" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⌋" + { "&RightSkeleton;" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "&RightSkeleton;" + { "⊢" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊢" + { "↦" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "↦" + { "⥛" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⥛" + { "⊳" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊳" + { "⧐" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⧐" + { "⊵" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊵" + { "⥏" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⥏" + { "⥜" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥜" + { "↾" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↾" + { "⥔" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥔" + { "⇀" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇀" + { "⥓" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⥓" + { "⥰" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⥰" + { "↓" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "↓" + { "←" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::HStretch }, // "←" + { "→" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::HStretch }, // "→" + { "↑" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::VStretch }, // "↑" + { "∘" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∘" + { "√" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "√" + { "□" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "□" + { "⊓" , QwtMml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⊓" + { "⊏" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊏" + { "⊑" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊑" + { "⊐" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊐" + { "⊒" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊒" + { "⊔" , QwtMml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⊔" + { "⋆" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋆" + { "⋐" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋐" + { "⊆" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊆" + { "≻" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≻" + { "⪰" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪰" + { "≽" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≽" + { "≿" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≿" + { "∋" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∋" + { "∑" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∑" + { "⊃" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊃" + { "⊇" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊇" + { "∴" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∴" + { "∼" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∼" + { "≃" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≃" + { "≅" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≅" + { "≈" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≈" + { "⃛" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⃛" + { "_" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "_" + { "⏟" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⏟" + { "⎵" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⎵" + { "⏝" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⏝" + { "⋃" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⋃" + { "⊎" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⊎" + { "↑" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "↑" + { "⤒" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⤒" + { "⇅" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⇅" + { "↕" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "↕" + { "⥮" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⥮" + { "⊥" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊥" + { "↥" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "↥" + { "↖" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↖" + { "↗" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↗" + { "⋁" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋁" + { "∣" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∣" + { "|" , QwtMml::InfixForm, { 0, 0, 0, "0em", "0", 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "|" + { "❘" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "❘" + { "≀" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≀" + { "⋀" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋀" + { "&" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "&" + { "&&" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "&&" + { "≤" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≤" + { "<" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "<" + { "<=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "<=" + { "<>" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "<>" + { "'" , QwtMml::PostfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "'" + { "(" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "(" + { ")" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // ")" + { "*" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "*" + { "**" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "**" + { "*=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "*=" + { "+" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "+" + { "+" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "veryverythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "+" + { "++" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "++" + { "+=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "+=" + { "," , QwtMml::InfixForm, { 0, 0, 0, "0em", 0, 0, "verythickmathspace", "true", 0 }, QwtMmlOperSpec::NoStretch }, // "," + { "-" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "-" + { "-" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "veryverythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "-" + { "--" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "--" + { "-=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "-=" + { "->" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "->" + { "." , QwtMml::InfixForm, { 0, 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "." + { ".." , QwtMml::PostfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ".." + { "..." , QwtMml::PostfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "..." + { "/" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "/" + { "//" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "//" + { "/=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "/=" + { ":" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ":" + { ":=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ":=" + { ";" , QwtMml::InfixForm, { 0, 0, 0, "0em", 0, 0, "verythickmathspace", "true", 0 }, QwtMmlOperSpec::NoStretch }, // ";" + { ";" , QwtMml::PostfixForm, { 0, 0, 0, "0em", 0, 0, "0em", "true", 0 }, QwtMmlOperSpec::NoStretch }, // ";" + { "=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "=" + { "==" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "==" + { ">" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ">" + { ">=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ">=" + { "?" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "?" + { "@" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "@" + { "[" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "[" + { "]" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "]" + { "^" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "^" + { "_" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "_" + { "lim" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, "true", "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "lim" + { "max" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, "true", "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "max" + { "min" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, "true", "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "min" + { "{" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "{" + { "|" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "|" + { "||" , QwtMml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "||" + { "}" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "}" + { "~" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "~" + + { 0 , QwtMml::InfixForm, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, QwtMmlOperSpec::NoStretch } +}; + +static const QwtMmlOperSpec g_oper_spec_defaults = +{ 0 , QwtMml::InfixForm, { "false", "false", "false", "thickmathspace", "1", "false", "thickmathspace", "false", "false" }, QwtMmlOperSpec::NoStretch }; + +static const uint g_oper_spec_count = sizeof( g_oper_spec_data ) / sizeof( QwtMmlOperSpec ) - 1; + +static const QwtMmlEntitySpec g_xml_entity_data[] = +{ + { "angzarr", "⍼" }, + { "cirmid", "⫯" }, + { "cudarrl", "⤸" }, + { "cudarrr", "⤵" }, + { "cularr", "↶" }, + { "cularrp", "⤽" }, + { "curarr", "↷" }, + { "curarrm", "⤼" }, + { "Darr", "↡" }, + { "dArr", "⇓" }, + { "ddarr", "⇊" }, + { "DDotrahd", "⤑" }, + { "dfisht", "⥿" }, + { "dHar", "⥥" }, + { "dharl", "⇃" }, + { "dharr", "⇂" }, + { "duarr", "⇵" }, + { "duhar", "⥯" }, + { "dzigrarr", "⟿" }, + { "erarr", "⥱" }, + { "hArr", "⇔" }, + { "harr", "↔" }, + { "harrcir", "⥈" }, + { "harrw", "↭" }, + { "hoarr", "⇿" }, + { "imof", "⊷" }, + { "lAarr", "⇚" }, + { "Larr", "↞" }, + { "larrbfs", "⤟" }, + { "larrfs", "⤝" }, + { "larrhk", "↩" }, + { "larrlp", "↫" }, + { "larrpl", "⤹" }, + { "larrsim", "⥳" }, + { "larrtl", "↢" }, + { "lAtail", "⤛" }, + { "latail", "⤙" }, + { "lBarr", "⤎" }, + { "lbarr", "⤌" }, + { "ldca", "⤶" }, + { "ldrdhar", "⥧" }, + { "ldrushar", "⥋" }, + { "ldsh", "↲" }, + { "lfisht", "⥼" }, + { "lHar", "⥢" }, + { "lhard", "↽" }, + { "lharu", "↼" }, + { "lharul", "⥪" }, + { "llarr", "⇇" }, + { "llhard", "⥫" }, + { "loarr", "⇽" }, + { "lrarr", "⇆" }, + { "lrhar", "⇋" }, + { "lrhard", "⥭" }, + { "lsh", "↰" }, + { "lurdshar", "⥊" }, + { "luruhar", "⥦" }, + { "Map", "⤅" }, + { "map", "↦" }, + { "midcir", "⫰" }, + { "mumap", "⊸" }, + { "nearhk", "⤤" }, + { "neArr", "⇗" }, + { "nearr", "↗" }, + { "nesear", "⤨" }, + { "nhArr", "⇎" }, + { "nharr", "↮" }, + { "nlArr", "⇍" }, + { "nlarr", "↚" }, + { "nrArr", "⇏" }, + { "nrarr", "↛" }, + { "nrarrc", "⤳̸" }, + { "nrarrw", "↝̸" }, + { "nvHarr", "⤄" }, + { "nvlArr", "⤂" }, + { "nvrArr", "⤃" }, + { "nwarhk", "⤣" }, + { "nwArr", "⇖" }, + { "nwarr", "↖" }, + { "nwnear", "⤧" }, + { "olarr", "↺" }, + { "orarr", "↻" }, + { "origof", "⊶" }, + { "rAarr", "⇛" }, + { "Rarr", "↠" }, + { "rarrap", "⥵" }, + { "rarrbfs", "⤠" }, + { "rarrc", "⤳" }, + { "rarrfs", "⤞" }, + { "rarrhk", "↪" }, + { "rarrlp", "↬" }, + { "rarrpl", "⥅" }, + { "rarrsim", "⥴" }, + { "Rarrtl", "⤖" }, + { "rarrtl", "↣" }, + { "rarrw", "↝" }, + { "rAtail", "⤜" }, + { "ratail", "⤚" }, + { "RBarr", "⤐" }, + { "rBarr", "⤏" }, + { "rbarr", "⤍" }, + { "rdca", "⤷" }, + { "rdldhar", "⥩" }, + { "rdsh", "↳" }, + { "rfisht", "⥽" }, + { "rHar", "⥤" }, + { "rhard", "⇁" }, + { "rharu", "⇀" }, + { "rharul", "⥬" }, + { "rlarr", "⇄" }, + { "rlhar", "⇌" }, + { "roarr", "⇾" }, + { "rrarr", "⇉" }, + { "rsh", "↱" }, + { "ruluhar", "⥨" }, + { "searhk", "⤥" }, + { "seArr", "⇘" }, + { "searr", "↘" }, + { "seswar", "⤩" }, + { "simrarr", "⥲" }, + { "slarr", "←" }, + { "srarr", "→" }, + { "swarhk", "⤦" }, + { "swArr", "⇙" }, + { "swarr", "↙" }, + { "swnwar", "⤪" }, + { "Uarr", "↟" }, + { "uArr", "⇑" }, + { "Uarrocir", "⥉" }, + { "udarr", "⇅" }, + { "udhar", "⥮" }, + { "ufisht", "⥾" }, + { "uHar", "⥣" }, + { "uharl", "↿" }, + { "uharr", "↾" }, + { "uuarr", "⇈" }, + { "vArr", "⇕" }, + { "varr", "↕" }, + { "xhArr", "⟺" }, + { "xharr", "⟷" }, + { "xlArr", "⟸" }, + { "xlarr", "⟵" }, + { "xmap", "⟼" }, + { "xrArr", "⟹" }, + { "xrarr", "⟶" }, + { "zigrarr", "⇝" }, + { "ac", "∾" }, + { "acE", "∾̳" }, + { "amalg", "⨿" }, + { "barvee", "⊽" }, + { "Barwed", "⌆" }, + { "barwed", "⌅" }, + { "bsolb", "⧅" }, + { "Cap", "⋒" }, + { "capand", "⩄" }, + { "capbrcup", "⩉" }, + { "capcap", "⩋" }, + { "capcup", "⩇" }, + { "capdot", "⩀" }, + { "caps", "∩︀" }, + { "ccaps", "⩍" }, + { "ccups", "⩌" }, + { "ccupssm", "⩐" }, + { "coprod", "∐" }, + { "Cup", "⋓" }, + { "cupbrcap", "⩈" }, + { "cupcap", "⩆" }, + { "cupcup", "⩊" }, + { "cupdot", "⊍" }, + { "cupor", "⩅" }, + { "cups", "∪︀" }, + { "cuvee", "⋎" }, + { "cuwed", "⋏" }, + { "Dagger", "‡" }, + { "dagger", "†" }, + { "diam", "⋄" }, + { "divonx", "⋇" }, + { "eplus", "⩱" }, + { "hercon", "⊹" }, + { "intcal", "⊺" }, + { "iprod", "⨼" }, + { "loplus", "⨭" }, + { "lotimes", "⨴" }, + { "lthree", "⋋" }, + { "ltimes", "⋉" }, + { "midast", "*" }, + { "minusb", "⊟" }, + { "minusd", "∸" }, + { "minusdu", "⨪" }, + { "ncap", "⩃" }, + { "ncup", "⩂" }, + { "oast", "⊛" }, + { "ocir", "⊚" }, + { "odash", "⊝" }, + { "odiv", "⨸" }, + { "odot", "⊙" }, + { "odsold", "⦼" }, + { "ofcir", "⦿" }, + { "ogt", "⧁" }, + { "ohbar", "⦵" }, + { "olcir", "⦾" }, + { "olt", "⧀" }, + { "omid", "⦶" }, + { "ominus", "⊖" }, + { "opar", "⦷" }, + { "operp", "⦹" }, + { "oplus", "⊕" }, + { "osol", "⊘" }, + { "Otimes", "⨷" }, + { "otimes", "⊗" }, + { "otimesas", "⨶" }, + { "ovbar", "⌽" }, + { "plusacir", "⨣" }, + { "plusb", "⊞" }, + { "pluscir", "⨢" }, + { "plusdo", "∔" }, + { "plusdu", "⨥" }, + { "pluse", "⩲" }, + { "plussim", "⨦" }, + { "plustwo", "⨧" }, + { "prod", "∏" }, + { "race", "⧚" }, + { "roplus", "⨮" }, + { "rotimes", "⨵" }, + { "rthree", "⋌" }, + { "rtimes", "⋊" }, + { "sdot", "⋅" }, + { "sdotb", "⊡" }, + { "setmn", "∖" }, + { "simplus", "⨤" }, + { "smashp", "⨳" }, + { "solb", "⧄" }, + { "sqcap", "⊓" }, + { "sqcaps", "⊓︀" }, + { "sqcup", "⊔" }, + { "sqcups", "⊔︀" }, + { "ssetmn", "∖" }, + { "sstarf", "⋆" }, + { "subdot", "⪽" }, + { "sum", "∑" }, + { "supdot", "⪾" }, + { "timesb", "⊠" }, + { "timesbar", "⨱" }, + { "timesd", "⨰" }, + { "tridot", "◬" }, + { "triminus", "⨺" }, + { "triplus", "⨹" }, + { "trisb", "⧍" }, + { "tritime", "⨻" }, + { "uplus", "⊎" }, + { "veebar", "⊻" }, + { "wedbar", "⩟" }, + { "wreath", "≀" }, + { "xcap", "⋂" }, + { "xcirc", "◯" }, + { "xcup", "⋃" }, + { "xdtri", "▽" }, + { "xodot", "⨀" }, + { "xoplus", "⨁" }, + { "xotime", "⨂" }, + { "xsqcup", "⨆" }, + { "xuplus", "⨄" }, + { "xutri", "△" }, + { "xvee", "⋁" }, + { "xwedge", "⋀" }, + { "dlcorn", "⌞" }, + { "drcorn", "⌟" }, + { "gtlPar", "⦕" }, + { "langd", "⦑" }, + { "lbrke", "⦋" }, + { "lbrksld", "⦏" }, + { "lbrkslu", "⦍" }, + { "lceil", "⌈" }, + { "lfloor", "⌊" }, + { "lmoust", "⎰" }, + { "lparlt", "⦓" }, + { "ltrPar", "⦖" }, + { "rangd", "⦒" }, + { "rbrke", "⦌" }, + { "rbrksld", "⦎" }, + { "rbrkslu", "⦐" }, + { "rceil", "⌉" }, + { "rfloor", "⌋" }, + { "rmoust", "⎱" }, + { "rpargt", "⦔" }, + { "ulcorn", "⌜" }, + { "urcorn", "⌝" }, + { "gnap", "⪊" }, + { "gnE", "≩" }, + { "gne", "⪈" }, + { "gnsim", "⋧" }, + { "gvnE", "≩︀" }, + { "lnap", "⪉" }, + { "lnE", "≨" }, + { "lne", "⪇" }, + { "lnsim", "⋦" }, + { "lvnE", "≨︀" }, + { "nap", "≉" }, + { "napE", "⩰̸" }, + { "napid", "≋̸" }, + { "ncong", "≇" }, + { "ncongdot", "⩭̸" }, + { "nequiv", "≢" }, + { "ngE", "≧̸" }, + { "nge", "≱" }, + { "nges", "⩾̸" }, + { "nGg", "⋙̸" }, + { "ngsim", "≵" }, + { "nGt", "≫⃒" }, + { "ngt", "≯" }, + { "nGtv", "≫̸" }, + { "nlE", "≦̸" }, + { "nle", "≰" }, + { "nles", "⩽̸" }, + { "nLl", "⋘̸" }, + { "nlsim", "≴" }, + { "nLt", "≪⃒" }, + { "nlt", "≮" }, + { "nltri", "⋪" }, + { "nltrie", "⋬" }, + { "nLtv", "≪̸" }, + { "nmid", "∤" }, + { "npar", "∦" }, + { "npr", "⊀" }, + { "nprcue", "⋠" }, + { "npre", "⪯̸" }, + { "nrtri", "⋫" }, + { "nrtrie", "⋭" }, + { "nsc", "⊁" }, + { "nsccue", "⋡" }, + { "nsce", "⪰̸" }, + { "nsim", "≁" }, + { "nsime", "≄" }, + { "nsmid", "∤" }, + { "nspar", "∦" }, + { "nsqsube", "⋢" }, + { "nsqsupe", "⋣" }, + { "nsub", "⊄" }, + { "nsubE", "⫅̸" }, + { "nsube", "⊈" }, + { "nsup", "⊅" }, + { "nsupE", "⫆̸" }, + { "nsupe", "⊉" }, + { "ntgl", "≹" }, + { "ntlg", "≸" }, + { "nvap", "≍⃒" }, + { "nVDash", "⊯" }, + { "nVdash", "⊮" }, + { "nvDash", "⊭" }, + { "nvdash", "⊬" }, + { "nvge", "≥⃒" }, + { "nvgt", ">⃒" }, + { "nvle", "≤⃒" }, + { "nvlt", "<⃒" }, + { "nvltrie", "⊴⃒" }, + { "nvrtrie", "⊵⃒" }, + { "nvsim", "∼⃒" }, + { "parsim", "⫳" }, + { "prnap", "⪹" }, + { "prnE", "⪵" }, + { "prnsim", "⋨" }, + { "rnmid", "⫮" }, + { "scnap", "⪺" }, + { "scnE", "⪶" }, + { "scnsim", "⋩" }, + { "simne", "≆" }, + { "solbar", "⌿" }, + { "subnE", "⫋" }, + { "subne", "⊊" }, + { "supnE", "⫌" }, + { "supne", "⊋" }, + { "vnsub", "⊂⃒" }, + { "vnsup", "⊃⃒" }, + { "vsubnE", "⫋︀" }, + { "vsubne", "⊊︀" }, + { "vsupnE", "⫌︀" }, + { "vsupne", "⊋︀" }, + { "ang", "∠" }, + { "ange", "⦤" }, + { "angmsd", "∡" }, + { "angmsdaa", "⦨" }, + { "angmsdab", "⦩" }, + { "angmsdac", "⦪" }, + { "angmsdad", "⦫" }, + { "angmsdae", "⦬" }, + { "angmsdaf", "⦭" }, + { "angmsdag", "⦮" }, + { "angmsdah", "⦯" }, + { "angrtvb", "⊾" }, + { "angrtvbd", "⦝" }, + { "bbrk", "⎵" }, + { "bemptyv", "⦰" }, + { "beth", "ℶ" }, + { "boxbox", "⧉" }, + { "bprime", "‵" }, + { "bsemi", "⁏" }, + { "cemptyv", "⦲" }, + { "cirE", "⧃" }, + { "cirscir", "⧂" }, + { "comp", "∁" }, + { "daleth", "ℸ" }, + { "demptyv", "⦱" }, + { "ell", "ℓ" }, + { "empty", "∅" }, + { "emptyv", "∅" }, + { "gimel", "ℷ" }, + { "iiota", "℩" }, + { "image", "ℑ" }, + { "imath", "ı" }, + { "jmath", "j" }, + { "laemptyv", "⦴" }, + { "lltri", "◺" }, + { "lrtri", "⊿" }, + { "mho", "℧" }, + { "nang", "∠⃒" }, + { "nexist", "∄" }, + { "oS", "Ⓢ" }, + { "planck", "ℏ" }, + { "plankv", "ℏ" }, + { "raemptyv", "⦳" }, + { "range", "⦥" }, + { "real", "ℜ" }, + { "tbrk", "⎴" }, + { "ultri", "◸" }, + { "urtri", "◹" }, + { "vzigzag", "⦚" }, + { "weierp", "℘" }, + { "apE", "⩰" }, + { "ape", "≊" }, + { "apid", "≋" }, + { "asymp", "≈" }, + { "Barv", "⫧" }, + { "bcong", "≌" }, + { "bepsi", "϶" }, + { "bowtie", "⋈" }, + { "bsim", "∽" }, + { "bsime", "⋍" }, + { "bsolhsub", "\⊂" }, + { "bump", "≎" }, + { "bumpE", "⪮" }, + { "bumpe", "≏" }, + { "cire", "≗" }, + { "Colon", "∷" }, + { "Colone", "⩴" }, + { "colone", "≔" }, + { "congdot", "⩭" }, + { "csub", "⫏" }, + { "csube", "⫑" }, + { "csup", "⫐" }, + { "csupe", "⫒" }, + { "cuepr", "⋞" }, + { "cuesc", "⋟" }, + { "Dashv", "⫤" }, + { "dashv", "⊣" }, + { "easter", "⩮" }, + { "ecir", "≖" }, + { "ecolon", "≕" }, + { "eDDot", "⩷" }, + { "eDot", "≑" }, + { "efDot", "≒" }, + { "eg", "⪚" }, + { "egs", "⪖" }, + { "egsdot", "⪘" }, + { "el", "⪙" }, + { "els", "⪕" }, + { "elsdot", "⪗" }, + { "equest", "≟" }, + { "equivDD", "⩸" }, + { "erDot", "≓" }, + { "esdot", "≐" }, + { "Esim", "⩳" }, + { "esim", "≂" }, + { "fork", "⋔" }, + { "forkv", "⫙" }, + { "frown", "⌢" }, + { "gap", "⪆" }, + { "gE", "≧" }, + { "gEl", "⪌" }, + { "gel", "⋛" }, + { "ges", "⩾" }, + { "gescc", "⪩" }, + { "gesdot", "⪀" }, + { "gesdoto", "⪂" }, + { "gesdotol", "⪄" }, + { "gesl", "⋛︀" }, + { "gesles", "⪔" }, + { "Gg", "⋙" }, + { "gl", "≷" }, + { "gla", "⪥" }, + { "glE", "⪒" }, + { "glj", "⪤" }, + { "gsim", "≳" }, + { "gsime", "⪎" }, + { "gsiml", "⪐" }, + { "Gt", "≫" }, + { "gtcc", "⪧" }, + { "gtcir", "⩺" }, + { "gtdot", "⋗" }, + { "gtquest", "⩼" }, + { "gtrarr", "⥸" }, + { "homtht", "∻" }, + { "lap", "⪅" }, + { "lat", "⪫" }, + { "late", "⪭" }, + { "lates", "⪭︀" }, + { "lE", "≦" }, + { "lEg", "⪋" }, + { "leg", "⋚" }, + { "les", "⩽" }, + { "lescc", "⪨" }, + { "lesdot", "⩿" }, + { "lesdoto", "⪁" }, + { "lesdotor", "⪃" }, + { "lesg", "⋚︀" }, + { "lesges", "⪓" }, + { "lg", "≶" }, + { "lgE", "⪑" }, + { "Ll", "⋘" }, + { "lsim", "≲" }, + { "lsime", "⪍" }, + { "lsimg", "⪏" }, + { "Lt", "≪" }, + { "ltcc", "⪦" }, + { "ltcir", "⩹" }, + { "ltdot", "⋖" }, + { "ltlarr", "⥶" }, + { "ltquest", "⩻" }, + { "ltrie", "⊴" }, + { "mcomma", "⨩" }, + { "mDDot", "∺" }, + { "mid", "∣" }, + { "mlcp", "⫛" }, + { "models", "⊧" }, + { "mstpos", "∾" }, + { "Pr", "⪻" }, + { "pr", "≺" }, + { "prap", "⪷" }, + { "prcue", "≼" }, + { "prE", "⪳" }, + { "pre", "⪯" }, + { "prsim", "≾" }, + { "prurel", "⊰" }, + { "ratio", "∶" }, + { "rtrie", "⊵" }, + { "rtriltri", "⧎" }, + { "Sc", "⪼" }, + { "sc", "≻" }, + { "scap", "⪸" }, + { "sccue", "≽" }, + { "scE", "⪴" }, + { "sce", "⪰" }, + { "scsim", "≿" }, + { "sdote", "⩦" }, + { "simg", "⪞" }, + { "simgE", "⪠" }, + { "siml", "⪝" }, + { "simlE", "⪟" }, + { "smid", "∣" }, + { "smile", "⌣" }, + { "smt", "⪪" }, + { "smte", "⪬" }, + { "smtes", "⪬︀" }, + { "spar", "∥" }, + { "sqsub", "⊏" }, + { "sqsube", "⊑" }, + { "sqsup", "⊐" }, + { "sqsupe", "⊒" }, + { "Sub", "⋐" }, + { "subE", "⫅" }, + { "subedot", "⫃" }, + { "submult", "⫁" }, + { "subplus", "⪿" }, + { "subrarr", "⥹" }, + { "subsim", "⫇" }, + { "subsub", "⫕" }, + { "subsup", "⫓" }, + { "Sup", "⋑" }, + { "supdsub", "⫘" }, + { "supE", "⫆" }, + { "supedot", "⫄" }, + { "suphsol", "⊅" }, + { "suphsub", "⫗" }, + { "suplarr", "⥻" }, + { "supmult", "⫂" }, + { "supplus", "⫀" }, + { "supsim", "⫈" }, + { "supsub", "⫔" }, + { "supsup", "⫖" }, + { "thkap", "≈" }, + { "topfork", "⫚" }, + { "trie", "≜" }, + { "twixt", "≬" }, + { "Vbar", "⫫" }, + { "vBar", "⫨" }, + { "vBarv", "⫩" }, + { "VDash", "⊫" }, + { "Vdash", "⊩" }, + { "vDash", "⊨" }, + { "vdash", "⊢" }, + { "Vdashl", "⫦" }, + { "vltri", "⊲" }, + { "vprop", "∝" }, + { "vrtri", "⊳" }, + { "Vvdash", "⊪" }, + { "alpha", "α" }, + { "beta", "β" }, + { "chi", "χ" }, + { "Delta", "Δ" }, + { "delta", "δ" }, + { "epsi", "ε" }, + { "epsiv", "ɛ" }, + { "eta", "η" }, + { "Gamma", "Γ" }, + { "gamma", "γ" }, + { "Gammad", "Ϝ" }, + { "gammad", "ϝ" }, + { "iota", "ι" }, + { "kappa", "κ" }, + { "kappav", "ϰ" }, + { "Lambda", "Λ" }, + { "lambda", "λ" }, + { "mu", "μ" }, + { "nu", "ν" }, + { "Omega", "Ω" }, + { "omega", "ω" }, + { "Phi", "Φ" }, + { "phi", "ϕ" }, + { "phiv", "φ" }, + { "Pi", "Π" }, + { "pi", "π" }, + { "piv", "ϖ" }, + { "Psi", "Ψ" }, + { "psi", "ψ" }, + { "rho", "ρ" }, + { "rhov", "ϱ" }, + { "Sigma", "Σ" }, + { "sigma", "σ" }, + { "sigmav", "ς" }, + { "tau", "τ" }, + { "Theta", "Θ" }, + { "theta", "θ" }, + { "thetav", "ϑ" }, + { "Upsi", "ϒ" }, + { "upsi", "υ" }, + { "Xi", "Ξ" }, + { "xi", "ξ" }, + { "zeta", "ζ" }, + { "Cfr", "ℭ" }, + { "Hfr", "ℌ" }, + { "Ifr", "ℑ" }, + { "Rfr", "ℜ" }, + { "Zfr", "ℨ" }, + { "Copf", "ℂ" }, + { "Hopf", "ℍ" }, + { "Nopf", "ℕ" }, + { "Popf", "ℙ" }, + { "Qopf", "ℚ" }, + { "Ropf", "ℝ" }, + { "Zopf", "ℤ" }, + { "Bscr", "ℬ" }, + { "Escr", "ℰ" }, + { "escr", "ℯ" }, + { "Fscr", "ℱ" }, + { "gscr", "ℊ" }, + { "Hscr", "ℋ" }, + { "Iscr", "ℐ" }, + { "Lscr", "ℒ" }, + { "Mscr", "ℳ" }, + { "oscr", "ℴ" }, + { "pscr", "𝓅" }, + { "Rscr", "ℛ" }, + { "acd", "∿" }, + { "aleph", "ℵ" }, + { "And", "⩓" }, + { "and", "∧" }, + { "andand", "⩕" }, + { "andd", "⩜" }, + { "andslope", "⩘" }, + { "andv", "⩚" }, + { "angrt", "∟" }, + { "angsph", "∢" }, + { "angst", "Å" }, + { "ap", "≈" }, + { "apacir", "⩯" }, + { "awconint", "∳" }, + { "awint", "⨑" }, + { "becaus", "∵" }, + { "bernou", "ℬ" }, + { "bne", "=⃥" }, + { "bnequiv", "≡⃥" }, + { "bNot", "⫭" }, + { "bnot", "⌐" }, + { "bottom", "⊥" }, + { "cap", "∩" }, + { "Cconint", "∰" }, + { "cirfnint", "⨐" }, + { "compfn", "∘" }, + { "cong", "≅" }, + { "Conint", "∯" }, + { "conint", "∮" }, + { "ctdot", "⋯" }, + { "cup", "∪" }, + { "cwconint", "∲" }, + { "cwint", "∱" }, + { "cylcty", "⌭" }, + { "disin", "⋲" }, + { "Dot", "¨" }, + { "DotDot", "⃜" }, + { "dsol", "⧶" }, + { "dtdot", "⋱" }, + { "dwangle", "⦦" }, + { "epar", "⋕" }, + { "eparsl", "⧣" }, + { "equiv", "≡" }, + { "eqvparsl", "⧥" }, + { "exist", "∃" }, + { "fnof", "ƒ" }, + { "forall", "∀" }, + { "fpartint", "⨍" }, + { "ge", "≥" }, + { "hamilt", "ℋ" }, + { "iff", "⇔" }, + { "iinfin", "⧜" }, + { "infin", "∞" }, + { "Int", "∬" }, + { "int", "∫" }, + { "intlarhk", "⨗" }, + { "isin", "∈" }, + { "isindot", "⋵" }, + { "isinE", "⋹" }, + { "isins", "⋴" }, + { "isinsv", "⋳" }, + { "isinv", "∈" }, + { "lagran", "ℒ" }, + { "Lang", "《" }, + { "lang", "〈" }, + { "lArr", "⇐" }, + { "lbbrk", "〔" }, + { "le", "≤" }, + { "loang", "〘" }, + { "lobrk", "〚" }, + { "lopar", "⦅" }, + { "lowast", "∗" }, + { "minus", "−" }, + { "mnplus", "∓" }, + { "nabla", "∇" }, + { "ne", "≠" }, + { "nedot", "≐̸" }, + { "nhpar", "⫲" }, + { "ni", "∋" }, + { "nis", "⋼" }, + { "nisd", "⋺" }, + { "niv", "∋" }, + { "Not", "⫬" }, + { "notin", "∉" }, + { "notindot", "⋵̸" }, + { "notinva", "∉" }, + { "notinvb", "⋷" }, + { "notinvc", "⋶" }, + { "notni", "∌" }, + { "notniva", "∌" }, + { "notnivb", "⋾" }, + { "notnivc", "⋽" }, + { "nparsl", "⫽⃥" }, + { "npart", "∂̸" }, + { "npolint", "⨔" }, + { "nvinfin", "⧞" }, + { "olcross", "⦻" }, + { "Or", "⩔" }, + { "or", "∨" }, + { "ord", "⩝" }, + { "order", "ℴ" }, + { "oror", "⩖" }, + { "orslope", "⩗" }, + { "orv", "⩛" }, + { "par", "∥" }, + { "parsl", "⫽" }, + { "part", "∂" }, + { "permil", "‰" }, + { "perp", "⊥" }, + { "pertenk", "‱" }, + { "phmmat", "ℳ" }, + { "pointint", "⨕" }, + { "Prime", "″" }, + { "prime", "′" }, + { "profalar", "⌮" }, + { "profline", "⌒" }, + { "profsurf", "⌓" }, + { "prop", "∝" }, + { "qint", "⨌" }, + { "qprime", "⁗" }, + { "quatint", "⨖" }, + { "radic", "√" }, + { "Rang", "》" }, + { "rang", "〉" }, + { "rArr", "⇒" }, + { "rbbrk", "〕" }, + { "roang", "〙" }, + { "robrk", "〛" }, + { "ropar", "⦆" }, + { "rppolint", "⨒" }, + { "scpolint", "⨓" }, + { "sim", "∼" }, + { "simdot", "⩪" }, + { "sime", "≃" }, + { "smeparsl", "⧤" }, + { "square", "□" }, + { "squarf", "▪" }, + { "sub", "⊂" }, + { "sube", "⊆" }, + { "sup", "⊃" }, + { "supe", "⊇" }, + { "tdot", "⃛" }, + { "there4", "∴" }, + { "tint", "∭" }, + { "top", "⊤" }, + { "topbot", "⌶" }, + { "topcir", "⫱" }, + { "tprime", "‴" }, + { "utdot", "⋰" }, + { "uwangle", "⦧" }, + { "vangrt", "⦜" }, + { "veeeq", "≚" }, + { "Verbar", "‖" }, + { "wedgeq", "≙" }, + { "xnis", "⋻" }, + { "boxDL", "╗" }, + { "boxDl", "╖" }, + { "boxdL", "╕" }, + { "boxdl", "┐" }, + { "boxDR", "╔" }, + { "boxDr", "╓" }, + { "boxdR", "╒" }, + { "boxdr", "┌" }, + { "boxH", "═" }, + { "boxh", "─" }, + { "boxHD", "╦" }, + { "boxHd", "╤" }, + { "boxhD", "╥" }, + { "boxhd", "┬" }, + { "boxHU", "╩" }, + { "boxHu", "╧" }, + { "boxhU", "╨" }, + { "boxhu", "┴" }, + { "boxUL", "╝" }, + { "boxUl", "╜" }, + { "boxuL", "╛" }, + { "boxul", "┘" }, + { "boxUR", "╚" }, + { "boxUr", "╙" }, + { "boxuR", "╘" }, + { "boxur", "└" }, + { "boxV", "║" }, + { "boxv", "│" }, + { "boxVH", "╬" }, + { "boxVh", "╫" }, + { "boxvH", "╪" }, + { "boxvh", "┼" }, + { "boxVL", "╣" }, + { "boxVl", "╢" }, + { "boxvL", "╡" }, + { "boxvl", "┤" }, + { "boxVR", "╠" }, + { "boxVr", "╟" }, + { "boxvR", "╞" }, + { "boxvr", "├" }, + { "Acy", "А" }, + { "acy", "а" }, + { "Bcy", "Б" }, + { "bcy", "б" }, + { "CHcy", "Ч" }, + { "chcy", "ч" }, + { "Dcy", "Д" }, + { "dcy", "д" }, + { "Ecy", "Э" }, + { "ecy", "э" }, + { "Fcy", "Ф" }, + { "fcy", "ф" }, + { "Gcy", "Г" }, + { "gcy", "г" }, + { "HARDcy", "Ъ" }, + { "hardcy", "ъ" }, + { "Icy", "И" }, + { "icy", "и" }, + { "IEcy", "Е" }, + { "iecy", "е" }, + { "IOcy", "Ё" }, + { "iocy", "ё" }, + { "Jcy", "Й" }, + { "jcy", "й" }, + { "Kcy", "К" }, + { "kcy", "к" }, + { "KHcy", "Х" }, + { "khcy", "х" }, + { "Lcy", "Л" }, + { "lcy", "л" }, + { "Mcy", "М" }, + { "mcy", "м" }, + { "Ncy", "Н" }, + { "ncy", "н" }, + { "numero", "№" }, + { "Ocy", "О" }, + { "ocy", "о" }, + { "Pcy", "П" }, + { "pcy", "п" }, + { "Rcy", "Р" }, + { "rcy", "р" }, + { "Scy", "С" }, + { "scy", "с" }, + { "SHCHcy", "Щ" }, + { "shchcy", "щ" }, + { "SHcy", "Ш" }, + { "shcy", "ш" }, + { "SOFTcy", "Ь" }, + { "softcy", "ь" }, + { "Tcy", "Т" }, + { "tcy", "т" }, + { "TScy", "Ц" }, + { "tscy", "ц" }, + { "Ucy", "У" }, + { "ucy", "у" }, + { "Vcy", "В" }, + { "vcy", "в" }, + { "YAcy", "Я" }, + { "yacy", "я" }, + { "Ycy", "Ы" }, + { "ycy", "ы" }, + { "YUcy", "Ю" }, + { "yucy", "ю" }, + { "Zcy", "З" }, + { "zcy", "з" }, + { "ZHcy", "Ж" }, + { "zhcy", "ж" }, + { "DJcy", "Ђ" }, + { "djcy", "ђ" }, + { "DScy", "Ѕ" }, + { "dscy", "ѕ" }, + { "DZcy", "Џ" }, + { "dzcy", "џ" }, + { "GJcy", "Ѓ" }, + { "gjcy", "ѓ" }, + { "Iukcy", "І" }, + { "iukcy", "і" }, + { "Jsercy", "Ј" }, + { "jsercy", "ј" }, + { "Jukcy", "Є" }, + { "jukcy", "є" }, + { "KJcy", "Ќ" }, + { "kjcy", "ќ" }, + { "LJcy", "Љ" }, + { "ljcy", "љ" }, + { "NJcy", "Њ" }, + { "njcy", "њ" }, + { "TSHcy", "Ћ" }, + { "tshcy", "ћ" }, + { "Ubrcy", "Ў" }, + { "ubrcy", "ў" }, + { "YIcy", "Ї" }, + { "yicy", "ї" }, + { "acute", "´" }, + { "breve", "˘" }, + { "caron", "ˇ" }, + { "cedil", "¸" }, + { "circ", "ˆ" }, + { "dblac", "˝" }, + { "die", "¨" }, + { "dot", "˙" }, + { "grave", "`" }, + { "macr", "¯" }, + { "ogon", "˛" }, + { "ring", "˚" }, + { "tilde", "˜" }, + { "uml", "¨" }, + { "Aacute", "Á" }, + { "aacute", "á" }, + { "Acirc", "Â" }, + { "acirc", "â" }, + { "AElig", "Æ" }, + { "aelig", "æ" }, + { "Agrave", "À" }, + { "agrave", "à" }, + { "Aring", "Å" }, + { "aring", "å" }, + { "Atilde", "Ã" }, + { "atilde", "ã" }, + { "Auml", "Ä" }, + { "auml", "ä" }, + { "Ccedil", "Ç" }, + { "ccedil", "ç" }, + { "Eacute", "É" }, + { "eacute", "é" }, + { "Ecirc", "Ê" }, + { "ecirc", "ê" }, + { "Egrave", "È" }, + { "egrave", "è" }, + { "ETH", "Ð" }, + { "eth", "ð" }, + { "Euml", "Ë" }, + { "euml", "ë" }, + { "Iacute", "Í" }, + { "iacute", "í" }, + { "Icirc", "Î" }, + { "icirc", "î" }, + { "Igrave", "Ì" }, + { "igrave", "ì" }, + { "Iuml", "Ï" }, + { "iuml", "ï" }, + { "Ntilde", "Ñ" }, + { "ntilde", "ñ" }, + { "Oacute", "Ó" }, + { "oacute", "ó" }, + { "Ocirc", "Ô" }, + { "ocirc", "ô" }, + { "Ograve", "Ò" }, + { "ograve", "ò" }, + { "Oslash", "Ø" }, + { "oslash", "ø" }, + { "Otilde", "Õ" }, + { "otilde", "õ" }, + { "Ouml", "Ö" }, + { "ouml", "ö" }, + { "szlig", "ß" }, + { "THORN", "Þ" }, + { "thorn", "þ" }, + { "Uacute", "Ú" }, + { "uacute", "ú" }, + { "Ucirc", "Û" }, + { "ucirc", "û" }, + { "Ugrave", "Ù" }, + { "ugrave", "ù" }, + { "Uuml", "Ü" }, + { "uuml", "ü" }, + { "Yacute", "Ý" }, + { "yacute", "ý" }, + { "yuml", "ÿ" }, + { "Abreve", "Ă" }, + { "abreve", "ă" }, + { "Amacr", "Ā" }, + { "amacr", "ā" }, + { "Aogon", "Ą" }, + { "aogon", "ą" }, + { "Cacute", "Ć" }, + { "cacute", "ć" }, + { "Ccaron", "Č" }, + { "ccaron", "č" }, + { "Ccirc", "Ĉ" }, + { "ccirc", "ĉ" }, + { "Cdot", "Ċ" }, + { "cdot", "ċ" }, + { "Dcaron", "Ď" }, + { "dcaron", "ď" }, + { "Dstrok", "Đ" }, + { "dstrok", "đ" }, + { "Ecaron", "Ě" }, + { "ecaron", "ě" }, + { "Edot", "Ė" }, + { "edot", "ė" }, + { "Emacr", "Ē" }, + { "emacr", "ē" }, + { "ENG", "Ŋ" }, + { "eng", "ŋ" }, + { "Eogon", "Ę" }, + { "eogon", "ę" }, + { "gacute", "ǵ" }, + { "Gbreve", "Ğ" }, + { "gbreve", "ğ" }, + { "Gcedil", "Ģ" }, + { "Gcirc", "Ĝ" }, + { "gcirc", "ĝ" }, + { "Gdot", "Ġ" }, + { "gdot", "ġ" }, + { "Hcirc", "Ĥ" }, + { "hcirc", "ĥ" }, + { "Hstrok", "Ħ" }, + { "hstrok", "ħ" }, + { "Idot", "İ" }, + { "IJlig", "IJ" }, + { "ijlig", "ij" }, + { "Imacr", "Ī" }, + { "imacr", "ī" }, + { "inodot", "ı" }, + { "Iogon", "Į" }, + { "iogon", "į" }, + { "Itilde", "Ĩ" }, + { "itilde", "ĩ" }, + { "Jcirc", "Ĵ" }, + { "jcirc", "ĵ" }, + { "Kcedil", "Ķ" }, + { "kcedil", "ķ" }, + { "kgreen", "ĸ" }, + { "Lacute", "Ĺ" }, + { "lacute", "ĺ" }, + { "Lcaron", "Ľ" }, + { "lcaron", "ľ" }, + { "Lcedil", "Ļ" }, + { "lcedil", "ļ" }, + { "Lmidot", "Ŀ" }, + { "lmidot", "ŀ" }, + { "Lstrok", "Ł" }, + { "lstrok", "ł" }, + { "Nacute", "Ń" }, + { "nacute", "ń" }, + { "napos", "ʼn" }, + { "Ncaron", "Ň" }, + { "ncaron", "ň" }, + { "Ncedil", "Ņ" }, + { "ncedil", "ņ" }, + { "Odblac", "Ő" }, + { "odblac", "ő" }, + { "OElig", "Œ" }, + { "oelig", "œ" }, + { "Omacr", "Ō" }, + { "omacr", "ō" }, + { "Racute", "Ŕ" }, + { "racute", "ŕ" }, + { "Rcaron", "Ř" }, + { "rcaron", "ř" }, + { "Rcedil", "Ŗ" }, + { "rcedil", "ŗ" }, + { "Sacute", "Ś" }, + { "sacute", "ś" }, + { "Scaron", "Š" }, + { "scaron", "š" }, + { "Scedil", "Ş" }, + { "scedil", "ş" }, + { "Scirc", "Ŝ" }, + { "scirc", "ŝ" }, + { "Tcaron", "Ť" }, + { "tcaron", "ť" }, + { "Tcedil", "Ţ" }, + { "tcedil", "ţ" }, + { "Tstrok", "Ŧ" }, + { "tstrok", "ŧ" }, + { "Ubreve", "Ŭ" }, + { "ubreve", "ŭ" }, + { "Udblac", "Ű" }, + { "udblac", "ű" }, + { "Umacr", "Ū" }, + { "umacr", "ū" }, + { "Uogon", "Ų" }, + { "uogon", "ų" }, + { "Uring", "Ů" }, + { "uring", "ů" }, + { "Utilde", "Ũ" }, + { "utilde", "ũ" }, + { "Wcirc", "Ŵ" }, + { "wcirc", "ŵ" }, + { "Ycirc", "Ŷ" }, + { "ycirc", "ŷ" }, + { "Yuml", "Ÿ" }, + { "Zacute", "Ź" }, + { "zacute", "ź" }, + { "Zcaron", "Ž" }, + { "zcaron", "ž" }, + { "Zdot", "Ż" }, + { "zdot", "ż" }, + { "apos", "'" }, + { "ast", "*" }, + { "brvbar", "¦" }, + { "bsol", "\" }, + { "cent", "¢" }, + { "colon", ":" }, + { "comma", "," }, + { "commat", "@" }, + { "copy", "©" }, + { "curren", "¤" }, + { "darr", "↓" }, + { "deg", "°" }, + { "divide", "÷" }, + { "dollar", "$" }, + { "equals", "=" }, + { "excl", "!" }, + { "frac12", "½" }, + { "frac14", "¼" }, + { "frac18", "⅛" }, + { "frac34", "¾" }, + { "frac38", "⅜" }, + { "frac58", "⅝" }, + { "frac78", "⅞" }, + { "gt", ">" }, + { "half", "½" }, + { "horbar", "―" }, + { "hyphen", "‐" }, + { "iexcl", "¡" }, + { "iquest", "¿" }, + { "laquo", "«" }, + { "larr", "←" }, + { "lcub", "{" }, + { "ldquo", "“" }, + { "lowbar", "_" }, + { "lpar", "(" }, + { "lsqb", "[" }, + { "lsquo", "‘" }, + { "lt", "<" }, + { "micro", "µ" }, + { "middot", "·" }, + { "nbsp", " " }, + { "not", "¬" }, + { "num", "#" }, + { "ohm", "Ω" }, + { "ordf", "ª" }, + { "ordm", "º" }, + { "para", "¶" }, + { "percnt", "%" }, + { "period", "." }, + { "plus", "+" }, + { "plusmn", "±" }, + { "pound", "£" }, + { "quest", "?" }, + { "quot", """ }, + { "raquo", "»" }, + { "rarr", "→" }, + { "rcub", "}" }, + { "rdquo", "”" }, + { "reg", "®" }, + { "rpar", ")" }, + { "rsqb", "]" }, + { "rsquo", "’" }, + { "sect", "§" }, + { "semi", ";" }, + { "shy", "­" }, + { "sol", "/" }, + { "sung", "♪" }, + { "sup1", "¹" }, + { "sup2", "²" }, + { "sup3", "³" }, + { "times", "×" }, + { "trade", "™" }, + { "uarr", "↑" }, + { "verbar", "|" }, + { "yen", "¥" }, + { "blank", "␣" }, + { "blk12", "▒" }, + { "blk14", "░" }, + { "blk34", "▓" }, + { "block", "█" }, + { "bull", "•" }, + { "caret", "⁁" }, + { "check", "✓" }, + { "cir", "○" }, + { "clubs", "♣" }, + { "copysr", "℗" }, + { "cross", "✗" }, + { "Dagger", "‡" }, + { "dagger", "†" }, + { "dash", "‐" }, + { "diams", "♦" }, + { "dlcrop", "⌍" }, + { "drcrop", "⌌" }, + { "dtri", "▿" }, + { "dtrif", "▾" }, + { "emsp", " " }, + { "emsp13", " " }, + { "emsp14", " " }, + { "ensp", " " }, + { "female", "♀" }, + { "ffilig", "ffi" }, + { "fflig", "ff" }, + { "ffllig", "ffl" }, + { "filig", "fi" }, + { "flat", "♭" }, + { "fllig", "fl" }, + { "frac13", "⅓" }, + { "frac15", "⅕" }, + { "frac16", "⅙" }, + { "frac23", "⅔" }, + { "frac25", "⅖" }, + { "frac35", "⅗" }, + { "frac45", "⅘" }, + { "frac56", "⅚" }, + { "hairsp", " " }, + { "hearts", "♥" }, + { "hellip", "…" }, + { "hybull", "⁃" }, + { "incare", "℅" }, + { "ldquor", "„" }, + { "lhblk", "▄" }, + { "loz", "◊" }, + { "lozf", "⧫" }, + { "lsquor", "‚" }, + { "ltri", "◃" }, + { "ltrif", "◂" }, + { "male", "♂" }, + { "malt", "✠" }, + { "marker", "▮" }, + { "mdash", "—" }, + { "mldr", "…" }, + { "natur", "♮" }, + { "ndash", "–" }, + { "nldr", "‥" }, + { "numsp", " " }, + { "phone", "☎" }, + { "puncsp", " " }, + { "rdquor", "”" }, + { "rect", "▭" }, + { "rsquor", "’" }, + { "rtri", "▹" }, + { "rtrif", "▸" }, + { "rx", "℞" }, + { "sext", "✶" }, + { "sharp", "♯" }, + { "spades", "♠" }, + { "squ", "□" }, + { "squf", "▪" }, + { "star", "☆" }, + { "starf", "★" }, + { "target", "⌖" }, + { "telrec", "⌕" }, + { "thinsp", " " }, + { "uhblk", "▀" }, + { "ulcrop", "⌏" }, + { "urcrop", "⌎" }, + { "utri", "▵" }, + { "utrif", "▴" }, + { "vellip", "⋮" }, + { "af", "⁡" }, + { "asympeq", "≍" }, + { "Cross", "⨯" }, + { "DD", "ⅅ" }, + { "dd", "ⅆ" }, + { "DownArrowBar", "⤓" }, + { "DownBreve", "̑" }, + { "DownLeftRightVector", "⥐" }, + { "DownLeftTeeVector", "⥞" }, + { "DownLeftVectorBar", "⥖" }, + { "DownRightTeeVector", "⥟" }, + { "DownRightVectorBar", "⥗" }, + { "ee", "ⅇ" }, + { "EmptySmallSquare", "◻" }, + { "EmptyVerySmallSquare", "▫" }, + { "Equal", "⩵" }, + { "FilledSmallSquare", "◼" }, + { "FilledVerySmallSquare", "▪" }, + { "GreaterGreater", "⪢" }, + { "Hat", "^" }, + { "HorizontalLine", "─" }, + { "ic", "⁣" }, + { "ii", "ⅈ" }, + { "it", "⁢" }, + { "larrb", "⇤" }, + { "LeftDownTeeVector", "⥡" }, + { "LeftDownVectorBar", "⥙" }, + { "LeftRightVector", "⥎" }, + { "LeftTeeVector", "⥚" }, + { "LeftTriangleBar", "⧏" }, + { "LeftUpDownVector", "⥑" }, + { "LeftUpTeeVector", "⥠" }, + { "LeftUpVectorBar", "⥘" }, + { "LeftVectorBar", "⥒" }, + { "LessLess", "⪡" }, + { "mapstodown", "↧" }, + { "mapstoleft", "↤" }, + { "mapstoup", "↥" }, + { "MediumSpace", " " }, + { "nbump", "≎̸" }, + { "nbumpe", "≏̸" }, + { "nesim", "≂̸" }, + { "NewLine", " " }, + { "NoBreak", "⁠" }, + { "NotCupCap", "≭" }, + { "NotHumpEqual", "≏̸" }, + { "NotLeftTriangleBar", "⧏̸" }, + { "NotNestedGreaterGreater", "⪢̸" }, + { "NotNestedLessLess", "⪡̸" }, + { "NotRightTriangleBar", "⧐̸" }, + { "NotSquareSubset", "⊏̸" }, + { "NotSquareSuperset", "⊐̸" }, + { "NotSucceedsTilde", "≿̸" }, + { "OverBar", "¯" }, + { "OverBrace", "︷" }, + { "OverBracket", "⎴" }, + { "OverParenthesis", "︵" }, + { "planckh", "ℎ" }, + { "Product", "∏" }, + { "rarrb", "⇥" }, + { "RightDownTeeVector", "⥝" }, + { "RightDownVectorBar", "⥕" }, + { "RightTeeVector", "⥛" }, + { "RightTriangleBar", "⧐" }, + { "RightUpDownVector", "⥏" }, + { "RightUpTeeVector", "⥜" }, + { "RightUpVectorBar", "⥔" }, + { "RightVectorBar", "⥓" }, + { "RoundImplies", "⥰" }, + { "RuleDelayed", "⧴" }, + { "Tab", " " }, + { "ThickSpace", "   " }, + { "UnderBar", "̲" }, + { "UnderBrace", "︸" }, + { "UnderBracket", "⎵" }, + { "UnderParenthesis", "︶" }, + { "UpArrowBar", "⤒" }, + { "Upsilon", "Υ" }, + { "VerticalLine", "|" }, + { "VerticalSeparator", "❘" }, + { "ZeroWidthSpace", "​" }, + { "angle", "∠" }, + { "ApplyFunction", "⁡" }, + { "approx", "≈" }, + { "approxeq", "≊" }, + { "Assign", "≔" }, + { "backcong", "≌" }, + { "backepsilon", "϶" }, + { "backprime", "‵" }, + { "backsim", "∽" }, + { "backsimeq", "⋍" }, + { "Backslash", "∖" }, + { "barwedge", "⌅" }, + { "Because", "∵" }, + { "because", "∵" }, + { "Bernoullis", "ℬ" }, + { "between", "≬" }, + { "bigcap", "⋂" }, + { "bigcirc", "◯" }, + { "bigcup", "⋃" }, + { "bigodot", "⨀" }, + { "bigoplus", "⨁" }, + { "bigotimes", "⨂" }, + { "bigsqcup", "⨆" }, + { "bigstar", "★" }, + { "bigtriangledown", "▽" }, + { "bigtriangleup", "△" }, + { "biguplus", "⨄" }, + { "bigvee", "⋁" }, + { "bigwedge", "⋀" }, + { "bkarow", "⤍" }, + { "blacklozenge", "⧫" }, + { "blacksquare", "▪" }, + { "blacktriangle", "▴" }, + { "blacktriangledown", "▾" }, + { "blacktriangleleft", "◂" }, + { "blacktriangleright", "▸" }, + { "bot", "⊥" }, + { "boxminus", "⊟" }, + { "boxplus", "⊞" }, + { "boxtimes", "⊠" }, + { "Breve", "˘" }, + { "bullet", "•" }, + { "Bumpeq", "≎" }, + { "bumpeq", "≏" }, + { "CapitalDifferentialD", "ⅅ" }, + { "Cayleys", "ℭ" }, + { "Cedilla", "¸" }, + { "CenterDot", "·" }, + { "centerdot", "·" }, + { "checkmark", "✓" }, + { "circeq", "≗" }, + { "circlearrowleft", "↺" }, + { "circlearrowright", "↻" }, + { "circledast", "⊛" }, + { "circledcirc", "⊚" }, + { "circleddash", "⊝" }, + { "CircleDot", "⊙" }, + { "circledR", "®" }, + { "circledS", "Ⓢ" }, + { "CircleMinus", "⊖" }, + { "CirclePlus", "⊕" }, + { "CircleTimes", "⊗" }, + { "ClockwiseContourIntegral", "∲" }, + { "CloseCurlyDoubleQuote", "”" }, + { "CloseCurlyQuote", "’" }, + { "clubsuit", "♣" }, + { "coloneq", "≔" }, + { "complement", "∁" }, + { "complexes", "ℂ" }, + { "Congruent", "≡" }, + { "ContourIntegral", "∮" }, + { "Coproduct", "∐" }, + { "CounterClockwiseContourIntegral", "∳" }, + { "CupCap", "≍" }, + { "curlyeqprec", "⋞" }, + { "curlyeqsucc", "⋟" }, + { "curlyvee", "⋎" }, + { "curlywedge", "⋏" }, + { "curvearrowleft", "↶" }, + { "curvearrowright", "↷" }, + { "dbkarow", "⤏" }, + { "ddagger", "‡" }, + { "ddotseq", "⩷" }, + { "Del", "∇" }, + { "DiacriticalAcute", "´" }, + { "DiacriticalDot", "˙" }, + { "DiacriticalDoubleAcute", "˝" }, + { "DiacriticalGrave", "`" }, + { "DiacriticalTilde", "˜" }, + { "Diamond", "⋄" }, + { "diamond", "⋄" }, + { "diamondsuit", "♦" }, + { "DifferentialD", "ⅆ" }, + { "digamma", "ϝ" }, + { "div", "÷" }, + { "divideontimes", "⋇" }, + { "doteq", "≐" }, + { "doteqdot", "≑" }, + { "DotEqual", "≐" }, + { "dotminus", "∸" }, + { "dotplus", "∔" }, + { "dotsquare", "⊡" }, + { "doublebarwedge", "⌆" }, + { "DoubleContourIntegral", "∯" }, + { "DoubleDot", "¨" }, + { "DoubleDownArrow", "⇓" }, + { "DoubleLeftArrow", "⇐" }, + { "DoubleLeftRightArrow", "⇔" }, + { "DoubleLeftTee", "⫤" }, + { "DoubleLongLeftArrow", "⟸" }, + { "DoubleLongLeftRightArrow", "⟺" }, + { "DoubleLongRightArrow", "⟹" }, + { "DoubleRightArrow", "⇒" }, + { "DoubleRightTee", "⊨" }, + { "DoubleUpArrow", "⇑" }, + { "DoubleUpDownArrow", "⇕" }, + { "DoubleVerticalBar", "∥" }, + { "DownArrow", "↓" }, + { "Downarrow", "⇓" }, + { "downarrow", "↓" }, + { "DownArrowUpArrow", "⇵" }, + { "downdownarrows", "⇊" }, + { "downharpoonleft", "⇃" }, + { "downharpoonright", "⇂" }, + { "DownLeftVector", "↽" }, + { "DownRightVector", "⇁" }, + { "DownTee", "⊤" }, + { "DownTeeArrow", "↧" }, + { "drbkarow", "⤐" }, + { "Element", "∈" }, + { "emptyset", "∅" }, + { "eqcirc", "≖" }, + { "eqcolon", "≕" }, + { "eqsim", "≂" }, + { "eqslantgtr", "⪖" }, + { "eqslantless", "⪕" }, + { "EqualTilde", "≂" }, + { "Equilibrium", "⇌" }, + { "Exists", "∃" }, + { "expectation", "ℰ" }, + { "ExponentialE", "ⅇ" }, + { "exponentiale", "ⅇ" }, + { "fallingdotseq", "≒" }, + { "ForAll", "∀" }, + { "Fouriertrf", "ℱ" }, + { "geq", "≥" }, + { "geqq", "≧" }, + { "geqslant", "⩾" }, + { "gg", "≫" }, + { "ggg", "⋙" }, + { "gnapprox", "⪊" }, + { "gneq", "⪈" }, + { "gneqq", "≩" }, + { "GreaterEqual", "≥" }, + { "GreaterEqualLess", "⋛" }, + { "GreaterFullEqual", "≧" }, + { "GreaterLess", "≷" }, + { "GreaterSlantEqual", "⩾" }, + { "GreaterTilde", "≳" }, + { "gtrapprox", "⪆" }, + { "gtrdot", "⋗" }, + { "gtreqless", "⋛" }, + { "gtreqqless", "⪌" }, + { "gtrless", "≷" }, + { "gtrsim", "≳" }, + { "gvertneqq", "≩︀" }, + { "Hacek", "ˇ" }, + { "hbar", "ℏ" }, + { "heartsuit", "♥" }, + { "HilbertSpace", "ℋ" }, + { "hksearow", "⤥" }, + { "hkswarow", "⤦" }, + { "hookleftarrow", "↩" }, + { "hookrightarrow", "↪" }, + { "hslash", "ℏ" }, + { "HumpDownHump", "≎" }, + { "HumpEqual", "≏" }, + { "iiiint", "⨌" }, + { "iiint", "∭" }, + { "Im", "ℑ" }, + { "ImaginaryI", "ⅈ" }, + { "imagline", "ℐ" }, + { "imagpart", "ℑ" }, + { "Implies", "⇒" }, + { "in", "∈" }, + { "integers", "ℤ" }, + { "Integral", "∫" }, + { "intercal", "⊺" }, + { "Intersection", "⋂" }, + { "intprod", "⨼" }, + { "InvisibleComma", "⁣" }, + { "InvisibleTimes", "⁢" }, + { "langle", "〈" }, + { "Laplacetrf", "ℒ" }, + { "lbrace", "{" }, + { "lbrack", "[" }, + { "LeftAngleBracket", "〈" }, + { "LeftArrow", "←" }, + { "Leftarrow", "⇐" }, + { "leftarrow", "←" }, + { "LeftArrowBar", "⇤" }, + { "LeftArrowRightArrow", "⇆" }, + { "leftarrowtail", "↢" }, + { "LeftCeiling", "⌈" }, + { "LeftDoubleBracket", "〚" }, + { "LeftDownVector", "⇃" }, + { "LeftFloor", "⌊" }, + { "leftharpoondown", "↽" }, + { "leftharpoonup", "↼" }, + { "leftleftarrows", "⇇" }, + { "LeftRightArrow", "↔" }, + { "Leftrightarrow", "⇔" }, + { "leftrightarrow", "↔" }, + { "leftrightarrows", "⇆" }, + { "leftrightharpoons", "⇋" }, + { "leftrightsquigarrow", "↭" }, + { "LeftTee", "⊣" }, + { "LeftTeeArrow", "↤" }, + { "leftthreetimes", "⋋" }, + { "LeftTriangle", "⊲" }, + { "LeftTriangleEqual", "⊴" }, + { "LeftUpVector", "↿" }, + { "LeftVector", "↼" }, + { "leq", "≤" }, + { "leqq", "≦" }, + { "leqslant", "⩽" }, + { "lessapprox", "⪅" }, + { "lessdot", "⋖" }, + { "lesseqgtr", "⋚" }, + { "lesseqqgtr", "⪋" }, + { "LessEqualGreater", "⋚" }, + { "LessFullEqual", "≦" }, + { "LessGreater", "≶" }, + { "lessgtr", "≶" }, + { "lesssim", "≲" }, + { "LessSlantEqual", "⩽" }, + { "LessTilde", "≲" }, + { "ll", "≪" }, + { "llcorner", "⌞" }, + { "Lleftarrow", "⇚" }, + { "lmoustache", "⎰" }, + { "lnapprox", "⪉" }, + { "lneq", "⪇" }, + { "lneqq", "≨" }, + { "LongLeftArrow", "⟵" }, + { "Longleftarrow", "⟸" }, + { "longleftarrow", "⟵" }, + { "LongLeftRightArrow", "⟷" }, + { "Longleftrightarrow", "⟺" }, + { "longleftrightarrow", "⟷" }, + { "longmapsto", "⟼" }, + { "LongRightArrow", "⟶" }, + { "Longrightarrow", "⟹" }, + { "longrightarrow", "⟶" }, + { "looparrowleft", "↫" }, + { "looparrowright", "↬" }, + { "LowerLeftArrow", "↙" }, + { "LowerRightArrow", "↘" }, + { "lozenge", "◊" }, + { "lrcorner", "⌟" }, + { "Lsh", "↰" }, + { "lvertneqq", "≨︀" }, + { "maltese", "✠" }, + { "mapsto", "↦" }, + { "measuredangle", "∡" }, + { "Mellintrf", "ℳ" }, + { "MinusPlus", "∓" }, + { "mp", "∓" }, + { "multimap", "⊸" }, + { "napprox", "≉" }, + { "natural", "♮" }, + { "naturals", "ℕ" }, + { "nearrow", "↗" }, + { "NegativeMediumSpace", "​" }, + { "NegativeThickSpace", "​" }, + { "NegativeThinSpace", "​" }, + { "NegativeVeryThinSpace", "​" }, + { "NestedGreaterGreater", "≫" }, + { "NestedLessLess", "≪" }, + { "nexists", "∄" }, + { "ngeq", "≱" }, + { "ngeqq", "≧̸" }, + { "ngeqslant", "⩾̸" }, + { "ngtr", "≯" }, + { "nLeftarrow", "⇍" }, + { "nleftarrow", "↚" }, + { "nLeftrightarrow", "⇎" }, + { "nleftrightarrow", "↮" }, + { "nleq", "≰" }, + { "nleqq", "≦̸" }, + { "nleqslant", "⩽̸" }, + { "nless", "≮" }, + { "NonBreakingSpace", " " }, + { "NotCongruent", "≢" }, + { "NotDoubleVerticalBar", "∦" }, + { "NotElement", "∉" }, + { "NotEqual", "≠" }, + { "NotEqualTilde", "≂̸" }, + { "NotExists", "∄" }, + { "NotGreater", "≯" }, + { "NotGreaterEqual", "≱" }, + { "NotGreaterFullEqual", "≦̸" }, + { "NotGreaterGreater", "≫̸" }, + { "NotGreaterLess", "≹" }, + { "NotGreaterSlantEqual", "⩾̸" }, + { "NotGreaterTilde", "≵" }, + { "NotHumpDownHump", "≎̸" }, + { "NotLeftTriangle", "⋪" }, + { "NotLeftTriangleEqual", "⋬" }, + { "NotLess", "≮" }, + { "NotLessEqual", "≰" }, + { "NotLessGreater", "≸" }, + { "NotLessLess", "≪̸" }, + { "NotLessSlantEqual", "⩽̸" }, + { "NotLessTilde", "≴" }, + { "NotPrecedes", "⊀" }, + { "NotPrecedesEqual", "⪯̸" }, + { "NotPrecedesSlantEqual", "⋠" }, + { "NotReverseElement", "∌" }, + { "NotRightTriangle", "⋫" }, + { "NotRightTriangleEqual", "⋭" }, + { "NotSquareSubsetEqual", "⋢" }, + { "NotSquareSupersetEqual", "⋣" }, + { "NotSubset", "⊂⃒" }, + { "NotSubsetEqual", "⊈" }, + { "NotSucceeds", "⊁" }, + { "NotSucceedsEqual", "⪰̸" }, + { "NotSucceedsSlantEqual", "⋡" }, + { "NotSuperset", "⊃⃒" }, + { "NotSupersetEqual", "⊉" }, + { "NotTilde", "≁" }, + { "NotTildeEqual", "≄" }, + { "NotTildeFullEqual", "≇" }, + { "NotTildeTilde", "≉" }, + { "NotVerticalBar", "∤" }, + { "nparallel", "∦" }, + { "nprec", "⊀" }, + { "npreceq", "⪯̸" }, + { "nRightarrow", "⇏" }, + { "nrightarrow", "↛" }, + { "nshortmid", "∤" }, + { "nshortparallel", "∦" }, + { "nsimeq", "≄" }, + { "nsubset", "⊂⃒" }, + { "nsubseteq", "⊈" }, + { "nsubseteqq", "⫅̸" }, + { "nsucc", "⊁" }, + { "nsucceq", "⪰̸" }, + { "nsupset", "⊃⃒" }, + { "nsupseteq", "⊉" }, + { "nsupseteqq", "⫆̸" }, + { "ntriangleleft", "⋪" }, + { "ntrianglelefteq", "⋬" }, + { "ntriangleright", "⋫" }, + { "ntrianglerighteq", "⋭" }, + { "nwarrow", "↖" }, + { "oint", "∮" }, + { "OpenCurlyDoubleQuote", "“" }, + { "OpenCurlyQuote", "‘" }, + { "orderof", "ℴ" }, + { "parallel", "∥" }, + { "PartialD", "∂" }, + { "pitchfork", "⋔" }, + { "PlusMinus", "±" }, + { "pm", "±" }, + { "Poincareplane", "ℌ" }, + { "prec", "≺" }, + { "precapprox", "⪷" }, + { "preccurlyeq", "≼" }, + { "Precedes", "≺" }, + { "PrecedesEqual", "⪯" }, + { "PrecedesSlantEqual", "≼" }, + { "PrecedesTilde", "≾" }, + { "preceq", "⪯" }, + { "precnapprox", "⪹" }, + { "precneqq", "⪵" }, + { "precnsim", "⋨" }, + { "precsim", "≾" }, + { "primes", "ℙ" }, + { "Proportion", "∷" }, + { "Proportional", "∝" }, + { "propto", "∝" }, + { "quaternions", "ℍ" }, + { "questeq", "≟" }, + { "rangle", "〉" }, + { "rationals", "ℚ" }, + { "rbrace", "}" }, + { "rbrack", "]" }, + { "Re", "ℜ" }, + { "realine", "ℛ" }, + { "realpart", "ℜ" }, + { "reals", "ℝ" }, + { "ReverseElement", "∋" }, + { "ReverseEquilibrium", "⇋" }, + { "ReverseUpEquilibrium", "⥯" }, + { "RightAngleBracket", "〉" }, + { "RightArrow", "→" }, + { "Rightarrow", "⇒" }, + { "rightarrow", "→" }, + { "RightArrowBar", "⇥" }, + { "RightArrowLeftArrow", "⇄" }, + { "rightarrowtail", "↣" }, + { "RightCeiling", "⌉" }, + { "RightDoubleBracket", "〛" }, + { "RightDownVector", "⇂" }, + { "RightFloor", "⌋" }, + { "rightharpoondown", "⇁" }, + { "rightharpoonup", "⇀" }, + { "rightleftarrows", "⇄" }, + { "rightleftharpoons", "⇌" }, + { "rightrightarrows", "⇉" }, + { "rightsquigarrow", "↝" }, + { "RightTee", "⊢" }, + { "RightTeeArrow", "↦" }, + { "rightthreetimes", "⋌" }, + { "RightTriangle", "⊳" }, + { "RightTriangleEqual", "⊵" }, + { "RightUpVector", "↾" }, + { "RightVector", "⇀" }, + { "risingdotseq", "≓" }, + { "rmoustache", "⎱" }, + { "Rrightarrow", "⇛" }, + { "Rsh", "↱" }, + { "searrow", "↘" }, + { "setminus", "∖" }, + { "ShortDownArrow", "↓" }, + { "ShortLeftArrow", "←" }, + { "shortmid", "∣" }, + { "shortparallel", "∥" }, + { "ShortRightArrow", "→" }, + { "ShortUpArrow", "↑" }, + { "simeq", "≃" }, + { "SmallCircle", "∘" }, + { "smallsetminus", "∖" }, + { "spadesuit", "♠" }, + { "Sqrt", "√" }, + { "sqsubset", "⊏" }, + { "sqsubseteq", "⊑" }, + { "sqsupset", "⊐" }, + { "sqsupseteq", "⊒" }, + { "Square", "□" }, + { "SquareIntersection", "⊓" }, + { "SquareSubset", "⊏" }, + { "SquareSubsetEqual", "⊑" }, + { "SquareSuperset", "⊐" }, + { "SquareSupersetEqual", "⊒" }, + { "SquareUnion", "⊔" }, + { "Star", "⋆" }, + { "straightepsilon", "ε" }, + { "straightphi", "ϕ" }, + { "Subset", "⋐" }, + { "subset", "⊂" }, + { "subseteq", "⊆" }, + { "subseteqq", "⫅" }, + { "SubsetEqual", "⊆" }, + { "subsetneq", "⊊" }, + { "subsetneqq", "⫋" }, + { "succ", "≻" }, + { "succapprox", "⪸" }, + { "succcurlyeq", "≽" }, + { "Succeeds", "≻" }, + { "SucceedsEqual", "⪰" }, + { "SucceedsSlantEqual", "≽" }, + { "SucceedsTilde", "≿" }, + { "succeq", "⪰" }, + { "succnapprox", "⪺" }, + { "succneqq", "⪶" }, + { "succnsim", "⋩" }, + { "succsim", "≿" }, + { "SuchThat", "∋" }, + { "Sum", "∑" }, + { "Superset", "⊃" }, + { "SupersetEqual", "⊇" }, + { "Supset", "⋑" }, + { "supset", "⊃" }, + { "supseteq", "⊇" }, + { "supseteqq", "⫆" }, + { "supsetneq", "⊋" }, + { "supsetneqq", "⫌" }, + { "swarrow", "↙" }, + { "Therefore", "∴" }, + { "therefore", "∴" }, + { "thickapprox", "≈" }, + { "thicksim", "∼" }, + { "ThinSpace", " " }, + { "Tilde", "∼" }, + { "TildeEqual", "≃" }, + { "TildeFullEqual", "≅" }, + { "TildeTilde", "≈" }, + { "toea", "⤨" }, + { "tosa", "⤩" }, + { "triangle", "▵" }, + { "triangledown", "▿" }, + { "triangleleft", "◃" }, + { "trianglelefteq", "⊴" }, + { "triangleq", "≜" }, + { "triangleright", "▹" }, + { "trianglerighteq", "⊵" }, + { "TripleDot", "⃛" }, + { "twoheadleftarrow", "↞" }, + { "twoheadrightarrow", "↠" }, + { "ulcorner", "⌜" }, + { "Union", "⋃" }, + { "UnionPlus", "⊎" }, + { "UpArrow", "↑" }, + { "Uparrow", "⇑" }, + { "uparrow", "↑" }, + { "UpArrowDownArrow", "⇅" }, + { "UpDownArrow", "↕" }, + { "Updownarrow", "⇕" }, + { "updownarrow", "↕" }, + { "UpEquilibrium", "⥮" }, + { "upharpoonleft", "↿" }, + { "upharpoonright", "↾" }, + { "UpperLeftArrow", "↖" }, + { "UpperRightArrow", "↗" }, + { "upsilon", "υ" }, + { "UpTee", "⊥" }, + { "UpTeeArrow", "↥" }, + { "upuparrows", "⇈" }, + { "urcorner", "⌝" }, + { "varepsilon", "ɛ" }, + { "varkappa", "ϰ" }, + { "varnothing", "∅" }, + { "varphi", "φ" }, + { "varpi", "ϖ" }, + { "varpropto", "∝" }, + { "varrho", "ϱ" }, + { "varsigma", "ς" }, + { "varsubsetneq", "⊊︀" }, + { "varsubsetneqq", "⫋︀" }, + { "varsupsetneq", "⊋︀" }, + { "varsupsetneqq", "⫌︀" }, + { "vartheta", "ϑ" }, + { "vartriangleleft", "⊲" }, + { "vartriangleright", "⊳" }, + { "Vee", "⋁" }, + { "vee", "∨" }, + { "Vert", "‖" }, + { "vert", "|" }, + { "VerticalBar", "∣" }, + { "VerticalTilde", "≀" }, + { "VeryThinSpace", " " }, + { "Wedge", "⋀" }, + { "wedge", "∧" }, + { "wp", "℘" }, + { "wr", "≀" }, + { "zeetrf", "ℨ" }, + { 0, 0 } +}; + +// ******************************************************************* +// QwtMmlDocument +// ******************************************************************* + +QString QwtMmlDocument::fontName( QwtMathMLDocument::MmlFont type ) const +{ + switch ( type ) + { + case QwtMathMLDocument::NormalFont: + return m_normal_font_name; + case QwtMathMLDocument::FrakturFont: + return m_fraktur_font_name; + case QwtMathMLDocument::SansSerifFont: + return m_sans_serif_font_name; + case QwtMathMLDocument::ScriptFont: + return m_script_font_name; + case QwtMathMLDocument::MonospaceFont: + return m_monospace_font_name; + case QwtMathMLDocument::DoublestruckFont: + return m_doublestruck_font_name; + }; + + return QString::null; +} + +void QwtMmlDocument::setFontName( QwtMathMLDocument::MmlFont type, const QString &name ) +{ + switch ( type ) + { + case QwtMathMLDocument::NormalFont: + m_normal_font_name = name; + break; + case QwtMathMLDocument::FrakturFont: + m_fraktur_font_name = name; + break; + case QwtMathMLDocument::SansSerifFont: + m_sans_serif_font_name = name; + break; + case QwtMathMLDocument::ScriptFont: + m_script_font_name = name; + break; + case QwtMathMLDocument::MonospaceFont: + m_monospace_font_name = name; + break; + case QwtMathMLDocument::DoublestruckFont: + m_doublestruck_font_name = name; + break; + }; +} + +QwtMml::NodeType domToQwtMmlNodeType( const QDomNode &dom_node ) +{ + QwtMml::NodeType mml_type = QwtMml::NoNode; + + switch ( dom_node.nodeType() ) + { + case QDomNode::ElementNode: + { + QString tag = dom_node.nodeName(); + const QwtMmlNodeSpec *spec = mmlFindNodeSpec( tag ); + + // treat urecognised tags as mrow + if ( spec == 0 ) + mml_type = QwtMml::UnknownNode; + else + mml_type = spec->type; + + break; + } + case QDomNode::TextNode: + mml_type = QwtMml::TextNode; + break; + + case QDomNode::DocumentNode: + mml_type = QwtMml::MrowNode; + break; + + case QDomNode::EntityReferenceNode: +// qWarning("EntityReferenceNode: name=\"" + dom_node.nodeName() + "\" value=\"" + dom_node.nodeValue() + "\""); + break; + + case QDomNode::AttributeNode: + case QDomNode::CDATASectionNode: + case QDomNode::EntityNode: + case QDomNode::ProcessingInstructionNode: + case QDomNode::CommentNode: + case QDomNode::DocumentTypeNode: + case QDomNode::DocumentFragmentNode: + case QDomNode::NotationNode: + case QDomNode::BaseNode: + case QDomNode::CharacterDataNode: + break; + } + + return mml_type; +} + + +QwtMmlDocument::QwtMmlDocument() +{ + m_root_node = 0; + + // Some defaults which happen to work on my computer, + // but probably won't work on other's +#if defined(Q_WS_WIN) + m_normal_font_name = "Times New Roman"; +#else + m_normal_font_name = "Century Schoolbook L"; +#endif + m_fraktur_font_name = "Fraktur"; + m_sans_serif_font_name = "Luxi Sans"; + m_script_font_name = "Urw Chancery L"; + m_monospace_font_name = "Luxi Mono"; + m_doublestruck_font_name = "Doublestruck"; + m_base_font_point_size = 16; + m_foreground_color = Qt::black; + m_background_color = Qt::white; +} + +QwtMmlDocument::~QwtMmlDocument() +{ + clear(); +} + +void QwtMmlDocument::clear() +{ + delete m_root_node; + m_root_node = 0; +} + +void QwtMmlDocument::dump() const +{ + if ( m_root_node == 0 ) + return; + + QString indent; + _dump( m_root_node, indent ); +} + +void QwtMmlDocument::_dump( const QwtMmlNode *node, QString &indent ) const +{ + if ( node == 0 ) return; + + qWarning( ( indent + node->toStr() ).toLatin1().data() ); + + indent += " "; + const QwtMmlNode *child = node->firstChild(); + for ( ; child != 0; child = child->nextSibling() ) + _dump( child, indent ); + indent.truncate( indent.length() - 2 ); +} + +bool QwtMmlDocument::setContent( QString text, QString *errorMsg, + int *errorLine, int *errorColumn ) +{ + clear(); + + QString prefix = "\n"; + prefix.append( entityDeclarations() ); + + uint prefix_lines = 0; + for ( int i = 0; i < prefix.length(); ++i ) + { + if ( prefix.at( i ) == '\n' ) + ++prefix_lines; + } + + QDomDocument dom; + if ( !dom.setContent( prefix + text, false, errorMsg, errorLine, errorColumn ) ) + { + if ( errorLine != 0 ) + *errorLine -= prefix_lines; + return false; + } + + // we don't have access to line info from now on + if ( errorLine != 0 ) *errorLine = -1; + if ( errorColumn != 0 ) *errorColumn = -1; + + bool ok; + QwtMmlNode *root_node = domToMml( dom, &ok, errorMsg ); + if ( !ok ) + return false; + + if ( root_node == 0 ) + { + if ( errorMsg != 0 ) + *errorMsg = "empty document"; + return false; + } + + insertChild( 0, root_node, 0 ); + layout(); + + /* QFile of("/tmp/dump.xml"); + of.open(IO_WriteOnly); + QTextStream os(&of); + os.setEncoding(QTextStream::UnicodeUTF8); + os << dom.toString(); */ + + return true; +} + +void QwtMmlDocument::layout() +{ + if ( m_root_node == 0 ) + return; + + m_root_node->layout(); + m_root_node->stretch(); +// dump(); +} + +bool QwtMmlDocument::insertChild( QwtMmlNode *parent, QwtMmlNode *new_node, + QString *errorMsg ) +{ + if ( new_node == 0 ) + return true; + + Q_ASSERT( new_node->parent() == 0 + && new_node->nextSibling() == 0 + && new_node->previousSibling() == 0 ); + + if ( parent != 0 ) + { + if ( !mmlCheckChildType( parent->nodeType(), new_node->nodeType(), errorMsg ) ) + return false; + } + + if ( parent == 0 ) + { + if ( m_root_node == 0 ) + m_root_node = new_node; + else + { + QwtMmlNode *n = m_root_node->lastSibling(); + n->m_next_sibling = new_node; + new_node->m_previous_sibling = n; + } + } + else + { + new_node->m_parent = parent; + if ( parent->hasChildNodes() ) + { + QwtMmlNode *n = parent->firstChild()->lastSibling(); + n->m_next_sibling = new_node; + new_node->m_previous_sibling = n; + } + else parent->m_first_child = new_node; + } + + return true; +} + +QwtMmlNode *QwtMmlDocument::createNode( NodeType type, + const QwtMmlAttributeMap &mml_attr, + const QString &mml_value, + QString *errorMsg ) +{ + Q_ASSERT( type != NoNode ); + + QwtMmlNode *mml_node = 0; + + if ( !mmlCheckAttributes( type, mml_attr, errorMsg ) ) + return 0; + + switch ( type ) + { + case MiNode: + mml_node = new QwtMmlMiNode( this, mml_attr ); + break; + case MnNode: + mml_node = new QwtMmlMnNode( this, mml_attr ); + break; + case MfracNode: + mml_node = new QwtMmlMfracNode( this, mml_attr ); + break; + case MrowNode: + mml_node = new QwtMmlMrowNode( this, mml_attr ); + break; + case MsqrtNode: + mml_node = new QwtMmlMsqrtNode( this, mml_attr ); + break; + case MrootNode: + mml_node = new QwtMmlMrootNode( this, mml_attr ); + break; + case MsupNode: + mml_node = new QwtMmlMsupNode( this, mml_attr ); + break; + case MsubNode: + mml_node = new QwtMmlMsubNode( this, mml_attr ); + break; + case MsubsupNode: + mml_node = new QwtMmlMsubsupNode( this, mml_attr ); + break; + case MoNode: + mml_node = new QwtMmlMoNode( this, mml_attr ); + break; + case MstyleNode: + mml_node = new QwtMmlMstyleNode( this, mml_attr ); + break; + case TextNode: + mml_node = new QwtMmlTextNode( mml_value, this ); + break; + case MphantomNode: + mml_node = new QwtMmlMphantomNode( this, mml_attr ); + break; + case MfencedNode: + mml_node = new QwtMmlMfencedNode( this, mml_attr ); + break; + case MtableNode: + mml_node = new QwtMmlMtableNode( this, mml_attr ); + break; + case MtrNode: + mml_node = new QwtMmlMtrNode( this, mml_attr ); + break; + case MtdNode: + mml_node = new QwtMmlMtdNode( this, mml_attr ); + break; + case MoverNode: + mml_node = new QwtMmlMoverNode( this, mml_attr ); + break; + case MunderNode: + mml_node = new QwtMmlMunderNode( this, mml_attr ); + break; + case MunderoverNode: + mml_node = new QwtMmlMunderoverNode( this, mml_attr ); + break; + case MalignMarkNode: + mml_node = new QwtMmlMalignMarkNode( this ); + break; + case MerrorNode: + mml_node = new QwtMmlMerrorNode( this, mml_attr ); + break; + case MtextNode: + mml_node = new QwtMmlMtextNode( this, mml_attr ); + break; + case MpaddedNode: + mml_node = new QwtMmlMpaddedNode( this, mml_attr ); + break; + case MspaceNode: + mml_node = new QwtMmlMspaceNode( this, mml_attr ); + break; + case UnknownNode: + mml_node = new QwtMmlUnknownNode( this, mml_attr ); + break; + case NoNode: + mml_node = 0; + break; + } + + return mml_node; +} + +void QwtMmlDocument::insertOperator( QwtMmlNode *node, const QString &text ) +{ + QwtMmlNode *text_node = createNode( TextNode, QwtMmlAttributeMap(), text, 0 ); + QwtMmlNode *mo_node = createNode( MoNode, QwtMmlAttributeMap(), QString::null, 0 ); + + bool ok = insertChild( node, mo_node, 0 ); + Q_ASSERT( ok ); + ok = insertChild( mo_node, text_node, 0 ); + Q_ASSERT( ok ); +} + +QwtMmlNode *QwtMmlDocument::domToMml( const QDomNode &dom_node, bool *ok, QString *errorMsg ) +{ + // create the node + + Q_ASSERT( ok != 0 ); + + NodeType mml_type = domToQwtMmlNodeType( dom_node ); + + if ( mml_type == NoNode ) + { + *ok = true; + return 0; + } + + QDomNamedNodeMap dom_attr = dom_node.attributes(); + QwtMmlAttributeMap mml_attr; + for ( unsigned i = 0; i < dom_attr.length(); ++i ) + { + QDomNode attr_node = dom_attr.item( i ); + Q_ASSERT( !attr_node.nodeName().isNull() ); + Q_ASSERT( !attr_node.nodeValue().isNull() ); + mml_attr[attr_node.nodeName()] = attr_node.nodeValue(); + } + + QString mml_value; + if ( mml_type == TextNode ) + mml_value = dom_node.nodeValue(); + QwtMmlNode *mml_node = createNode( mml_type, mml_attr, mml_value, errorMsg ); + if ( mml_node == 0 ) + { + *ok = false; + return 0; + } + + // create the node's children according to the child_spec + + const QwtMmlNodeSpec *spec = mmlFindNodeSpec( mml_type ); + QDomNodeList dom_child_list = dom_node.childNodes(); + int child_cnt = dom_child_list.count(); + QwtMmlNode *mml_child = 0; + + QString separator_list; + if ( mml_type == MfencedNode ) + separator_list = mml_node->explicitAttribute( "separators", "," ); + + switch ( spec->child_spec ) + { + case QwtMmlNodeSpec::ChildIgnore: + break; + + case QwtMmlNodeSpec::ImplicitMrow: + + if ( child_cnt > 0 ) + { + mml_child = createImplicitMrowNode( dom_node, ok, errorMsg ); + if ( !*ok ) + { + delete mml_node; + return 0; + } + + if ( !insertChild( mml_node, mml_child, errorMsg ) ) + { + delete mml_node; + delete mml_child; + *ok = false; + return 0; + } + } + + break; + + default: + // exact ammount of children specified - check... + if ( spec->child_spec != child_cnt ) + { + if ( errorMsg != 0 ) + *errorMsg = QString( "element " ) + + spec->tag + + " requires exactly " + + QString::number( spec->child_spec ) + + " arguments, got " + + QString::number( child_cnt ); + delete mml_node; + *ok = false; + return 0; + } + + // ...and continue just as in ChildAny + + case QwtMmlNodeSpec::ChildAny: + if ( mml_type == MfencedNode ) + insertOperator( mml_node, mml_node->explicitAttribute( "open", "(" ) ); + + for ( int i = 0; i < child_cnt; ++i ) + { + QDomNode dom_child = dom_child_list.item( i ); + + QwtMmlNode *mml_child = domToMml( dom_child, ok, errorMsg ); + if ( !*ok ) + { + delete mml_node; + return 0; + } + + if ( mml_type == MtableNode && mml_child->nodeType() != MtrNode ) + { + QwtMmlNode *mtr_node = createNode( MtrNode, QwtMmlAttributeMap(), QString::null, 0 ); + insertChild( mml_node, mtr_node, 0 ); + if ( !insertChild( mtr_node, mml_child, errorMsg ) ) + { + delete mml_node; + delete mml_child; + *ok = false; + return 0; + } + } + else if ( mml_type == MtrNode && mml_child->nodeType() != MtdNode ) + { + QwtMmlNode *mtd_node = createNode( MtdNode, QwtMmlAttributeMap(), QString::null, 0 ); + insertChild( mml_node, mtd_node, 0 ); + if ( !insertChild( mtd_node, mml_child, errorMsg ) ) + { + delete mml_node; + delete mml_child; + *ok = false; + return 0; + } + } + else + { + if ( !insertChild( mml_node, mml_child, errorMsg ) ) + { + delete mml_node; + delete mml_child; + *ok = false; + return 0; + } + } + + if ( i < child_cnt - 1 && mml_type == MfencedNode && !separator_list.isEmpty() ) + { + QChar separator; + if ( i >= ( int )separator_list.length() ) + separator = separator_list.at( separator_list.length() - 1 ); + else + separator = separator_list[i]; + insertOperator( mml_node, QString( separator ) ); + } + } + + if ( mml_type == MfencedNode ) + insertOperator( mml_node, mml_node->explicitAttribute( "close", ")" ) ); + + break; + } + + *ok = true; + return mml_node; +} + +QwtMmlNode *QwtMmlDocument::createImplicitMrowNode( const QDomNode &dom_node, bool *ok, + QString *errorMsg ) +{ + QDomNodeList dom_child_list = dom_node.childNodes(); + int child_cnt = dom_child_list.count(); + + if ( child_cnt == 0 ) + { + *ok = true; + return 0; + } + + if ( child_cnt == 1 ) + return domToMml( dom_child_list.item( 0 ), ok, errorMsg ); + + QwtMmlNode *mml_node = createNode( MrowNode, QwtMmlAttributeMap(), + QString::null, errorMsg ); + Q_ASSERT( mml_node != 0 ); // there is no reason in heaven or hell for this to fail + + for ( int i = 0; i < child_cnt; ++i ) + { + QDomNode dom_child = dom_child_list.item( i ); + + QwtMmlNode *mml_child = domToMml( dom_child, ok, errorMsg ); + if ( !*ok ) + { + delete mml_node; + return 0; + } + + if ( !insertChild( mml_node, mml_child, errorMsg ) ) + { + delete mml_node; + delete mml_child; + *ok = false; + return 0; + } + } + + return mml_node; +} + +void QwtMmlDocument::paint( QPainter *p, const QPoint &pos ) const +{ + if ( m_root_node == 0 ) + return; + + /* p->save(); + p->setPen(Qt::blue); + p->drawLine(pos.x() - 5, pos.y(), pos.x() + 5, pos.y()); + p->drawLine(pos.x(), pos.y() - 5, pos.x(), pos.y() + 5); + p->restore(); */ + + QRect mr = m_root_node->myRect(); + m_root_node->setRelOrigin( pos - mr.topLeft() ); + m_root_node->paint( p ); +} + +QSize QwtMmlDocument::size() const +{ + if ( m_root_node == 0 ) + return QSize( 0, 0 ); + return m_root_node->deviceRect().size(); +} + + + + +// ******************************************************************* +// QwtMmlNode +// ******************************************************************* + + +QwtMmlNode::QwtMmlNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) +{ + m_parent = 0; + m_first_child = 0; + m_next_sibling = 0; + m_previous_sibling = 0; + + m_node_type = type; + m_document = document; + m_attribute_map = attribute_map; + + m_my_rect = m_parent_rect = QRect( 0, 0, 0, 0 ); + m_rel_origin = QPoint( 0, 0 ); + m_stretched = false; +} + +QwtMmlNode::~QwtMmlNode() +{ + QwtMmlNode *n = firstChild(); + while ( n != 0 ) + { + QwtMmlNode *tmp = n->nextSibling(); + delete n; + n = tmp; + } +} + +static QString rectToStr( const QRect &rect ) +{ + return QString( "[(%1, %2), %3x%4]" ) + .arg( rect.x() ) + .arg( rect.y() ) + .arg( rect.width() ) + .arg( rect.height() ); +} + +QString QwtMmlNode::toStr() const +{ + const QwtMmlNodeSpec *spec = mmlFindNodeSpec( nodeType() ); + Q_ASSERT( spec != 0 ); + + return QString( "%1 %2 mr=%3 pr=%4 dr=%5 ro=(%7, %8) str=%9" ) + .arg( spec->type_str ) + .arg( ( unsigned long )this, 0, 16 ) + .arg( rectToStr( myRect() ) ) + .arg( rectToStr( parentRect() ) ) + .arg( rectToStr( deviceRect() ) ) + .arg( m_rel_origin.x() ) + .arg( m_rel_origin.y() ) + .arg( ( int )isStretched() ); +} + +int QwtMmlNode::interpretSpacing( const QString &value, bool *ok ) const +{ + return ::interpretSpacing( value, em(), ex(), ok ); +} + +int QwtMmlNode::basePos() const +{ + QFontMetrics fm( font() ); + return fm.strikeOutPos(); +} + +int QwtMmlNode::underlinePos() const +{ + QFontMetrics fm( font() ); + return basePos() + fm.underlinePos(); +} +int QwtMmlNode::overlinePos() const +{ + QFontMetrics fm( font() ); + return basePos() - fm.overlinePos(); +} + +QwtMmlNode *QwtMmlNode::lastSibling() const +{ + const QwtMmlNode *n = this; + while ( !n->isLastSibling() ) + n = n->nextSibling(); + return const_cast( n ); +} + +QwtMmlNode *QwtMmlNode::firstSibling() const +{ + const QwtMmlNode *n = this; + while ( !n->isFirstSibling() ) + n = n->previousSibling(); + return const_cast( n ); +} + +int QwtMmlNode::em() const +{ + return QFontMetrics( font() ).boundingRect( 'm' ).width(); +} + +int QwtMmlNode::ex() const +{ + return QFontMetrics( font() ).boundingRect( 'x' ).height(); +} + +int QwtMmlNode::scriptlevel( const QwtMmlNode * ) const +{ + int parent_sl; + const QwtMmlNode *p = parent(); + if ( p == 0 ) + parent_sl = 0; + else + parent_sl = p->scriptlevel( this ); + + QString expl_sl_str = explicitAttribute( "scriptlevel" ); + if ( expl_sl_str.isNull() ) + return parent_sl; + + if ( expl_sl_str.startsWith( "+" ) || expl_sl_str.startsWith( "-" ) ) + { + bool ok; + int expl_sl = expl_sl_str.toInt( &ok ); + if ( ok ) + { + return parent_sl + expl_sl; + } + else + { + qWarning( ( "QwtMmlNode::scriptlevel(): bad value " + expl_sl_str ).toLatin1().data() ); + return parent_sl; + } + } + + bool ok; + int expl_sl = expl_sl_str.toInt( &ok ); + if ( ok ) + return expl_sl; + + + if ( expl_sl_str == "+" ) + return parent_sl + 1; + else if ( expl_sl_str == "-" ) + return parent_sl - 1; + else + { + qWarning( ( "QwtMmlNode::scriptlevel(): could not parse value: \"" + expl_sl_str + "\"" ).toLatin1().data() ); + return parent_sl; + } +} + +QPoint QwtMmlNode::devicePoint( const QPoint &p ) const +{ + QRect mr = myRect(); + QRect dr = deviceRect(); + + if ( isStretched() ) + return dr.topLeft() + QPoint( ( p.x() - mr.left() ) * dr.width() / mr.width(), + ( p.y() - mr.top() ) * dr.height() / mr.height() ); + else + return dr.topLeft() + p - mr.topLeft(); +} + +QString QwtMmlNode::inheritAttributeFromMrow( const QString &name, + const QString &def ) const +{ + const QwtMmlNode *p = this; + for ( ; p != 0; p = p->parent() ) + { + if ( p == this || p->nodeType() == MstyleNode ) + { + QString value = p->explicitAttribute( name ); + if ( !value.isNull() ) + return value; + } + } + + return def; +} + +QColor QwtMmlNode::color() const +{ + // If we are child of return red + const QwtMmlNode *p = this; + for ( ; p != 0; p = p->parent() ) + { + if ( p->nodeType() == MerrorNode ) + return QColor( "red" ); + } + + QString value_str = inheritAttributeFromMrow( "mathcolor" ); + if ( value_str.isNull() ) + value_str = inheritAttributeFromMrow( "color" ); + if ( value_str.isNull() ) + return QColor(); + + return QColor( value_str ); +} + +QColor QwtMmlNode::background() const +{ + QString value_str = inheritAttributeFromMrow( "mathbackground" ); + if ( value_str.isNull() ) + value_str = inheritAttributeFromMrow( "background" ); + if ( value_str.isNull() ) + return QColor(); + + return QColor( value_str ); +} + +static void updateFontAttr( QwtMmlAttributeMap &font_attr, const QwtMmlNode *n, + const QString &name, const QString &preferred_name = QString::null ) +{ + if ( font_attr.contains( preferred_name ) || font_attr.contains( name ) ) + return; + QString value = n->explicitAttribute( name ); + if ( !value.isNull() ) + font_attr[name] = value; +} + +static QwtMmlAttributeMap collectFontAttributes( const QwtMmlNode *node ) +{ + QwtMmlAttributeMap font_attr; + + for ( const QwtMmlNode *n = node; n != 0; n = n->parent() ) + { + if ( n == node || n->nodeType() == QwtMml::MstyleNode ) + { + updateFontAttr( font_attr, n, "mathvariant" ); + updateFontAttr( font_attr, n, "mathsize" ); + + // depreciated attributes + updateFontAttr( font_attr, n, "fontsize", "mathsize" ); + updateFontAttr( font_attr, n, "fontweight", "mathvariant" ); + updateFontAttr( font_attr, n, "fontstyle", "mathvariant" ); + updateFontAttr( font_attr, n, "fontfamily", "mathvariant" ); + } + } + + return font_attr; +} + +QFont QwtMmlNode::font() const +{ + QFont fn( document()->fontName( QwtMathMLDocument::NormalFont ), + document()->baseFontPointSize() ); + + int ps = fn.pointSize(); + int sl = scriptlevel(); + if ( sl >= 0 ) + { + for ( int i = 0; i < sl; ++i ) + ps = ( int )( ps * g_script_size_multiplier ); + } + else + { + for ( int i = 0; i > sl; --i ) + ps = ( int )( ps / g_script_size_multiplier ); + } + if ( ps < g_min_font_point_size ) + ps = g_min_font_point_size; + fn.setPointSize( ps ); + + int em = QFontMetrics( fn ).boundingRect( 'm' ).width(); + int ex = QFontMetrics( fn ).boundingRect( 'x' ).height(); + + QwtMmlAttributeMap font_attr = collectFontAttributes( this ); + + if ( font_attr.contains( "mathvariant" ) ) + { + QString value = font_attr["mathvariant"]; + + bool ok; + uint mv = interpretMathVariant( value, &ok ); + + if ( ok ) + { + if ( mv & ScriptMV ) + fn.setFamily( document()->fontName( QwtMathMLDocument::ScriptFont ) ); + + if ( mv & FrakturMV ) + fn.setFamily( document()->fontName( QwtMathMLDocument::FrakturFont ) ); + + if ( mv & SansSerifMV ) + fn.setFamily( document()->fontName( QwtMathMLDocument::SansSerifFont ) ); + + if ( mv & MonospaceMV ) + fn.setFamily( document()->fontName( QwtMathMLDocument::MonospaceFont ) ); + + if ( mv & DoubleStruckMV ) + fn.setFamily( document()->fontName( QwtMathMLDocument::DoublestruckFont ) ); + + if ( mv & BoldMV ) + fn.setBold( true ); + + if ( mv & ItalicMV ) + fn.setItalic( true ); + } + } + + if ( font_attr.contains( "mathsize" ) ) + { + QString value = font_attr["mathsize"]; + fn = interpretMathSize( value, fn, em, ex, 0 ); + } + + fn = interpretDepreciatedFontAttr( font_attr, fn, em, ex ); + + if ( nodeType() == MiNode + && !font_attr.contains( "mathvariant" ) + && !font_attr.contains( "fontstyle" ) ) + { + const QwtMmlMiNode *mi_node = ( const QwtMmlMiNode* ) this; + if ( mi_node->text().length() == 1 ) + fn.setItalic( true ); + } + + if ( nodeType() == MoNode ) + { + fn.setItalic( false ); + fn.setBold( false ); + } + + return fn; +} + +QString QwtMmlNode::explicitAttribute( const QString &name, const QString &def ) const +{ + QwtMmlAttributeMap::const_iterator it = m_attribute_map.find( name ); + if ( it != m_attribute_map.end() ) + return *it; + return def; +} + + +QRect QwtMmlNode::parentRect() const +{ + if ( isStretched() ) + return m_parent_rect; + + QRect mr = myRect(); + QPoint ro = relOrigin(); + + return QRect( ro + mr.topLeft(), mr.size() ); +} + + +void QwtMmlNode::stretchTo( const QRect &rect ) +{ + m_parent_rect = rect; + m_stretched = true; +} + +void QwtMmlNode::setRelOrigin( const QPoint &rel_origin ) +{ + m_rel_origin = rel_origin + QPoint( -myRect().left(), 0 ); + m_stretched = false; +} + +void QwtMmlNode::updateMyRect() +{ + m_my_rect = symbolRect(); + QwtMmlNode *child = firstChild(); + for ( ; child != 0; child = child->nextSibling() ) + m_my_rect |= child->parentRect(); +} + +void QwtMmlNode::layout() +{ + m_parent_rect = QRect( 0, 0, 0, 0 ); + m_stretched = false; + m_rel_origin = QPoint( 0, 0 ); + + QwtMmlNode *child = firstChild(); + for ( ; child != 0; child = child->nextSibling() ) + child->layout(); + + layoutSymbol(); + + updateMyRect(); + + if ( parent() == 0 ) + m_rel_origin = QPoint( 0, 0 ); +} + + +QRect QwtMmlNode::deviceRect() const +{ + if ( parent() == 0 ) + return QRect( relOrigin() + myRect().topLeft(), myRect().size() ); + + /* if (!isStretched()) { + QRect pdr = parent()->deviceRect(); + QRect pmr = parent()->myRect(); + QRect pr = parentRect(); + QRect mr = myRect(); + return QRect(pdr.left() + pr.left() - pmr.left(), + pdr.top() + pr.top() - pmr.top(), + mr.width(), mr.height()); + } + */ + QRect pdr = parent()->deviceRect(); + QRect pr = parentRect(); + QRect pmr = parent()->myRect(); + + float scale_w = 0; + if ( pmr.width() != 0 ) + scale_w = ( float )pdr.width() / pmr.width(); + float scale_h = 0; + if ( pmr.height() != 0 ) + scale_h = ( float )pdr.height() / pmr.height(); + + return QRect( pdr.left() + ROUND( ( pr.left() - pmr.left() ) * scale_w ), + pdr.top() + ROUND( ( pr.top() - pmr.top() ) * scale_h ), + ROUND( ( pr.width() * scale_w ) ), + ROUND( ( pr.height() * scale_h ) ) ); +} + +void QwtMmlNode::layoutSymbol() +{ + // default behaves like an mrow + + // now lay them out in a neat row, aligning their origins to my origin + int w = 0; + QwtMmlNode *child = firstChild(); + for ( ; child != 0; child = child->nextSibling() ) + { + child->setRelOrigin( QPoint( w, 0 ) ); + w += child->parentRect().width() + 1; + } +} + +void QwtMmlNode::paint( QPainter *p ) +{ + if ( !myRect().isValid() ) + return; + p->save(); + + QColor fg = color(); + QColor bg = background(); + if ( bg.isValid() ) + p->fillRect( myRect(), bg ); + if ( fg.isValid() ) + p->setPen( color() ); + + QwtMmlNode *child = firstChild(); + for ( ; child != 0; child = child->nextSibling() ) + child->paint( p ); + + paintSymbol( p ); + + p->restore(); +} + +void QwtMmlNode::paintSymbol( QPainter *p ) const +{ + if ( g_draw_frames && myRect().isValid() ) + { + p->save(); + p->setPen( Qt::red ); + p->drawRect( m_my_rect ); + QPen pen = p->pen(); + pen.setStyle( Qt::DotLine ); + p->setPen( pen ); + p->drawLine( myRect().left(), 0, myRect().right(), 0 ); + p->restore(); + } +} + +void QwtMmlNode::stretch() +{ + QwtMmlNode *child = firstChild(); + for ( ; child != 0; child = child->nextSibling() ) + child->stretch(); +} + +QString QwtMmlTokenNode::text() const +{ + QString result; + + const QwtMmlNode *child = firstChild(); + for ( ; child != 0; child = child->nextSibling() ) + { + if ( child->nodeType() != TextNode ) continue; + if ( !result.isEmpty() ) + result += ' '; + result += static_cast( child )->text(); + } + + return result; +} + +QwtMmlNode *QwtMmlMfracNode::numerator() const +{ + QwtMmlNode *node = firstChild(); + Q_ASSERT( node != 0 ); + return node; +} + +QwtMmlNode *QwtMmlMfracNode::denominator() const +{ + QwtMmlNode *node = numerator()->nextSibling(); + Q_ASSERT( node != 0 ); + return node; +} + +QRect QwtMmlMfracNode::symbolRect() const +{ + int num_width = numerator()->myRect().width(); + int denom_width = denominator()->myRect().width(); + int my_width = qMax( num_width, denom_width ) + 4; + + return QRect( -my_width / 2, 0, my_width, 1 ); +} + +void QwtMmlMfracNode::layoutSymbol() +{ + QwtMmlNode *num = numerator(); + QwtMmlNode *denom = denominator(); + + QRect num_rect = num->myRect(); + QRect denom_rect = denom->myRect(); + + int spacing = ( int )( g_mfrac_spacing * ( num_rect.height() + denom_rect.height() ) ); + + num->setRelOrigin( QPoint( -num_rect.width() / 2, - spacing - num_rect.bottom() ) ); + denom->setRelOrigin( QPoint( -denom_rect.width() / 2, spacing - denom_rect.top() ) ); +} + +static bool zeroLineThickness( const QString &s ) +{ + if ( s.length() == 0 || !s[0].isDigit() ) + return false; + + for ( int i = 0; i < s.length(); ++i ) + { + QChar c = s.at( i ); + if ( c.isDigit() && c != '0' ) + return false; + } + return true; +} + +void QwtMmlMfracNode::paintSymbol( QPainter *p ) const +{ + QString linethickness_str = inheritAttributeFromMrow( "linethickness", "1" ); + + /* InterpretSpacing returns an int, which might be 0 even if the thickness + is > 0, though very very small. That's ok, because the painter then paints + a line of thickness 1. However, we have to run this check if the line + thickness really is zero */ + if ( !zeroLineThickness( linethickness_str ) ) + { + bool ok; + int linethickness = interpretSpacing( linethickness_str, &ok ); + if ( !ok ) + linethickness = 1; + + p->save(); + QPen pen = p->pen(); + pen.setWidth( linethickness ); + p->setPen( pen ); + QSize s = myRect().size(); + p->drawLine( -s.width() / 2, 0, s.width() / 2, 0 ); + p->restore(); + } +} + +QwtMmlNode *QwtMmlRootBaseNode::base() const +{ + QwtMmlNode *node = firstChild(); +// Q_ASSERT(node != 0); + return node; +} + +QwtMmlNode *QwtMmlRootBaseNode::index() const +{ + QwtMmlNode *b = base(); + if ( b == 0 ) + return 0; + return b->nextSibling(); +} + +int QwtMmlRootBaseNode::scriptlevel( const QwtMmlNode *child ) const +{ + int sl = QwtMmlNode::scriptlevel(); + + QwtMmlNode *i = index(); + if ( child != 0 && child == i ) + return sl + 1; + else + return sl; +} + + +QRect QwtMmlRootBaseNode::symbolRect() const +{ + QwtMmlNode *b = base(); + QRect base_rect; + if ( b == 0 ) + base_rect = QRect( 0, 0, 1, 1 ); + else + base_rect = base()->myRect(); + + int margin = ( int )( g_mroot_base_margin * base_rect.height() ); + int tw = tailWidth(); + + return QRect( -tw, base_rect.top() - margin, tw, + base_rect.height() + 2 * margin ); +} + +int QwtMmlRootBaseNode::tailWidth() const +{ + QFontMetrics fm( font() ); + return fm.boundingRect( g_radical_char ).width(); +} + +void QwtMmlRootBaseNode::layoutSymbol() +{ + QwtMmlNode *b = base(); + QSize base_size; + if ( b != 0 ) + { + b->setRelOrigin( QPoint( 0, 0 ) ); + base_size = base()->myRect().size(); + } + else + base_size = QSize( 1, 1 ); + + QwtMmlNode *i = index(); + if ( i != 0 ) + { + int tw = tailWidth(); + + QRect i_rect = i->myRect(); + i->setRelOrigin( QPoint( -tw / 2 - i_rect.width(), + -i_rect.bottom() - 4 ) ); + } +} + +void QwtMmlRootBaseNode::paintSymbol( QPainter *p ) const +{ + QFont fn = font(); + + p->save(); + + QRect sr = symbolRect(); + + QRect r = sr; + r.moveTopLeft( devicePoint( sr.topLeft() ) ); + p->setViewport( r ); + p->setWindow( QFontMetrics( fn ).boundingRect( g_radical_char ) ); + p->setFont( font() ); + p->drawText( 0, 0, QString( g_radical_char ) ); + + p->restore(); + + p->drawLine( sr.right(), sr.top(), myRect().right(), sr.top() ); +} + +QwtMmlTextNode::QwtMmlTextNode( const QString &text, QwtMmlDocument *document ) + : QwtMmlNode( TextNode, document, QwtMmlAttributeMap() ) +{ + m_text = text; + // Trim whitespace from ends, but keep nbsp and thinsp + m_text.remove( QRegExp( "^[^\\S\\x00a0\\x2009]+" ) ); + m_text.remove( QRegExp( "[^\\S\\x00a0\\x2009]+$" ) ); + + if ( m_text == QString( QChar( 0x62, 0x20 ) ) // ⁢ + || m_text == QString( QChar( 0x63, 0x20 ) ) // ⁣ + || m_text == QString( QChar( 0x61, 0x20 ) ) ) // ⁡ + m_text = ""; +} + +QString QwtMmlTextNode::toStr() const +{ + return QwtMmlNode::toStr() + ", text=\"" + m_text + "\""; +} + +void QwtMmlTextNode::paintSymbol( QPainter *p ) const +{ + QwtMmlNode::paintSymbol( p ); + + QFont fn = font(); + + QFontInfo fi( fn ); +// qWarning("MmlTextNode::paintSymbol(): requested: %s, used: %s, size=%d, italic=%d, bold=%d, text=\"%s\" sl=%d", +// fn.family().latin1(), fi.family().latin1(), fi.pointSize(), (int)fi.italic(), (int)fi.bold(), m_text.latin1(), scriptlevel()); + + QFontMetrics fm( fn ); + + p->save(); + p->setFont( fn ); + + QPoint dPos = devicePoint( relOrigin() ); + p->drawText( dPos.x(), dPos.y() + fm.strikeOutPos(), m_text ); + + p->restore(); +} + +QRect QwtMmlTextNode::symbolRect() const +{ + QFontMetrics fm( font() ); + + QRect br = fm.tightBoundingRect( m_text ); + br.translate( 0, fm.strikeOutPos() ); + + return br; +} + +QwtMmlNode *QwtMmlSubsupBaseNode::base() const +{ + QwtMmlNode *b = firstChild(); + Q_ASSERT( b != 0 ); + return b; +} + +QwtMmlNode *QwtMmlSubsupBaseNode::sscript() const +{ + QwtMmlNode *s = base()->nextSibling(); + Q_ASSERT( s != 0 ); + return s; +} + +int QwtMmlSubsupBaseNode::scriptlevel( const QwtMmlNode *child ) const +{ + int sl = QwtMmlNode::scriptlevel(); + + QwtMmlNode *s = sscript(); + if ( child != 0 && child == s ) + return sl + 1; + else + return sl; +} + +void QwtMmlMsupNode::layoutSymbol() +{ + QwtMmlNode *b = base(); + QwtMmlNode *s = sscript(); + + b->setRelOrigin( QPoint( -b->myRect().width(), 0 ) ); + s->setRelOrigin( QPoint( 0, b->myRect().top() ) ); +} + +void QwtMmlMsubNode::layoutSymbol() +{ + QwtMmlNode *b = base(); + QwtMmlNode *s = sscript(); + + b->setRelOrigin( QPoint( -b->myRect().width(), 0 ) ); + s->setRelOrigin( QPoint( 0, b->myRect().bottom() ) ); +} + +QwtMmlNode *QwtMmlMsubsupNode::base() const +{ + QwtMmlNode *b = firstChild(); + Q_ASSERT( b != 0 ); + return b; +} + +QwtMmlNode *QwtMmlMsubsupNode::subscript() const +{ + QwtMmlNode *sub = base()->nextSibling(); + Q_ASSERT( sub != 0 ); + return sub; +} + +QwtMmlNode *QwtMmlMsubsupNode::superscript() const +{ + QwtMmlNode *sup = subscript()->nextSibling(); + Q_ASSERT( sup != 0 ); + return sup; +} + +void QwtMmlMsubsupNode::layoutSymbol() +{ + QwtMmlNode *b = base(); + QwtMmlNode *sub = subscript(); + QwtMmlNode *sup = superscript(); + + b->setRelOrigin( QPoint( -b->myRect().width(), 0 ) ); + sub->setRelOrigin( QPoint( 0, b->myRect().bottom() ) ); + sup->setRelOrigin( QPoint( 0, b->myRect().top() ) ); +} + +int QwtMmlMsubsupNode::scriptlevel( const QwtMmlNode *child ) const +{ + int sl = QwtMmlNode::scriptlevel(); + + QwtMmlNode *sub = subscript(); + QwtMmlNode *sup = superscript(); + + if ( child != 0 && ( child == sup || child == sub ) ) + return sl + 1; + else + return sl; +} + +QString QwtMmlMoNode::toStr() const +{ + return QwtMmlNode::toStr() + QString( " form=%1" ).arg( ( int )form() ); +} + +void QwtMmlMoNode::layoutSymbol() +{ + QwtMmlNode *child = firstChild(); + if ( child == 0 ) + return; + + child->setRelOrigin( QPoint( 0, 0 ) ); + + if ( m_oper_spec == 0 ) + m_oper_spec = mmlFindOperSpec( text(), form() ); +} + +QwtMmlMoNode::QwtMmlMoNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map ) + : QwtMmlTokenNode( MoNode, document, attribute_map ) +{ + m_oper_spec = 0; +} + +QString QwtMmlMoNode::dictionaryAttribute( const QString &name ) const +{ + const QwtMmlNode *p = this; + for ( ; p != 0; p = p->parent() ) + { + if ( p == this || p->nodeType() == MstyleNode ) + { + QString expl_attr = p->explicitAttribute( name ); + if ( !expl_attr.isNull() ) + return expl_attr; + } + } + + return mmlDictAttribute( name, m_oper_spec ); +} + +QwtMml::FormType QwtMmlMoNode::form() const +{ + QString value_str = inheritAttributeFromMrow( "form" ); + if ( !value_str.isNull() ) + { + bool ok; + FormType value = interpretForm( value_str, &ok ); + if ( ok ) + return value; + else + qWarning( "Could not convert %s to form", value_str.toLatin1().data() ); + + } + + // Default heuristic. + if ( firstSibling() == ( QwtMmlNode* )this && lastSibling() != ( QwtMmlNode* )this ) + return PrefixForm; + else if ( lastSibling() == ( QwtMmlNode* )this && firstSibling() != ( QwtMmlNode* )this ) + return PostfixForm; + else return InfixForm; + +} + +void QwtMmlMoNode::stretch() +{ + if ( parent() == 0 ) + return; + + if ( m_oper_spec == 0 ) + return; + + if ( m_oper_spec->stretch_dir == QwtMmlOperSpec::HStretch + && parent()->nodeType() == MrowNode + && ( nextSibling() != 0 || previousSibling() != 0 ) ) + return; + + QRect pmr = parent()->myRect(); + QRect pr = parentRect(); + + switch ( m_oper_spec->stretch_dir ) + { + case QwtMmlOperSpec::VStretch: + stretchTo( QRect( pr.left(), pmr.top(), pr.width(), pmr.height() ) ); + break; + case QwtMmlOperSpec::HStretch: + stretchTo( QRect( pmr.left(), pr.top(), pmr.width(), pr.height() ) ); + break; + case QwtMmlOperSpec::HVStretch: + stretchTo( pmr ); + break; + case QwtMmlOperSpec::NoStretch: + break; + } +} + +int QwtMmlMoNode::lspace() const +{ + Q_ASSERT( m_oper_spec != 0 ); + if ( parent() == 0 + || ( parent()->nodeType() != MrowNode + && parent()->nodeType() != MfencedNode + && parent()->nodeType() != UnknownNode ) + || ( previousSibling() == 0 && nextSibling() == 0 ) ) + return 0; + else + return interpretSpacing( dictionaryAttribute( "lspace" ), 0 ); +} + +int QwtMmlMoNode::rspace() const +{ + Q_ASSERT( m_oper_spec != 0 ); + if ( parent() == 0 + || ( parent()->nodeType() != MrowNode + && parent()->nodeType() != MfencedNode + && parent()->nodeType() != UnknownNode ) + || ( previousSibling() == 0 && nextSibling() == 0 ) ) + return 0; + else + return interpretSpacing( dictionaryAttribute( "rspace" ), 0 ); +} + +QRect QwtMmlMoNode::symbolRect() const +{ + const QwtMmlNode *child = firstChild(); + + if ( child == 0 ) + return QRect( 0, 0, 0, 0 ); + + QRect cmr = child->myRect(); + + return QRect( -lspace(), cmr.top(), + cmr.width() + lspace() + rspace(), cmr.height() ); +} + +int QwtMmlMtableNode::rowspacing() const +{ + QString value = explicitAttribute( "rowspacing" ); + if ( value.isNull() ) + return ex(); + bool ok; + int r = interpretSpacing( value, &ok ); + + if ( ok ) + return r; + else + return ex(); +} + +int QwtMmlMtableNode::columnspacing() const +{ + QString value = explicitAttribute( "columnspacing" ); + if ( value.isNull() ) + return ( int )( 0.8 * em() ); + bool ok; + int r = interpretSpacing( value, &ok ); + + if ( ok ) + return r; + else + return ( int )( 0.8 * em() ); +} + +uint QwtMmlMtableNode::CellSizeData::colWidthSum() const +{ + uint w = 0; + for ( int i = 0; i < col_widths.count(); ++i ) + w += col_widths[i]; + return w; +} + +uint QwtMmlMtableNode::CellSizeData::rowHeightSum() const +{ + uint h = 0; + for ( int i = 0; i < row_heights.count(); ++i ) + h += row_heights[i]; + return h; +} + +void QwtMmlMtableNode::CellSizeData::init( const QwtMmlNode *first_row ) +{ + col_widths.clear(); + row_heights.clear(); + + const QwtMmlNode *mtr = first_row; + for ( ; mtr != 0; mtr = mtr->nextSibling() ) + { + + Q_ASSERT( mtr->nodeType() == MtrNode ); + + int col_cnt = 0; + const QwtMmlNode *mtd = mtr->firstChild(); + for ( ; mtd != 0; mtd = mtd->nextSibling(), ++col_cnt ) + { + + Q_ASSERT( mtd->nodeType() == MtdNode ); + + QRect mtdmr = mtd->myRect(); + + if ( col_cnt == col_widths.count() ) + col_widths.append( mtdmr.width() ); + else + col_widths[col_cnt] = qMax( col_widths[col_cnt], mtdmr.width() ); + } + + row_heights.append( mtr->myRect().height() ); + } +} + +void QwtMmlMtableNode::layoutSymbol() +{ + // Obtain natural widths of columns + m_cell_size_data.init( firstChild() ); + + int col_spc = columnspacing(); + int row_spc = rowspacing(); + int frame_spc_hor = framespacing_hor(); + QString columnwidth_attr = explicitAttribute( "columnwidth", "auto" ); + + // Is table width set by user? If so, set col_width_sum and never ever change it. + int col_width_sum = m_cell_size_data.colWidthSum(); + bool width_set_by_user = false; + QString width_str = explicitAttribute( "width", "auto" ); + if ( width_str != "auto" ) + { + bool ok; + + int w = interpretSpacing( width_str, &ok ); + if ( ok ) + { + col_width_sum = w + - col_spc * ( m_cell_size_data.numCols() - 1 ) + - frame_spc_hor * 2; + width_set_by_user = true; + } + } + + // Find out what kind of columns we are dealing with and set the widths of + // statically sized columns. + int fixed_width_sum = 0; // sum of widths of statically sized set columns + int auto_width_sum = 0; // sum of natural widths of auto sized columns + int relative_width_sum = 0; // sum of natural widths of relatively sized columns + double relative_fraction_sum = 0; // total fraction of width taken by relatively + // sized columns + int i; + for ( i = 0; i < m_cell_size_data.numCols(); ++i ) + { + QString value = interpretListAttr( columnwidth_attr, i, "auto" ); + + // Is it an auto sized column? + if ( value == "auto" || value == "fit" ) + { + auto_width_sum += m_cell_size_data.col_widths[i]; + continue; + } + + // Is it a statically sized column? + bool ok; + int w = interpretSpacing( value, &ok ); + if ( ok ) + { + // Yup, sets its width to the user specified value + m_cell_size_data.col_widths[i] = w; + fixed_width_sum += w; + continue; + } + + // Is it a relatively sized column? + if ( value.endsWith( "%" ) ) + { + value.truncate( value.length() - 1 ); + double factor = value.toFloat( &ok ); + if ( ok && !value.isEmpty() ) + { + factor /= 100.0; + relative_width_sum += m_cell_size_data.col_widths[i]; + relative_fraction_sum += factor; + if ( !width_set_by_user ) + { + // If the table width was not set by the user, we are free to increase + // it so that the width of this column will be >= than its natural width + int min_col_width_sum = ROUND( m_cell_size_data.col_widths[i] / factor ); + if ( min_col_width_sum > col_width_sum ) + col_width_sum = min_col_width_sum; + } + continue; + } + else + qWarning( "MmlMtableNode::layoutSymbol(): could not parse value %s%%", value.toLatin1().data() ); + } + + // Relatively sized column, but we failed to parse the factor. Treat is like an auto + // column. + auto_width_sum += m_cell_size_data.col_widths[i]; + } + + // Work out how much space remains for the auto olumns, after allocating + // the statically sized and the relatively sized columns. + int required_auto_width_sum = col_width_sum + - ROUND( relative_fraction_sum * col_width_sum ) + - fixed_width_sum; + + if ( !width_set_by_user && required_auto_width_sum < auto_width_sum ) + { + if ( relative_fraction_sum < 1 ) + col_width_sum = ROUND( ( fixed_width_sum + auto_width_sum ) / ( 1 - relative_fraction_sum ) ); + else + col_width_sum = fixed_width_sum + auto_width_sum + relative_width_sum; + required_auto_width_sum = auto_width_sum; + } + + // Ratio by which we have to shring/grow all auto sized columns to make it all fit + double auto_width_scale = 1; + if ( auto_width_sum > 0 ) + auto_width_scale = ( float )required_auto_width_sum / auto_width_sum; + + // Set correct sizes for the auto sized and the relatively sized columns. + for ( i = 0; i < m_cell_size_data.numCols(); ++i ) + { + QString value = interpretListAttr( columnwidth_attr, i, "auto" ); + + // Is it a relatively sized column? + if ( value.endsWith( "%" ) ) + { + bool ok; + int w = interpretPercentSpacing( value, col_width_sum, &ok ); + if ( ok ) + m_cell_size_data.col_widths[i] = w; + else + // We're treating parsing errors here as auto sized columns + m_cell_size_data.col_widths[i] + = ROUND( auto_width_scale * m_cell_size_data.col_widths[i] ); + } + // Is it an auto sized column? + else if ( value == "auto" ) + { + m_cell_size_data.col_widths[i] + = ROUND( auto_width_scale * m_cell_size_data.col_widths[i] ); + } + } + + QString s; + QList &col_widths = m_cell_size_data.col_widths; + for ( i = 0; i < col_widths.count(); ++i ) + { + s += QString( "[w=%1 %2%%]" ) + .arg( col_widths[i] ) + .arg( 100 * col_widths[i] / m_cell_size_data.colWidthSum() ); + } +// qWarning(s); + + m_content_width = m_cell_size_data.colWidthSum() + + col_spc * ( m_cell_size_data.numCols() - 1 ); + m_content_height = m_cell_size_data.rowHeightSum() + + row_spc * ( m_cell_size_data.numRows() - 1 ); + + int bottom = -m_content_height / 2; + QwtMmlNode *child = firstChild(); + for ( ; child != 0; child = child->nextSibling() ) + { + Q_ASSERT( child->nodeType() == MtrNode ); + QwtMmlMtrNode *row = ( QwtMmlMtrNode* ) child; + + row->layoutCells( m_cell_size_data.col_widths, col_spc ); + QRect rmr = row->myRect(); + row->setRelOrigin( QPoint( 0, bottom - rmr.top() ) ); + bottom += rmr.height() + row_spc; + } +} + +QRect QwtMmlMtableNode::symbolRect() const +{ + int frame_spc_hor = framespacing_hor(); + int frame_spc_ver = framespacing_ver(); + + return QRect( -frame_spc_hor, + -m_content_height / 2 - frame_spc_ver, + m_content_width + 2 * frame_spc_hor, + m_content_height + 2 * frame_spc_ver ); +} + +QwtMml::FrameType QwtMmlMtableNode::frame() const +{ + QString value = explicitAttribute( "frame", "none" ); + return interpretFrameType( value, 0, 0 ); +} + +QwtMml::FrameType QwtMmlMtableNode::columnlines( int idx ) const +{ + QString value = explicitAttribute( "columnlines", "none" ); + return interpretFrameType( value, idx, 0 ); +} + +QwtMml::FrameType QwtMmlMtableNode::rowlines( int idx ) const +{ + QString value = explicitAttribute( "rowlines", "none" ); + return interpretFrameType( value, idx, 0 ); +} + +void QwtMmlMtableNode::paintSymbol( QPainter *p ) const +{ + FrameType f = frame(); + if ( f != FrameNone ) + { + p->save(); + + QPen pen = p->pen(); + if ( f == FrameDashed ) + pen.setStyle( Qt::DashLine ); + else + pen.setStyle( Qt::SolidLine ); + p->setPen( pen ); + p->drawRect( myRect() ); + + p->restore(); + } + + p->save(); + + int col_spc = columnspacing(); + int row_spc = rowspacing(); + + QPen pen = p->pen(); + int col_offset = 0; + int i; + for ( i = 0; i < m_cell_size_data.numCols() - 1; ++i ) + { + FrameType f = columnlines( i ); + col_offset += m_cell_size_data.col_widths[i]; + + if ( f != FrameNone ) + { + if ( f == FrameDashed ) + pen.setStyle( Qt::DashLine ); + else if ( f == FrameSolid ) + pen.setStyle( Qt::SolidLine ); + + p->setPen( pen ); + int x = col_offset + col_spc / 2; + p->drawLine( x, -m_content_height / 2, x, m_content_height / 2 ); + } + col_offset += col_spc; + } + + int row_offset = 0; + for ( i = 0; i < m_cell_size_data.numRows() - 1; ++i ) + { + FrameType f = rowlines( i ); + row_offset += m_cell_size_data.row_heights[i]; + + if ( f != FrameNone ) + { + if ( f == FrameDashed ) + pen.setStyle( Qt::DashLine ); + else if ( f == FrameSolid ) + pen.setStyle( Qt::SolidLine ); + + p->setPen( pen ); + int y = row_offset + row_spc / 2 - m_content_height / 2; + p->drawLine( 0, y, m_content_width, y ); + } + row_offset += row_spc; + } + + p->restore(); +} + +int QwtMmlMtableNode::framespacing_ver() const +{ + if ( frame() == FrameNone ) + return ( int )( 0.2 * em() ); + + QString value = explicitAttribute( "framespacing", "0.4em 0.5ex" ); + + bool ok; + FrameSpacing fs = interpretFrameSpacing( value, em(), ex(), &ok ); + if ( ok ) + return fs.m_ver; + else + return ( int )( 0.5 * ex() ); +} + +int QwtMmlMtableNode::framespacing_hor() const +{ + if ( frame() == FrameNone ) + return ( int )( 0.2 * em() ); + + QString value = explicitAttribute( "framespacing", "0.4em 0.5ex" ); + + bool ok; + FrameSpacing fs = interpretFrameSpacing( value, em(), ex(), &ok ); + if ( ok ) + return fs.m_hor; + else + return ( int )( 0.4 * em() ); +} + +void QwtMmlMtrNode::layoutCells( const QList &col_widths, + int col_spc ) +{ + QRect mr = myRect(); + + QwtMmlNode *child = firstChild(); + int col_offset = 0; + uint colnum = 0; + for ( ; child != 0; child = child->nextSibling(), ++colnum ) + { + Q_ASSERT( child->nodeType() == MtdNode ); + QwtMmlMtdNode *mtd = ( QwtMmlMtdNode* ) child; + + QRect r = QRect( 0, mr.top(), col_widths[colnum], mr.height() ); + mtd->setMyRect( r ); + mtd->setRelOrigin( QPoint( col_offset, 0 ) ); + col_offset += col_widths[colnum] + col_spc; + } + + updateMyRect(); +} + +int QwtMmlMtdNode::scriptlevel( const QwtMmlNode *child ) const +{ + int sl = QwtMmlNode::scriptlevel(); + if ( child != 0 && child == firstChild() ) + return sl + m_scriptlevel_adjust; + else + return sl; +} + +void QwtMmlMtdNode::setMyRect( const QRect &rect ) +{ + QwtMmlNode::setMyRect( rect ); + QwtMmlNode *child = firstChild(); + if ( child == 0 ) + return; + + if ( rect.width() < child->myRect().width() ) + { + while ( rect.width() < child->myRect().width() + && child->font().pointSize() > g_min_font_point_size ) + { + +// qWarning("MmlMtdNode::setMyRect(): rect.width()=%d, child()->myRect().width=%d sl=%d", +// rect.width(), child->myRect().width(), m_scriptlevel_adjust); + + ++m_scriptlevel_adjust; + child->layout(); + } + +// qWarning("MmlMtdNode::setMyRect(): rect.width()=%d, child()->myRect().width=%d sl=%d", +// rect.width(), child->myRect().width(), m_scriptlevel_adjust); + } + + QRect mr = myRect(); + QRect cmr = child->myRect(); + + QPoint child_rel_origin; + + switch ( columnalign() ) + { + case ColAlignLeft: + child_rel_origin.setX( 0 ); + break; + case ColAlignCenter: + child_rel_origin.setX( mr.left() + ( mr.width() - cmr.width() ) / 2 ); + break; + case ColAlignRight: + child_rel_origin.setX( mr.right() - cmr.width() ); + break; + } + + switch ( rowalign() ) + { + case RowAlignTop: + child_rel_origin.setY( mr.top() - cmr.top() ); + break; + case RowAlignCenter: + case RowAlignBaseline: + child_rel_origin.setY( mr.top() - cmr.top() + ( mr.height() - cmr.height() ) / 2 ); + break; + case RowAlignBottom: + child_rel_origin.setY( mr.bottom() - cmr.bottom() ); + break; + case RowAlignAxis: + child_rel_origin.setY( 0 ); + break; + } + + child->setRelOrigin( child_rel_origin ); +} + +uint QwtMmlMtdNode::colNum() +{ + QwtMmlNode *syb = previousSibling(); + + uint i = 0; + for ( ; syb != 0; syb = syb->previousSibling() ) + ++i; + + return i; +} + +uint QwtMmlMtdNode::rowNum() +{ + QwtMmlNode *row = parent()->previousSibling(); + + uint i = 0; + for ( ; row != 0; row = row->previousSibling() ) + ++i; + + return i; +} + +QwtMmlMtdNode::ColAlign QwtMmlMtdNode::columnalign() +{ + QString val = explicitAttribute( "columnalign" ); + if ( !val.isNull() ) + return interpretColAlign( val, 0, 0 ); + + QwtMmlNode *node = parent(); // + if ( node == 0 ) + return ColAlignCenter; + + uint colnum = colNum(); + val = node->explicitAttribute( "columnalign" ); + if ( !val.isNull() ) + return interpretColAlign( val, colnum, 0 ); + + node = node->parent(); // + if ( node == 0 ) + return ColAlignCenter; + + val = node->explicitAttribute( "columnalign" ); + if ( !val.isNull() ) + return interpretColAlign( val, colnum, 0 ); + + return ColAlignCenter; +} + +QwtMmlMtdNode::RowAlign QwtMmlMtdNode::rowalign() +{ + QString val = explicitAttribute( "rowalign" ); + if ( !val.isNull() ) + return interpretRowAlign( val, 0, 0 ); + + QwtMmlNode *node = parent(); // + if ( node == 0 ) + return RowAlignAxis; + + uint rownum = rowNum(); + val = node->explicitAttribute( "rowalign" ); + if ( !val.isNull() ) + return interpretRowAlign( val, rownum, 0 ); + + node = node->parent(); // + if ( node == 0 ) + return RowAlignAxis; + + val = node->explicitAttribute( "rowalign" ); + if ( !val.isNull() ) + return interpretRowAlign( val, rownum, 0 ); + + return RowAlignAxis; +} + +void QwtMmlMoverNode::layoutSymbol() +{ + QwtMmlNode *base = firstChild(); + Q_ASSERT( base != 0 ); + QwtMmlNode *over = base->nextSibling(); + Q_ASSERT( over != 0 ); + + QRect base_rect = base->myRect(); + QRect over_rect = over->myRect(); + + int spacing = ( int )( g_mfrac_spacing * ( over_rect.height() + + base_rect.height() ) ); + + base->setRelOrigin( QPoint( -base_rect.width() / 2, 0 ) ); + over->setRelOrigin( QPoint( -over_rect.width() / 2, + base_rect.top() - spacing - over_rect.bottom() ) ); +} + +int QwtMmlMoverNode::scriptlevel( const QwtMmlNode *node ) const +{ + QwtMmlNode *base = firstChild(); + Q_ASSERT( base != 0 ); + QwtMmlNode *over = base->nextSibling(); + Q_ASSERT( over != 0 ); + + int sl = QwtMmlNode::scriptlevel(); + if ( node != 0 && node == over ) + return sl + 1; + else + return sl; +} + +void QwtMmlMunderNode::layoutSymbol() +{ + QwtMmlNode *base = firstChild(); + Q_ASSERT( base != 0 ); + QwtMmlNode *under = base->nextSibling(); + Q_ASSERT( under != 0 ); + + QRect base_rect = base->myRect(); + QRect under_rect = under->myRect(); + + int spacing = ( int )( g_mfrac_spacing * ( under_rect.height() + base_rect.height() ) ); + + base->setRelOrigin( QPoint( -base_rect.width() / 2, 0 ) ); + under->setRelOrigin( QPoint( -under_rect.width() / 2, base_rect.bottom() + spacing - under_rect.top() ) ); +} + +int QwtMmlMunderNode::scriptlevel( const QwtMmlNode *node ) const +{ + QwtMmlNode *base = firstChild(); + Q_ASSERT( base != 0 ); + QwtMmlNode *under = base->nextSibling(); + Q_ASSERT( under != 0 ); + + int sl = QwtMmlNode::scriptlevel(); + if ( node != 0 && node == under ) + return sl + 1; + else + return sl; +} + +void QwtMmlMunderoverNode::layoutSymbol() +{ + QwtMmlNode *base = firstChild(); + Q_ASSERT( base != 0 ); + QwtMmlNode *under = base->nextSibling(); + Q_ASSERT( under != 0 ); + QwtMmlNode *over = under->nextSibling(); + Q_ASSERT( over != 0 ); + + QRect base_rect = base->myRect(); + QRect under_rect = under->myRect(); + QRect over_rect = over->myRect(); + + int spacing = ( int )( g_mfrac_spacing * ( base_rect.height() + + under_rect.height() + + over_rect.height() ) ); + + base->setRelOrigin( QPoint( -base_rect.width() / 2, 0 ) ); + under->setRelOrigin( QPoint( -under_rect.width() / 2, base_rect.bottom() + spacing - under_rect.top() ) ); + over->setRelOrigin( QPoint( -over_rect.width() / 2, base_rect.top() - spacing - under_rect.bottom() ) ); +} + +int QwtMmlMunderoverNode::scriptlevel( const QwtMmlNode *node ) const +{ + QwtMmlNode *base = firstChild(); + Q_ASSERT( base != 0 ); + QwtMmlNode *under = base->nextSibling(); + Q_ASSERT( under != 0 ); + QwtMmlNode *over = under->nextSibling(); + Q_ASSERT( over != 0 ); + + int sl = QwtMmlNode::scriptlevel(); + if ( node != 0 && ( node == under || node == over ) ) + return sl + 1; + else + return sl; +} + +int QwtMmlMpaddedNode::interpretSpacing( QString value, int base_value, bool *ok ) const +{ + if ( ok != 0 ) + *ok = false; + + value.replace( ' ', "" ); + + QString sign, factor_str, pseudo_unit; + bool percent = false; + + // extract the sign + int idx = 0; + if ( idx < value.length() && ( value.at( idx ) == '+' || value.at( idx ) == '-' ) ) + sign = value.at( idx++ ); + + // extract the factor + while ( idx < value.length() && ( value.at( idx ).isDigit() || value.at( idx ) == '.' ) ) + factor_str.append( value.at( idx++ ) ); + + // extract the % sign + if ( idx < value.length() && value.at( idx ) == '%' ) + { + percent = true; + ++idx; + } + + // extract the pseudo-unit + pseudo_unit = value.mid( idx ); + + bool float_ok; + double factor = factor_str.toFloat( &float_ok ); + if ( !float_ok || factor < 0 ) + { + qWarning( "MmlMpaddedNode::interpretSpacing(): could not parse \"%s\"", value.toLatin1().data() ); + return 0; + } + + if ( percent ) + factor /= 100.0; + + QRect cr; + if ( firstChild() == 0 ) + cr = QRect( 0, 0, 0, 0 ); + else + cr = firstChild()->myRect(); + + int unit_size; + + if ( pseudo_unit.isEmpty() ) + unit_size = base_value; + else if ( pseudo_unit == "width" ) + unit_size = cr.width(); + else if ( pseudo_unit == "height" ) + unit_size = -cr.top(); + else if ( pseudo_unit == "depth" ) + unit_size = cr.bottom(); + else + { + bool unit_ok; + unit_size = QwtMmlNode::interpretSpacing( "1" + pseudo_unit, &unit_ok ); + if ( !unit_ok ) + { + qWarning( "MmlMpaddedNode::interpretSpacing(): could not parse \"%s\"", value.toLatin1().data() ); + return 0; + } + } + + if ( ok != 0 ) + *ok = true; + + if ( sign.isNull() ) + return ( int )( factor * unit_size ); + else if ( sign == "+" ) + return base_value + ( int )( factor * unit_size ); + else // sign == "-" + return base_value - ( int )( factor * unit_size ); +} + +int QwtMmlMpaddedNode::lspace() const +{ + QString value = explicitAttribute( "lspace" ); + + if ( value.isNull() ) + return 0; + + bool ok; + int lspace = interpretSpacing( value, 0, &ok ); + + if ( ok ) + return lspace; + + return 0; +} + +int QwtMmlMpaddedNode::width() const +{ + int child_width = 0; + if ( firstChild() != 0 ) + child_width = firstChild()->myRect().width(); + + QString value = explicitAttribute( "width" ); + if ( value.isNull() ) + return child_width; + + bool ok; + int w = interpretSpacing( value, child_width, &ok ); + if ( ok ) + return w; + + return child_width; +} + +int QwtMmlMpaddedNode::height() const +{ + QRect cr; + if ( firstChild() == 0 ) + cr = QRect( 0, 0, 0, 0 ); + else + cr = firstChild()->myRect(); + + QString value = explicitAttribute( "height" ); + if ( value.isNull() ) + return -cr.top(); + + bool ok; + int h = interpretSpacing( value, -cr.top(), &ok ); + if ( ok ) + return h; + + return -cr.top(); +} + +int QwtMmlMpaddedNode::depth() const +{ + QRect cr; + if ( firstChild() == 0 ) + cr = QRect( 0, 0, 0, 0 ); + else + cr = firstChild()->myRect(); + + QString value = explicitAttribute( "depth" ); + if ( value.isNull() ) + return cr.bottom(); + + bool ok; + int h = interpretSpacing( value, cr.bottom(), &ok ); + if ( ok ) + return h; + + return cr.bottom(); +} + +void QwtMmlMpaddedNode::layoutSymbol() +{ + QwtMmlNode *child = firstChild(); + if ( child == 0 ) + return; + + child->setRelOrigin( QPoint( 0, 0 ) ); +} + + +QRect QwtMmlMpaddedNode::symbolRect() const +{ + return QRect( -lspace(), -height(), lspace() + width(), height() + depth() ); +} + +// ******************************************************************* +// Static helper functions +// ******************************************************************* + +static QString entityDeclarations() +{ + QString result = "name != 0; ++ent ) + { + result += "\tname ) + " \"" + ent->value + "\">\n"; + } + + result += "]>\n"; + + return result; +} + +static int interpretSpacing( QString value, int em, int ex, bool *ok ) +{ + if ( ok != 0 ) + *ok = true; + + if ( value == "thin" ) + return 1; + + if ( value == "medium" ) + return 2; + + if ( value == "thick" ) + return 3; + + struct HSpacingValue + { + const char *name; + float factor; + }; + + static const HSpacingValue g_h_spacing_data[] = + { + { "veryverythinmathspace", ( float ) 0.0555556 }, + { "verythinmathspace", ( float ) 0.111111 }, + { "thinmathspace", ( float ) 0.166667 }, + { "mediummathspace", ( float ) 0.222222 }, + { "thickmathspace", ( float ) 0.277778 }, + { "verythickmathspace", ( float ) 0.333333 }, + { "veryverythickmathspace", ( float ) 0.388889 }, + { 0, ( float ) 0 } + }; + + const HSpacingValue *v = g_h_spacing_data; + for ( ; v->name != 0; ++v ) + { + if ( value == v->name ) + return ( int )( em * v->factor ); + } + + if ( value.endsWith( "em" ) ) + { + value.truncate( value.length() - 2 ); + bool float_ok; + float factor = value.toFloat( &float_ok ); + if ( float_ok && factor >= 0 ) + return ( int )( em * factor ); + else + { + qWarning( "interpretSpacing(): could not parse \"%sem\"", value.toLatin1().data() ); + if ( ok != 0 ) + *ok = false; + return 0; + } + } + + if ( value.endsWith( "ex" ) ) + { + value.truncate( value.length() - 2 ); + bool float_ok; + float factor = value.toFloat( &float_ok ); + if ( float_ok && factor >= 0 ) + return ( int )( ex * factor ); + else + { + qWarning( "interpretSpacing(): could not parse \"%sex\"", value.toLatin1().data() ); + if ( ok != 0 ) + *ok = false; + return 0; + } + } + + if ( value.endsWith( "cm" ) ) + { + value.truncate( value.length() - 2 ); + bool float_ok; + float factor = value.toFloat( &float_ok ); + if ( float_ok && factor >= 0 ) + { + Q_ASSERT( qApp->desktop() != 0 ); + QDesktopWidget *dw = qApp->desktop(); + Q_ASSERT( dw->width() != 0 ); + Q_ASSERT( dw->widthMM() != 0 ); + return ( int )( factor * 10 * dw->width() / dw->widthMM() ); + } + else + { + qWarning( "interpretSpacing(): could not parse \"%scm\"", value.toLatin1().data() ); + if ( ok != 0 ) + *ok = false; + return 0; + } + } + + if ( value.endsWith( "mm" ) ) + { + value.truncate( value.length() - 2 ); + bool float_ok; + float factor = value.toFloat( &float_ok ); + if ( float_ok && factor >= 0 ) + { + Q_ASSERT( qApp->desktop() != 0 ); + QDesktopWidget *dw = qApp->desktop(); + Q_ASSERT( dw->width() != 0 ); + Q_ASSERT( dw->widthMM() != 0 ); + return ( int )( factor * dw->width() / dw->widthMM() ); + } + else + { + qWarning( "interpretSpacing(): could not parse \"%smm\"", value.toLatin1().data() ); + if ( ok != 0 ) + *ok = false; + return 0; + } + } + + if ( value.endsWith( "in" ) ) + { + value.truncate( value.length() - 2 ); + bool float_ok; + float factor = value.toFloat( &float_ok ); + if ( float_ok && factor >= 0 ) + { + Q_ASSERT( qApp->desktop() != 0 ); + QDesktopWidget *dw = qApp->desktop(); + Q_ASSERT( dw->width() != 0 ); + Q_ASSERT( dw->widthMM() != 0 ); + return ( int )( factor * 10 * dw->width() / ( 2.54 * dw->widthMM() ) ); + } + else + { + qWarning( "interpretSpacing(): could not parse \"%sin\"", value.toLatin1().data() ); + if ( ok != 0 ) + *ok = false; + return 0; + } + } + + if ( value.endsWith( "px" ) ) + { + value.truncate( value.length() - 2 ); + bool float_ok; + int i = ( int ) value.toFloat( &float_ok ); + if ( float_ok && i >= 0 ) + return i; + else + { + qWarning( "interpretSpacing(): could not parse \"%spx\"", value.toLatin1().data() ); + if ( ok != 0 ) + *ok = false; + return 0; + } + } + + bool float_ok; + int i = ( int )value.toFloat( &float_ok ); + if ( float_ok && i >= 0 ) + return i; + + qWarning( "interpretSpacing(): could not parse \"%s\"", value.toLatin1().data() ); + if ( ok != 0 ) + *ok = false; + return 0; +} + +static int interpretPercentSpacing( QString value, int base, bool *ok ) +{ + if ( !value.endsWith( "%" ) ) + { + if ( ok != 0 ) + *ok = false; + return 0; + } + + value.truncate( value.length() - 1 ); + bool float_ok; + float factor = value.toFloat( &float_ok ); + if ( float_ok && factor >= 0 ) + { + if ( ok != 0 ) + *ok = true; + return ( int )( base * factor / 100.0 ); + } + + qWarning( "interpretPercentSpacing(): could not parse \"%s%%\"", value.toLatin1().data() ); + if ( ok != 0 ) + *ok = false; + return 0; +} + +static int interpretPointSize( QString value, bool *ok ) +{ + if ( !value.endsWith( "pt" ) ) + { + if ( ok != 0 ) + *ok = false; + return 0; + } + + value.truncate( value.length() - 2 ); + bool float_ok; + int pt_size = ( int ) value.toFloat( &float_ok ); + if ( float_ok && pt_size > 0 ) + { + if ( ok != 0 ) + *ok = true; + return pt_size; + } + + qWarning( "interpretPointSize(): could not parse \"%spt\"", value.toLatin1().data() ); + if ( ok != 0 ) + *ok = false; + return 0; +} + +static const QwtMmlNodeSpec *mmlFindNodeSpec( QwtMml::NodeType type ) +{ + const QwtMmlNodeSpec *spec = g_node_spec_data; + for ( ; spec->type != QwtMml::NoNode; ++spec ) + { + if ( type == spec->type ) return spec; + } + return 0; +} + +static const QwtMmlNodeSpec *mmlFindNodeSpec( const QString &tag ) +{ + const QwtMmlNodeSpec *spec = g_node_spec_data; + for ( ; spec->type != QwtMml::NoNode; ++spec ) + { + if ( tag == spec->tag ) return spec; + } + return 0; +} + +static bool mmlCheckChildType( QwtMml::NodeType parent_type, QwtMml::NodeType child_type, + QString *error_str ) +{ + if ( parent_type == QwtMml::UnknownNode || child_type == QwtMml::UnknownNode ) + return true; + + const QwtMmlNodeSpec *child_spec = mmlFindNodeSpec( child_type ); + const QwtMmlNodeSpec *parent_spec = mmlFindNodeSpec( parent_type ); + + Q_ASSERT( parent_spec != 0 ); + Q_ASSERT( child_spec != 0 ); + + QString allowed_child_types( parent_spec->child_types ); + // null list means any child type is valid + if ( allowed_child_types.isNull() ) + return true; + + QString child_type_str = QString( " " ) + child_spec->type_str + " "; + if ( !allowed_child_types.contains( child_type_str ) ) + { + if ( error_str != 0 ) + *error_str = QString( "illegal child " ) + + child_spec->type_str + + " for parent " + + parent_spec->type_str; + return false; + } + + return true; +} + +static bool mmlCheckAttributes( QwtMml::NodeType child_type, const QwtMmlAttributeMap &attr, + QString *error_str ) +{ + const QwtMmlNodeSpec *spec = mmlFindNodeSpec( child_type ); + Q_ASSERT( spec != 0 ); + + QString allowed_attr( spec->attributes ); + // empty list means any attr is valid + if ( allowed_attr.isEmpty() ) + return true; + + QwtMmlAttributeMap::const_iterator it = attr.begin(), end = attr.end(); + for ( ; it != end; ++it ) + { + QString name = it.key(); + + if ( name.indexOf( ':' ) != -1 ) + continue; + + QString padded_name = " " + name + " "; + if ( !allowed_attr.contains( padded_name ) ) + { + if ( error_str != 0 ) + *error_str = QString( "illegal attribute " ) + + name + + " in " + + spec->type_str; + return false; + } + } + + return true; +} + +static int attributeIndex( const QString &name ) +{ + for ( unsigned i = 0; i < g_oper_spec_rows; ++i ) + { + if ( name == g_oper_spec_names[i] ) + return i; + } + return -1; +} + +static QString decodeEntityValue( QString literal ) +{ + QString result; + + while ( !literal.isEmpty() ) + { + + if ( !literal.startsWith( "&#" ) ) + { + qWarning( ( "decodeEntityValue(): bad entity literal: \"" + literal + "\"" ).toLatin1().data() ); + return QString::null; + } + + literal = literal.right( literal.length() - 2 ); + + int i = literal.indexOf( ';' ); + if ( i == -1 ) + { + qWarning( ( "decodeEntityValue(): bad entity literal: \"" + literal + "\"" ).toLatin1().data() ); + return QString::null; + } + + QString char_code = literal.left( i ); + literal = literal.right( literal.length() - i - 1 ); + + if ( char_code.isEmpty() ) + { + qWarning( ( "decodeEntityValue(): bad entity literal: \"" + literal + "\"" ).toLatin1().data() ); + return QString::null; + } + + if ( char_code.at( 0 ) == 'x' ) + { + char_code = char_code.right( char_code.length() - 1 ); + bool ok; + unsigned c = char_code.toUInt( &ok, 16 ); + if ( !ok ) + { + qWarning( ( "decodeEntityValue(): bad entity literal: \"" + literal + "\"" ).toLatin1().data() ); + return QString::null; + } + result += QChar( c ); + } + else + { + bool ok; + unsigned c = char_code.toUInt( &ok, 10 ); + if ( !ok ) + { + qWarning( ( "decodeEntityValue(): bad entity literal: \"" + literal + "\"" ).toLatin1().data() ); + return QString::null; + } + result += QChar( c ); + } + } + + return result; +} + +static const QwtMmlEntitySpec *searchEntitySpecData( const QString &value, const QwtMmlEntitySpec *from = 0 ) +{ + const QwtMmlEntitySpec *ent = from; + if ( ent == 0 ) + ent = g_xml_entity_data; + for ( ; ent->name != 0; ++ent ) + { + QString ent_value = decodeEntityValue( ent->value ); + if ( value == ent_value ) + return ent; + } + return 0; +} + +struct OperSpecSearchResult +{ + OperSpecSearchResult() { prefix_form = infix_form = postfix_form = 0; } + + const QwtMmlOperSpec *prefix_form, + *infix_form, + *postfix_form; + + const QwtMmlOperSpec *&getForm( QwtMml::FormType f ); + bool haveForm( QwtMml::FormType f ) + { return getForm( f ) != 0; } + void addForm( const QwtMmlOperSpec *spec ) + { getForm( spec->form ) = spec; } +}; + +const QwtMmlOperSpec *&OperSpecSearchResult::getForm( QwtMml::FormType f ) +{ + switch ( f ) + { + case QwtMml::PrefixForm: + return prefix_form; + case QwtMml::InfixForm: + return infix_form; + case QwtMml::PostfixForm: + return postfix_form; + } + return postfix_form; // just to avoid warning +} + +/* + Searches g_oper_spec_data and returns any instance of operator name. There may + be more instances, but since the list is sorted, they will be next to each other. +*/ +static const QwtMmlOperSpec *searchOperSpecData( const QString &name ) +{ + const char *name_latin1 = name.toLatin1().data(); + + // binary search + // establish invariant g_oper_spec_data[begin].name < name < g_oper_spec_data[end].name + + int cmp = qstrcmp( name_latin1, g_oper_spec_data[0].name ); + if ( cmp < 0 ) + return 0; + + if ( cmp == 0 ) + return g_oper_spec_data; + + uint begin = 0; + uint end = g_oper_spec_count; + + // invariant holds + while ( end - begin > 1 ) + { + uint mid = ( begin + end ) / 2; + + const QwtMmlOperSpec *spec = g_oper_spec_data + mid; + int cmp = qstrcmp( name_latin1, spec->name ); + if ( cmp < 0 ) + end = mid; + else if ( cmp > 0 ) + begin = mid; + else + return spec; + } + + return 0; +} + +/* + This searches g_oper_spec_data until at least one name in name_list is found with FormType form, + or until name_list is exhausted. The idea here is that if we don't find the operator in the + specified form, we still want to use some other available form of that operator. +*/ +static OperSpecSearchResult _mmlFindOperSpec( const QStringList &name_list, QwtMml::FormType form ) +{ + OperSpecSearchResult result; + + QStringList::const_iterator it = name_list.begin(); + for ( ; it != name_list.end(); ++it ) + { + const QString &name = *it; + + const QwtMmlOperSpec *spec = searchOperSpecData( name ); + + if ( spec == 0 ) + continue; + + const char *name_latin1 = name.toLatin1().data(); + + // backtrack to the first instance of name + while ( spec > g_oper_spec_data && qstrcmp( ( spec - 1 )->name, name_latin1 ) == 0 ) + --spec; + + // iterate over instances of name until the instances are exhausted or until we + // find an instance in the specified form. + do + { + result.addForm( spec++ ); + if ( result.haveForm( form ) ) + break; + } + while ( qstrcmp( spec->name, name_latin1 ) == 0 ); + + if ( result.haveForm( form ) ) + break; + } + + return result; +} + +/* + text is a string between and . It can be a character ('+'), an + entity reference ("∞") or a character reference ("∞"). Our + job is to find an operator spec in the operator dictionary (g_oper_spec_data) + that matches text. Things are further complicated by the fact, that many + operators come in several forms (prefix, infix, postfix). + + If available, this function returns an operator spec matching text in the specified + form. If such operator is not available, returns an operator spec that matches + text, but of some other form in the preference order specified by the MathML spec. + If that's not available either, returns the default operator spec. +*/ +static const QwtMmlOperSpec *mmlFindOperSpec( const QString &text, QwtMml::FormType form ) +{ + QStringList name_list; + name_list.append( text ); + + // First, just try to find text in the operator dictionary. + OperSpecSearchResult result = _mmlFindOperSpec( name_list, form ); + + if ( !result.haveForm( form ) ) + { + // Try to find other names for the operator represented by text. + + const QwtMmlEntitySpec *ent = 0; + for ( ;; ) + { + ent = searchEntitySpecData( text, ent ); + if ( ent == 0 ) + break; + name_list.append( '&' + QString( ent->name ) + ';' ); + ++ent; + } + + result = _mmlFindOperSpec( name_list, form ); + } + + const QwtMmlOperSpec *spec = result.getForm( form ); + if ( spec != 0 ) + return spec; + + spec = result.getForm( QwtMml::InfixForm ); + if ( spec != 0 ) + return spec; + + spec = result.getForm( QwtMml::PostfixForm ); + if ( spec != 0 ) + return spec; + + spec = result.getForm( QwtMml::PrefixForm ); + if ( spec != 0 ) + return spec; + + return &g_oper_spec_defaults; +} + +static QString mmlDictAttribute( const QString &name, const QwtMmlOperSpec *spec ) +{ + int i = attributeIndex( name ); + if ( i == -1 ) + return QString::null; + else + return spec->attributes[i]; +} + +static uint interpretMathVariant( const QString &value, bool *ok ) +{ + struct MathVariantValue + { + const char *value; + uint mv; + }; + + static const MathVariantValue g_mv_data[] = + { + { "normal", QwtMml::NormalMV }, + { "bold", QwtMml::BoldMV }, + { "italic", QwtMml::ItalicMV }, + { "bold-italic", QwtMml::BoldMV | QwtMml::ItalicMV }, + { "double-struck", QwtMml::DoubleStruckMV }, + { "bold-fraktur", QwtMml::BoldMV | QwtMml::FrakturMV }, + { "script", QwtMml::ScriptMV }, + { "bold-script", QwtMml::BoldMV | QwtMml::ScriptMV }, + { "fraktur", QwtMml::FrakturMV }, + { "sans-serif", QwtMml::SansSerifMV }, + { "bold-sans-serif", QwtMml::BoldMV | QwtMml::SansSerifMV }, + { "sans-serif-italic", QwtMml::SansSerifMV | QwtMml::ItalicMV }, + { "sans-serif-bold-italic", QwtMml::SansSerifMV | QwtMml::ItalicMV | QwtMml::BoldMV }, + { "monospace", QwtMml::MonospaceMV }, + { 0, 0 } + }; + + const MathVariantValue *v = g_mv_data; + for ( ; v->value != 0; ++v ) + { + if ( value == v->value ) + { + if ( ok != 0 ) + *ok = true; + return v->mv; + } + } + + if ( ok != 0 ) + *ok = false; + + qWarning( "interpretMathVariant(): could not parse value: \"%s\"", value.toLatin1().data() ); + + return QwtMml::NormalMV; +} + +static QwtMml::FormType interpretForm( const QString &value, bool *ok ) +{ + if ( ok != 0 ) + *ok = true; + + if ( value == "prefix" ) + return QwtMml::PrefixForm; + if ( value == "infix" ) + return QwtMml::InfixForm; + if ( value == "postfix" ) + return QwtMml::PostfixForm; + + if ( ok != 0 ) + *ok = false; + + qWarning( "interpretForm(): could not parse value \"%s\"", value.toLatin1().data() ); + return QwtMml::InfixForm; +} + +static QwtMml::ColAlign interpretColAlign( const QString &value_list, uint colnum, bool *ok ) +{ + QString value = interpretListAttr( value_list, colnum, "center" ); + + if ( ok != 0 ) + *ok = true; + + if ( value == "left" ) + return QwtMml::ColAlignLeft; + if ( value == "right" ) + return QwtMml::ColAlignRight; + if ( value == "center" ) + return QwtMml::ColAlignCenter; + + if ( ok != 0 ) + *ok = false; + + qWarning( "interpretColAlign(): could not parse value \"%s\"", value.toLatin1().data() ); + return QwtMml::ColAlignCenter; +} + +static QwtMml::RowAlign interpretRowAlign( const QString &value_list, uint rownum, bool *ok ) +{ + QString value = interpretListAttr( value_list, rownum, "axis" ); + + if ( ok != 0 ) + *ok = true; + + if ( value == "top" ) + return QwtMml::RowAlignTop; + if ( value == "center" ) + return QwtMml::RowAlignCenter; + if ( value == "bottom" ) + return QwtMml::RowAlignBottom; + if ( value == "baseline" ) + return QwtMml::RowAlignBaseline; + if ( value == "axis" ) + return QwtMml::RowAlignAxis; + + if ( ok != 0 ) + *ok = false; + + qWarning( "interpretRowAlign(): could not parse value \"%s\"", value.toLatin1().data() ); + return QwtMml::RowAlignAxis; +} + +static QString interpretListAttr( const QString &value_list, int idx, const QString &def ) +{ + QStringList l = value_list.split( ' ' ); + + if ( l.count() == 0 ) + return def; + + if ( l.count() <= idx ) + return l[l.count() - 1]; + else + return l[idx]; +} + +static QwtMml::FrameType interpretFrameType( const QString &value_list, uint idx, bool *ok ) +{ + if ( ok != 0 ) + *ok = true; + + QString value = interpretListAttr( value_list, idx, "none" ); + + if ( value == "none" ) + return QwtMml::FrameNone; + if ( value == "solid" ) + return QwtMml::FrameSolid; + if ( value == "dashed" ) + return QwtMml::FrameDashed; + + if ( ok != 0 ) + *ok = false; + + qWarning( "interpretFrameType(): could not parse value \"%s\"", value.toLatin1().data() ); + return QwtMml::FrameNone; +} + + +static QwtMml::FrameSpacing interpretFrameSpacing( const QString &value_list, int em, int ex, bool *ok ) +{ + QwtMml::FrameSpacing fs; + + QStringList l = value_list.split( ' ' ); + if ( l.count() != 2 ) + { + qWarning( "interpretFrameSpacing: could not parse value \"%s\"", value_list.toLatin1().data() ); + if ( ok != 0 ) + *ok = false; + return QwtMml::FrameSpacing( ( int )( 0.4 * em ), ( int )( 0.5 * ex ) ); + } + + bool hor_ok, ver_ok; + fs.m_hor = interpretSpacing( l[0], em, ex, &hor_ok ); + fs.m_ver = interpretSpacing( l[1], em, ex, &ver_ok ); + + if ( ok != 0 ) + *ok = hor_ok && ver_ok; + + return fs; +} + +static QFont interpretDepreciatedFontAttr( const QwtMmlAttributeMap &font_attr, QFont &fn, int em, int ex ) +{ + if ( font_attr.contains( "fontsize" ) ) + { + QString value = font_attr["fontsize"]; + + for ( ;; ) + { + + bool ok; + int ptsize = interpretPointSize( value, &ok ); + if ( ok ) + { + fn.setPointSize( ptsize ); + break; + } + + ptsize = interpretPercentSpacing( value, fn.pointSize(), &ok ); + if ( ok ) + { + fn.setPointSize( ptsize ); + break; + } + + int size = interpretSpacing( value, em, ex, &ok ); + if ( ok ) + { + fn.setPixelSize( size ); + break; + } + + break; + } + } + + if ( font_attr.contains( "fontweight" ) ) + { + QString value = font_attr["fontweight"]; + if ( value == "normal" ) + fn.setBold( false ); + else if ( value == "bold" ) + fn.setBold( true ); + else + qWarning( "interpretDepreciatedFontAttr(): could not parse fontweight \"%s\"", value.toLatin1().data() ); + } + + if ( font_attr.contains( "fontstyle" ) ) + { + QString value = font_attr["fontstyle"]; + if ( value == "normal" ) + fn.setItalic( false ); + else if ( value == "italic" ) + fn.setItalic( true ); + else + qWarning( "interpretDepreciatedFontAttr(): could not parse fontstyle \"%s\"", value.toLatin1().data() ); + } + + if ( font_attr.contains( "fontfamily" ) ) + { + QString value = font_attr["fontfamily"]; + fn.setFamily( value ); + } + + return fn; +} + +static QFont interpretMathSize( QString value, QFont &fn, int em, int ex, bool *ok ) +{ + if ( ok != 0 ) + *ok = true; + + if ( value == "small" ) + { + fn.setPointSize( ( int )( fn.pointSize() * 0.7 ) ); + return fn; + } + + if ( value == "normal" ) + return fn; + + if ( value == "big" ) + { + fn.setPointSize( ( int )( fn.pointSize() * 1.5 ) ); + return fn; + } + + bool size_ok; + + int ptsize = interpretPointSize( value, &size_ok ); + if ( size_ok ) + { + fn.setPointSize( ptsize ); + return fn; + } + + int size = interpretSpacing( value, em, ex, &size_ok ); + if ( size_ok ) + { + fn.setPixelSize( size ); + return fn; + } + + if ( ok != 0 ) + *ok = false; + qWarning( "interpretMathSize(): could not parse mathsize \"%s\"", value.toLatin1().data() ); + return fn; +} + +/*! + \class QwtMathMLDocument + + \brief The QwtMathMLDocument class renders mathematical formulas written in MathML 2.0. +*/ + +/*! + Constructs an empty MML document. +*/ +QwtMathMLDocument::QwtMathMLDocument() +{ + m_doc = new QwtMmlDocument; +} + +/*! + Destroys the MML document. +*/ +QwtMathMLDocument::~QwtMathMLDocument() +{ + delete m_doc; +} + +/*! + Clears the contents of this MML document. +*/ +void QwtMathMLDocument::clear() +{ + m_doc->clear(); +} + +/*! + Sets the MathML expression to be rendered. The expression is given + in the string \a text. If the expression is successfully parsed, + this method returns true; otherwise it returns false. If an error + occured \a errorMsg is set to a diagnostic message, while \a + errorLine and \a errorColumn contain the location of the error. + Any of \a errorMsg, \a errorLine and \a errorColumn may be 0, + in which case they are not set. + + \a text should contain MathML 2.0 presentation markup elements enclosed + in a element. +*/ +bool QwtMathMLDocument::setContent( QString text, QString *errorMsg, + int *errorLine, int *errorColumn ) +{ + return m_doc->setContent( text, errorMsg, errorLine, errorColumn ); +} + +/*! + Renders this MML document with the painter \a p at position \a pos. +*/ +void QwtMathMLDocument::paint( QPainter *p, const QPoint &pos ) const +{ + m_doc->paint( p, pos ); +} + +/*! + Returns the size of this MML document, as rendered, in pixels. +*/ +QSize QwtMathMLDocument::size() const +{ + return m_doc->size(); +} + +/*! + Returns the name of the font used to render the font \a type. + + \sa setFontName() setBaseFontPointSize() baseFontPointSize() QwtMathMLDocument::MmlFont +*/ +QString QwtMathMLDocument::fontName( QwtMathMLDocument::MmlFont type ) const +{ + return m_doc->fontName( type ); +} + +/*! + Sets the name of the font used to render the font \a type to \a name. + + \sa fontName() setBaseFontPointSize() baseFontPointSize() QwtMathMLDocument::MmlFont +*/ +void QwtMathMLDocument::setFontName( QwtMathMLDocument::MmlFont type, const QString &name ) +{ + m_doc->setFontName( type, name ); +} + +/*! + Returns the point size of the font used to render expressions + whose scriptlevel is 0. + + \sa setBaseFontPointSize() fontName() setFontName() +*/ +int QwtMathMLDocument::baseFontPointSize() const +{ + return m_doc->baseFontPointSize(); +} + +/*! + Sets the point \a size of the font used to render expressions + whose scriptlevel is 0. + + \sa baseFontPointSize() fontName() setFontName() +*/ +void QwtMathMLDocument::setBaseFontPointSize( int size ) +{ + m_doc->setBaseFontPointSize( size ); +} diff --git a/qwt/textengines/mathml/qwt_mml_document.h b/qwt/textengines/mathml/qwt_mml_document.h new file mode 100644 index 000000000..1d9ce0b9b --- /dev/null +++ b/qwt/textengines/mathml/qwt_mml_document.h @@ -0,0 +1,45 @@ +#ifndef _QWT_MML_DOCUMENT_H_ +#define _QWT_MML_DOCUMENT_H_ 1 + +#include +#include + +class QPainter; +class QPoint; + +class QwtMmlDocument; + +class QWT_EXPORT QwtMathMLDocument +{ +public: + enum MmlFont + { + NormalFont, + FrakturFont, + SansSerifFont, + ScriptFont, + MonospaceFont, + DoublestruckFont + }; + + QwtMathMLDocument(); + ~QwtMathMLDocument(); + + void clear(); + + bool setContent( QString text, QString *errorMsg = 0, + int *errorLine = 0, int *errorColumn = 0 ); + void paint( QPainter *p, const QPoint &pos ) const; + QSize size() const; + + QString fontName( MmlFont type ) const; + void setFontName( MmlFont type, const QString &name ); + + int baseFontPointSize() const; + void setBaseFontPointSize( int size ); + +private: + QwtMmlDocument *m_doc; +}; + +#endif diff --git a/qwt/textengines/mathml/qwtmathml.prf b/qwt/textengines/mathml/qwtmathml.prf new file mode 100644 index 000000000..288303762 --- /dev/null +++ b/qwt/textengines/mathml/qwtmathml.prf @@ -0,0 +1,37 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include ( ./qwtconfig.pri ) + +contains(QWT_CONFIG, QwtDll) { + + DEFINES *= QWT_DLL +} + +QT *= xml + +contains(QWT_CONFIG, QwtFramework) { + + INCLUDEPATH *= $${QWT_INSTALL_LIBS}/qwtmathml.framework/Headers + LIBS *= -F$${QWT_INSTALL_LIBS} +} +else { + + INCLUDEPATH *= $${QWT_INSTALL_HEADERS} + LIBS *= -L$${QWT_INSTALL_LIBS} +} + +INCLUDEPATH_QWTMATHML = $${INCLUDEPATH} +qtAddLibrary(qwtmathml) + +# we don't want qtAddLibrary to expand the +# include path, with directories, that might +# conflict with other installations of qwt + +INCLUDEPATH = $${INCLUDEPATH_QWTMATHML}