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