1 #include <QApplication>
2 #include <QMap>
3 #include <QDesktopWidget>
4 #include <QPainter>
5 #include <QDomNode>
6 #include <QDebug>
7
8 #include "qwt_mml_document.h"
9
10 // *******************************************************************
11 // Declarations
12 // *******************************************************************
13
14 #define ROUND(a) (int)((a)+.5)
15
16 static bool g_draw_frames = false;
17 static const double g_mfrac_spacing = 0.1;
18 static const double g_mroot_base_margin = 0.1;
19 static const double g_script_size_multiplier = 0.7071; // sqrt(1/2)
20 static const int g_min_font_point_size = 8;
21 static const QChar g_radical_char = QChar( 0x1A, 0x22 );
22 static const unsigned g_oper_spec_rows = 9;
23
24 struct QwtMml
25 {
26 enum NodeType
27 {
28 NoNode = 0, MiNode, MnNode, MfracNode, MrowNode, MsqrtNode,
29 MrootNode, MsupNode, MsubNode, MsubsupNode, MoNode,
30 MstyleNode, TextNode, MphantomNode, MfencedNode,
31 MtableNode, MtrNode, MtdNode, MoverNode, MunderNode,
32 MunderoverNode, MerrorNode, MtextNode, MpaddedNode,
33 MspaceNode, MalignMarkNode, UnknownNode
34 };
35
36 enum MathVariant
37 {
38 NormalMV = 0x0000,
39 BoldMV = 0x0001,
40 ItalicMV = 0x0002,
41 DoubleStruckMV = 0x0004,
42 ScriptMV = 0x0008,
43 FrakturMV = 0x0010,
44 SansSerifMV = 0x0020,
45 MonospaceMV = 0x0040
46 };
47
48 enum FormType { PrefixForm, InfixForm, PostfixForm };
49 enum ColAlign { ColAlignLeft, ColAlignCenter, ColAlignRight };
50 enum RowAlign { RowAlignTop, RowAlignCenter, RowAlignBottom,
51 RowAlignAxis, RowAlignBaseline
52 };
53 enum FrameType { FrameNone, FrameSolid, FrameDashed };
54
55 struct FrameSpacing
56 {
FrameSpacingQwtMml::FrameSpacing57 FrameSpacing( int hor = 0, int ver = 0 )
58 : m_hor( hor ), m_ver( ver ) {}
59 int m_hor, m_ver;
60 };
61 };
62
63 struct QwtMmlOperSpec
64 {
65 enum StretchDir { NoStretch, HStretch, VStretch, HVStretch };
66
67 const char *name;
68 QwtMml::FormType form;
69 const char *attributes[g_oper_spec_rows];
70 StretchDir stretch_dir;
71 };
72
73 struct QwtMmlNodeSpec
74 {
75 QwtMml::NodeType type;
76 const char *tag;
77 const char *type_str;
78 int child_spec;
79 const char *child_types;
80 const char *attributes;
81
82 enum ChildSpec
83 {
84 ChildAny = -1, // any number of children allowed
85 ChildIgnore = -2, // do not build subexpression of children
86 ImplicitMrow = -3 // if more than one child, build mrow
87 };
88 };
89
90 struct QwtMmlEntitySpec
91 {
92 const char *name;
93 const char *value;
94 };
95
96 typedef QMap<QString, QString> QwtMmlAttributeMap;
97 class QwtMmlNode;
98
99 class QwtMmlDocument : public QwtMml
100 {
101 public:
102 QwtMmlDocument();
103 ~QwtMmlDocument();
104 void clear();
105
106 bool setContent( QString text, QString *errorMsg = 0,
107 int *errorLine = 0, int *errorColumn = 0 );
108 void paint( QPainter *p, const QPoint &pos ) const;
109 void dump() const;
110 QSize size() const;
111 void layout();
112
113 QString fontName( QwtMathMLDocument::MmlFont type ) const;
114 void setFontName( QwtMathMLDocument::MmlFont type, const QString &name );
115
baseFontPointSize() const116 int baseFontPointSize() const
117 { return m_base_font_point_size; }
setBaseFontPointSize(int size)118 void setBaseFontPointSize( int size )
119 { m_base_font_point_size = size; }
foregroundColor() const120 QColor foregroundColor() const
121 { return m_foreground_color; }
setForegroundColor(const QColor & color)122 void setForegroundColor( const QColor &color )
123 { m_foreground_color = color; }
backgroundColor() const124 QColor backgroundColor() const
125 { return m_background_color; }
setBackgroundColor(const QColor & color)126 void setBackgroundColor( const QColor &color )
127 { m_background_color = color; }
128
129 private:
130 void _dump( const QwtMmlNode *node, QString &indent ) const;
131 bool insertChild( QwtMmlNode *parent, QwtMmlNode *new_node, QString *errorMsg );
132
133 QwtMmlNode *domToMml( const QDomNode &dom_node, bool *ok, QString *errorMsg );
134 QwtMmlNode *createNode( NodeType type, const QwtMmlAttributeMap &mml_attr,
135 const QString &mml_value, QString *errorMsg );
136 QwtMmlNode *createImplicitMrowNode( const QDomNode &dom_node, bool *ok,
137 QString *errorMsg );
138
139 void insertOperator( QwtMmlNode *node, const QString &text );
140
141 QwtMmlNode *m_root_node;
142
143 QString m_normal_font_name;
144 QString m_fraktur_font_name;
145 QString m_sans_serif_font_name;
146 QString m_script_font_name;
147 QString m_monospace_font_name;
148 QString m_doublestruck_font_name;
149 int m_base_font_point_size;
150 QColor m_foreground_color;
151 QColor m_background_color;
152 };
153
154 class QwtMmlNode : public QwtMml
155 {
156 friend class QwtMmlDocument;
157
158 public:
159 QwtMmlNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map );
160 virtual ~QwtMmlNode();
161
162 // Mml stuff
nodeType() const163 NodeType nodeType() const
164 { return m_node_type; }
165
166 virtual QString toStr() const;
167
168 void setRelOrigin( const QPoint &rel_origin );
relOrigin() const169 QPoint relOrigin() const
170 { return m_rel_origin; }
171 void stretchTo( const QRect &rect );
isStretched() const172 bool isStretched() const
173 { return m_stretched; }
174 QPoint devicePoint( const QPoint &p ) const;
175
myRect() const176 QRect myRect() const
177 { return m_my_rect; }
178 QRect parentRect() const;
179 virtual QRect deviceRect() const;
180 void updateMyRect();
setMyRect(const QRect & rect)181 virtual void setMyRect( const QRect &rect )
182 { m_my_rect = rect; }
183
184 virtual void stretch();
185 virtual void layout();
186 virtual void paint( QPainter *p );
187
188 int basePos() const;
189 int overlinePos() const;
190 int underlinePos() const;
191 int em() const;
192 int ex() const;
193
194 QString explicitAttribute( const QString &name, const QString &def = QString() ) const;
195 QString inheritAttributeFromMrow( const QString &name, const QString &def = QString() ) const;
196
197 virtual QFont font() const;
198 virtual QColor color() const;
199 virtual QColor background() const;
200 virtual int scriptlevel( const QwtMmlNode *child = 0 ) const;
201
202
203 // Node stuff
document() const204 QwtMmlDocument *document() const
205 { return m_document; }
parent() const206 QwtMmlNode *parent() const
207 { return m_parent; }
firstChild() const208 QwtMmlNode *firstChild() const
209 { return m_first_child; }
nextSibling() const210 QwtMmlNode *nextSibling() const
211 { return m_next_sibling; }
previousSibling() const212 QwtMmlNode *previousSibling() const
213 { return m_previous_sibling; }
214 QwtMmlNode *lastSibling() const;
215 QwtMmlNode *firstSibling() const;
isLastSibling() const216 bool isLastSibling() const
217 { return m_next_sibling == 0; }
isFirstSibling() const218 bool isFirstSibling() const
219 { return m_previous_sibling == 0; }
hasChildNodes() const220 bool hasChildNodes() const
221 { return m_first_child != 0; }
222
223 protected:
224 virtual void layoutSymbol();
225 virtual void paintSymbol( QPainter *p ) const;
symbolRect() const226 virtual QRect symbolRect() const
227 { return QRect( 0, 0, 0, 0 ); }
228
229 QwtMmlNode *parentWithExplicitAttribute( const QString &name, NodeType type = NoNode );
230 int interpretSpacing( const QString &value, bool *ok ) const;
231
232 private:
233 QwtMmlAttributeMap m_attribute_map;
234 bool m_stretched;
235 QRect m_my_rect, m_parent_rect;
236 QPoint m_rel_origin;
237
238 NodeType m_node_type;
239 QwtMmlDocument *m_document;
240
241 QwtMmlNode *m_parent,
242 *m_first_child,
243 *m_next_sibling,
244 *m_previous_sibling;
245 };
246
247 class QwtMmlTokenNode : public QwtMmlNode
248 {
249 public:
QwtMmlTokenNode(NodeType type,QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)250 QwtMmlTokenNode( NodeType type, QwtMmlDocument *document,
251 const QwtMmlAttributeMap &attribute_map )
252 : QwtMmlNode( type, document, attribute_map ) {}
253
254 QString text() const;
255 };
256
257 class QwtMmlMphantomNode : public QwtMmlNode
258 {
259 public:
QwtMmlMphantomNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)260 QwtMmlMphantomNode( QwtMmlDocument *document,
261 const QwtMmlAttributeMap &attribute_map )
262 : QwtMmlNode( MphantomNode, document, attribute_map ) {}
263
paint(QPainter *)264 virtual void paint( QPainter * ) {}
265 };
266
267 class QwtMmlUnknownNode : public QwtMmlNode
268 {
269 public:
QwtMmlUnknownNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)270 QwtMmlUnknownNode( QwtMmlDocument *document,
271 const QwtMmlAttributeMap &attribute_map )
272 : QwtMmlNode( UnknownNode, document, attribute_map ) {}
273 };
274
275 class QwtMmlMfencedNode : public QwtMmlNode
276 {
277 public:
QwtMmlMfencedNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)278 QwtMmlMfencedNode( QwtMmlDocument *document,
279 const QwtMmlAttributeMap &attribute_map )
280 : QwtMmlNode( MfencedNode, document, attribute_map ) {}
281 };
282
283 class QwtMmlMalignMarkNode : public QwtMmlNode
284 {
285 public:
QwtMmlMalignMarkNode(QwtMmlDocument * document)286 QwtMmlMalignMarkNode( QwtMmlDocument *document )
287 : QwtMmlNode( MalignMarkNode, document, QwtMmlAttributeMap() ) {}
288 };
289
290 class QwtMmlMfracNode : public QwtMmlNode
291 {
292 public:
QwtMmlMfracNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)293 QwtMmlMfracNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
294 : QwtMmlNode( MfracNode, document, attribute_map ) {}
295
296 QwtMmlNode *numerator() const;
297 QwtMmlNode *denominator() const;
298
299 protected:
300 virtual void layoutSymbol();
301 virtual void paintSymbol( QPainter *p ) const;
302 virtual QRect symbolRect() const;
303 };
304
305 class QwtMmlMrowNode : public QwtMmlNode
306 {
307 public:
QwtMmlMrowNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)308 QwtMmlMrowNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
309 : QwtMmlNode( MrowNode, document, attribute_map ) {}
310 };
311
312 class QwtMmlRootBaseNode : public QwtMmlNode
313 {
314 public:
QwtMmlRootBaseNode(NodeType type,QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)315 QwtMmlRootBaseNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
316 : QwtMmlNode( type, document, attribute_map ) {}
317
318 QwtMmlNode *base() const;
319 QwtMmlNode *index() const;
320
321 virtual int scriptlevel( const QwtMmlNode *child = 0 ) const;
322
323 protected:
324 virtual void layoutSymbol();
325 virtual void paintSymbol( QPainter *p ) const;
326 virtual QRect symbolRect() const;
327 int tailWidth() const;
328 };
329
330 class QwtMmlMrootNode : public QwtMmlRootBaseNode
331 {
332 public:
QwtMmlMrootNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)333 QwtMmlMrootNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
334 : QwtMmlRootBaseNode( MrootNode, document, attribute_map ) {}
335 };
336
337 class QwtMmlMsqrtNode : public QwtMmlRootBaseNode
338 {
339 public:
QwtMmlMsqrtNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)340 QwtMmlMsqrtNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
341 : QwtMmlRootBaseNode( MsqrtNode, document, attribute_map ) {}
342
343 };
344
345
346 class QwtMmlTextNode : public QwtMmlNode
347 {
348 public:
349 QwtMmlTextNode( const QString &text, QwtMmlDocument *document );
350
351 virtual QString toStr() const;
text() const352 QString text() const
353 { return m_text; }
354
355 // TextNodes are not xml elements, so they can't have attributes of
356 // their own. Everything is taken from the parent.
font() const357 virtual QFont font() const
358 { return parent()->font(); }
scriptlevel(const QwtMmlNode * =0) const359 virtual int scriptlevel( const QwtMmlNode* = 0 ) const
360 { return parent()->scriptlevel( this ); }
color() const361 virtual QColor color() const
362 { return parent()->color(); }
background() const363 virtual QColor background() const
364 { return parent()->background(); }
365
366 protected:
367 virtual void paintSymbol( QPainter *p ) const;
368 virtual QRect symbolRect() const;
369
370 QString m_text;
371 };
372
373 class QwtMmlMiNode : public QwtMmlTokenNode
374 {
375 public:
QwtMmlMiNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)376 QwtMmlMiNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
377 : QwtMmlTokenNode( MiNode, document, attribute_map ) {}
378 };
379
380 class QwtMmlMnNode : public QwtMmlTokenNode
381 {
382 public:
QwtMmlMnNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)383 QwtMmlMnNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
384 : QwtMmlTokenNode( MnNode, document, attribute_map ) {}
385 };
386
387 class QwtMmlSubsupBaseNode : public QwtMmlNode
388 {
389 public:
QwtMmlSubsupBaseNode(NodeType type,QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)390 QwtMmlSubsupBaseNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
391 : QwtMmlNode( type, document, attribute_map ) {}
392
393 QwtMmlNode *base() const;
394 QwtMmlNode *sscript() const;
395
396 virtual int scriptlevel( const QwtMmlNode *child = 0 ) const;
397 };
398
399 class QwtMmlMsupNode : public QwtMmlSubsupBaseNode
400 {
401 public:
QwtMmlMsupNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)402 QwtMmlMsupNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
403 : QwtMmlSubsupBaseNode( MsupNode, document, attribute_map ) {}
404
405 protected:
406 virtual void layoutSymbol();
407 };
408
409 class QwtMmlMsubNode : public QwtMmlSubsupBaseNode
410 {
411 public:
QwtMmlMsubNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)412 QwtMmlMsubNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
413 : QwtMmlSubsupBaseNode( MsubNode, document, attribute_map ) {}
414
415 protected:
416 virtual void layoutSymbol();
417 };
418
419 class QwtMmlMsubsupNode : public QwtMmlNode
420 {
421 public:
QwtMmlMsubsupNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)422 QwtMmlMsubsupNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
423 : QwtMmlNode( MsubsupNode, document, attribute_map ) {}
424
425 QwtMmlNode *base() const;
426 QwtMmlNode *superscript() const;
427 QwtMmlNode *subscript() const;
428
429 virtual int scriptlevel( const QwtMmlNode *child = 0 ) const;
430
431 protected:
432 virtual void layoutSymbol();
433 };
434
435 class QwtMmlMoNode : public QwtMmlTokenNode
436 {
437 public:
438 QwtMmlMoNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map );
439
440 QString dictionaryAttribute( const QString &name ) const;
441 virtual void stretch();
442 virtual int lspace() const;
443 virtual int rspace() const;
444
445 virtual QString toStr() const;
446
447 protected:
448 virtual void layoutSymbol();
449 virtual QRect symbolRect() const;
450
451 virtual FormType form() const;
452
453 private:
454 const QwtMmlOperSpec *m_oper_spec;
455 };
456
457 class QwtMmlMstyleNode : public QwtMmlNode
458 {
459 public:
QwtMmlMstyleNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)460 QwtMmlMstyleNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
461 : QwtMmlNode( MstyleNode, document, attribute_map ) {}
462 };
463
464 class QwtMmlTableBaseNode : public QwtMmlNode
465 {
466 public:
QwtMmlTableBaseNode(NodeType type,QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)467 QwtMmlTableBaseNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
468 : QwtMmlNode( type, document, attribute_map ) {}
469 };
470
471 class QwtMmlMtableNode : public QwtMmlTableBaseNode
472 {
473 public:
QwtMmlMtableNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)474 QwtMmlMtableNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
475 : QwtMmlTableBaseNode( MtableNode, document, attribute_map ) {}
476
477 int rowspacing() const;
478 int columnspacing() const;
479 int framespacing_hor() const;
480 int framespacing_ver() const;
481 FrameType frame() const;
482 FrameType columnlines( int idx ) const;
483 FrameType rowlines( int idx ) const;
484
485 protected:
486 virtual void layoutSymbol();
487 virtual QRect symbolRect() const;
488 virtual void paintSymbol( QPainter *p ) const;
489
490 private:
491 struct CellSizeData
492 {
493 void init( const QwtMmlNode *first_row );
494 QList<int> col_widths, row_heights;
numColsQwtMmlMtableNode::CellSizeData495 int numCols() const { return col_widths.count(); }
numRowsQwtMmlMtableNode::CellSizeData496 int numRows() const { return row_heights.count(); }
497 uint colWidthSum() const;
498 uint rowHeightSum() const;
499 };
500
501 CellSizeData m_cell_size_data;
502 int m_content_width, m_content_height;
503 };
504
505 class QwtMmlMtrNode : public QwtMmlTableBaseNode
506 {
507 public:
QwtMmlMtrNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)508 QwtMmlMtrNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
509 : QwtMmlTableBaseNode( MtrNode, document, attribute_map ) {}
510 void layoutCells( const QList<int> &col_widths, int col_spc );
511 };
512
513 class QwtMmlMtdNode : public QwtMmlTableBaseNode
514 {
515 public:
QwtMmlMtdNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)516 QwtMmlMtdNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
517 : QwtMmlTableBaseNode( MtdNode, document, attribute_map )
518 { m_scriptlevel_adjust = 0; }
519 virtual void setMyRect( const QRect &rect );
520
521 ColAlign columnalign();
522 RowAlign rowalign();
523 uint colNum();
524 uint rowNum();
525 virtual int scriptlevel( const QwtMmlNode *child = 0 ) const;
526
527 private:
528 int m_scriptlevel_adjust; // added or subtracted to scriptlevel to
529 // make contents fit the cell
530 };
531
532 class QwtMmlMoverNode : public QwtMmlNode
533 {
534 public:
QwtMmlMoverNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)535 QwtMmlMoverNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
536 : QwtMmlNode( MoverNode, document, attribute_map ) {}
537 virtual int scriptlevel( const QwtMmlNode *node = 0 ) const;
538
539 protected:
540 virtual void layoutSymbol();
541 };
542
543 class QwtMmlMunderNode : public QwtMmlNode
544 {
545 public:
QwtMmlMunderNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)546 QwtMmlMunderNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
547 : QwtMmlNode( MunderNode, document, attribute_map ) {}
548 virtual int scriptlevel( const QwtMmlNode *node = 0 ) const;
549
550 protected:
551 virtual void layoutSymbol();
552 };
553
554 class QwtMmlMunderoverNode : public QwtMmlNode
555 {
556 public:
QwtMmlMunderoverNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)557 QwtMmlMunderoverNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
558 : QwtMmlNode( MunderoverNode, document, attribute_map ) {}
559 virtual int scriptlevel( const QwtMmlNode *node = 0 ) const;
560
561 protected:
562 virtual void layoutSymbol();
563 };
564
565 class QwtMmlMerrorNode : public QwtMmlNode
566 {
567 public:
QwtMmlMerrorNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)568 QwtMmlMerrorNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
569 : QwtMmlNode( MerrorNode, document, attribute_map ) {}
570 };
571
572 class QwtMmlMtextNode : public QwtMmlNode
573 {
574 public:
QwtMmlMtextNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)575 QwtMmlMtextNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
576 : QwtMmlNode( MtextNode, document, attribute_map ) {}
577 };
578
579 class QwtMmlMpaddedNode : public QwtMmlNode
580 {
581 public:
QwtMmlMpaddedNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)582 QwtMmlMpaddedNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
583 : QwtMmlNode( MpaddedNode, document, attribute_map ) {}
584
585 public:
586 int lspace() const;
587 int width() const;
588 int height() const;
589 int depth() const;
590
591 protected:
592 int interpretSpacing( QString value, int base_value, bool *ok ) const;
593 virtual void layoutSymbol();
594 virtual QRect symbolRect() const;
595 };
596
597 class QwtMmlMspaceNode : public QwtMmlNode
598 {
599 public:
QwtMmlMspaceNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)600 QwtMmlMspaceNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
601 : QwtMmlNode( MspaceNode, document, attribute_map ) {}
602 };
603
604 static const QwtMmlNodeSpec *mmlFindNodeSpec( QwtMml::NodeType type );
605 static const QwtMmlNodeSpec *mmlFindNodeSpec( const QString &tag );
606 static bool mmlCheckChildType( QwtMml::NodeType parent_type,
607 QwtMml::NodeType child_type, QString *error_str );
608 static bool mmlCheckAttributes( QwtMml::NodeType child_type,
609 const QwtMmlAttributeMap &attr, QString *error_str );
610 static QString mmlDictAttribute( const QString &name, const QwtMmlOperSpec *spec );
611 static const QwtMmlOperSpec *mmlFindOperSpec( const QString &name, QwtMml::FormType form );
612 static int interpretSpacing( QString name, int em, int ex, bool *ok );
613 static int interpretPercentSpacing( QString value, int base, bool *ok );
614 static uint interpretMathVariant( const QString &value, bool *ok );
615 static QwtMml::FormType interpretForm( const QString &value, bool *ok );
616 static QwtMml::FrameType interpretFrameType( const QString &value_list, uint idx, bool *ok );
617 static QwtMml::FrameSpacing interpretFrameSpacing( const QString &value_list, int em, int ex, bool *ok );
618 static QwtMml::ColAlign interpretColAlign( const QString &value_list, uint colnum, bool *ok );
619 static QwtMml::RowAlign interpretRowAlign( const QString &value_list, uint rownum, bool *ok );
620 static QwtMml::FrameType interpretFrameType( const QString &value_list, uint idx, bool *ok );
621 static QFont interpretDepreciatedFontAttr( const QwtMmlAttributeMap &font_attr, QFont &fn, int em, int ex );
622 static QFont interpretMathSize( QString value, QFont &fn, int em, int ex, bool *ok );
623 static QString interpretListAttr( const QString &value_list, int idx, const QString &def );
624 static QString rectToStr( const QRect &rect );
625 static QString entityDeclarations();
626
627
628 #define MML_ATT_COMMON " class style id xref actiontype "
629 #define MML_ATT_FONTSIZE " fontsize fontweight fontstyle fontfamily color "
630 #define MML_ATT_MATHVARIANT " mathvariant mathsize mathcolor mathbackground "
631 #define MML_ATT_FONTINFO MML_ATT_FONTSIZE MML_ATT_MATHVARIANT
632 #define MML_ATT_OPINFO " form fence separator lspace rspace stretchy symmetric " \
633 " maxsize minsize largeop movablelimits accent "
634 #define MML_ATT_SIZEINFO " width height depth "
635 #define MML_ATT_TABLEINFO " align rowalign columnalign columnwidth groupalign " \
636 " alignmentscope side rowspacing columnspacing rowlines " \
637 " columnlines width frame framespacing equalrows " \
638 " equalcolumns displaystyle "
639 #define MML_ATT_MFRAC " bevelled numalign denomalign linethickness "
640 #define MML_ATT_MSTYLE MML_ATT_FONTINFO MML_ATT_OPINFO \
641 " scriptlevel lquote rquote linethickness displaystyle " \
642 " scriptsizemultiplier scriptminsize background " \
643 " veryverythinmathspace verythinmathspace thinmathspace " \
644 " mediummathspace thickmathspace verythickmathspace " \
645 " veryverythickmathspace open close separators " \
646 " subscriptshift superscriptshift accentunder tableinfo " \
647 " rowspan columnspan edge selection bevelled "
648 #define MML_ATT_MTABLE " align rowalign columnalign groupalign alignmentscope " \
649 " columnwidth width rowspacing columnspacing rowlines columnlines " \
650 " frame framespacing equalrows equalcolumns displaystyle side " \
651 " minlabelspacing "
652
653 static const QwtMmlNodeSpec g_node_spec_data[] =
654 {
655
656 // type tag type_str child_spec child_types attributes ""=none, 0=any
657 // ----------------------- --------------- ------------------- ----------------------- ------------------------ ------------------------------------
658 { QwtMml::MiNode, "mi", "MiNode", QwtMmlNodeSpec::ChildAny, " TextNode MalignMark ", MML_ATT_COMMON MML_ATT_FONTINFO },
659 { QwtMml::MnNode, "mn", "MnNode", QwtMmlNodeSpec::ChildAny, " TextNode MalignMark ", MML_ATT_COMMON MML_ATT_FONTINFO },
660 { QwtMml::MfracNode, "mfrac", "MfracNode", 2, 0, MML_ATT_COMMON MML_ATT_MFRAC },
661 { QwtMml::MrowNode, "mrow", "MrowNode", QwtMmlNodeSpec::ChildAny, 0, MML_ATT_COMMON " display mode " },
662 { QwtMml::MsqrtNode, "msqrt", "MsqrtNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON },
663 { QwtMml::MrootNode, "mroot", "MrootNode", 2, 0, MML_ATT_COMMON },
664 { QwtMml::MsupNode, "msup", "MsupNode", 2, 0, MML_ATT_COMMON " subscriptshift " },
665 { QwtMml::MsubNode, "msub", "MsubNode", 2, 0, MML_ATT_COMMON " superscriptshift " },
666 { QwtMml::MsubsupNode, "msubsup", "MsubsupNode", 3, 0, MML_ATT_COMMON " subscriptshift superscriptshift " },
667 { QwtMml::MoNode, "mo", "MoNode", QwtMmlNodeSpec::ChildAny, " TextNode MalignMark ", MML_ATT_COMMON MML_ATT_FONTINFO MML_ATT_OPINFO },
668 { QwtMml::MstyleNode, "mstyle", "MstyleNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON MML_ATT_MSTYLE },
669 { QwtMml::MphantomNode, "mphantom", "MphantomNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON },
670 { QwtMml::MalignMarkNode, "malignmark", "MalignMarkNode", 0, 0, "" },
671 { QwtMml::MfencedNode, "mfenced", "MfencedNode", QwtMmlNodeSpec::ChildAny, 0, MML_ATT_COMMON " open close separators " },
672 { QwtMml::MtableNode, "mtable", "MtableNode", QwtMmlNodeSpec::ChildAny, " MtrNode ", MML_ATT_COMMON MML_ATT_MTABLE },
673 { QwtMml::MtrNode, "mtr", "MtrNode", QwtMmlNodeSpec::ChildAny, " MtdNode ", MML_ATT_COMMON " rowalign columnalign groupalign " },
674 { QwtMml::MtdNode, "mtd", "MtdNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON " rowspan columnspan rowalign columnalign groupalign " },
675 { QwtMml::MoverNode, "mover", "MoverNode", 2, 0, MML_ATT_COMMON " accent " },
676 { QwtMml::MunderNode, "munder", "MunderNode", 2, 0, MML_ATT_COMMON " accentunder " },
677 { QwtMml::MunderoverNode, "munderover", "MunderoverNode", 3, 0, MML_ATT_COMMON " accentunder accent " },
678 { QwtMml::MerrorNode, "merror", "MerrorNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON },
679 { QwtMml::MtextNode, "mtext", "MtextNode", 1, " TextNode ", MML_ATT_COMMON " width height depth linebreak " },
680 { QwtMml::MpaddedNode, "mpadded", "MpaddedNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON " width height depth lspace " },
681 { QwtMml::MspaceNode, "mspace", "MspaceNode", QwtMmlNodeSpec::ImplicitMrow, 0, MML_ATT_COMMON " width height depth linebreak " },
682 { QwtMml::TextNode, 0, "TextNode", QwtMmlNodeSpec::ChildIgnore, 0, "" },
683 { QwtMml::UnknownNode, 0, "UnknownNode", QwtMmlNodeSpec::ChildAny, 0, 0 },
684 { QwtMml::NoNode, 0, 0, 0, 0, 0 }
685 };
686
687 static const char *g_oper_spec_names[g_oper_spec_rows] = { "accent", "fence", "largeop", "lspace", "minsize", "movablelimits", "rspace", "separator", "stretchy" /* stretchdir */ };
688 static const QwtMmlOperSpec g_oper_spec_data[] =
689 {
690
691 { "!!" , QwtMml::PostfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "!!"
692 { "!" , QwtMml::PostfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "!"
693 { "!=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "!="
694 { "⩓" , QwtMml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⩓"
695 { "⁡" , QwtMml::InfixForm, { 0, 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⁡"
696 { "≔" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≔"
697 { "∖" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "∖"
698 { "∵" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∵"
699 { "˘" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "˘"
700 { "⋒" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋒"
701 { "ⅅ" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⅅ"
702 { "¸" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "¸"
703 { "·" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "·"
704 { "⊙" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊙"
705 { "⊖" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊖"
706 { "⊕" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊕"
707 { "⊗" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊗"
708 { "∲" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, "true"}, QwtMmlOperSpec::VStretch }, // ∲"
709 { "”" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ”"
710 { "’" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "’"
711 { "∷" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∷"
712 { "≡" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≡"
713 { "∮" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "∮"
714 { "∐" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∐"
715 { "∳", QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // &CounterClockwiseContourInteg
716 { "⨯" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⨯"
717 { "⋓" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋓"
718 { "≍" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≍"
719 { "∇" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∇"
720 { "´" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "´"
721 { "˙" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "˙"
722 { "˝" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ˝"
723 { "`" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "`"
724 { "&DiacriticalLeftArrow;" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &DiacriticalLeftArrow;"
725 { "&DiacriticalLeftRightArrow;" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &DiacriticalLeftRightArrow;"
726 { "&DiacriticalLeftRightVector;" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &DiacriticalLeftRightVector;"
727 { "&DiacriticalLeftVector;" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &DiacriticalLeftVector;"
728 { "&DiacriticalRightArrow;" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &DiacriticalRightArrow;"
729 { "&DiacriticalRightVector;" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &DiacriticalRightVector;"
730 { "˜" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::NoStretch }, // "˜"
731 { "⋄" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋄"
732 { "ⅆ" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "ⅆ"
733 { "≐" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≐"
734 { "∯" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // ∯"
735 { "¨" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "¨"
736 { "⇓" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⇓"
737 { "⇐" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇐"
738 { "⇔" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // ⇔"
739 { "⫤" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⫤"
740 { "⟸" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⟸"
741 { "⟺" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // ⟺"
742 { "⟹" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // ⟹"
743 { "⇒" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇒"
744 { "⊨" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊨"
745 { "⇑" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⇑"
746 { "⇕" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⇕"
747 { "∥" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∥"
748 { "↓" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "↓"
749 { "⤓" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⤓"
750 { "⇵" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⇵"
751 { "̑" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "̑"
752 { "⥐" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥐"
753 { "⥞" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥞"
754 { "↽" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↽"
755 { "⥖" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥖"
756 { "⥟" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥟"
757 { "⇁" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⇁"
758 { "⥗" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥗"
759 { "⊤" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊤"
760 { "↧" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "↧"
761 { "∈" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∈"
762 { "⩵" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⩵"
763 { "≂" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≂"
764 { "⇌" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇌"
765 { "∃" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∃"
766 { "∀" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∀"
767 { "≥" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≥"
768 { "⋛" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋛"
769 { "≧" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≧"
770 { "⪢" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪢"
771 { "≷" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≷"
772 { "⩾" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⩾"
773 { "≳" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≳"
774 { "ˇ" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::NoStretch }, // "ˇ"
775 { "^" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "^"
776 { "─" , QwtMml::InfixForm, { 0, 0, 0, "0em", "0", 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "─"
777 { "≎" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≎"
778 { "≏" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≏"
779 { "⇒" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇒"
780 { "∫" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∫"
781 { "⋂" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⋂"
782 { "⁣" , QwtMml::InfixForm, { 0, 0, 0, "0em", 0, 0, "0em", "true", 0 }, QwtMmlOperSpec::NoStretch }, // "⁣"
783 { "⁢" , QwtMml::InfixForm, { 0, 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⁢"
784 { "⟨" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⟨"
785 { "←" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "←"
786 { "⇤" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇤"
787 { "⇆" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇆"
788 { "&LeftBracketingBar;" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "&LeftBracketingBar;"
789 { "⌈" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⌈"
790 { "⟦" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⟦"
791 { "&LeftDoubleBracketingBar;" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &LeftDoubleBracketingBar;"
792 { "⥡" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥡"
793 { "⇃" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⇃"
794 { "⥙" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥙"
795 { "⌊" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⌊"
796 { "↔" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "↔"
797 { "⥎" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⥎"
798 { "&LeftSkeleton;" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "&LeftSkeleton;"
799 { "⊣" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊣"
800 { "↤" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "↤"
801 { "⥚" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⥚"
802 { "⊲" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊲"
803 { "⧏" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⧏"
804 { "⊴" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊴"
805 { "⥑" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥑"
806 { "⥠" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥠"
807 { "↿" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↿"
808 { "⥘" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥘"
809 { "↼" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "↼"
810 { "⥒" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⥒"
811 { "⋚" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋚"
812 { "≦" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≦"
813 { "≶" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≶"
814 { "⪡" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪡"
815 { "⩽" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⩽"
816 { "≲" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≲"
817 { "⟵" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⟵"
818 { "⟷" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⟷"
819 { "⟶" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⟶"
820 { "↙" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↙"
821 { "↘" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↘"
822 { "∓" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "veryverythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∓"
823 { "≫" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ≫"
824 { "≪" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≪"
825 { "⫬" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⫬"
826 { "≢" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≢"
827 { "≭" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≭"
828 { "∦" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ∦"
829 { "∉" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∉"
830 { "≠" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≠"
831 { "≂̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≂̸"
832 { "∄" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∄"
833 { "≯" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≯"
834 { "≱" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≱"
835 { "≧̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≧̸"
836 { "≫̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≫̸"
837 { "≹" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≹"
838 { "⩾̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⩾̸"
839 { "≵" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≵"
840 { "≎̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≎̸"
841 { "≏̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≏̸"
842 { "⋪" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋪"
843 { "⧏̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⧏̸"
844 { "⋬" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⋬"
845 { "≮" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≮"
846 { "≰" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≰"
847 { "&NotLessFullEqual;" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "&NotLessFullEqual;"
848 { "≸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≸"
849 { "≪̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≪̸"
850 { "⩽̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⩽̸"
851 { "≴" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≴"
852 { "⪢̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⪢̸"
853 { "⪡̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪡̸"
854 { "⊀" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊀"
855 { "⪯̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪯̸"
856 { "⋠" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⋠"
857 { "&NotPrecedesTilde;" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "&NotPrecedesTilde;"
858 { "∌" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∌"
859 { "⋫" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋫"
860 { "⧐̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⧐̸"
861 { "⋭" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⋭"
862 { "⊏̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊏̸"
863 { "⋢" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⋢"
864 { "⊐̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊐̸"
865 { "⋣" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⋣"
866 { "⊂⃒" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊂⃒"
867 { "⊈" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊈"
868 { "⊁" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊁"
869 { "⪰̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪰̸"
870 { "⋡" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ⋡"
871 { "≿̸" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≿̸"
872 { "⊃⃒" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊃⃒"
873 { "⊉" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊉"
874 { "≁" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≁"
875 { "≄" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≄"
876 { "≇" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≇"
877 { "≉" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≉"
878 { "∤" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∤"
879 { "“" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // “"
880 { "‘" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "‘"
881 { "⩔" , QwtMml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⩔"
882 { "‾" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "‾"
883 { "⏞" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⏞"
884 { "⎴" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⎴"
885 { "⏜" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⏜"
886 { "∂" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∂"
887 { "±" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "veryverythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "±"
888 { "≺" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≺"
889 { "⪯" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪯"
890 { "≼" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≼"
891 { "≾" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≾"
892 { "∏" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∏"
893 { "∷" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∷"
894 { "∝" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∝"
895 { "∋" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∋"
896 { "⇋" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇋"
897 { "⥯" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // ⥯"
898 { "⟩" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⟩"
899 { "→" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "→"
900 { "⇥" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇥"
901 { "⇄" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇄"
902 { "&RightBracketingBar;" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "&RightBracketingBar;"
903 { "⌉" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⌉"
904 { "⟧" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⟧"
905 { "&RightDoubleBracketingBar;" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // &RightDoubleBracketingBar;"
906 { "⥝" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥝"
907 { "⇂" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⇂"
908 { "⥕" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥕"
909 { "⌋" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⌋"
910 { "&RightSkeleton;" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "&RightSkeleton;"
911 { "⊢" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊢"
912 { "↦" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "↦"
913 { "⥛" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⥛"
914 { "⊳" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊳"
915 { "⧐" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⧐"
916 { "⊵" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊵"
917 { "⥏" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⥏"
918 { "⥜" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥜"
919 { "↾" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↾"
920 { "⥔" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⥔"
921 { "⇀" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⇀"
922 { "⥓" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⥓"
923 { "⥰" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⥰"
924 { "↓" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "↓"
925 { "←" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::HStretch }, // "←"
926 { "→" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::HStretch }, // "→"
927 { "↑" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::VStretch }, // "↑"
928 { "∘" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∘"
929 { "√" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "√"
930 { "□" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "□"
931 { "⊓" , QwtMml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⊓"
932 { "⊏" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊏"
933 { "⊑" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊑"
934 { "⊐" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊐"
935 { "⊒" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊒"
936 { "⊔" , QwtMml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⊔"
937 { "⋆" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋆"
938 { "⋐" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋐"
939 { "⊆" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊆"
940 { "≻" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≻"
941 { "⪰" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⪰"
942 { "≽" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≽"
943 { "≿" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≿"
944 { "∋" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∋"
945 { "∑" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∑"
946 { "⊃" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊃"
947 { "⊇" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊇"
948 { "∴" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∴"
949 { "∼" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∼"
950 { "≃" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≃"
951 { "≅" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≅"
952 { "≈" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≈"
953 { "⃛" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⃛"
954 { "_" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "_"
955 { "⏟" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⏟"
956 { "⎵" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⎵"
957 { "⏝" , QwtMml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::HStretch }, // "⏝"
958 { "⋃" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⋃"
959 { "⊎" , QwtMml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "⊎"
960 { "↑" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "↑"
961 { "⤒" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⤒"
962 { "⇅" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⇅"
963 { "↕" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "↕"
964 { "⥮" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "⥮"
965 { "⊥" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⊥"
966 { "↥" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "↥"
967 { "↖" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↖"
968 { "↗" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::HVStretch }, // "↗"
969 { "⋁" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋁"
970 { "∣" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "∣"
971 { "|" , QwtMml::InfixForm, { 0, 0, 0, "0em", "0", 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "|"
972 { "❘" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "❘"
973 { "≀" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≀"
974 { "⋀" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "⋀"
975 { "&" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "&"
976 { "&&" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "&&"
977 { "≤" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "≤"
978 { "<" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "<"
979 { "<=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "<="
980 { "<>" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "<>"
981 { "'" , QwtMml::PostfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "'"
982 { "(" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "("
983 { ")" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // ")"
984 { "*" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "*"
985 { "**" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "**"
986 { "*=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "*="
987 { "+" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "+"
988 { "+" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "veryverythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "+"
989 { "++" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "++"
990 { "+=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "+="
991 { "," , QwtMml::InfixForm, { 0, 0, 0, "0em", 0, 0, "verythickmathspace", "true", 0 }, QwtMmlOperSpec::NoStretch }, // ","
992 { "-" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "-"
993 { "-" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "veryverythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "-"
994 { "--" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "--"
995 { "-=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "-="
996 { "->" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "->"
997 { "." , QwtMml::InfixForm, { 0, 0, 0, "0em", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "."
998 { ".." , QwtMml::PostfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ".."
999 { "..." , QwtMml::PostfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "0em", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "..."
1000 { "/" , QwtMml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "/"
1001 { "//" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "//"
1002 { "/=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "/="
1003 { ":" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ":"
1004 { ":=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ":="
1005 { ";" , QwtMml::InfixForm, { 0, 0, 0, "0em", 0, 0, "verythickmathspace", "true", 0 }, QwtMmlOperSpec::NoStretch }, // ";"
1006 { ";" , QwtMml::PostfixForm, { 0, 0, 0, "0em", 0, 0, "0em", "true", 0 }, QwtMmlOperSpec::NoStretch }, // ";"
1007 { "=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "="
1008 { "==" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "=="
1009 { ">" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ">"
1010 { ">=" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // ">="
1011 { "?" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "?"
1012 { "@" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "@"
1013 { "[" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "["
1014 { "]" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "]"
1015 { "^" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "^"
1016 { "_" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "_"
1017 { "lim" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, "true", "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "lim"
1018 { "max" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, "true", "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "max"
1019 { "min" , QwtMml::PrefixForm, { 0, 0, 0, "0em", 0, "true", "thinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "min"
1020 { "{" , QwtMml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "{"
1021 { "|" , QwtMml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, QwtMmlOperSpec::VStretch }, // "|"
1022 { "||" , QwtMml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "||"
1023 { "}" , QwtMml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, QwtMmlOperSpec::VStretch }, // "}"
1024 { "~" , QwtMml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, QwtMmlOperSpec::NoStretch }, // "~"
1025
1026 { 0 , QwtMml::InfixForm, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, QwtMmlOperSpec::NoStretch }
1027 };
1028
1029 static const QwtMmlOperSpec g_oper_spec_defaults =
1030 { 0 , QwtMml::InfixForm, { "false", "false", "false", "thickmathspace", "1", "false", "thickmathspace", "false", "false" }, QwtMmlOperSpec::NoStretch };
1031
1032 static const uint g_oper_spec_count = sizeof( g_oper_spec_data ) / sizeof( QwtMmlOperSpec ) - 1;
1033
1034 static const QwtMmlEntitySpec g_xml_entity_data[] =
1035 {
1036 { "angzarr", "⍼" },
1037 { "cirmid", "⫯" },
1038 { "cudarrl", "⤸" },
1039 { "cudarrr", "⤵" },
1040 { "cularr", "↶" },
1041 { "cularrp", "⤽" },
1042 { "curarr", "↷" },
1043 { "curarrm", "⤼" },
1044 { "Darr", "↡" },
1045 { "dArr", "⇓" },
1046 { "ddarr", "⇊" },
1047 { "DDotrahd", "⤑" },
1048 { "dfisht", "⥿" },
1049 { "dHar", "⥥" },
1050 { "dharl", "⇃" },
1051 { "dharr", "⇂" },
1052 { "duarr", "⇵" },
1053 { "duhar", "⥯" },
1054 { "dzigrarr", "⟿" },
1055 { "erarr", "⥱" },
1056 { "hArr", "⇔" },
1057 { "harr", "↔" },
1058 { "harrcir", "⥈" },
1059 { "harrw", "↭" },
1060 { "hoarr", "⇿" },
1061 { "imof", "⊷" },
1062 { "lAarr", "⇚" },
1063 { "Larr", "↞" },
1064 { "larrbfs", "⤟" },
1065 { "larrfs", "⤝" },
1066 { "larrhk", "↩" },
1067 { "larrlp", "↫" },
1068 { "larrpl", "⤹" },
1069 { "larrsim", "⥳" },
1070 { "larrtl", "↢" },
1071 { "lAtail", "⤛" },
1072 { "latail", "⤙" },
1073 { "lBarr", "⤎" },
1074 { "lbarr", "⤌" },
1075 { "ldca", "⤶" },
1076 { "ldrdhar", "⥧" },
1077 { "ldrushar", "⥋" },
1078 { "ldsh", "↲" },
1079 { "lfisht", "⥼" },
1080 { "lHar", "⥢" },
1081 { "lhard", "↽" },
1082 { "lharu", "↼" },
1083 { "lharul", "⥪" },
1084 { "llarr", "⇇" },
1085 { "llhard", "⥫" },
1086 { "loarr", "⇽" },
1087 { "lrarr", "⇆" },
1088 { "lrhar", "⇋" },
1089 { "lrhard", "⥭" },
1090 { "lsh", "↰" },
1091 { "lurdshar", "⥊" },
1092 { "luruhar", "⥦" },
1093 { "Map", "⤅" },
1094 { "map", "↦" },
1095 { "midcir", "⫰" },
1096 { "mumap", "⊸" },
1097 { "nearhk", "⤤" },
1098 { "neArr", "⇗" },
1099 { "nearr", "↗" },
1100 { "nesear", "⤨" },
1101 { "nhArr", "⇎" },
1102 { "nharr", "↮" },
1103 { "nlArr", "⇍" },
1104 { "nlarr", "↚" },
1105 { "nrArr", "⇏" },
1106 { "nrarr", "↛" },
1107 { "nrarrc", "⤳̸" },
1108 { "nrarrw", "↝̸" },
1109 { "nvHarr", "⤄" },
1110 { "nvlArr", "⤂" },
1111 { "nvrArr", "⤃" },
1112 { "nwarhk", "⤣" },
1113 { "nwArr", "⇖" },
1114 { "nwarr", "↖" },
1115 { "nwnear", "⤧" },
1116 { "olarr", "↺" },
1117 { "orarr", "↻" },
1118 { "origof", "⊶" },
1119 { "rAarr", "⇛" },
1120 { "Rarr", "↠" },
1121 { "rarrap", "⥵" },
1122 { "rarrbfs", "⤠" },
1123 { "rarrc", "⤳" },
1124 { "rarrfs", "⤞" },
1125 { "rarrhk", "↪" },
1126 { "rarrlp", "↬" },
1127 { "rarrpl", "⥅" },
1128 { "rarrsim", "⥴" },
1129 { "Rarrtl", "⤖" },
1130 { "rarrtl", "↣" },
1131 { "rarrw", "↝" },
1132 { "rAtail", "⤜" },
1133 { "ratail", "⤚" },
1134 { "RBarr", "⤐" },
1135 { "rBarr", "⤏" },
1136 { "rbarr", "⤍" },
1137 { "rdca", "⤷" },
1138 { "rdldhar", "⥩" },
1139 { "rdsh", "↳" },
1140 { "rfisht", "⥽" },
1141 { "rHar", "⥤" },
1142 { "rhard", "⇁" },
1143 { "rharu", "⇀" },
1144 { "rharul", "⥬" },
1145 { "rlarr", "⇄" },
1146 { "rlhar", "⇌" },
1147 { "roarr", "⇾" },
1148 { "rrarr", "⇉" },
1149 { "rsh", "↱" },
1150 { "ruluhar", "⥨" },
1151 { "searhk", "⤥" },
1152 { "seArr", "⇘" },
1153 { "searr", "↘" },
1154 { "seswar", "⤩" },
1155 { "simrarr", "⥲" },
1156 { "slarr", "←" },
1157 { "srarr", "→" },
1158 { "swarhk", "⤦" },
1159 { "swArr", "⇙" },
1160 { "swarr", "↙" },
1161 { "swnwar", "⤪" },
1162 { "Uarr", "↟" },
1163 { "uArr", "⇑" },
1164 { "Uarrocir", "⥉" },
1165 { "udarr", "⇅" },
1166 { "udhar", "⥮" },
1167 { "ufisht", "⥾" },
1168 { "uHar", "⥣" },
1169 { "uharl", "↿" },
1170 { "uharr", "↾" },
1171 { "uuarr", "⇈" },
1172 { "vArr", "⇕" },
1173 { "varr", "↕" },
1174 { "xhArr", "⟺" },
1175 { "xharr", "⟷" },
1176 { "xlArr", "⟸" },
1177 { "xlarr", "⟵" },
1178 { "xmap", "⟼" },
1179 { "xrArr", "⟹" },
1180 { "xrarr", "⟶" },
1181 { "zigrarr", "⇝" },
1182 { "ac", "∾" },
1183 { "acE", "∾̳" },
1184 { "amalg", "⨿" },
1185 { "barvee", "⊽" },
1186 { "Barwed", "⌆" },
1187 { "barwed", "⌅" },
1188 { "bsolb", "⧅" },
1189 { "Cap", "⋒" },
1190 { "capand", "⩄" },
1191 { "capbrcup", "⩉" },
1192 { "capcap", "⩋" },
1193 { "capcup", "⩇" },
1194 { "capdot", "⩀" },
1195 { "caps", "∩︀" },
1196 { "ccaps", "⩍" },
1197 { "ccups", "⩌" },
1198 { "ccupssm", "⩐" },
1199 { "coprod", "∐" },
1200 { "Cup", "⋓" },
1201 { "cupbrcap", "⩈" },
1202 { "cupcap", "⩆" },
1203 { "cupcup", "⩊" },
1204 { "cupdot", "⊍" },
1205 { "cupor", "⩅" },
1206 { "cups", "∪︀" },
1207 { "cuvee", "⋎" },
1208 { "cuwed", "⋏" },
1209 { "Dagger", "‡" },
1210 { "dagger", "†" },
1211 { "diam", "⋄" },
1212 { "divonx", "⋇" },
1213 { "eplus", "⩱" },
1214 { "hercon", "⊹" },
1215 { "intcal", "⊺" },
1216 { "iprod", "⨼" },
1217 { "loplus", "⨭" },
1218 { "lotimes", "⨴" },
1219 { "lthree", "⋋" },
1220 { "ltimes", "⋉" },
1221 { "midast", "*" },
1222 { "minusb", "⊟" },
1223 { "minusd", "∸" },
1224 { "minusdu", "⨪" },
1225 { "ncap", "⩃" },
1226 { "ncup", "⩂" },
1227 { "oast", "⊛" },
1228 { "ocir", "⊚" },
1229 { "odash", "⊝" },
1230 { "odiv", "⨸" },
1231 { "odot", "⊙" },
1232 { "odsold", "⦼" },
1233 { "ofcir", "⦿" },
1234 { "ogt", "⧁" },
1235 { "ohbar", "⦵" },
1236 { "olcir", "⦾" },
1237 { "olt", "⧀" },
1238 { "omid", "⦶" },
1239 { "ominus", "⊖" },
1240 { "opar", "⦷" },
1241 { "operp", "⦹" },
1242 { "oplus", "⊕" },
1243 { "osol", "⊘" },
1244 { "Otimes", "⨷" },
1245 { "otimes", "⊗" },
1246 { "otimesas", "⨶" },
1247 { "ovbar", "⌽" },
1248 { "plusacir", "⨣" },
1249 { "plusb", "⊞" },
1250 { "pluscir", "⨢" },
1251 { "plusdo", "∔" },
1252 { "plusdu", "⨥" },
1253 { "pluse", "⩲" },
1254 { "plussim", "⨦" },
1255 { "plustwo", "⨧" },
1256 { "prod", "∏" },
1257 { "race", "⧚" },
1258 { "roplus", "⨮" },
1259 { "rotimes", "⨵" },
1260 { "rthree", "⋌" },
1261 { "rtimes", "⋊" },
1262 { "sdot", "⋅" },
1263 { "sdotb", "⊡" },
1264 { "setmn", "∖" },
1265 { "simplus", "⨤" },
1266 { "smashp", "⨳" },
1267 { "solb", "⧄" },
1268 { "sqcap", "⊓" },
1269 { "sqcaps", "⊓︀" },
1270 { "sqcup", "⊔" },
1271 { "sqcups", "⊔︀" },
1272 { "ssetmn", "∖" },
1273 { "sstarf", "⋆" },
1274 { "subdot", "⪽" },
1275 { "sum", "∑" },
1276 { "supdot", "⪾" },
1277 { "timesb", "⊠" },
1278 { "timesbar", "⨱" },
1279 { "timesd", "⨰" },
1280 { "tridot", "◬" },
1281 { "triminus", "⨺" },
1282 { "triplus", "⨹" },
1283 { "trisb", "⧍" },
1284 { "tritime", "⨻" },
1285 { "uplus", "⊎" },
1286 { "veebar", "⊻" },
1287 { "wedbar", "⩟" },
1288 { "wreath", "≀" },
1289 { "xcap", "⋂" },
1290 { "xcirc", "◯" },
1291 { "xcup", "⋃" },
1292 { "xdtri", "▽" },
1293 { "xodot", "⨀" },
1294 { "xoplus", "⨁" },
1295 { "xotime", "⨂" },
1296 { "xsqcup", "⨆" },
1297 { "xuplus", "⨄" },
1298 { "xutri", "△" },
1299 { "xvee", "⋁" },
1300 { "xwedge", "⋀" },
1301 { "dlcorn", "⌞" },
1302 { "drcorn", "⌟" },
1303 { "gtlPar", "⦕" },
1304 { "langd", "⦑" },
1305 { "lbrke", "⦋" },
1306 { "lbrksld", "⦏" },
1307 { "lbrkslu", "⦍" },
1308 { "lceil", "⌈" },
1309 { "lfloor", "⌊" },
1310 { "lmoust", "⎰" },
1311 { "lparlt", "⦓" },
1312 { "ltrPar", "⦖" },
1313 { "rangd", "⦒" },
1314 { "rbrke", "⦌" },
1315 { "rbrksld", "⦎" },
1316 { "rbrkslu", "⦐" },
1317 { "rceil", "⌉" },
1318 { "rfloor", "⌋" },
1319 { "rmoust", "⎱" },
1320 { "rpargt", "⦔" },
1321 { "ulcorn", "⌜" },
1322 { "urcorn", "⌝" },
1323 { "gnap", "⪊" },
1324 { "gnE", "≩" },
1325 { "gne", "⪈" },
1326 { "gnsim", "⋧" },
1327 { "gvnE", "≩︀" },
1328 { "lnap", "⪉" },
1329 { "lnE", "≨" },
1330 { "lne", "⪇" },
1331 { "lnsim", "⋦" },
1332 { "lvnE", "≨︀" },
1333 { "nap", "≉" },
1334 { "napE", "⩰̸" },
1335 { "napid", "≋̸" },
1336 { "ncong", "≇" },
1337 { "ncongdot", "⩭̸" },
1338 { "nequiv", "≢" },
1339 { "ngE", "≧̸" },
1340 { "nge", "≱" },
1341 { "nges", "⩾̸" },
1342 { "nGg", "⋙̸" },
1343 { "ngsim", "≵" },
1344 { "nGt", "≫⃒" },
1345 { "ngt", "≯" },
1346 { "nGtv", "≫̸" },
1347 { "nlE", "≦̸" },
1348 { "nle", "≰" },
1349 { "nles", "⩽̸" },
1350 { "nLl", "⋘̸" },
1351 { "nlsim", "≴" },
1352 { "nLt", "≪⃒" },
1353 { "nlt", "≮" },
1354 { "nltri", "⋪" },
1355 { "nltrie", "⋬" },
1356 { "nLtv", "≪̸" },
1357 { "nmid", "∤" },
1358 { "npar", "∦" },
1359 { "npr", "⊀" },
1360 { "nprcue", "⋠" },
1361 { "npre", "⪯̸" },
1362 { "nrtri", "⋫" },
1363 { "nrtrie", "⋭" },
1364 { "nsc", "⊁" },
1365 { "nsccue", "⋡" },
1366 { "nsce", "⪰̸" },
1367 { "nsim", "≁" },
1368 { "nsime", "≄" },
1369 { "nsmid", "∤" },
1370 { "nspar", "∦" },
1371 { "nsqsube", "⋢" },
1372 { "nsqsupe", "⋣" },
1373 { "nsub", "⊄" },
1374 { "nsubE", "⫅̸" },
1375 { "nsube", "⊈" },
1376 { "nsup", "⊅" },
1377 { "nsupE", "⫆̸" },
1378 { "nsupe", "⊉" },
1379 { "ntgl", "≹" },
1380 { "ntlg", "≸" },
1381 { "nvap", "≍⃒" },
1382 { "nVDash", "⊯" },
1383 { "nVdash", "⊮" },
1384 { "nvDash", "⊭" },
1385 { "nvdash", "⊬" },
1386 { "nvge", "≥⃒" },
1387 { "nvgt", ">⃒" },
1388 { "nvle", "≤⃒" },
1389 { "nvlt", "<⃒" },
1390 { "nvltrie", "⊴⃒" },
1391 { "nvrtrie", "⊵⃒" },
1392 { "nvsim", "∼⃒" },
1393 { "parsim", "⫳" },
1394 { "prnap", "⪹" },
1395 { "prnE", "⪵" },
1396 { "prnsim", "⋨" },
1397 { "rnmid", "⫮" },
1398 { "scnap", "⪺" },
1399 { "scnE", "⪶" },
1400 { "scnsim", "⋩" },
1401 { "simne", "≆" },
1402 { "solbar", "⌿" },
1403 { "subnE", "⫋" },
1404 { "subne", "⊊" },
1405 { "supnE", "⫌" },
1406 { "supne", "⊋" },
1407 { "vnsub", "⊂⃒" },
1408 { "vnsup", "⊃⃒" },
1409 { "vsubnE", "⫋︀" },
1410 { "vsubne", "⊊︀" },
1411 { "vsupnE", "⫌︀" },
1412 { "vsupne", "⊋︀" },
1413 { "ang", "∠" },
1414 { "ange", "⦤" },
1415 { "angmsd", "∡" },
1416 { "angmsdaa", "⦨" },
1417 { "angmsdab", "⦩" },
1418 { "angmsdac", "⦪" },
1419 { "angmsdad", "⦫" },
1420 { "angmsdae", "⦬" },
1421 { "angmsdaf", "⦭" },
1422 { "angmsdag", "⦮" },
1423 { "angmsdah", "⦯" },
1424 { "angrtvb", "⊾" },
1425 { "angrtvbd", "⦝" },
1426 { "bbrk", "⎵" },
1427 { "bemptyv", "⦰" },
1428 { "beth", "ℶ" },
1429 { "boxbox", "⧉" },
1430 { "bprime", "‵" },
1431 { "bsemi", "⁏" },
1432 { "cemptyv", "⦲" },
1433 { "cirE", "⧃" },
1434 { "cirscir", "⧂" },
1435 { "comp", "∁" },
1436 { "daleth", "ℸ" },
1437 { "demptyv", "⦱" },
1438 { "ell", "ℓ" },
1439 { "empty", "∅" },
1440 { "emptyv", "∅" },
1441 { "gimel", "ℷ" },
1442 { "iiota", "℩" },
1443 { "image", "ℑ" },
1444 { "imath", "ı" },
1445 { "jmath", "j" },
1446 { "laemptyv", "⦴" },
1447 { "lltri", "◺" },
1448 { "lrtri", "⊿" },
1449 { "mho", "℧" },
1450 { "nang", "∠⃒" },
1451 { "nexist", "∄" },
1452 { "oS", "Ⓢ" },
1453 { "planck", "ℏ" },
1454 { "plankv", "ℏ" },
1455 { "raemptyv", "⦳" },
1456 { "range", "⦥" },
1457 { "real", "ℜ" },
1458 { "tbrk", "⎴" },
1459 { "ultri", "◸" },
1460 { "urtri", "◹" },
1461 { "vzigzag", "⦚" },
1462 { "weierp", "℘" },
1463 { "apE", "⩰" },
1464 { "ape", "≊" },
1465 { "apid", "≋" },
1466 { "asymp", "≈" },
1467 { "Barv", "⫧" },
1468 { "bcong", "≌" },
1469 { "bepsi", "϶" },
1470 { "bowtie", "⋈" },
1471 { "bsim", "∽" },
1472 { "bsime", "⋍" },
1473 { "bsolhsub", "\⊂" },
1474 { "bump", "≎" },
1475 { "bumpE", "⪮" },
1476 { "bumpe", "≏" },
1477 { "cire", "≗" },
1478 { "Colon", "∷" },
1479 { "Colone", "⩴" },
1480 { "colone", "≔" },
1481 { "congdot", "⩭" },
1482 { "csub", "⫏" },
1483 { "csube", "⫑" },
1484 { "csup", "⫐" },
1485 { "csupe", "⫒" },
1486 { "cuepr", "⋞" },
1487 { "cuesc", "⋟" },
1488 { "Dashv", "⫤" },
1489 { "dashv", "⊣" },
1490 { "easter", "⩮" },
1491 { "ecir", "≖" },
1492 { "ecolon", "≕" },
1493 { "eDDot", "⩷" },
1494 { "eDot", "≑" },
1495 { "efDot", "≒" },
1496 { "eg", "⪚" },
1497 { "egs", "⪖" },
1498 { "egsdot", "⪘" },
1499 { "el", "⪙" },
1500 { "els", "⪕" },
1501 { "elsdot", "⪗" },
1502 { "equest", "≟" },
1503 { "equivDD", "⩸" },
1504 { "erDot", "≓" },
1505 { "esdot", "≐" },
1506 { "Esim", "⩳" },
1507 { "esim", "≂" },
1508 { "fork", "⋔" },
1509 { "forkv", "⫙" },
1510 { "frown", "⌢" },
1511 { "gap", "⪆" },
1512 { "gE", "≧" },
1513 { "gEl", "⪌" },
1514 { "gel", "⋛" },
1515 { "ges", "⩾" },
1516 { "gescc", "⪩" },
1517 { "gesdot", "⪀" },
1518 { "gesdoto", "⪂" },
1519 { "gesdotol", "⪄" },
1520 { "gesl", "⋛︀" },
1521 { "gesles", "⪔" },
1522 { "Gg", "⋙" },
1523 { "gl", "≷" },
1524 { "gla", "⪥" },
1525 { "glE", "⪒" },
1526 { "glj", "⪤" },
1527 { "gsim", "≳" },
1528 { "gsime", "⪎" },
1529 { "gsiml", "⪐" },
1530 { "Gt", "≫" },
1531 { "gtcc", "⪧" },
1532 { "gtcir", "⩺" },
1533 { "gtdot", "⋗" },
1534 { "gtquest", "⩼" },
1535 { "gtrarr", "⥸" },
1536 { "homtht", "∻" },
1537 { "lap", "⪅" },
1538 { "lat", "⪫" },
1539 { "late", "⪭" },
1540 { "lates", "⪭︀" },
1541 { "lE", "≦" },
1542 { "lEg", "⪋" },
1543 { "leg", "⋚" },
1544 { "les", "⩽" },
1545 { "lescc", "⪨" },
1546 { "lesdot", "⩿" },
1547 { "lesdoto", "⪁" },
1548 { "lesdotor", "⪃" },
1549 { "lesg", "⋚︀" },
1550 { "lesges", "⪓" },
1551 { "lg", "≶" },
1552 { "lgE", "⪑" },
1553 { "Ll", "⋘" },
1554 { "lsim", "≲" },
1555 { "lsime", "⪍" },
1556 { "lsimg", "⪏" },
1557 { "Lt", "≪" },
1558 { "ltcc", "⪦" },
1559 { "ltcir", "⩹" },
1560 { "ltdot", "⋖" },
1561 { "ltlarr", "⥶" },
1562 { "ltquest", "⩻" },
1563 { "ltrie", "⊴" },
1564 { "mcomma", "⨩" },
1565 { "mDDot", "∺" },
1566 { "mid", "∣" },
1567 { "mlcp", "⫛" },
1568 { "models", "⊧" },
1569 { "mstpos", "∾" },
1570 { "Pr", "⪻" },
1571 { "pr", "≺" },
1572 { "prap", "⪷" },
1573 { "prcue", "≼" },
1574 { "prE", "⪳" },
1575 { "pre", "⪯" },
1576 { "prsim", "≾" },
1577 { "prurel", "⊰" },
1578 { "ratio", "∶" },
1579 { "rtrie", "⊵" },
1580 { "rtriltri", "⧎" },
1581 { "Sc", "⪼" },
1582 { "sc", "≻" },
1583 { "scap", "⪸" },
1584 { "sccue", "≽" },
1585 { "scE", "⪴" },
1586 { "sce", "⪰" },
1587 { "scsim", "≿" },
1588 { "sdote", "⩦" },
1589 { "simg", "⪞" },
1590 { "simgE", "⪠" },
1591 { "siml", "⪝" },
1592 { "simlE", "⪟" },
1593 { "smid", "∣" },
1594 { "smile", "⌣" },
1595 { "smt", "⪪" },
1596 { "smte", "⪬" },
1597 { "smtes", "⪬︀" },
1598 { "spar", "∥" },
1599 { "sqsub", "⊏" },
1600 { "sqsube", "⊑" },
1601 { "sqsup", "⊐" },
1602 { "sqsupe", "⊒" },
1603 { "Sub", "⋐" },
1604 { "subE", "⫅" },
1605 { "subedot", "⫃" },
1606 { "submult", "⫁" },
1607 { "subplus", "⪿" },
1608 { "subrarr", "⥹" },
1609 { "subsim", "⫇" },
1610 { "subsub", "⫕" },
1611 { "subsup", "⫓" },
1612 { "Sup", "⋑" },
1613 { "supdsub", "⫘" },
1614 { "supE", "⫆" },
1615 { "supedot", "⫄" },
1616 { "suphsol", "⊅" },
1617 { "suphsub", "⫗" },
1618 { "suplarr", "⥻" },
1619 { "supmult", "⫂" },
1620 { "supplus", "⫀" },
1621 { "supsim", "⫈" },
1622 { "supsub", "⫔" },
1623 { "supsup", "⫖" },
1624 { "thkap", "≈" },
1625 { "topfork", "⫚" },
1626 { "trie", "≜" },
1627 { "twixt", "≬" },
1628 { "Vbar", "⫫" },
1629 { "vBar", "⫨" },
1630 { "vBarv", "⫩" },
1631 { "VDash", "⊫" },
1632 { "Vdash", "⊩" },
1633 { "vDash", "⊨" },
1634 { "vdash", "⊢" },
1635 { "Vdashl", "⫦" },
1636 { "vltri", "⊲" },
1637 { "vprop", "∝" },
1638 { "vrtri", "⊳" },
1639 { "Vvdash", "⊪" },
1640 { "alpha", "α" },
1641 { "beta", "β" },
1642 { "chi", "χ" },
1643 { "Delta", "Δ" },
1644 { "delta", "δ" },
1645 { "epsi", "ε" },
1646 { "epsiv", "ɛ" },
1647 { "eta", "η" },
1648 { "Gamma", "Γ" },
1649 { "gamma", "γ" },
1650 { "Gammad", "Ϝ" },
1651 { "gammad", "ϝ" },
1652 { "iota", "ι" },
1653 { "kappa", "κ" },
1654 { "kappav", "ϰ" },
1655 { "Lambda", "Λ" },
1656 { "lambda", "λ" },
1657 { "mu", "μ" },
1658 { "nu", "ν" },
1659 { "Omega", "Ω" },
1660 { "omega", "ω" },
1661 { "Phi", "Φ" },
1662 { "phi", "ϕ" },
1663 { "phiv", "φ" },
1664 { "Pi", "Π" },
1665 { "pi", "π" },
1666 { "piv", "ϖ" },
1667 { "Psi", "Ψ" },
1668 { "psi", "ψ" },
1669 { "rho", "ρ" },
1670 { "rhov", "ϱ" },
1671 { "Sigma", "Σ" },
1672 { "sigma", "σ" },
1673 { "sigmav", "ς" },
1674 { "tau", "τ" },
1675 { "Theta", "Θ" },
1676 { "theta", "θ" },
1677 { "thetav", "ϑ" },
1678 { "Upsi", "ϒ" },
1679 { "upsi", "υ" },
1680 { "Xi", "Ξ" },
1681 { "xi", "ξ" },
1682 { "zeta", "ζ" },
1683 { "Cfr", "ℭ" },
1684 { "Hfr", "ℌ" },
1685 { "Ifr", "ℑ" },
1686 { "Rfr", "ℜ" },
1687 { "Zfr", "ℨ" },
1688 { "Copf", "ℂ" },
1689 { "Hopf", "ℍ" },
1690 { "Nopf", "ℕ" },
1691 { "Popf", "ℙ" },
1692 { "Qopf", "ℚ" },
1693 { "Ropf", "ℝ" },
1694 { "Zopf", "ℤ" },
1695 { "Bscr", "ℬ" },
1696 { "Escr", "ℰ" },
1697 { "escr", "ℯ" },
1698 { "Fscr", "ℱ" },
1699 { "gscr", "ℊ" },
1700 { "Hscr", "ℋ" },
1701 { "Iscr", "ℐ" },
1702 { "Lscr", "ℒ" },
1703 { "Mscr", "ℳ" },
1704 { "oscr", "ℴ" },
1705 { "pscr", "𝓅" },
1706 { "Rscr", "ℛ" },
1707 { "acd", "∿" },
1708 { "aleph", "ℵ" },
1709 { "And", "⩓" },
1710 { "and", "∧" },
1711 { "andand", "⩕" },
1712 { "andd", "⩜" },
1713 { "andslope", "⩘" },
1714 { "andv", "⩚" },
1715 { "angrt", "∟" },
1716 { "angsph", "∢" },
1717 { "angst", "Å" },
1718 { "ap", "≈" },
1719 { "apacir", "⩯" },
1720 { "awconint", "∳" },
1721 { "awint", "⨑" },
1722 { "becaus", "∵" },
1723 { "bernou", "ℬ" },
1724 { "bne", "=⃥" },
1725 { "bnequiv", "≡⃥" },
1726 { "bNot", "⫭" },
1727 { "bnot", "⌐" },
1728 { "bottom", "⊥" },
1729 { "cap", "∩" },
1730 { "Cconint", "∰" },
1731 { "cirfnint", "⨐" },
1732 { "compfn", "∘" },
1733 { "cong", "≅" },
1734 { "Conint", "∯" },
1735 { "conint", "∮" },
1736 { "ctdot", "⋯" },
1737 { "cup", "∪" },
1738 { "cwconint", "∲" },
1739 { "cwint", "∱" },
1740 { "cylcty", "⌭" },
1741 { "disin", "⋲" },
1742 { "Dot", "¨" },
1743 { "DotDot", "⃜" },
1744 { "dsol", "⧶" },
1745 { "dtdot", "⋱" },
1746 { "dwangle", "⦦" },
1747 { "epar", "⋕" },
1748 { "eparsl", "⧣" },
1749 { "equiv", "≡" },
1750 { "eqvparsl", "⧥" },
1751 { "exist", "∃" },
1752 { "fnof", "ƒ" },
1753 { "forall", "∀" },
1754 { "fpartint", "⨍" },
1755 { "ge", "≥" },
1756 { "hamilt", "ℋ" },
1757 { "iff", "⇔" },
1758 { "iinfin", "⧜" },
1759 { "infin", "∞" },
1760 { "Int", "∬" },
1761 { "int", "∫" },
1762 { "intlarhk", "⨗" },
1763 { "isin", "∈" },
1764 { "isindot", "⋵" },
1765 { "isinE", "⋹" },
1766 { "isins", "⋴" },
1767 { "isinsv", "⋳" },
1768 { "isinv", "∈" },
1769 { "lagran", "ℒ" },
1770 { "Lang", "《" },
1771 { "lang", "〈" },
1772 { "lArr", "⇐" },
1773 { "lbbrk", "〔" },
1774 { "le", "≤" },
1775 { "loang", "〘" },
1776 { "lobrk", "〚" },
1777 { "lopar", "⦅" },
1778 { "lowast", "∗" },
1779 { "minus", "−" },
1780 { "mnplus", "∓" },
1781 { "nabla", "∇" },
1782 { "ne", "≠" },
1783 { "nedot", "≐̸" },
1784 { "nhpar", "⫲" },
1785 { "ni", "∋" },
1786 { "nis", "⋼" },
1787 { "nisd", "⋺" },
1788 { "niv", "∋" },
1789 { "Not", "⫬" },
1790 { "notin", "∉" },
1791 { "notindot", "⋵̸" },
1792 { "notinva", "∉" },
1793 { "notinvb", "⋷" },
1794 { "notinvc", "⋶" },
1795 { "notni", "∌" },
1796 { "notniva", "∌" },
1797 { "notnivb", "⋾" },
1798 { "notnivc", "⋽" },
1799 { "nparsl", "⫽⃥" },
1800 { "npart", "∂̸" },
1801 { "npolint", "⨔" },
1802 { "nvinfin", "⧞" },
1803 { "olcross", "⦻" },
1804 { "Or", "⩔" },
1805 { "or", "∨" },
1806 { "ord", "⩝" },
1807 { "order", "ℴ" },
1808 { "oror", "⩖" },
1809 { "orslope", "⩗" },
1810 { "orv", "⩛" },
1811 { "par", "∥" },
1812 { "parsl", "⫽" },
1813 { "part", "∂" },
1814 { "permil", "‰" },
1815 { "perp", "⊥" },
1816 { "pertenk", "‱" },
1817 { "phmmat", "ℳ" },
1818 { "pointint", "⨕" },
1819 { "Prime", "″" },
1820 { "prime", "′" },
1821 { "profalar", "⌮" },
1822 { "profline", "⌒" },
1823 { "profsurf", "⌓" },
1824 { "prop", "∝" },
1825 { "qint", "⨌" },
1826 { "qprime", "⁗" },
1827 { "quatint", "⨖" },
1828 { "radic", "√" },
1829 { "Rang", "》" },
1830 { "rang", "〉" },
1831 { "rArr", "⇒" },
1832 { "rbbrk", "〕" },
1833 { "roang", "〙" },
1834 { "robrk", "〛" },
1835 { "ropar", "⦆" },
1836 { "rppolint", "⨒" },
1837 { "scpolint", "⨓" },
1838 { "sim", "∼" },
1839 { "simdot", "⩪" },
1840 { "sime", "≃" },
1841 { "smeparsl", "⧤" },
1842 { "square", "□" },
1843 { "squarf", "▪" },
1844 { "sub", "⊂" },
1845 { "sube", "⊆" },
1846 { "sup", "⊃" },
1847 { "supe", "⊇" },
1848 { "tdot", "⃛" },
1849 { "there4", "∴" },
1850 { "tint", "∭" },
1851 { "top", "⊤" },
1852 { "topbot", "⌶" },
1853 { "topcir", "⫱" },
1854 { "tprime", "‴" },
1855 { "utdot", "⋰" },
1856 { "uwangle", "⦧" },
1857 { "vangrt", "⦜" },
1858 { "veeeq", "≚" },
1859 { "Verbar", "‖" },
1860 { "wedgeq", "≙" },
1861 { "xnis", "⋻" },
1862 { "boxDL", "╗" },
1863 { "boxDl", "╖" },
1864 { "boxdL", "╕" },
1865 { "boxdl", "┐" },
1866 { "boxDR", "╔" },
1867 { "boxDr", "╓" },
1868 { "boxdR", "╒" },
1869 { "boxdr", "┌" },
1870 { "boxH", "═" },
1871 { "boxh", "─" },
1872 { "boxHD", "╦" },
1873 { "boxHd", "╤" },
1874 { "boxhD", "╥" },
1875 { "boxhd", "┬" },
1876 { "boxHU", "╩" },
1877 { "boxHu", "╧" },
1878 { "boxhU", "╨" },
1879 { "boxhu", "┴" },
1880 { "boxUL", "╝" },
1881 { "boxUl", "╜" },
1882 { "boxuL", "╛" },
1883 { "boxul", "┘" },
1884 { "boxUR", "╚" },
1885 { "boxUr", "╙" },
1886 { "boxuR", "╘" },
1887 { "boxur", "└" },
1888 { "boxV", "║" },
1889 { "boxv", "│" },
1890 { "boxVH", "╬" },
1891 { "boxVh", "╫" },
1892 { "boxvH", "╪" },
1893 { "boxvh", "┼" },
1894 { "boxVL", "╣" },
1895 { "boxVl", "╢" },
1896 { "boxvL", "╡" },
1897 { "boxvl", "┤" },
1898 { "boxVR", "╠" },
1899 { "boxVr", "╟" },
1900 { "boxvR", "╞" },
1901 { "boxvr", "├" },
1902 { "Acy", "А" },
1903 { "acy", "а" },
1904 { "Bcy", "Б" },
1905 { "bcy", "б" },
1906 { "CHcy", "Ч" },
1907 { "chcy", "ч" },
1908 { "Dcy", "Д" },
1909 { "dcy", "д" },
1910 { "Ecy", "Э" },
1911 { "ecy", "э" },
1912 { "Fcy", "Ф" },
1913 { "fcy", "ф" },
1914 { "Gcy", "Г" },
1915 { "gcy", "г" },
1916 { "HARDcy", "Ъ" },
1917 { "hardcy", "ъ" },
1918 { "Icy", "И" },
1919 { "icy", "и" },
1920 { "IEcy", "Е" },
1921 { "iecy", "е" },
1922 { "IOcy", "Ё" },
1923 { "iocy", "ё" },
1924 { "Jcy", "Й" },
1925 { "jcy", "й" },
1926 { "Kcy", "К" },
1927 { "kcy", "к" },
1928 { "KHcy", "Х" },
1929 { "khcy", "х" },
1930 { "Lcy", "Л" },
1931 { "lcy", "л" },
1932 { "Mcy", "М" },
1933 { "mcy", "м" },
1934 { "Ncy", "Н" },
1935 { "ncy", "н" },
1936 { "numero", "№" },
1937 { "Ocy", "О" },
1938 { "ocy", "о" },
1939 { "Pcy", "П" },
1940 { "pcy", "п" },
1941 { "Rcy", "Р" },
1942 { "rcy", "р" },
1943 { "Scy", "С" },
1944 { "scy", "с" },
1945 { "SHCHcy", "Щ" },
1946 { "shchcy", "щ" },
1947 { "SHcy", "Ш" },
1948 { "shcy", "ш" },
1949 { "SOFTcy", "Ь" },
1950 { "softcy", "ь" },
1951 { "Tcy", "Т" },
1952 { "tcy", "т" },
1953 { "TScy", "Ц" },
1954 { "tscy", "ц" },
1955 { "Ucy", "У" },
1956 { "ucy", "у" },
1957 { "Vcy", "В" },
1958 { "vcy", "в" },
1959 { "YAcy", "Я" },
1960 { "yacy", "я" },
1961 { "Ycy", "Ы" },
1962 { "ycy", "ы" },
1963 { "YUcy", "Ю" },
1964 { "yucy", "ю" },
1965 { "Zcy", "З" },
1966 { "zcy", "з" },
1967 { "ZHcy", "Ж" },
1968 { "zhcy", "ж" },
1969 { "DJcy", "Ђ" },
1970 { "djcy", "ђ" },
1971 { "DScy", "Ѕ" },
1972 { "dscy", "ѕ" },
1973 { "DZcy", "Џ" },
1974 { "dzcy", "џ" },
1975 { "GJcy", "Ѓ" },
1976 { "gjcy", "ѓ" },
1977 { "Iukcy", "І" },
1978 { "iukcy", "і" },
1979 { "Jsercy", "Ј" },
1980 { "jsercy", "ј" },
1981 { "Jukcy", "Є" },
1982 { "jukcy", "є" },
1983 { "KJcy", "Ќ" },
1984 { "kjcy", "ќ" },
1985 { "LJcy", "Љ" },
1986 { "ljcy", "љ" },
1987 { "NJcy", "Њ" },
1988 { "njcy", "њ" },
1989 { "TSHcy", "Ћ" },
1990 { "tshcy", "ћ" },
1991 { "Ubrcy", "Ў" },
1992 { "ubrcy", "ў" },
1993 { "YIcy", "Ї" },
1994 { "yicy", "ї" },
1995 { "acute", "´" },
1996 { "breve", "˘" },
1997 { "caron", "ˇ" },
1998 { "cedil", "¸" },
1999 { "circ", "ˆ" },
2000 { "dblac", "˝" },
2001 { "die", "¨" },
2002 { "dot", "˙" },
2003 { "grave", "`" },
2004 { "macr", "¯" },
2005 { "ogon", "˛" },
2006 { "ring", "˚" },
2007 { "tilde", "˜" },
2008 { "uml", "¨" },
2009 { "Aacute", "Á" },
2010 { "aacute", "á" },
2011 { "Acirc", "Â" },
2012 { "acirc", "â" },
2013 { "AElig", "Æ" },
2014 { "aelig", "æ" },
2015 { "Agrave", "À" },
2016 { "agrave", "à" },
2017 { "Aring", "Å" },
2018 { "aring", "å" },
2019 { "Atilde", "Ã" },
2020 { "atilde", "ã" },
2021 { "Auml", "Ä" },
2022 { "auml", "ä" },
2023 { "Ccedil", "Ç" },
2024 { "ccedil", "ç" },
2025 { "Eacute", "É" },
2026 { "eacute", "é" },
2027 { "Ecirc", "Ê" },
2028 { "ecirc", "ê" },
2029 { "Egrave", "È" },
2030 { "egrave", "è" },
2031 { "ETH", "Ð" },
2032 { "eth", "ð" },
2033 { "Euml", "Ë" },
2034 { "euml", "ë" },
2035 { "Iacute", "Í" },
2036 { "iacute", "í" },
2037 { "Icirc", "Î" },
2038 { "icirc", "î" },
2039 { "Igrave", "Ì" },
2040 { "igrave", "ì" },
2041 { "Iuml", "Ï" },
2042 { "iuml", "ï" },
2043 { "Ntilde", "Ñ" },
2044 { "ntilde", "ñ" },
2045 { "Oacute", "Ó" },
2046 { "oacute", "ó" },
2047 { "Ocirc", "Ô" },
2048 { "ocirc", "ô" },
2049 { "Ograve", "Ò" },
2050 { "ograve", "ò" },
2051 { "Oslash", "Ø" },
2052 { "oslash", "ø" },
2053 { "Otilde", "Õ" },
2054 { "otilde", "õ" },
2055 { "Ouml", "Ö" },
2056 { "ouml", "ö" },
2057 { "szlig", "ß" },
2058 { "THORN", "Þ" },
2059 { "thorn", "þ" },
2060 { "Uacute", "Ú" },
2061 { "uacute", "ú" },
2062 { "Ucirc", "Û" },
2063 { "ucirc", "û" },
2064 { "Ugrave", "Ù" },
2065 { "ugrave", "ù" },
2066 { "Uuml", "Ü" },
2067 { "uuml", "ü" },
2068 { "Yacute", "Ý" },
2069 { "yacute", "ý" },
2070 { "yuml", "ÿ" },
2071 { "Abreve", "Ă" },
2072 { "abreve", "ă" },
2073 { "Amacr", "Ā" },
2074 { "amacr", "ā" },
2075 { "Aogon", "Ą" },
2076 { "aogon", "ą" },
2077 { "Cacute", "Ć" },
2078 { "cacute", "ć" },
2079 { "Ccaron", "Č" },
2080 { "ccaron", "č" },
2081 { "Ccirc", "Ĉ" },
2082 { "ccirc", "ĉ" },
2083 { "Cdot", "Ċ" },
2084 { "cdot", "ċ" },
2085 { "Dcaron", "Ď" },
2086 { "dcaron", "ď" },
2087 { "Dstrok", "Đ" },
2088 { "dstrok", "đ" },
2089 { "Ecaron", "Ě" },
2090 { "ecaron", "ě" },
2091 { "Edot", "Ė" },
2092 { "edot", "ė" },
2093 { "Emacr", "Ē" },
2094 { "emacr", "ē" },
2095 { "ENG", "Ŋ" },
2096 { "eng", "ŋ" },
2097 { "Eogon", "Ę" },
2098 { "eogon", "ę" },
2099 { "gacute", "ǵ" },
2100 { "Gbreve", "Ğ" },
2101 { "gbreve", "ğ" },
2102 { "Gcedil", "Ģ" },
2103 { "Gcirc", "Ĝ" },
2104 { "gcirc", "ĝ" },
2105 { "Gdot", "Ġ" },
2106 { "gdot", "ġ" },
2107 { "Hcirc", "Ĥ" },
2108 { "hcirc", "ĥ" },
2109 { "Hstrok", "Ħ" },
2110 { "hstrok", "ħ" },
2111 { "Idot", "İ" },
2112 { "IJlig", "IJ" },
2113 { "ijlig", "ij" },
2114 { "Imacr", "Ī" },
2115 { "imacr", "ī" },
2116 { "inodot", "ı" },
2117 { "Iogon", "Į" },
2118 { "iogon", "į" },
2119 { "Itilde", "Ĩ" },
2120 { "itilde", "ĩ" },
2121 { "Jcirc", "Ĵ" },
2122 { "jcirc", "ĵ" },
2123 { "Kcedil", "Ķ" },
2124 { "kcedil", "ķ" },
2125 { "kgreen", "ĸ" },
2126 { "Lacute", "Ĺ" },
2127 { "lacute", "ĺ" },
2128 { "Lcaron", "Ľ" },
2129 { "lcaron", "ľ" },
2130 { "Lcedil", "Ļ" },
2131 { "lcedil", "ļ" },
2132 { "Lmidot", "Ŀ" },
2133 { "lmidot", "ŀ" },
2134 { "Lstrok", "Ł" },
2135 { "lstrok", "ł" },
2136 { "Nacute", "Ń" },
2137 { "nacute", "ń" },
2138 { "napos", "ʼn" },
2139 { "Ncaron", "Ň" },
2140 { "ncaron", "ň" },
2141 { "Ncedil", "Ņ" },
2142 { "ncedil", "ņ" },
2143 { "Odblac", "Ő" },
2144 { "odblac", "ő" },
2145 { "OElig", "Œ" },
2146 { "oelig", "œ" },
2147 { "Omacr", "Ō" },
2148 { "omacr", "ō" },
2149 { "Racute", "Ŕ" },
2150 { "racute", "ŕ" },
2151 { "Rcaron", "Ř" },
2152 { "rcaron", "ř" },
2153 { "Rcedil", "Ŗ" },
2154 { "rcedil", "ŗ" },
2155 { "Sacute", "Ś" },
2156 { "sacute", "ś" },
2157 { "Scaron", "Š" },
2158 { "scaron", "š" },
2159 { "Scedil", "Ş" },
2160 { "scedil", "ş" },
2161 { "Scirc", "Ŝ" },
2162 { "scirc", "ŝ" },
2163 { "Tcaron", "Ť" },
2164 { "tcaron", "ť" },
2165 { "Tcedil", "Ţ" },
2166 { "tcedil", "ţ" },
2167 { "Tstrok", "Ŧ" },
2168 { "tstrok", "ŧ" },
2169 { "Ubreve", "Ŭ" },
2170 { "ubreve", "ŭ" },
2171 { "Udblac", "Ű" },
2172 { "udblac", "ű" },
2173 { "Umacr", "Ū" },
2174 { "umacr", "ū" },
2175 { "Uogon", "Ų" },
2176 { "uogon", "ų" },
2177 { "Uring", "Ů" },
2178 { "uring", "ů" },
2179 { "Utilde", "Ũ" },
2180 { "utilde", "ũ" },
2181 { "Wcirc", "Ŵ" },
2182 { "wcirc", "ŵ" },
2183 { "Ycirc", "Ŷ" },
2184 { "ycirc", "ŷ" },
2185 { "Yuml", "Ÿ" },
2186 { "Zacute", "Ź" },
2187 { "zacute", "ź" },
2188 { "Zcaron", "Ž" },
2189 { "zcaron", "ž" },
2190 { "Zdot", "Ż" },
2191 { "zdot", "ż" },
2192 { "apos", "'" },
2193 { "ast", "*" },
2194 { "brvbar", "¦" },
2195 { "bsol", "\" },
2196 { "cent", "¢" },
2197 { "colon", ":" },
2198 { "comma", "," },
2199 { "commat", "@" },
2200 { "copy", "©" },
2201 { "curren", "¤" },
2202 { "darr", "↓" },
2203 { "deg", "°" },
2204 { "divide", "÷" },
2205 { "dollar", "$" },
2206 { "equals", "=" },
2207 { "excl", "!" },
2208 { "frac12", "½" },
2209 { "frac14", "¼" },
2210 { "frac18", "⅛" },
2211 { "frac34", "¾" },
2212 { "frac38", "⅜" },
2213 { "frac58", "⅝" },
2214 { "frac78", "⅞" },
2215 { "gt", ">" },
2216 { "half", "½" },
2217 { "horbar", "―" },
2218 { "hyphen", "‐" },
2219 { "iexcl", "¡" },
2220 { "iquest", "¿" },
2221 { "laquo", "«" },
2222 { "larr", "←" },
2223 { "lcub", "{" },
2224 { "ldquo", "“" },
2225 { "lowbar", "_" },
2226 { "lpar", "(" },
2227 { "lsqb", "[" },
2228 { "lsquo", "‘" },
2229 { "lt", "<" },
2230 { "micro", "µ" },
2231 { "middot", "·" },
2232 { "nbsp", " " },
2233 { "not", "¬" },
2234 { "num", "#" },
2235 { "ohm", "Ω" },
2236 { "ordf", "ª" },
2237 { "ordm", "º" },
2238 { "para", "¶" },
2239 { "percnt", "%" },
2240 { "period", "." },
2241 { "plus", "+" },
2242 { "plusmn", "±" },
2243 { "pound", "£" },
2244 { "quest", "?" },
2245 { "quot", """ },
2246 { "raquo", "»" },
2247 { "rarr", "→" },
2248 { "rcub", "}" },
2249 { "rdquo", "”" },
2250 { "reg", "®" },
2251 { "rpar", ")" },
2252 { "rsqb", "]" },
2253 { "rsquo", "’" },
2254 { "sect", "§" },
2255 { "semi", ";" },
2256 { "shy", "­" },
2257 { "sol", "/" },
2258 { "sung", "♪" },
2259 { "sup1", "¹" },
2260 { "sup2", "²" },
2261 { "sup3", "³" },
2262 { "times", "×" },
2263 { "trade", "™" },
2264 { "uarr", "↑" },
2265 { "verbar", "|" },
2266 { "yen", "¥" },
2267 { "blank", "␣" },
2268 { "blk12", "▒" },
2269 { "blk14", "░" },
2270 { "blk34", "▓" },
2271 { "block", "█" },
2272 { "bull", "•" },
2273 { "caret", "⁁" },
2274 { "check", "✓" },
2275 { "cir", "○" },
2276 { "clubs", "♣" },
2277 { "copysr", "℗" },
2278 { "cross", "✗" },
2279 { "Dagger", "‡" },
2280 { "dagger", "†" },
2281 { "dash", "‐" },
2282 { "diams", "♦" },
2283 { "dlcrop", "⌍" },
2284 { "drcrop", "⌌" },
2285 { "dtri", "▿" },
2286 { "dtrif", "▾" },
2287 { "emsp", " " },
2288 { "emsp13", " " },
2289 { "emsp14", " " },
2290 { "ensp", " " },
2291 { "female", "♀" },
2292 { "ffilig", "ffi" },
2293 { "fflig", "ff" },
2294 { "ffllig", "ffl" },
2295 { "filig", "fi" },
2296 { "flat", "♭" },
2297 { "fllig", "fl" },
2298 { "frac13", "⅓" },
2299 { "frac15", "⅕" },
2300 { "frac16", "⅙" },
2301 { "frac23", "⅔" },
2302 { "frac25", "⅖" },
2303 { "frac35", "⅗" },
2304 { "frac45", "⅘" },
2305 { "frac56", "⅚" },
2306 { "hairsp", " " },
2307 { "hearts", "♥" },
2308 { "hellip", "…" },
2309 { "hybull", "⁃" },
2310 { "incare", "℅" },
2311 { "ldquor", "„" },
2312 { "lhblk", "▄" },
2313 { "loz", "◊" },
2314 { "lozf", "⧫" },
2315 { "lsquor", "‚" },
2316 { "ltri", "◃" },
2317 { "ltrif", "◂" },
2318 { "male", "♂" },
2319 { "malt", "✠" },
2320 { "marker", "▮" },
2321 { "mdash", "—" },
2322 { "mldr", "…" },
2323 { "natur", "♮" },
2324 { "ndash", "–" },
2325 { "nldr", "‥" },
2326 { "numsp", " " },
2327 { "phone", "☎" },
2328 { "puncsp", " " },
2329 { "rdquor", "”" },
2330 { "rect", "▭" },
2331 { "rsquor", "’" },
2332 { "rtri", "▹" },
2333 { "rtrif", "▸" },
2334 { "rx", "℞" },
2335 { "sext", "✶" },
2336 { "sharp", "♯" },
2337 { "spades", "♠" },
2338 { "squ", "□" },
2339 { "squf", "▪" },
2340 { "star", "☆" },
2341 { "starf", "★" },
2342 { "target", "⌖" },
2343 { "telrec", "⌕" },
2344 { "thinsp", " " },
2345 { "uhblk", "▀" },
2346 { "ulcrop", "⌏" },
2347 { "urcrop", "⌎" },
2348 { "utri", "▵" },
2349 { "utrif", "▴" },
2350 { "vellip", "⋮" },
2351 { "af", "⁡" },
2352 { "asympeq", "≍" },
2353 { "Cross", "⨯" },
2354 { "DD", "ⅅ" },
2355 { "dd", "ⅆ" },
2356 { "DownArrowBar", "⤓" },
2357 { "DownBreve", "̑" },
2358 { "DownLeftRightVector", "⥐" },
2359 { "DownLeftTeeVector", "⥞" },
2360 { "DownLeftVectorBar", "⥖" },
2361 { "DownRightTeeVector", "⥟" },
2362 { "DownRightVectorBar", "⥗" },
2363 { "ee", "ⅇ" },
2364 { "EmptySmallSquare", "◻" },
2365 { "EmptyVerySmallSquare", "▫" },
2366 { "Equal", "⩵" },
2367 { "FilledSmallSquare", "◼" },
2368 { "FilledVerySmallSquare", "▪" },
2369 { "GreaterGreater", "⪢" },
2370 { "Hat", "^" },
2371 { "HorizontalLine", "─" },
2372 { "ic", "⁣" },
2373 { "ii", "ⅈ" },
2374 { "it", "⁢" },
2375 { "larrb", "⇤" },
2376 { "LeftDownTeeVector", "⥡" },
2377 { "LeftDownVectorBar", "⥙" },
2378 { "LeftRightVector", "⥎" },
2379 { "LeftTeeVector", "⥚" },
2380 { "LeftTriangleBar", "⧏" },
2381 { "LeftUpDownVector", "⥑" },
2382 { "LeftUpTeeVector", "⥠" },
2383 { "LeftUpVectorBar", "⥘" },
2384 { "LeftVectorBar", "⥒" },
2385 { "LessLess", "⪡" },
2386 { "mapstodown", "↧" },
2387 { "mapstoleft", "↤" },
2388 { "mapstoup", "↥" },
2389 { "MediumSpace", " " },
2390 { "nbump", "≎̸" },
2391 { "nbumpe", "≏̸" },
2392 { "nesim", "≂̸" },
2393 { "NewLine", "
" },
2394 { "NoBreak", "⁠" },
2395 { "NotCupCap", "≭" },
2396 { "NotHumpEqual", "≏̸" },
2397 { "NotLeftTriangleBar", "⧏̸" },
2398 { "NotNestedGreaterGreater", "⪢̸" },
2399 { "NotNestedLessLess", "⪡̸" },
2400 { "NotRightTriangleBar", "⧐̸" },
2401 { "NotSquareSubset", "⊏̸" },
2402 { "NotSquareSuperset", "⊐̸" },
2403 { "NotSucceedsTilde", "≿̸" },
2404 { "OverBar", "¯" },
2405 { "OverBrace", "︷" },
2406 { "OverBracket", "⎴" },
2407 { "OverParenthesis", "︵" },
2408 { "planckh", "ℎ" },
2409 { "Product", "∏" },
2410 { "rarrb", "⇥" },
2411 { "RightDownTeeVector", "⥝" },
2412 { "RightDownVectorBar", "⥕" },
2413 { "RightTeeVector", "⥛" },
2414 { "RightTriangleBar", "⧐" },
2415 { "RightUpDownVector", "⥏" },
2416 { "RightUpTeeVector", "⥜" },
2417 { "RightUpVectorBar", "⥔" },
2418 { "RightVectorBar", "⥓" },
2419 { "RoundImplies", "⥰" },
2420 { "RuleDelayed", "⧴" },
2421 { "Tab", "	" },
2422 { "ThickSpace", "   " },
2423 { "UnderBar", "̲" },
2424 { "UnderBrace", "︸" },
2425 { "UnderBracket", "⎵" },
2426 { "UnderParenthesis", "︶" },
2427 { "UpArrowBar", "⤒" },
2428 { "Upsilon", "Υ" },
2429 { "VerticalLine", "|" },
2430 { "VerticalSeparator", "❘" },
2431 { "ZeroWidthSpace", "​" },
2432 { "angle", "∠" },
2433 { "ApplyFunction", "⁡" },
2434 { "approx", "≈" },
2435 { "approxeq", "≊" },
2436 { "Assign", "≔" },
2437 { "backcong", "≌" },
2438 { "backepsilon", "϶" },
2439 { "backprime", "‵" },
2440 { "backsim", "∽" },
2441 { "backsimeq", "⋍" },
2442 { "Backslash", "∖" },
2443 { "barwedge", "⌅" },
2444 { "Because", "∵" },
2445 { "because", "∵" },
2446 { "Bernoullis", "ℬ" },
2447 { "between", "≬" },
2448 { "bigcap", "⋂" },
2449 { "bigcirc", "◯" },
2450 { "bigcup", "⋃" },
2451 { "bigodot", "⨀" },
2452 { "bigoplus", "⨁" },
2453 { "bigotimes", "⨂" },
2454 { "bigsqcup", "⨆" },
2455 { "bigstar", "★" },
2456 { "bigtriangledown", "▽" },
2457 { "bigtriangleup", "△" },
2458 { "biguplus", "⨄" },
2459 { "bigvee", "⋁" },
2460 { "bigwedge", "⋀" },
2461 { "bkarow", "⤍" },
2462 { "blacklozenge", "⧫" },
2463 { "blacksquare", "▪" },
2464 { "blacktriangle", "▴" },
2465 { "blacktriangledown", "▾" },
2466 { "blacktriangleleft", "◂" },
2467 { "blacktriangleright", "▸" },
2468 { "bot", "⊥" },
2469 { "boxminus", "⊟" },
2470 { "boxplus", "⊞" },
2471 { "boxtimes", "⊠" },
2472 { "Breve", "˘" },
2473 { "bullet", "•" },
2474 { "Bumpeq", "≎" },
2475 { "bumpeq", "≏" },
2476 { "CapitalDifferentialD", "ⅅ" },
2477 { "Cayleys", "ℭ" },
2478 { "Cedilla", "¸" },
2479 { "CenterDot", "·" },
2480 { "centerdot", "·" },
2481 { "checkmark", "✓" },
2482 { "circeq", "≗" },
2483 { "circlearrowleft", "↺" },
2484 { "circlearrowright", "↻" },
2485 { "circledast", "⊛" },
2486 { "circledcirc", "⊚" },
2487 { "circleddash", "⊝" },
2488 { "CircleDot", "⊙" },
2489 { "circledR", "®" },
2490 { "circledS", "Ⓢ" },
2491 { "CircleMinus", "⊖" },
2492 { "CirclePlus", "⊕" },
2493 { "CircleTimes", "⊗" },
2494 { "ClockwiseContourIntegral", "∲" },
2495 { "CloseCurlyDoubleQuote", "”" },
2496 { "CloseCurlyQuote", "’" },
2497 { "clubsuit", "♣" },
2498 { "coloneq", "≔" },
2499 { "complement", "∁" },
2500 { "complexes", "ℂ" },
2501 { "Congruent", "≡" },
2502 { "ContourIntegral", "∮" },
2503 { "Coproduct", "∐" },
2504 { "CounterClockwiseContourIntegral", "∳" },
2505 { "CupCap", "≍" },
2506 { "curlyeqprec", "⋞" },
2507 { "curlyeqsucc", "⋟" },
2508 { "curlyvee", "⋎" },
2509 { "curlywedge", "⋏" },
2510 { "curvearrowleft", "↶" },
2511 { "curvearrowright", "↷" },
2512 { "dbkarow", "⤏" },
2513 { "ddagger", "‡" },
2514 { "ddotseq", "⩷" },
2515 { "Del", "∇" },
2516 { "DiacriticalAcute", "´" },
2517 { "DiacriticalDot", "˙" },
2518 { "DiacriticalDoubleAcute", "˝" },
2519 { "DiacriticalGrave", "`" },
2520 { "DiacriticalTilde", "˜" },
2521 { "Diamond", "⋄" },
2522 { "diamond", "⋄" },
2523 { "diamondsuit", "♦" },
2524 { "DifferentialD", "ⅆ" },
2525 { "digamma", "ϝ" },
2526 { "div", "÷" },
2527 { "divideontimes", "⋇" },
2528 { "doteq", "≐" },
2529 { "doteqdot", "≑" },
2530 { "DotEqual", "≐" },
2531 { "dotminus", "∸" },
2532 { "dotplus", "∔" },
2533 { "dotsquare", "⊡" },
2534 { "doublebarwedge", "⌆" },
2535 { "DoubleContourIntegral", "∯" },
2536 { "DoubleDot", "¨" },
2537 { "DoubleDownArrow", "⇓" },
2538 { "DoubleLeftArrow", "⇐" },
2539 { "DoubleLeftRightArrow", "⇔" },
2540 { "DoubleLeftTee", "⫤" },
2541 { "DoubleLongLeftArrow", "⟸" },
2542 { "DoubleLongLeftRightArrow", "⟺" },
2543 { "DoubleLongRightArrow", "⟹" },
2544 { "DoubleRightArrow", "⇒" },
2545 { "DoubleRightTee", "⊨" },
2546 { "DoubleUpArrow", "⇑" },
2547 { "DoubleUpDownArrow", "⇕" },
2548 { "DoubleVerticalBar", "∥" },
2549 { "DownArrow", "↓" },
2550 { "Downarrow", "⇓" },
2551 { "downarrow", "↓" },
2552 { "DownArrowUpArrow", "⇵" },
2553 { "downdownarrows", "⇊" },
2554 { "downharpoonleft", "⇃" },
2555 { "downharpoonright", "⇂" },
2556 { "DownLeftVector", "↽" },
2557 { "DownRightVector", "⇁" },
2558 { "DownTee", "⊤" },
2559 { "DownTeeArrow", "↧" },
2560 { "drbkarow", "⤐" },
2561 { "Element", "∈" },
2562 { "emptyset", "∅" },
2563 { "eqcirc", "≖" },
2564 { "eqcolon", "≕" },
2565 { "eqsim", "≂" },
2566 { "eqslantgtr", "⪖" },
2567 { "eqslantless", "⪕" },
2568 { "EqualTilde", "≂" },
2569 { "Equilibrium", "⇌" },
2570 { "Exists", "∃" },
2571 { "expectation", "ℰ" },
2572 { "ExponentialE", "ⅇ" },
2573 { "exponentiale", "ⅇ" },
2574 { "fallingdotseq", "≒" },
2575 { "ForAll", "∀" },
2576 { "Fouriertrf", "ℱ" },
2577 { "geq", "≥" },
2578 { "geqq", "≧" },
2579 { "geqslant", "⩾" },
2580 { "gg", "≫" },
2581 { "ggg", "⋙" },
2582 { "gnapprox", "⪊" },
2583 { "gneq", "⪈" },
2584 { "gneqq", "≩" },
2585 { "GreaterEqual", "≥" },
2586 { "GreaterEqualLess", "⋛" },
2587 { "GreaterFullEqual", "≧" },
2588 { "GreaterLess", "≷" },
2589 { "GreaterSlantEqual", "⩾" },
2590 { "GreaterTilde", "≳" },
2591 { "gtrapprox", "⪆" },
2592 { "gtrdot", "⋗" },
2593 { "gtreqless", "⋛" },
2594 { "gtreqqless", "⪌" },
2595 { "gtrless", "≷" },
2596 { "gtrsim", "≳" },
2597 { "gvertneqq", "≩︀" },
2598 { "Hacek", "ˇ" },
2599 { "hbar", "ℏ" },
2600 { "heartsuit", "♥" },
2601 { "HilbertSpace", "ℋ" },
2602 { "hksearow", "⤥" },
2603 { "hkswarow", "⤦" },
2604 { "hookleftarrow", "↩" },
2605 { "hookrightarrow", "↪" },
2606 { "hslash", "ℏ" },
2607 { "HumpDownHump", "≎" },
2608 { "HumpEqual", "≏" },
2609 { "iiiint", "⨌" },
2610 { "iiint", "∭" },
2611 { "Im", "ℑ" },
2612 { "ImaginaryI", "ⅈ" },
2613 { "imagline", "ℐ" },
2614 { "imagpart", "ℑ" },
2615 { "Implies", "⇒" },
2616 { "in", "∈" },
2617 { "integers", "ℤ" },
2618 { "Integral", "∫" },
2619 { "intercal", "⊺" },
2620 { "Intersection", "⋂" },
2621 { "intprod", "⨼" },
2622 { "InvisibleComma", "⁣" },
2623 { "InvisibleTimes", "⁢" },
2624 { "langle", "〈" },
2625 { "Laplacetrf", "ℒ" },
2626 { "lbrace", "{" },
2627 { "lbrack", "[" },
2628 { "LeftAngleBracket", "〈" },
2629 { "LeftArrow", "←" },
2630 { "Leftarrow", "⇐" },
2631 { "leftarrow", "←" },
2632 { "LeftArrowBar", "⇤" },
2633 { "LeftArrowRightArrow", "⇆" },
2634 { "leftarrowtail", "↢" },
2635 { "LeftCeiling", "⌈" },
2636 { "LeftDoubleBracket", "〚" },
2637 { "LeftDownVector", "⇃" },
2638 { "LeftFloor", "⌊" },
2639 { "leftharpoondown", "↽" },
2640 { "leftharpoonup", "↼" },
2641 { "leftleftarrows", "⇇" },
2642 { "LeftRightArrow", "↔" },
2643 { "Leftrightarrow", "⇔" },
2644 { "leftrightarrow", "↔" },
2645 { "leftrightarrows", "⇆" },
2646 { "leftrightharpoons", "⇋" },
2647 { "leftrightsquigarrow", "↭" },
2648 { "LeftTee", "⊣" },
2649 { "LeftTeeArrow", "↤" },
2650 { "leftthreetimes", "⋋" },
2651 { "LeftTriangle", "⊲" },
2652 { "LeftTriangleEqual", "⊴" },
2653 { "LeftUpVector", "↿" },
2654 { "LeftVector", "↼" },
2655 { "leq", "≤" },
2656 { "leqq", "≦" },
2657 { "leqslant", "⩽" },
2658 { "lessapprox", "⪅" },
2659 { "lessdot", "⋖" },
2660 { "lesseqgtr", "⋚" },
2661 { "lesseqqgtr", "⪋" },
2662 { "LessEqualGreater", "⋚" },
2663 { "LessFullEqual", "≦" },
2664 { "LessGreater", "≶" },
2665 { "lessgtr", "≶" },
2666 { "lesssim", "≲" },
2667 { "LessSlantEqual", "⩽" },
2668 { "LessTilde", "≲" },
2669 { "ll", "≪" },
2670 { "llcorner", "⌞" },
2671 { "Lleftarrow", "⇚" },
2672 { "lmoustache", "⎰" },
2673 { "lnapprox", "⪉" },
2674 { "lneq", "⪇" },
2675 { "lneqq", "≨" },
2676 { "LongLeftArrow", "⟵" },
2677 { "Longleftarrow", "⟸" },
2678 { "longleftarrow", "⟵" },
2679 { "LongLeftRightArrow", "⟷" },
2680 { "Longleftrightarrow", "⟺" },
2681 { "longleftrightarrow", "⟷" },
2682 { "longmapsto", "⟼" },
2683 { "LongRightArrow", "⟶" },
2684 { "Longrightarrow", "⟹" },
2685 { "longrightarrow", "⟶" },
2686 { "looparrowleft", "↫" },
2687 { "looparrowright", "↬" },
2688 { "LowerLeftArrow", "↙" },
2689 { "LowerRightArrow", "↘" },
2690 { "lozenge", "◊" },
2691 { "lrcorner", "⌟" },
2692 { "Lsh", "↰" },
2693 { "lvertneqq", "≨︀" },
2694 { "maltese", "✠" },
2695 { "mapsto", "↦" },
2696 { "measuredangle", "∡" },
2697 { "Mellintrf", "ℳ" },
2698 { "MinusPlus", "∓" },
2699 { "mp", "∓" },
2700 { "multimap", "⊸" },
2701 { "napprox", "≉" },
2702 { "natural", "♮" },
2703 { "naturals", "ℕ" },
2704 { "nearrow", "↗" },
2705 { "NegativeMediumSpace", "​" },
2706 { "NegativeThickSpace", "​" },
2707 { "NegativeThinSpace", "​" },
2708 { "NegativeVeryThinSpace", "​" },
2709 { "NestedGreaterGreater", "≫" },
2710 { "NestedLessLess", "≪" },
2711 { "nexists", "∄" },
2712 { "ngeq", "≱" },
2713 { "ngeqq", "≧̸" },
2714 { "ngeqslant", "⩾̸" },
2715 { "ngtr", "≯" },
2716 { "nLeftarrow", "⇍" },
2717 { "nleftarrow", "↚" },
2718 { "nLeftrightarrow", "⇎" },
2719 { "nleftrightarrow", "↮" },
2720 { "nleq", "≰" },
2721 { "nleqq", "≦̸" },
2722 { "nleqslant", "⩽̸" },
2723 { "nless", "≮" },
2724 { "NonBreakingSpace", " " },
2725 { "NotCongruent", "≢" },
2726 { "NotDoubleVerticalBar", "∦" },
2727 { "NotElement", "∉" },
2728 { "NotEqual", "≠" },
2729 { "NotEqualTilde", "≂̸" },
2730 { "NotExists", "∄" },
2731 { "NotGreater", "≯" },
2732 { "NotGreaterEqual", "≱" },
2733 { "NotGreaterFullEqual", "≦̸" },
2734 { "NotGreaterGreater", "≫̸" },
2735 { "NotGreaterLess", "≹" },
2736 { "NotGreaterSlantEqual", "⩾̸" },
2737 { "NotGreaterTilde", "≵" },
2738 { "NotHumpDownHump", "≎̸" },
2739 { "NotLeftTriangle", "⋪" },
2740 { "NotLeftTriangleEqual", "⋬" },
2741 { "NotLess", "≮" },
2742 { "NotLessEqual", "≰" },
2743 { "NotLessGreater", "≸" },
2744 { "NotLessLess", "≪̸" },
2745 { "NotLessSlantEqual", "⩽̸" },
2746 { "NotLessTilde", "≴" },
2747 { "NotPrecedes", "⊀" },
2748 { "NotPrecedesEqual", "⪯̸" },
2749 { "NotPrecedesSlantEqual", "⋠" },
2750 { "NotReverseElement", "∌" },
2751 { "NotRightTriangle", "⋫" },
2752 { "NotRightTriangleEqual", "⋭" },
2753 { "NotSquareSubsetEqual", "⋢" },
2754 { "NotSquareSupersetEqual", "⋣" },
2755 { "NotSubset", "⊂⃒" },
2756 { "NotSubsetEqual", "⊈" },
2757 { "NotSucceeds", "⊁" },
2758 { "NotSucceedsEqual", "⪰̸" },
2759 { "NotSucceedsSlantEqual", "⋡" },
2760 { "NotSuperset", "⊃⃒" },
2761 { "NotSupersetEqual", "⊉" },
2762 { "NotTilde", "≁" },
2763 { "NotTildeEqual", "≄" },
2764 { "NotTildeFullEqual", "≇" },
2765 { "NotTildeTilde", "≉" },
2766 { "NotVerticalBar", "∤" },
2767 { "nparallel", "∦" },
2768 { "nprec", "⊀" },
2769 { "npreceq", "⪯̸" },
2770 { "nRightarrow", "⇏" },
2771 { "nrightarrow", "↛" },
2772 { "nshortmid", "∤" },
2773 { "nshortparallel", "∦" },
2774 { "nsimeq", "≄" },
2775 { "nsubset", "⊂⃒" },
2776 { "nsubseteq", "⊈" },
2777 { "nsubseteqq", "⫅̸" },
2778 { "nsucc", "⊁" },
2779 { "nsucceq", "⪰̸" },
2780 { "nsupset", "⊃⃒" },
2781 { "nsupseteq", "⊉" },
2782 { "nsupseteqq", "⫆̸" },
2783 { "ntriangleleft", "⋪" },
2784 { "ntrianglelefteq", "⋬" },
2785 { "ntriangleright", "⋫" },
2786 { "ntrianglerighteq", "⋭" },
2787 { "nwarrow", "↖" },
2788 { "oint", "∮" },
2789 { "OpenCurlyDoubleQuote", "“" },
2790 { "OpenCurlyQuote", "‘" },
2791 { "orderof", "ℴ" },
2792 { "parallel", "∥" },
2793 { "PartialD", "∂" },
2794 { "pitchfork", "⋔" },
2795 { "PlusMinus", "±" },
2796 { "pm", "±" },
2797 { "Poincareplane", "ℌ" },
2798 { "prec", "≺" },
2799 { "precapprox", "⪷" },
2800 { "preccurlyeq", "≼" },
2801 { "Precedes", "≺" },
2802 { "PrecedesEqual", "⪯" },
2803 { "PrecedesSlantEqual", "≼" },
2804 { "PrecedesTilde", "≾" },
2805 { "preceq", "⪯" },
2806 { "precnapprox", "⪹" },
2807 { "precneqq", "⪵" },
2808 { "precnsim", "⋨" },
2809 { "precsim", "≾" },
2810 { "primes", "ℙ" },
2811 { "Proportion", "∷" },
2812 { "Proportional", "∝" },
2813 { "propto", "∝" },
2814 { "quaternions", "ℍ" },
2815 { "questeq", "≟" },
2816 { "rangle", "〉" },
2817 { "rationals", "ℚ" },
2818 { "rbrace", "}" },
2819 { "rbrack", "]" },
2820 { "Re", "ℜ" },
2821 { "realine", "ℛ" },
2822 { "realpart", "ℜ" },
2823 { "reals", "ℝ" },
2824 { "ReverseElement", "∋" },
2825 { "ReverseEquilibrium", "⇋" },
2826 { "ReverseUpEquilibrium", "⥯" },
2827 { "RightAngleBracket", "〉" },
2828 { "RightArrow", "→" },
2829 { "Rightarrow", "⇒" },
2830 { "rightarrow", "→" },
2831 { "RightArrowBar", "⇥" },
2832 { "RightArrowLeftArrow", "⇄" },
2833 { "rightarrowtail", "↣" },
2834 { "RightCeiling", "⌉" },
2835 { "RightDoubleBracket", "〛" },
2836 { "RightDownVector", "⇂" },
2837 { "RightFloor", "⌋" },
2838 { "rightharpoondown", "⇁" },
2839 { "rightharpoonup", "⇀" },
2840 { "rightleftarrows", "⇄" },
2841 { "rightleftharpoons", "⇌" },
2842 { "rightrightarrows", "⇉" },
2843 { "rightsquigarrow", "↝" },
2844 { "RightTee", "⊢" },
2845 { "RightTeeArrow", "↦" },
2846 { "rightthreetimes", "⋌" },
2847 { "RightTriangle", "⊳" },
2848 { "RightTriangleEqual", "⊵" },
2849 { "RightUpVector", "↾" },
2850 { "RightVector", "⇀" },
2851 { "risingdotseq", "≓" },
2852 { "rmoustache", "⎱" },
2853 { "Rrightarrow", "⇛" },
2854 { "Rsh", "↱" },
2855 { "searrow", "↘" },
2856 { "setminus", "∖" },
2857 { "ShortDownArrow", "↓" },
2858 { "ShortLeftArrow", "←" },
2859 { "shortmid", "∣" },
2860 { "shortparallel", "∥" },
2861 { "ShortRightArrow", "→" },
2862 { "ShortUpArrow", "↑" },
2863 { "simeq", "≃" },
2864 { "SmallCircle", "∘" },
2865 { "smallsetminus", "∖" },
2866 { "spadesuit", "♠" },
2867 { "Sqrt", "√" },
2868 { "sqsubset", "⊏" },
2869 { "sqsubseteq", "⊑" },
2870 { "sqsupset", "⊐" },
2871 { "sqsupseteq", "⊒" },
2872 { "Square", "□" },
2873 { "SquareIntersection", "⊓" },
2874 { "SquareSubset", "⊏" },
2875 { "SquareSubsetEqual", "⊑" },
2876 { "SquareSuperset", "⊐" },
2877 { "SquareSupersetEqual", "⊒" },
2878 { "SquareUnion", "⊔" },
2879 { "Star", "⋆" },
2880 { "straightepsilon", "ε" },
2881 { "straightphi", "ϕ" },
2882 { "Subset", "⋐" },
2883 { "subset", "⊂" },
2884 { "subseteq", "⊆" },
2885 { "subseteqq", "⫅" },
2886 { "SubsetEqual", "⊆" },
2887 { "subsetneq", "⊊" },
2888 { "subsetneqq", "⫋" },
2889 { "succ", "≻" },
2890 { "succapprox", "⪸" },
2891 { "succcurlyeq", "≽" },
2892 { "Succeeds", "≻" },
2893 { "SucceedsEqual", "⪰" },
2894 { "SucceedsSlantEqual", "≽" },
2895 { "SucceedsTilde", "≿" },
2896 { "succeq", "⪰" },
2897 { "succnapprox", "⪺" },
2898 { "succneqq", "⪶" },
2899 { "succnsim", "⋩" },
2900 { "succsim", "≿" },
2901 { "SuchThat", "∋" },
2902 { "Sum", "∑" },
2903 { "Superset", "⊃" },
2904 { "SupersetEqual", "⊇" },
2905 { "Supset", "⋑" },
2906 { "supset", "⊃" },
2907 { "supseteq", "⊇" },
2908 { "supseteqq", "⫆" },
2909 { "supsetneq", "⊋" },
2910 { "supsetneqq", "⫌" },
2911 { "swarrow", "↙" },
2912 { "Therefore", "∴" },
2913 { "therefore", "∴" },
2914 { "thickapprox", "≈" },
2915 { "thicksim", "∼" },
2916 { "ThinSpace", " " },
2917 { "Tilde", "∼" },
2918 { "TildeEqual", "≃" },
2919 { "TildeFullEqual", "≅" },
2920 { "TildeTilde", "≈" },
2921 { "toea", "⤨" },
2922 { "tosa", "⤩" },
2923 { "triangle", "▵" },
2924 { "triangledown", "▿" },
2925 { "triangleleft", "◃" },
2926 { "trianglelefteq", "⊴" },
2927 { "triangleq", "≜" },
2928 { "triangleright", "▹" },
2929 { "trianglerighteq", "⊵" },
2930 { "TripleDot", "⃛" },
2931 { "twoheadleftarrow", "↞" },
2932 { "twoheadrightarrow", "↠" },
2933 { "ulcorner", "⌜" },
2934 { "Union", "⋃" },
2935 { "UnionPlus", "⊎" },
2936 { "UpArrow", "↑" },
2937 { "Uparrow", "⇑" },
2938 { "uparrow", "↑" },
2939 { "UpArrowDownArrow", "⇅" },
2940 { "UpDownArrow", "↕" },
2941 { "Updownarrow", "⇕" },
2942 { "updownarrow", "↕" },
2943 { "UpEquilibrium", "⥮" },
2944 { "upharpoonleft", "↿" },
2945 { "upharpoonright", "↾" },
2946 { "UpperLeftArrow", "↖" },
2947 { "UpperRightArrow", "↗" },
2948 { "upsilon", "υ" },
2949 { "UpTee", "⊥" },
2950 { "UpTeeArrow", "↥" },
2951 { "upuparrows", "⇈" },
2952 { "urcorner", "⌝" },
2953 { "varepsilon", "ɛ" },
2954 { "varkappa", "ϰ" },
2955 { "varnothing", "∅" },
2956 { "varphi", "φ" },
2957 { "varpi", "ϖ" },
2958 { "varpropto", "∝" },
2959 { "varrho", "ϱ" },
2960 { "varsigma", "ς" },
2961 { "varsubsetneq", "⊊︀" },
2962 { "varsubsetneqq", "⫋︀" },
2963 { "varsupsetneq", "⊋︀" },
2964 { "varsupsetneqq", "⫌︀" },
2965 { "vartheta", "ϑ" },
2966 { "vartriangleleft", "⊲" },
2967 { "vartriangleright", "⊳" },
2968 { "Vee", "⋁" },
2969 { "vee", "∨" },
2970 { "Vert", "‖" },
2971 { "vert", "|" },
2972 { "VerticalBar", "∣" },
2973 { "VerticalTilde", "≀" },
2974 { "VeryThinSpace", " " },
2975 { "Wedge", "⋀" },
2976 { "wedge", "∧" },
2977 { "wp", "℘" },
2978 { "wr", "≀" },
2979 { "zeetrf", "ℨ" },
2980 { 0, 0 }
2981 };
2982
2983 // *******************************************************************
2984 // QwtMmlDocument
2985 // *******************************************************************
2986
fontName(QwtMathMLDocument::MmlFont type) const2987 QString QwtMmlDocument::fontName( QwtMathMLDocument::MmlFont type ) const
2988 {
2989 switch ( type )
2990 {
2991 case QwtMathMLDocument::NormalFont:
2992 return m_normal_font_name;
2993 case QwtMathMLDocument::FrakturFont:
2994 return m_fraktur_font_name;
2995 case QwtMathMLDocument::SansSerifFont:
2996 return m_sans_serif_font_name;
2997 case QwtMathMLDocument::ScriptFont:
2998 return m_script_font_name;
2999 case QwtMathMLDocument::MonospaceFont:
3000 return m_monospace_font_name;
3001 case QwtMathMLDocument::DoublestruckFont:
3002 return m_doublestruck_font_name;
3003 };
3004
3005 return QString();
3006 }
3007
setFontName(QwtMathMLDocument::MmlFont type,const QString & name)3008 void QwtMmlDocument::setFontName( QwtMathMLDocument::MmlFont type, const QString &name )
3009 {
3010 switch ( type )
3011 {
3012 case QwtMathMLDocument::NormalFont:
3013 m_normal_font_name = name;
3014 break;
3015 case QwtMathMLDocument::FrakturFont:
3016 m_fraktur_font_name = name;
3017 break;
3018 case QwtMathMLDocument::SansSerifFont:
3019 m_sans_serif_font_name = name;
3020 break;
3021 case QwtMathMLDocument::ScriptFont:
3022 m_script_font_name = name;
3023 break;
3024 case QwtMathMLDocument::MonospaceFont:
3025 m_monospace_font_name = name;
3026 break;
3027 case QwtMathMLDocument::DoublestruckFont:
3028 m_doublestruck_font_name = name;
3029 break;
3030 };
3031 }
3032
domToQwtMmlNodeType(const QDomNode & dom_node)3033 QwtMml::NodeType domToQwtMmlNodeType( const QDomNode &dom_node )
3034 {
3035 QwtMml::NodeType mml_type = QwtMml::NoNode;
3036
3037 switch ( dom_node.nodeType() )
3038 {
3039 case QDomNode::ElementNode:
3040 {
3041 QString tag = dom_node.nodeName();
3042 const QwtMmlNodeSpec *spec = mmlFindNodeSpec( tag );
3043
3044 // treat urecognised tags as mrow
3045 if ( spec == 0 )
3046 mml_type = QwtMml::UnknownNode;
3047 else
3048 mml_type = spec->type;
3049
3050 break;
3051 }
3052 case QDomNode::TextNode:
3053 mml_type = QwtMml::TextNode;
3054 break;
3055
3056 case QDomNode::DocumentNode:
3057 mml_type = QwtMml::MrowNode;
3058 break;
3059
3060 case QDomNode::EntityReferenceNode:
3061 // qWarning("EntityReferenceNode: name=\"" + dom_node.nodeName() + "\" value=\"" + dom_node.nodeValue() + "\"");
3062 break;
3063
3064 case QDomNode::AttributeNode:
3065 case QDomNode::CDATASectionNode:
3066 case QDomNode::EntityNode:
3067 case QDomNode::ProcessingInstructionNode:
3068 case QDomNode::CommentNode:
3069 case QDomNode::DocumentTypeNode:
3070 case QDomNode::DocumentFragmentNode:
3071 case QDomNode::NotationNode:
3072 case QDomNode::BaseNode:
3073 case QDomNode::CharacterDataNode:
3074 break;
3075 }
3076
3077 return mml_type;
3078 }
3079
3080
QwtMmlDocument()3081 QwtMmlDocument::QwtMmlDocument()
3082 {
3083 m_root_node = 0;
3084
3085 // Some defaults which happen to work on my computer,
3086 // but probably won't work on other's
3087 #if defined(Q_OS_WIN)
3088 m_normal_font_name = "Times New Roman";
3089 #else
3090 m_normal_font_name = "Century Schoolbook L";
3091 #endif
3092 m_fraktur_font_name = "Fraktur";
3093 m_sans_serif_font_name = "Luxi Sans";
3094 m_script_font_name = "Urw Chancery L";
3095 m_monospace_font_name = "Luxi Mono";
3096 m_doublestruck_font_name = "Doublestruck";
3097 m_base_font_point_size = 16;
3098 m_foreground_color = Qt::black;
3099 m_background_color = Qt::white;
3100 }
3101
~QwtMmlDocument()3102 QwtMmlDocument::~QwtMmlDocument()
3103 {
3104 clear();
3105 }
3106
clear()3107 void QwtMmlDocument::clear()
3108 {
3109 delete m_root_node;
3110 m_root_node = 0;
3111 }
3112
dump() const3113 void QwtMmlDocument::dump() const
3114 {
3115 if ( m_root_node == 0 )
3116 return;
3117
3118 QString indent;
3119 _dump( m_root_node, indent );
3120 }
3121
_dump(const QwtMmlNode * node,QString & indent) const3122 void QwtMmlDocument::_dump( const QwtMmlNode *node, QString &indent ) const
3123 {
3124 if ( node == 0 ) return;
3125
3126 qWarning() << indent + node->toStr();
3127
3128 indent += " ";
3129 const QwtMmlNode *child = node->firstChild();
3130 for ( ; child != 0; child = child->nextSibling() )
3131 _dump( child, indent );
3132 indent.truncate( indent.length() - 2 );
3133 }
3134
setContent(QString text,QString * errorMsg,int * errorLine,int * errorColumn)3135 bool QwtMmlDocument::setContent( QString text, QString *errorMsg,
3136 int *errorLine, int *errorColumn )
3137 {
3138 clear();
3139
3140 QString prefix = "<?xml version=\"2.0\"?>\n";
3141 prefix.append( entityDeclarations() );
3142
3143 uint prefix_lines = 0;
3144 for ( int i = 0; i < prefix.length(); ++i )
3145 {
3146 if ( prefix.at( i ) == '\n' )
3147 ++prefix_lines;
3148 }
3149
3150 QDomDocument dom;
3151 if ( !dom.setContent( prefix + text, false, errorMsg, errorLine, errorColumn ) )
3152 {
3153 if ( errorLine != 0 )
3154 *errorLine -= prefix_lines;
3155 return false;
3156 }
3157
3158 // we don't have access to line info from now on
3159 if ( errorLine != 0 ) *errorLine = -1;
3160 if ( errorColumn != 0 ) *errorColumn = -1;
3161
3162 bool ok;
3163 QwtMmlNode *root_node = domToMml( dom, &ok, errorMsg );
3164 if ( !ok )
3165 return false;
3166
3167 if ( root_node == 0 )
3168 {
3169 if ( errorMsg != 0 )
3170 *errorMsg = "empty document";
3171 return false;
3172 }
3173
3174 insertChild( 0, root_node, 0 );
3175 layout();
3176
3177 /* QFile of("/tmp/dump.xml");
3178 of.open(IO_WriteOnly);
3179 QTextStream os(&of);
3180 os.setEncoding(QTextStream::UnicodeUTF8);
3181 os << dom.toString(); */
3182
3183 return true;
3184 }
3185
layout()3186 void QwtMmlDocument::layout()
3187 {
3188 if ( m_root_node == 0 )
3189 return;
3190
3191 m_root_node->layout();
3192 m_root_node->stretch();
3193 // dump();
3194 }
3195
insertChild(QwtMmlNode * parent,QwtMmlNode * new_node,QString * errorMsg)3196 bool QwtMmlDocument::insertChild( QwtMmlNode *parent, QwtMmlNode *new_node,
3197 QString *errorMsg )
3198 {
3199 if ( new_node == 0 )
3200 return true;
3201
3202 Q_ASSERT( new_node->parent() == 0
3203 && new_node->nextSibling() == 0
3204 && new_node->previousSibling() == 0 );
3205
3206 if ( parent != 0 )
3207 {
3208 if ( !mmlCheckChildType( parent->nodeType(), new_node->nodeType(), errorMsg ) )
3209 return false;
3210 }
3211
3212 if ( parent == 0 )
3213 {
3214 if ( m_root_node == 0 )
3215 m_root_node = new_node;
3216 else
3217 {
3218 QwtMmlNode *n = m_root_node->lastSibling();
3219 n->m_next_sibling = new_node;
3220 new_node->m_previous_sibling = n;
3221 }
3222 }
3223 else
3224 {
3225 new_node->m_parent = parent;
3226 if ( parent->hasChildNodes() )
3227 {
3228 QwtMmlNode *n = parent->firstChild()->lastSibling();
3229 n->m_next_sibling = new_node;
3230 new_node->m_previous_sibling = n;
3231 }
3232 else parent->m_first_child = new_node;
3233 }
3234
3235 return true;
3236 }
3237
createNode(NodeType type,const QwtMmlAttributeMap & mml_attr,const QString & mml_value,QString * errorMsg)3238 QwtMmlNode *QwtMmlDocument::createNode( NodeType type,
3239 const QwtMmlAttributeMap &mml_attr,
3240 const QString &mml_value,
3241 QString *errorMsg )
3242 {
3243 Q_ASSERT( type != NoNode );
3244
3245 QwtMmlNode *mml_node = 0;
3246
3247 if ( !mmlCheckAttributes( type, mml_attr, errorMsg ) )
3248 return 0;
3249
3250 switch ( type )
3251 {
3252 case MiNode:
3253 mml_node = new QwtMmlMiNode( this, mml_attr );
3254 break;
3255 case MnNode:
3256 mml_node = new QwtMmlMnNode( this, mml_attr );
3257 break;
3258 case MfracNode:
3259 mml_node = new QwtMmlMfracNode( this, mml_attr );
3260 break;
3261 case MrowNode:
3262 mml_node = new QwtMmlMrowNode( this, mml_attr );
3263 break;
3264 case MsqrtNode:
3265 mml_node = new QwtMmlMsqrtNode( this, mml_attr );
3266 break;
3267 case MrootNode:
3268 mml_node = new QwtMmlMrootNode( this, mml_attr );
3269 break;
3270 case MsupNode:
3271 mml_node = new QwtMmlMsupNode( this, mml_attr );
3272 break;
3273 case MsubNode:
3274 mml_node = new QwtMmlMsubNode( this, mml_attr );
3275 break;
3276 case MsubsupNode:
3277 mml_node = new QwtMmlMsubsupNode( this, mml_attr );
3278 break;
3279 case MoNode:
3280 mml_node = new QwtMmlMoNode( this, mml_attr );
3281 break;
3282 case MstyleNode:
3283 mml_node = new QwtMmlMstyleNode( this, mml_attr );
3284 break;
3285 case TextNode:
3286 mml_node = new QwtMmlTextNode( mml_value, this );
3287 break;
3288 case MphantomNode:
3289 mml_node = new QwtMmlMphantomNode( this, mml_attr );
3290 break;
3291 case MfencedNode:
3292 mml_node = new QwtMmlMfencedNode( this, mml_attr );
3293 break;
3294 case MtableNode:
3295 mml_node = new QwtMmlMtableNode( this, mml_attr );
3296 break;
3297 case MtrNode:
3298 mml_node = new QwtMmlMtrNode( this, mml_attr );
3299 break;
3300 case MtdNode:
3301 mml_node = new QwtMmlMtdNode( this, mml_attr );
3302 break;
3303 case MoverNode:
3304 mml_node = new QwtMmlMoverNode( this, mml_attr );
3305 break;
3306 case MunderNode:
3307 mml_node = new QwtMmlMunderNode( this, mml_attr );
3308 break;
3309 case MunderoverNode:
3310 mml_node = new QwtMmlMunderoverNode( this, mml_attr );
3311 break;
3312 case MalignMarkNode:
3313 mml_node = new QwtMmlMalignMarkNode( this );
3314 break;
3315 case MerrorNode:
3316 mml_node = new QwtMmlMerrorNode( this, mml_attr );
3317 break;
3318 case MtextNode:
3319 mml_node = new QwtMmlMtextNode( this, mml_attr );
3320 break;
3321 case MpaddedNode:
3322 mml_node = new QwtMmlMpaddedNode( this, mml_attr );
3323 break;
3324 case MspaceNode:
3325 mml_node = new QwtMmlMspaceNode( this, mml_attr );
3326 break;
3327 case UnknownNode:
3328 mml_node = new QwtMmlUnknownNode( this, mml_attr );
3329 break;
3330 case NoNode:
3331 mml_node = 0;
3332 break;
3333 }
3334
3335 return mml_node;
3336 }
3337
insertOperator(QwtMmlNode * node,const QString & text)3338 void QwtMmlDocument::insertOperator( QwtMmlNode *node, const QString &text )
3339 {
3340 QwtMmlNode *text_node = createNode( TextNode, QwtMmlAttributeMap(), text, 0 );
3341 QwtMmlNode *mo_node = createNode( MoNode, QwtMmlAttributeMap(), QString(), 0 );
3342
3343 bool ok = insertChild( node, mo_node, 0 );
3344 Q_ASSERT( ok );
3345 ok = insertChild( mo_node, text_node, 0 );
3346 Q_ASSERT( ok );
3347 }
3348
domToMml(const QDomNode & dom_node,bool * ok,QString * errorMsg)3349 QwtMmlNode *QwtMmlDocument::domToMml( const QDomNode &dom_node, bool *ok, QString *errorMsg )
3350 {
3351 // create the node
3352
3353 Q_ASSERT( ok != 0 );
3354
3355 NodeType mml_type = domToQwtMmlNodeType( dom_node );
3356
3357 if ( mml_type == NoNode )
3358 {
3359 *ok = true;
3360 return 0;
3361 }
3362
3363 QDomNamedNodeMap dom_attr = dom_node.attributes();
3364 QwtMmlAttributeMap mml_attr;
3365 for ( int i = 0; i < dom_attr.length(); ++i )
3366 {
3367 QDomNode attr_node = dom_attr.item( i );
3368 Q_ASSERT( !attr_node.nodeName().isNull() );
3369 Q_ASSERT( !attr_node.nodeValue().isNull() );
3370 mml_attr[attr_node.nodeName()] = attr_node.nodeValue();
3371 }
3372
3373 QString mml_value;
3374 if ( mml_type == TextNode )
3375 mml_value = dom_node.nodeValue();
3376 QwtMmlNode *mml_node = createNode( mml_type, mml_attr, mml_value, errorMsg );
3377 if ( mml_node == 0 )
3378 {
3379 *ok = false;
3380 return 0;
3381 }
3382
3383 // create the node's children according to the child_spec
3384
3385 const QwtMmlNodeSpec *spec = mmlFindNodeSpec( mml_type );
3386 QDomNodeList dom_child_list = dom_node.childNodes();
3387 int child_cnt = dom_child_list.count();
3388 QwtMmlNode *mml_child = 0;
3389
3390 QString separator_list;
3391 if ( mml_type == MfencedNode )
3392 separator_list = mml_node->explicitAttribute( "separators", "," );
3393
3394 switch ( spec->child_spec )
3395 {
3396 case QwtMmlNodeSpec::ChildIgnore:
3397 break;
3398
3399 case QwtMmlNodeSpec::ImplicitMrow:
3400
3401 if ( child_cnt > 0 )
3402 {
3403 mml_child = createImplicitMrowNode( dom_node, ok, errorMsg );
3404 if ( !*ok )
3405 {
3406 delete mml_node;
3407 return 0;
3408 }
3409
3410 if ( !insertChild( mml_node, mml_child, errorMsg ) )
3411 {
3412 delete mml_node;
3413 delete mml_child;
3414 *ok = false;
3415 return 0;
3416 }
3417 }
3418
3419 break;
3420
3421 default:
3422 // exact ammount of children specified - check...
3423 if ( spec->child_spec != child_cnt )
3424 {
3425 if ( errorMsg != 0 )
3426 *errorMsg = QString( "element " )
3427 + spec->tag
3428 + " requires exactly "
3429 + QString::number( spec->child_spec )
3430 + " arguments, got "
3431 + QString::number( child_cnt );
3432 delete mml_node;
3433 *ok = false;
3434 return 0;
3435 }
3436
3437 // ...and continue just as in ChildAny
3438 #ifdef Q_FALLTHROUGH
3439 Q_FALLTHROUGH();
3440 #endif
3441
3442 case QwtMmlNodeSpec::ChildAny:
3443 if ( mml_type == MfencedNode )
3444 insertOperator( mml_node, mml_node->explicitAttribute( "open", "(" ) );
3445
3446 for ( int i = 0; i < child_cnt; ++i )
3447 {
3448 QDomNode dom_child = dom_child_list.item( i );
3449
3450 QwtMmlNode *mml_child = domToMml( dom_child, ok, errorMsg );
3451 if ( !*ok )
3452 {
3453 delete mml_node;
3454 return 0;
3455 }
3456
3457 if ( mml_type == MtableNode && mml_child->nodeType() != MtrNode )
3458 {
3459 QwtMmlNode *mtr_node = createNode( MtrNode, QwtMmlAttributeMap(), QString(), 0 );
3460 insertChild( mml_node, mtr_node, 0 );
3461 if ( !insertChild( mtr_node, mml_child, errorMsg ) )
3462 {
3463 delete mml_node;
3464 delete mml_child;
3465 *ok = false;
3466 return 0;
3467 }
3468 }
3469 else if ( mml_type == MtrNode && mml_child->nodeType() != MtdNode )
3470 {
3471 QwtMmlNode *mtd_node = createNode( MtdNode, QwtMmlAttributeMap(), QString(), 0 );
3472 insertChild( mml_node, mtd_node, 0 );
3473 if ( !insertChild( mtd_node, mml_child, errorMsg ) )
3474 {
3475 delete mml_node;
3476 delete mml_child;
3477 *ok = false;
3478 return 0;
3479 }
3480 }
3481 else
3482 {
3483 if ( !insertChild( mml_node, mml_child, errorMsg ) )
3484 {
3485 delete mml_node;
3486 delete mml_child;
3487 *ok = false;
3488 return 0;
3489 }
3490 }
3491
3492 if ( i < child_cnt - 1 && mml_type == MfencedNode && !separator_list.isEmpty() )
3493 {
3494 QChar separator;
3495 if ( i >= ( int )separator_list.length() )
3496 separator = separator_list.at( separator_list.length() - 1 );
3497 else
3498 separator = separator_list[i];
3499 insertOperator( mml_node, QString( separator ) );
3500 }
3501 }
3502
3503 if ( mml_type == MfencedNode )
3504 insertOperator( mml_node, mml_node->explicitAttribute( "close", ")" ) );
3505
3506 break;
3507 }
3508
3509 *ok = true;
3510 return mml_node;
3511 }
3512
createImplicitMrowNode(const QDomNode & dom_node,bool * ok,QString * errorMsg)3513 QwtMmlNode *QwtMmlDocument::createImplicitMrowNode( const QDomNode &dom_node, bool *ok,
3514 QString *errorMsg )
3515 {
3516 QDomNodeList dom_child_list = dom_node.childNodes();
3517 int child_cnt = dom_child_list.count();
3518
3519 if ( child_cnt == 0 )
3520 {
3521 *ok = true;
3522 return 0;
3523 }
3524
3525 if ( child_cnt == 1 )
3526 return domToMml( dom_child_list.item( 0 ), ok, errorMsg );
3527
3528 QwtMmlNode *mml_node = createNode( MrowNode, QwtMmlAttributeMap(),
3529 QString(), errorMsg );
3530 Q_ASSERT( mml_node != 0 ); // there is no reason in heaven or hell for this to fail
3531
3532 for ( int i = 0; i < child_cnt; ++i )
3533 {
3534 QDomNode dom_child = dom_child_list.item( i );
3535
3536 QwtMmlNode *mml_child = domToMml( dom_child, ok, errorMsg );
3537 if ( !*ok )
3538 {
3539 delete mml_node;
3540 return 0;
3541 }
3542
3543 if ( !insertChild( mml_node, mml_child, errorMsg ) )
3544 {
3545 delete mml_node;
3546 delete mml_child;
3547 *ok = false;
3548 return 0;
3549 }
3550 }
3551
3552 return mml_node;
3553 }
3554
paint(QPainter * p,const QPoint & pos) const3555 void QwtMmlDocument::paint( QPainter *p, const QPoint &pos ) const
3556 {
3557 if ( m_root_node == 0 )
3558 return;
3559
3560 /* p->save();
3561 p->setPen(Qt::blue);
3562 p->drawLine(pos.x() - 5, pos.y(), pos.x() + 5, pos.y());
3563 p->drawLine(pos.x(), pos.y() - 5, pos.x(), pos.y() + 5);
3564 p->restore(); */
3565
3566 QRect mr = m_root_node->myRect();
3567 m_root_node->setRelOrigin( pos - mr.topLeft() );
3568 m_root_node->paint( p );
3569 }
3570
size() const3571 QSize QwtMmlDocument::size() const
3572 {
3573 if ( m_root_node == 0 )
3574 return QSize( 0, 0 );
3575 return m_root_node->deviceRect().size();
3576 }
3577
3578
3579
3580
3581 // *******************************************************************
3582 // QwtMmlNode
3583 // *******************************************************************
3584
3585
QwtMmlNode(NodeType type,QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)3586 QwtMmlNode::QwtMmlNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
3587 {
3588 m_parent = 0;
3589 m_first_child = 0;
3590 m_next_sibling = 0;
3591 m_previous_sibling = 0;
3592
3593 m_node_type = type;
3594 m_document = document;
3595 m_attribute_map = attribute_map;
3596
3597 m_my_rect = m_parent_rect = QRect( 0, 0, 0, 0 );
3598 m_rel_origin = QPoint( 0, 0 );
3599 m_stretched = false;
3600 }
3601
~QwtMmlNode()3602 QwtMmlNode::~QwtMmlNode()
3603 {
3604 QwtMmlNode *n = firstChild();
3605 while ( n != 0 )
3606 {
3607 QwtMmlNode *tmp = n->nextSibling();
3608 delete n;
3609 n = tmp;
3610 }
3611 }
3612
rectToStr(const QRect & rect)3613 static QString rectToStr( const QRect &rect )
3614 {
3615 return QString( "[(%1, %2), %3x%4]" )
3616 .arg( rect.x() )
3617 .arg( rect.y() )
3618 .arg( rect.width() )
3619 .arg( rect.height() );
3620 }
3621
toStr() const3622 QString QwtMmlNode::toStr() const
3623 {
3624 const QwtMmlNodeSpec *spec = mmlFindNodeSpec( nodeType() );
3625 Q_ASSERT( spec != 0 );
3626
3627 return QString( "%1 %2 mr=%3 pr=%4 dr=%5 ro=(%7, %8) str=%9" )
3628 .arg( spec->type_str )
3629 .arg( ( quintptr )this, 0, 16 )
3630 .arg( rectToStr( myRect() ) )
3631 .arg( rectToStr( parentRect() ) )
3632 .arg( rectToStr( deviceRect() ) )
3633 .arg( m_rel_origin.x() )
3634 .arg( m_rel_origin.y() )
3635 .arg( ( int )isStretched() );
3636 }
3637
interpretSpacing(const QString & value,bool * ok) const3638 int QwtMmlNode::interpretSpacing( const QString &value, bool *ok ) const
3639 {
3640 return ::interpretSpacing( value, em(), ex(), ok );
3641 }
3642
basePos() const3643 int QwtMmlNode::basePos() const
3644 {
3645 QFontMetrics fm( font() );
3646 return fm.strikeOutPos();
3647 }
3648
underlinePos() const3649 int QwtMmlNode::underlinePos() const
3650 {
3651 QFontMetrics fm( font() );
3652 return basePos() + fm.underlinePos();
3653 }
overlinePos() const3654 int QwtMmlNode::overlinePos() const
3655 {
3656 QFontMetrics fm( font() );
3657 return basePos() - fm.overlinePos();
3658 }
3659
lastSibling() const3660 QwtMmlNode *QwtMmlNode::lastSibling() const
3661 {
3662 const QwtMmlNode *n = this;
3663 while ( !n->isLastSibling() )
3664 n = n->nextSibling();
3665 return const_cast<QwtMmlNode*>( n );
3666 }
3667
firstSibling() const3668 QwtMmlNode *QwtMmlNode::firstSibling() const
3669 {
3670 const QwtMmlNode *n = this;
3671 while ( !n->isFirstSibling() )
3672 n = n->previousSibling();
3673 return const_cast<QwtMmlNode*>( n );
3674 }
3675
em() const3676 int QwtMmlNode::em() const
3677 {
3678 return QFontMetrics( font() ).boundingRect( 'm' ).width();
3679 }
3680
ex() const3681 int QwtMmlNode::ex() const
3682 {
3683 return QFontMetrics( font() ).boundingRect( 'x' ).height();
3684 }
3685
scriptlevel(const QwtMmlNode *) const3686 int QwtMmlNode::scriptlevel( const QwtMmlNode * ) const
3687 {
3688 int parent_sl;
3689 const QwtMmlNode *p = parent();
3690 if ( p == 0 )
3691 parent_sl = 0;
3692 else
3693 parent_sl = p->scriptlevel( this );
3694
3695 QString expl_sl_str = explicitAttribute( "scriptlevel" );
3696 if ( expl_sl_str.isNull() )
3697 return parent_sl;
3698
3699 if ( expl_sl_str.startsWith( "+" ) || expl_sl_str.startsWith( "-" ) )
3700 {
3701 bool ok;
3702 int expl_sl = expl_sl_str.toInt( &ok );
3703 if ( ok )
3704 {
3705 return parent_sl + expl_sl;
3706 }
3707 else
3708 {
3709 qWarning() << "QwtMmlNode::scriptlevel(): bad value " + expl_sl_str;
3710 return parent_sl;
3711 }
3712 }
3713
3714 bool ok;
3715 int expl_sl = expl_sl_str.toInt( &ok );
3716 if ( ok )
3717 return expl_sl;
3718
3719
3720 if ( expl_sl_str == "+" )
3721 return parent_sl + 1;
3722 else if ( expl_sl_str == "-" )
3723 return parent_sl - 1;
3724 else
3725 {
3726 qWarning() << "QwtMmlNode::scriptlevel(): could not parse value: \"" + expl_sl_str + "\"";
3727 return parent_sl;
3728 }
3729 }
3730
devicePoint(const QPoint & p) const3731 QPoint QwtMmlNode::devicePoint( const QPoint &p ) const
3732 {
3733 QRect mr = myRect();
3734 QRect dr = deviceRect();
3735
3736 if ( isStretched() )
3737 return dr.topLeft() + QPoint( ( p.x() - mr.left() ) * dr.width() / mr.width(),
3738 ( p.y() - mr.top() ) * dr.height() / mr.height() );
3739 else
3740 return dr.topLeft() + p - mr.topLeft();
3741 }
3742
inheritAttributeFromMrow(const QString & name,const QString & def) const3743 QString QwtMmlNode::inheritAttributeFromMrow( const QString &name,
3744 const QString &def ) const
3745 {
3746 const QwtMmlNode *p = this;
3747 for ( ; p != 0; p = p->parent() )
3748 {
3749 if ( p == this || p->nodeType() == MstyleNode )
3750 {
3751 QString value = p->explicitAttribute( name );
3752 if ( !value.isNull() )
3753 return value;
3754 }
3755 }
3756
3757 return def;
3758 }
3759
color() const3760 QColor QwtMmlNode::color() const
3761 {
3762 // If we are child of <merror> return red
3763 const QwtMmlNode *p = this;
3764 for ( ; p != 0; p = p->parent() )
3765 {
3766 if ( p->nodeType() == MerrorNode )
3767 return QColor( "red" );
3768 }
3769
3770 QString value_str = inheritAttributeFromMrow( "mathcolor" );
3771 if ( value_str.isNull() )
3772 value_str = inheritAttributeFromMrow( "color" );
3773 if ( value_str.isNull() )
3774 return QColor();
3775
3776 return QColor( value_str );
3777 }
3778
background() const3779 QColor QwtMmlNode::background() const
3780 {
3781 QString value_str = inheritAttributeFromMrow( "mathbackground" );
3782 if ( value_str.isNull() )
3783 value_str = inheritAttributeFromMrow( "background" );
3784 if ( value_str.isNull() )
3785 return QColor();
3786
3787 return QColor( value_str );
3788 }
3789
updateFontAttr(QwtMmlAttributeMap & font_attr,const QwtMmlNode * n,const QString & name,const QString & preferred_name=QString ())3790 static void updateFontAttr( QwtMmlAttributeMap &font_attr, const QwtMmlNode *n,
3791 const QString &name, const QString &preferred_name = QString() )
3792 {
3793 if ( font_attr.contains( preferred_name ) || font_attr.contains( name ) )
3794 return;
3795 QString value = n->explicitAttribute( name );
3796 if ( !value.isNull() )
3797 font_attr[name] = value;
3798 }
3799
collectFontAttributes(const QwtMmlNode * node)3800 static QwtMmlAttributeMap collectFontAttributes( const QwtMmlNode *node )
3801 {
3802 QwtMmlAttributeMap font_attr;
3803
3804 for ( const QwtMmlNode *n = node; n != 0; n = n->parent() )
3805 {
3806 if ( n == node || n->nodeType() == QwtMml::MstyleNode )
3807 {
3808 updateFontAttr( font_attr, n, "mathvariant" );
3809 updateFontAttr( font_attr, n, "mathsize" );
3810
3811 // depreciated attributes
3812 updateFontAttr( font_attr, n, "fontsize", "mathsize" );
3813 updateFontAttr( font_attr, n, "fontweight", "mathvariant" );
3814 updateFontAttr( font_attr, n, "fontstyle", "mathvariant" );
3815 updateFontAttr( font_attr, n, "fontfamily", "mathvariant" );
3816 }
3817 }
3818
3819 return font_attr;
3820 }
3821
font() const3822 QFont QwtMmlNode::font() const
3823 {
3824 QFont fn( document()->fontName( QwtMathMLDocument::NormalFont ),
3825 document()->baseFontPointSize() );
3826
3827 int ps = fn.pointSize();
3828 int sl = scriptlevel();
3829 if ( sl >= 0 )
3830 {
3831 for ( int i = 0; i < sl; ++i )
3832 ps = ( int )( ps * g_script_size_multiplier );
3833 }
3834 else
3835 {
3836 for ( int i = 0; i > sl; --i )
3837 ps = ( int )( ps / g_script_size_multiplier );
3838 }
3839 if ( ps < g_min_font_point_size )
3840 ps = g_min_font_point_size;
3841 fn.setPointSize( ps );
3842
3843 int em = QFontMetrics( fn ).boundingRect( 'm' ).width();
3844 int ex = QFontMetrics( fn ).boundingRect( 'x' ).height();
3845
3846 QwtMmlAttributeMap font_attr = collectFontAttributes( this );
3847
3848 if ( font_attr.contains( "mathvariant" ) )
3849 {
3850 QString value = font_attr["mathvariant"];
3851
3852 bool ok;
3853 uint mv = interpretMathVariant( value, &ok );
3854
3855 if ( ok )
3856 {
3857 if ( mv & ScriptMV )
3858 fn.setFamily( document()->fontName( QwtMathMLDocument::ScriptFont ) );
3859
3860 if ( mv & FrakturMV )
3861 fn.setFamily( document()->fontName( QwtMathMLDocument::FrakturFont ) );
3862
3863 if ( mv & SansSerifMV )
3864 fn.setFamily( document()->fontName( QwtMathMLDocument::SansSerifFont ) );
3865
3866 if ( mv & MonospaceMV )
3867 fn.setFamily( document()->fontName( QwtMathMLDocument::MonospaceFont ) );
3868
3869 if ( mv & DoubleStruckMV )
3870 fn.setFamily( document()->fontName( QwtMathMLDocument::DoublestruckFont ) );
3871
3872 if ( mv & BoldMV )
3873 fn.setBold( true );
3874
3875 if ( mv & ItalicMV )
3876 fn.setItalic( true );
3877 }
3878 }
3879
3880 if ( font_attr.contains( "mathsize" ) )
3881 {
3882 QString value = font_attr["mathsize"];
3883 fn = interpretMathSize( value, fn, em, ex, 0 );
3884 }
3885
3886 fn = interpretDepreciatedFontAttr( font_attr, fn, em, ex );
3887
3888 if ( nodeType() == MiNode
3889 && !font_attr.contains( "mathvariant" )
3890 && !font_attr.contains( "fontstyle" ) )
3891 {
3892 const QwtMmlMiNode *mi_node = ( const QwtMmlMiNode* ) this;
3893 if ( mi_node->text().length() == 1 )
3894 fn.setItalic( true );
3895 }
3896
3897 if ( nodeType() == MoNode )
3898 {
3899 fn.setItalic( false );
3900 fn.setBold( false );
3901 }
3902
3903 return fn;
3904 }
3905
explicitAttribute(const QString & name,const QString & def) const3906 QString QwtMmlNode::explicitAttribute( const QString &name, const QString &def ) const
3907 {
3908 QwtMmlAttributeMap::const_iterator it = m_attribute_map.find( name );
3909 if ( it != m_attribute_map.end() )
3910 return *it;
3911 return def;
3912 }
3913
3914
parentRect() const3915 QRect QwtMmlNode::parentRect() const
3916 {
3917 if ( isStretched() )
3918 return m_parent_rect;
3919
3920 QRect mr = myRect();
3921 QPoint ro = relOrigin();
3922
3923 return QRect( ro + mr.topLeft(), mr.size() );
3924 }
3925
3926
stretchTo(const QRect & rect)3927 void QwtMmlNode::stretchTo( const QRect &rect )
3928 {
3929 m_parent_rect = rect;
3930 m_stretched = true;
3931 }
3932
setRelOrigin(const QPoint & rel_origin)3933 void QwtMmlNode::setRelOrigin( const QPoint &rel_origin )
3934 {
3935 m_rel_origin = rel_origin + QPoint( -myRect().left(), 0 );
3936 m_stretched = false;
3937 }
3938
updateMyRect()3939 void QwtMmlNode::updateMyRect()
3940 {
3941 m_my_rect = symbolRect();
3942 QwtMmlNode *child = firstChild();
3943 for ( ; child != 0; child = child->nextSibling() )
3944 m_my_rect |= child->parentRect();
3945 }
3946
layout()3947 void QwtMmlNode::layout()
3948 {
3949 m_parent_rect = QRect( 0, 0, 0, 0 );
3950 m_stretched = false;
3951 m_rel_origin = QPoint( 0, 0 );
3952
3953 QwtMmlNode *child = firstChild();
3954 for ( ; child != 0; child = child->nextSibling() )
3955 child->layout();
3956
3957 layoutSymbol();
3958
3959 updateMyRect();
3960
3961 if ( parent() == 0 )
3962 m_rel_origin = QPoint( 0, 0 );
3963 }
3964
3965
deviceRect() const3966 QRect QwtMmlNode::deviceRect() const
3967 {
3968 if ( parent() == 0 )
3969 return QRect( relOrigin() + myRect().topLeft(), myRect().size() );
3970
3971 /* if (!isStretched()) {
3972 QRect pdr = parent()->deviceRect();
3973 QRect pmr = parent()->myRect();
3974 QRect pr = parentRect();
3975 QRect mr = myRect();
3976 return QRect(pdr.left() + pr.left() - pmr.left(),
3977 pdr.top() + pr.top() - pmr.top(),
3978 mr.width(), mr.height());
3979 }
3980 */
3981 QRect pdr = parent()->deviceRect();
3982 QRect pr = parentRect();
3983 QRect pmr = parent()->myRect();
3984
3985 float scale_w = 0;
3986 if ( pmr.width() != 0 )
3987 scale_w = ( float )pdr.width() / pmr.width();
3988 float scale_h = 0;
3989 if ( pmr.height() != 0 )
3990 scale_h = ( float )pdr.height() / pmr.height();
3991
3992 return QRect( pdr.left() + ROUND( ( pr.left() - pmr.left() ) * scale_w ),
3993 pdr.top() + ROUND( ( pr.top() - pmr.top() ) * scale_h ),
3994 ROUND( ( pr.width() * scale_w ) ),
3995 ROUND( ( pr.height() * scale_h ) ) );
3996 }
3997
layoutSymbol()3998 void QwtMmlNode::layoutSymbol()
3999 {
4000 // default behaves like an mrow
4001
4002 // now lay them out in a neat row, aligning their origins to my origin
4003 int w = 0;
4004 QwtMmlNode *child = firstChild();
4005 for ( ; child != 0; child = child->nextSibling() )
4006 {
4007 child->setRelOrigin( QPoint( w, 0 ) );
4008 w += child->parentRect().width() + 1;
4009 }
4010 }
4011
paint(QPainter * p)4012 void QwtMmlNode::paint( QPainter *p )
4013 {
4014 if ( !myRect().isValid() )
4015 return;
4016 p->save();
4017
4018 QColor fg = color();
4019 QColor bg = background();
4020 if ( bg.isValid() )
4021 p->fillRect( myRect(), bg );
4022 if ( fg.isValid() )
4023 p->setPen( QPen( color(), 0 ) );
4024
4025 QwtMmlNode *child = firstChild();
4026 for ( ; child != 0; child = child->nextSibling() )
4027 child->paint( p );
4028
4029 paintSymbol( p );
4030
4031 p->restore();
4032 }
4033
paintSymbol(QPainter * p) const4034 void QwtMmlNode::paintSymbol( QPainter *p ) const
4035 {
4036 if ( g_draw_frames && myRect().isValid() )
4037 {
4038 p->save();
4039 p->setPen( QPen( Qt::red, 0 ) );
4040 p->drawRect( m_my_rect );
4041 QPen pen = p->pen();
4042 pen.setStyle( Qt::DotLine );
4043 p->setPen( pen );
4044 p->drawLine( myRect().left(), 0, myRect().right(), 0 );
4045 p->restore();
4046 }
4047 }
4048
stretch()4049 void QwtMmlNode::stretch()
4050 {
4051 QwtMmlNode *child = firstChild();
4052 for ( ; child != 0; child = child->nextSibling() )
4053 child->stretch();
4054 }
4055
text() const4056 QString QwtMmlTokenNode::text() const
4057 {
4058 QString result;
4059
4060 const QwtMmlNode *child = firstChild();
4061 for ( ; child != 0; child = child->nextSibling() )
4062 {
4063 if ( child->nodeType() != TextNode ) continue;
4064 if ( !result.isEmpty() )
4065 result += ' ';
4066 result += static_cast<const QwtMmlTextNode *>( child )->text();
4067 }
4068
4069 return result;
4070 }
4071
numerator() const4072 QwtMmlNode *QwtMmlMfracNode::numerator() const
4073 {
4074 QwtMmlNode *node = firstChild();
4075 Q_ASSERT( node != 0 );
4076 return node;
4077 }
4078
denominator() const4079 QwtMmlNode *QwtMmlMfracNode::denominator() const
4080 {
4081 QwtMmlNode *node = numerator()->nextSibling();
4082 Q_ASSERT( node != 0 );
4083 return node;
4084 }
4085
symbolRect() const4086 QRect QwtMmlMfracNode::symbolRect() const
4087 {
4088 int num_width = numerator()->myRect().width();
4089 int denom_width = denominator()->myRect().width();
4090 int my_width = qMax( num_width, denom_width ) + 4;
4091
4092 return QRect( -my_width / 2, 0, my_width, 1 );
4093 }
4094
layoutSymbol()4095 void QwtMmlMfracNode::layoutSymbol()
4096 {
4097 QwtMmlNode *num = numerator();
4098 QwtMmlNode *denom = denominator();
4099
4100 QRect num_rect = num->myRect();
4101 QRect denom_rect = denom->myRect();
4102
4103 int spacing = ( int )( g_mfrac_spacing * ( num_rect.height() + denom_rect.height() ) );
4104
4105 num->setRelOrigin( QPoint( -num_rect.width() / 2, - spacing - num_rect.bottom() ) );
4106 denom->setRelOrigin( QPoint( -denom_rect.width() / 2, spacing - denom_rect.top() ) );
4107 }
4108
zeroLineThickness(const QString & s)4109 static bool zeroLineThickness( const QString &s )
4110 {
4111 if ( s.length() == 0 || !s[0].isDigit() )
4112 return false;
4113
4114 for ( int i = 0; i < s.length(); ++i )
4115 {
4116 QChar c = s.at( i );
4117 if ( c.isDigit() && c != '0' )
4118 return false;
4119 }
4120 return true;
4121 }
4122
paintSymbol(QPainter * p) const4123 void QwtMmlMfracNode::paintSymbol( QPainter *p ) const
4124 {
4125 QString linethickness_str = inheritAttributeFromMrow( "linethickness", "1" );
4126
4127 /* InterpretSpacing returns an int, which might be 0 even if the thickness
4128 is > 0, though very very small. That's ok, because the painter then paints
4129 a line of thickness 1. However, we have to run this check if the line
4130 thickness really is zero */
4131 if ( !zeroLineThickness( linethickness_str ) )
4132 {
4133 bool ok;
4134 int linethickness = interpretSpacing( linethickness_str, &ok );
4135 if ( !ok )
4136 linethickness = 1;
4137
4138 p->save();
4139 QPen pen = p->pen();
4140 pen.setWidth( linethickness );
4141 p->setPen( pen );
4142 QSize s = myRect().size();
4143 p->drawLine( -s.width() / 2, 0, s.width() / 2, 0 );
4144 p->restore();
4145 }
4146 }
4147
base() const4148 QwtMmlNode *QwtMmlRootBaseNode::base() const
4149 {
4150 QwtMmlNode *node = firstChild();
4151 // Q_ASSERT(node != 0);
4152 return node;
4153 }
4154
index() const4155 QwtMmlNode *QwtMmlRootBaseNode::index() const
4156 {
4157 QwtMmlNode *b = base();
4158 if ( b == 0 )
4159 return 0;
4160 return b->nextSibling();
4161 }
4162
scriptlevel(const QwtMmlNode * child) const4163 int QwtMmlRootBaseNode::scriptlevel( const QwtMmlNode *child ) const
4164 {
4165 int sl = QwtMmlNode::scriptlevel();
4166
4167 QwtMmlNode *i = index();
4168 if ( child != 0 && child == i )
4169 return sl + 1;
4170 else
4171 return sl;
4172 }
4173
4174
symbolRect() const4175 QRect QwtMmlRootBaseNode::symbolRect() const
4176 {
4177 QwtMmlNode *b = base();
4178 QRect base_rect;
4179 if ( b == 0 )
4180 base_rect = QRect( 0, 0, 1, 1 );
4181 else
4182 base_rect = base()->myRect();
4183
4184 int margin = ( int )( g_mroot_base_margin * base_rect.height() );
4185 int tw = tailWidth();
4186
4187 return QRect( -tw, base_rect.top() - margin, tw,
4188 base_rect.height() + 2 * margin );
4189 }
4190
tailWidth() const4191 int QwtMmlRootBaseNode::tailWidth() const
4192 {
4193 QFontMetrics fm( font() );
4194 return fm.boundingRect( g_radical_char ).width();
4195 }
4196
layoutSymbol()4197 void QwtMmlRootBaseNode::layoutSymbol()
4198 {
4199 QwtMmlNode *b = base();
4200 QSize base_size;
4201 if ( b != 0 )
4202 {
4203 b->setRelOrigin( QPoint( 0, 0 ) );
4204 base_size = base()->myRect().size();
4205 }
4206 else
4207 base_size = QSize( 1, 1 );
4208
4209 QwtMmlNode *i = index();
4210 if ( i != 0 )
4211 {
4212 int tw = tailWidth();
4213
4214 QRect i_rect = i->myRect();
4215 i->setRelOrigin( QPoint( -tw / 2 - i_rect.width(),
4216 -i_rect.bottom() - 4 ) );
4217 }
4218 }
4219
paintSymbol(QPainter * p) const4220 void QwtMmlRootBaseNode::paintSymbol( QPainter *p ) const
4221 {
4222 QFont fn = font();
4223
4224 p->save();
4225
4226 QRect sr = symbolRect();
4227
4228 QRect r = sr;
4229 r.moveTopLeft( devicePoint( sr.topLeft() ) );
4230 p->setViewport( r );
4231 p->setWindow( QFontMetrics( fn ).boundingRect( g_radical_char ) );
4232 p->setFont( font() );
4233 p->drawText( 0, 0, QString( g_radical_char ) );
4234
4235 p->restore();
4236
4237 p->drawLine( sr.right(), sr.top(), myRect().right(), sr.top() );
4238 }
4239
QwtMmlTextNode(const QString & text,QwtMmlDocument * document)4240 QwtMmlTextNode::QwtMmlTextNode( const QString &text, QwtMmlDocument *document )
4241 : QwtMmlNode( TextNode, document, QwtMmlAttributeMap() )
4242 {
4243 m_text = text;
4244 // Trim whitespace from ends, but keep nbsp and thinsp
4245 m_text.remove( QRegExp( "^[^\\S\\x00a0\\x2009]+" ) );
4246 m_text.remove( QRegExp( "[^\\S\\x00a0\\x2009]+$" ) );
4247
4248 if ( m_text == QString( QChar( 0x62, 0x20 ) ) // ⁢
4249 || m_text == QString( QChar( 0x63, 0x20 ) ) // ⁣
4250 || m_text == QString( QChar( 0x61, 0x20 ) ) ) // ⁡
4251 m_text = "";
4252 }
4253
toStr() const4254 QString QwtMmlTextNode::toStr() const
4255 {
4256 return QwtMmlNode::toStr() + ", text=\"" + m_text + "\"";
4257 }
4258
paintSymbol(QPainter * p) const4259 void QwtMmlTextNode::paintSymbol( QPainter *p ) const
4260 {
4261 QwtMmlNode::paintSymbol( p );
4262
4263 QFont fn = font();
4264
4265 QFontInfo fi( fn );
4266 // qWarning("MmlTextNode::paintSymbol(): requested: %s, used: %s, size=%d, italic=%d, bold=%d, text=\"%s\" sl=%d",
4267 // fn.family().latin1(), fi.family().latin1(), fi.pointSize(), (int)fi.italic(), (int)fi.bold(), m_text.latin1(), scriptlevel());
4268
4269 QFontMetrics fm( fn );
4270
4271 p->save();
4272 p->setFont( fn );
4273
4274 QPoint dPos = devicePoint( relOrigin() );
4275 p->drawText( dPos.x(), dPos.y() + fm.strikeOutPos(), m_text );
4276
4277 p->restore();
4278 }
4279
symbolRect() const4280 QRect QwtMmlTextNode::symbolRect() const
4281 {
4282 QFontMetrics fm( font() );
4283
4284 QRect br = fm.tightBoundingRect( m_text );
4285 br.translate( 0, fm.strikeOutPos() );
4286
4287 return br;
4288 }
4289
base() const4290 QwtMmlNode *QwtMmlSubsupBaseNode::base() const
4291 {
4292 QwtMmlNode *b = firstChild();
4293 Q_ASSERT( b != 0 );
4294 return b;
4295 }
4296
sscript() const4297 QwtMmlNode *QwtMmlSubsupBaseNode::sscript() const
4298 {
4299 QwtMmlNode *s = base()->nextSibling();
4300 Q_ASSERT( s != 0 );
4301 return s;
4302 }
4303
scriptlevel(const QwtMmlNode * child) const4304 int QwtMmlSubsupBaseNode::scriptlevel( const QwtMmlNode *child ) const
4305 {
4306 int sl = QwtMmlNode::scriptlevel();
4307
4308 QwtMmlNode *s = sscript();
4309 if ( child != 0 && child == s )
4310 return sl + 1;
4311 else
4312 return sl;
4313 }
4314
layoutSymbol()4315 void QwtMmlMsupNode::layoutSymbol()
4316 {
4317 QwtMmlNode *b = base();
4318 QwtMmlNode *s = sscript();
4319
4320 b->setRelOrigin( QPoint( -b->myRect().width(), 0 ) );
4321 s->setRelOrigin( QPoint( 0, b->myRect().top() ) );
4322 }
4323
layoutSymbol()4324 void QwtMmlMsubNode::layoutSymbol()
4325 {
4326 QwtMmlNode *b = base();
4327 QwtMmlNode *s = sscript();
4328
4329 b->setRelOrigin( QPoint( -b->myRect().width(), 0 ) );
4330 s->setRelOrigin( QPoint( 0, b->myRect().bottom() ) );
4331 }
4332
base() const4333 QwtMmlNode *QwtMmlMsubsupNode::base() const
4334 {
4335 QwtMmlNode *b = firstChild();
4336 Q_ASSERT( b != 0 );
4337 return b;
4338 }
4339
subscript() const4340 QwtMmlNode *QwtMmlMsubsupNode::subscript() const
4341 {
4342 QwtMmlNode *sub = base()->nextSibling();
4343 Q_ASSERT( sub != 0 );
4344 return sub;
4345 }
4346
superscript() const4347 QwtMmlNode *QwtMmlMsubsupNode::superscript() const
4348 {
4349 QwtMmlNode *sup = subscript()->nextSibling();
4350 Q_ASSERT( sup != 0 );
4351 return sup;
4352 }
4353
layoutSymbol()4354 void QwtMmlMsubsupNode::layoutSymbol()
4355 {
4356 QwtMmlNode *b = base();
4357 QwtMmlNode *sub = subscript();
4358 QwtMmlNode *sup = superscript();
4359
4360 b->setRelOrigin( QPoint( -b->myRect().width(), 0 ) );
4361 sub->setRelOrigin( QPoint( 0, b->myRect().bottom() ) );
4362 sup->setRelOrigin( QPoint( 0, b->myRect().top() ) );
4363 }
4364
scriptlevel(const QwtMmlNode * child) const4365 int QwtMmlMsubsupNode::scriptlevel( const QwtMmlNode *child ) const
4366 {
4367 int sl = QwtMmlNode::scriptlevel();
4368
4369 QwtMmlNode *sub = subscript();
4370 QwtMmlNode *sup = superscript();
4371
4372 if ( child != 0 && ( child == sup || child == sub ) )
4373 return sl + 1;
4374 else
4375 return sl;
4376 }
4377
toStr() const4378 QString QwtMmlMoNode::toStr() const
4379 {
4380 return QwtMmlNode::toStr() + QString( " form=%1" ).arg( ( int )form() );
4381 }
4382
layoutSymbol()4383 void QwtMmlMoNode::layoutSymbol()
4384 {
4385 QwtMmlNode *child = firstChild();
4386 if ( child == 0 )
4387 return;
4388
4389 child->setRelOrigin( QPoint( 0, 0 ) );
4390
4391 if ( m_oper_spec == 0 )
4392 m_oper_spec = mmlFindOperSpec( text(), form() );
4393 }
4394
QwtMmlMoNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)4395 QwtMmlMoNode::QwtMmlMoNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
4396 : QwtMmlTokenNode( MoNode, document, attribute_map )
4397 {
4398 m_oper_spec = 0;
4399 }
4400
dictionaryAttribute(const QString & name) const4401 QString QwtMmlMoNode::dictionaryAttribute( const QString &name ) const
4402 {
4403 const QwtMmlNode *p = this;
4404 for ( ; p != 0; p = p->parent() )
4405 {
4406 if ( p == this || p->nodeType() == MstyleNode )
4407 {
4408 QString expl_attr = p->explicitAttribute( name );
4409 if ( !expl_attr.isNull() )
4410 return expl_attr;
4411 }
4412 }
4413
4414 return mmlDictAttribute( name, m_oper_spec );
4415 }
4416
form() const4417 QwtMml::FormType QwtMmlMoNode::form() const
4418 {
4419 QString value_str = inheritAttributeFromMrow( "form" );
4420 if ( !value_str.isNull() )
4421 {
4422 bool ok;
4423 FormType value = interpretForm( value_str, &ok );
4424 if ( ok )
4425 return value;
4426 else
4427 qWarning( "Could not convert %s to form", value_str.toLatin1().data() );
4428
4429 }
4430
4431 // Default heuristic.
4432 if ( firstSibling() == ( QwtMmlNode* )this && lastSibling() != ( QwtMmlNode* )this )
4433 return PrefixForm;
4434 else if ( lastSibling() == ( QwtMmlNode* )this && firstSibling() != ( QwtMmlNode* )this )
4435 return PostfixForm;
4436 else return InfixForm;
4437
4438 }
4439
stretch()4440 void QwtMmlMoNode::stretch()
4441 {
4442 if ( parent() == 0 )
4443 return;
4444
4445 if ( m_oper_spec == 0 )
4446 return;
4447
4448 if ( m_oper_spec->stretch_dir == QwtMmlOperSpec::HStretch
4449 && parent()->nodeType() == MrowNode
4450 && ( nextSibling() != 0 || previousSibling() != 0 ) )
4451 return;
4452
4453 QRect pmr = parent()->myRect();
4454 QRect pr = parentRect();
4455
4456 switch ( m_oper_spec->stretch_dir )
4457 {
4458 case QwtMmlOperSpec::VStretch:
4459 stretchTo( QRect( pr.left(), pmr.top(), pr.width(), pmr.height() ) );
4460 break;
4461 case QwtMmlOperSpec::HStretch:
4462 stretchTo( QRect( pmr.left(), pr.top(), pmr.width(), pr.height() ) );
4463 break;
4464 case QwtMmlOperSpec::HVStretch:
4465 stretchTo( pmr );
4466 break;
4467 case QwtMmlOperSpec::NoStretch:
4468 break;
4469 }
4470 }
4471
lspace() const4472 int QwtMmlMoNode::lspace() const
4473 {
4474 Q_ASSERT( m_oper_spec != 0 );
4475 if ( parent() == 0
4476 || ( parent()->nodeType() != MrowNode
4477 && parent()->nodeType() != MfencedNode
4478 && parent()->nodeType() != UnknownNode )
4479 || ( previousSibling() == 0 && nextSibling() == 0 ) )
4480 return 0;
4481 else
4482 return interpretSpacing( dictionaryAttribute( "lspace" ), 0 );
4483 }
4484
rspace() const4485 int QwtMmlMoNode::rspace() const
4486 {
4487 Q_ASSERT( m_oper_spec != 0 );
4488 if ( parent() == 0
4489 || ( parent()->nodeType() != MrowNode
4490 && parent()->nodeType() != MfencedNode
4491 && parent()->nodeType() != UnknownNode )
4492 || ( previousSibling() == 0 && nextSibling() == 0 ) )
4493 return 0;
4494 else
4495 return interpretSpacing( dictionaryAttribute( "rspace" ), 0 );
4496 }
4497
symbolRect() const4498 QRect QwtMmlMoNode::symbolRect() const
4499 {
4500 const QwtMmlNode *child = firstChild();
4501
4502 if ( child == 0 )
4503 return QRect( 0, 0, 0, 0 );
4504
4505 QRect cmr = child->myRect();
4506
4507 return QRect( -lspace(), cmr.top(),
4508 cmr.width() + lspace() + rspace(), cmr.height() );
4509 }
4510
rowspacing() const4511 int QwtMmlMtableNode::rowspacing() const
4512 {
4513 QString value = explicitAttribute( "rowspacing" );
4514 if ( value.isNull() )
4515 return ex();
4516 bool ok;
4517 int r = interpretSpacing( value, &ok );
4518
4519 if ( ok )
4520 return r;
4521 else
4522 return ex();
4523 }
4524
columnspacing() const4525 int QwtMmlMtableNode::columnspacing() const
4526 {
4527 QString value = explicitAttribute( "columnspacing" );
4528 if ( value.isNull() )
4529 return ( int )( 0.8 * em() );
4530 bool ok;
4531 int r = interpretSpacing( value, &ok );
4532
4533 if ( ok )
4534 return r;
4535 else
4536 return ( int )( 0.8 * em() );
4537 }
4538
colWidthSum() const4539 uint QwtMmlMtableNode::CellSizeData::colWidthSum() const
4540 {
4541 uint w = 0;
4542 for ( int i = 0; i < col_widths.count(); ++i )
4543 w += col_widths[i];
4544 return w;
4545 }
4546
rowHeightSum() const4547 uint QwtMmlMtableNode::CellSizeData::rowHeightSum() const
4548 {
4549 uint h = 0;
4550 for ( int i = 0; i < row_heights.count(); ++i )
4551 h += row_heights[i];
4552 return h;
4553 }
4554
init(const QwtMmlNode * first_row)4555 void QwtMmlMtableNode::CellSizeData::init( const QwtMmlNode *first_row )
4556 {
4557 col_widths.clear();
4558 row_heights.clear();
4559
4560 const QwtMmlNode *mtr = first_row;
4561 for ( ; mtr != 0; mtr = mtr->nextSibling() )
4562 {
4563
4564 Q_ASSERT( mtr->nodeType() == MtrNode );
4565
4566 int col_cnt = 0;
4567 const QwtMmlNode *mtd = mtr->firstChild();
4568 for ( ; mtd != 0; mtd = mtd->nextSibling(), ++col_cnt )
4569 {
4570
4571 Q_ASSERT( mtd->nodeType() == MtdNode );
4572
4573 QRect mtdmr = mtd->myRect();
4574
4575 if ( col_cnt == col_widths.count() )
4576 col_widths.append( mtdmr.width() );
4577 else
4578 col_widths[col_cnt] = qMax( col_widths[col_cnt], mtdmr.width() );
4579 }
4580
4581 row_heights.append( mtr->myRect().height() );
4582 }
4583 }
4584
layoutSymbol()4585 void QwtMmlMtableNode::layoutSymbol()
4586 {
4587 // Obtain natural widths of columns
4588 m_cell_size_data.init( firstChild() );
4589
4590 int col_spc = columnspacing();
4591 int row_spc = rowspacing();
4592 int frame_spc_hor = framespacing_hor();
4593 QString columnwidth_attr = explicitAttribute( "columnwidth", "auto" );
4594
4595 // Is table width set by user? If so, set col_width_sum and never ever change it.
4596 int col_width_sum = m_cell_size_data.colWidthSum();
4597 bool width_set_by_user = false;
4598 QString width_str = explicitAttribute( "width", "auto" );
4599 if ( width_str != "auto" )
4600 {
4601 bool ok;
4602
4603 int w = interpretSpacing( width_str, &ok );
4604 if ( ok )
4605 {
4606 col_width_sum = w
4607 - col_spc * ( m_cell_size_data.numCols() - 1 )
4608 - frame_spc_hor * 2;
4609 width_set_by_user = true;
4610 }
4611 }
4612
4613 // Find out what kind of columns we are dealing with and set the widths of
4614 // statically sized columns.
4615 int fixed_width_sum = 0; // sum of widths of statically sized set columns
4616 int auto_width_sum = 0; // sum of natural widths of auto sized columns
4617 int relative_width_sum = 0; // sum of natural widths of relatively sized columns
4618 double relative_fraction_sum = 0; // total fraction of width taken by relatively
4619 // sized columns
4620 int i;
4621 for ( i = 0; i < m_cell_size_data.numCols(); ++i )
4622 {
4623 QString value = interpretListAttr( columnwidth_attr, i, "auto" );
4624
4625 // Is it an auto sized column?
4626 if ( value == "auto" || value == "fit" )
4627 {
4628 auto_width_sum += m_cell_size_data.col_widths[i];
4629 continue;
4630 }
4631
4632 // Is it a statically sized column?
4633 bool ok;
4634 int w = interpretSpacing( value, &ok );
4635 if ( ok )
4636 {
4637 // Yup, sets its width to the user specified value
4638 m_cell_size_data.col_widths[i] = w;
4639 fixed_width_sum += w;
4640 continue;
4641 }
4642
4643 // Is it a relatively sized column?
4644 if ( value.endsWith( "%" ) )
4645 {
4646 value.truncate( value.length() - 1 );
4647 double factor = value.toFloat( &ok );
4648 if ( ok && !value.isEmpty() )
4649 {
4650 factor /= 100.0;
4651 relative_width_sum += m_cell_size_data.col_widths[i];
4652 relative_fraction_sum += factor;
4653 if ( !width_set_by_user )
4654 {
4655 // If the table width was not set by the user, we are free to increase
4656 // it so that the width of this column will be >= than its natural width
4657 int min_col_width_sum = ROUND( m_cell_size_data.col_widths[i] / factor );
4658 if ( min_col_width_sum > col_width_sum )
4659 col_width_sum = min_col_width_sum;
4660 }
4661 continue;
4662 }
4663 else
4664 qWarning( "MmlMtableNode::layoutSymbol(): could not parse value %s%%", value.toLatin1().data() );
4665 }
4666
4667 // Relatively sized column, but we failed to parse the factor. Treat is like an auto
4668 // column.
4669 auto_width_sum += m_cell_size_data.col_widths[i];
4670 }
4671
4672 // Work out how much space remains for the auto olumns, after allocating
4673 // the statically sized and the relatively sized columns.
4674 int required_auto_width_sum = col_width_sum
4675 - ROUND( relative_fraction_sum * col_width_sum )
4676 - fixed_width_sum;
4677
4678 if ( !width_set_by_user && required_auto_width_sum < auto_width_sum )
4679 {
4680 if ( relative_fraction_sum < 1 )
4681 col_width_sum = ROUND( ( fixed_width_sum + auto_width_sum ) / ( 1 - relative_fraction_sum ) );
4682 else
4683 col_width_sum = fixed_width_sum + auto_width_sum + relative_width_sum;
4684 required_auto_width_sum = auto_width_sum;
4685 }
4686
4687 // Ratio by which we have to shring/grow all auto sized columns to make it all fit
4688 double auto_width_scale = 1;
4689 if ( auto_width_sum > 0 )
4690 auto_width_scale = ( float )required_auto_width_sum / auto_width_sum;
4691
4692 // Set correct sizes for the auto sized and the relatively sized columns.
4693 for ( i = 0; i < m_cell_size_data.numCols(); ++i )
4694 {
4695 QString value = interpretListAttr( columnwidth_attr, i, "auto" );
4696
4697 // Is it a relatively sized column?
4698 if ( value.endsWith( "%" ) )
4699 {
4700 bool ok;
4701 int w = interpretPercentSpacing( value, col_width_sum, &ok );
4702 if ( ok )
4703 m_cell_size_data.col_widths[i] = w;
4704 else
4705 // We're treating parsing errors here as auto sized columns
4706 m_cell_size_data.col_widths[i]
4707 = ROUND( auto_width_scale * m_cell_size_data.col_widths[i] );
4708 }
4709 // Is it an auto sized column?
4710 else if ( value == "auto" )
4711 {
4712 m_cell_size_data.col_widths[i]
4713 = ROUND( auto_width_scale * m_cell_size_data.col_widths[i] );
4714 }
4715 }
4716
4717 QString s;
4718 QList<int> &col_widths = m_cell_size_data.col_widths;
4719 for ( i = 0; i < col_widths.count(); ++i )
4720 {
4721 s += QString( "[w=%1 %2%%]" )
4722 .arg( col_widths[i] )
4723 .arg( 100 * col_widths[i] / m_cell_size_data.colWidthSum() );
4724 }
4725 // qWarning(s);
4726
4727 m_content_width = m_cell_size_data.colWidthSum()
4728 + col_spc * ( m_cell_size_data.numCols() - 1 );
4729 m_content_height = m_cell_size_data.rowHeightSum()
4730 + row_spc * ( m_cell_size_data.numRows() - 1 );
4731
4732 int bottom = -m_content_height / 2;
4733 QwtMmlNode *child = firstChild();
4734 for ( ; child != 0; child = child->nextSibling() )
4735 {
4736 Q_ASSERT( child->nodeType() == MtrNode );
4737 QwtMmlMtrNode *row = ( QwtMmlMtrNode* ) child;
4738
4739 row->layoutCells( m_cell_size_data.col_widths, col_spc );
4740 QRect rmr = row->myRect();
4741 row->setRelOrigin( QPoint( 0, bottom - rmr.top() ) );
4742 bottom += rmr.height() + row_spc;
4743 }
4744 }
4745
symbolRect() const4746 QRect QwtMmlMtableNode::symbolRect() const
4747 {
4748 int frame_spc_hor = framespacing_hor();
4749 int frame_spc_ver = framespacing_ver();
4750
4751 return QRect( -frame_spc_hor,
4752 -m_content_height / 2 - frame_spc_ver,
4753 m_content_width + 2 * frame_spc_hor,
4754 m_content_height + 2 * frame_spc_ver );
4755 }
4756
frame() const4757 QwtMml::FrameType QwtMmlMtableNode::frame() const
4758 {
4759 QString value = explicitAttribute( "frame", "none" );
4760 return interpretFrameType( value, 0, 0 );
4761 }
4762
columnlines(int idx) const4763 QwtMml::FrameType QwtMmlMtableNode::columnlines( int idx ) const
4764 {
4765 QString value = explicitAttribute( "columnlines", "none" );
4766 return interpretFrameType( value, idx, 0 );
4767 }
4768
rowlines(int idx) const4769 QwtMml::FrameType QwtMmlMtableNode::rowlines( int idx ) const
4770 {
4771 QString value = explicitAttribute( "rowlines", "none" );
4772 return interpretFrameType( value, idx, 0 );
4773 }
4774
paintSymbol(QPainter * p) const4775 void QwtMmlMtableNode::paintSymbol( QPainter *p ) const
4776 {
4777 FrameType f = frame();
4778 if ( f != FrameNone )
4779 {
4780 p->save();
4781
4782 QPen pen = p->pen();
4783 if ( f == FrameDashed )
4784 pen.setStyle( Qt::DashLine );
4785 else
4786 pen.setStyle( Qt::SolidLine );
4787 p->setPen( pen );
4788 p->drawRect( myRect() );
4789
4790 p->restore();
4791 }
4792
4793 p->save();
4794
4795 int col_spc = columnspacing();
4796 int row_spc = rowspacing();
4797
4798 QPen pen = p->pen();
4799 int col_offset = 0;
4800 int i;
4801 for ( i = 0; i < m_cell_size_data.numCols() - 1; ++i )
4802 {
4803 FrameType f = columnlines( i );
4804 col_offset += m_cell_size_data.col_widths[i];
4805
4806 if ( f != FrameNone )
4807 {
4808 if ( f == FrameDashed )
4809 pen.setStyle( Qt::DashLine );
4810 else if ( f == FrameSolid )
4811 pen.setStyle( Qt::SolidLine );
4812
4813 p->setPen( pen );
4814 int x = col_offset + col_spc / 2;
4815 p->drawLine( x, -m_content_height / 2, x, m_content_height / 2 );
4816 }
4817 col_offset += col_spc;
4818 }
4819
4820 int row_offset = 0;
4821 for ( i = 0; i < m_cell_size_data.numRows() - 1; ++i )
4822 {
4823 FrameType f = rowlines( i );
4824 row_offset += m_cell_size_data.row_heights[i];
4825
4826 if ( f != FrameNone )
4827 {
4828 if ( f == FrameDashed )
4829 pen.setStyle( Qt::DashLine );
4830 else if ( f == FrameSolid )
4831 pen.setStyle( Qt::SolidLine );
4832
4833 p->setPen( pen );
4834 int y = row_offset + row_spc / 2 - m_content_height / 2;
4835 p->drawLine( 0, y, m_content_width, y );
4836 }
4837 row_offset += row_spc;
4838 }
4839
4840 p->restore();
4841 }
4842
framespacing_ver() const4843 int QwtMmlMtableNode::framespacing_ver() const
4844 {
4845 if ( frame() == FrameNone )
4846 return ( int )( 0.2 * em() );
4847
4848 QString value = explicitAttribute( "framespacing", "0.4em 0.5ex" );
4849
4850 bool ok;
4851 FrameSpacing fs = interpretFrameSpacing( value, em(), ex(), &ok );
4852 if ( ok )
4853 return fs.m_ver;
4854 else
4855 return ( int )( 0.5 * ex() );
4856 }
4857
framespacing_hor() const4858 int QwtMmlMtableNode::framespacing_hor() const
4859 {
4860 if ( frame() == FrameNone )
4861 return ( int )( 0.2 * em() );
4862
4863 QString value = explicitAttribute( "framespacing", "0.4em 0.5ex" );
4864
4865 bool ok;
4866 FrameSpacing fs = interpretFrameSpacing( value, em(), ex(), &ok );
4867 if ( ok )
4868 return fs.m_hor;
4869 else
4870 return ( int )( 0.4 * em() );
4871 }
4872
layoutCells(const QList<int> & col_widths,int col_spc)4873 void QwtMmlMtrNode::layoutCells( const QList<int> &col_widths,
4874 int col_spc )
4875 {
4876 QRect mr = myRect();
4877
4878 QwtMmlNode *child = firstChild();
4879 int col_offset = 0;
4880 uint colnum = 0;
4881 for ( ; child != 0; child = child->nextSibling(), ++colnum )
4882 {
4883 Q_ASSERT( child->nodeType() == MtdNode );
4884 QwtMmlMtdNode *mtd = ( QwtMmlMtdNode* ) child;
4885
4886 QRect r = QRect( 0, mr.top(), col_widths[colnum], mr.height() );
4887 mtd->setMyRect( r );
4888 mtd->setRelOrigin( QPoint( col_offset, 0 ) );
4889 col_offset += col_widths[colnum] + col_spc;
4890 }
4891
4892 updateMyRect();
4893 }
4894
scriptlevel(const QwtMmlNode * child) const4895 int QwtMmlMtdNode::scriptlevel( const QwtMmlNode *child ) const
4896 {
4897 int sl = QwtMmlNode::scriptlevel();
4898 if ( child != 0 && child == firstChild() )
4899 return sl + m_scriptlevel_adjust;
4900 else
4901 return sl;
4902 }
4903
setMyRect(const QRect & rect)4904 void QwtMmlMtdNode::setMyRect( const QRect &rect )
4905 {
4906 QwtMmlNode::setMyRect( rect );
4907 QwtMmlNode *child = firstChild();
4908 if ( child == 0 )
4909 return;
4910
4911 if ( rect.width() < child->myRect().width() )
4912 {
4913 while ( rect.width() < child->myRect().width()
4914 && child->font().pointSize() > g_min_font_point_size )
4915 {
4916
4917 // qWarning("MmlMtdNode::setMyRect(): rect.width()=%d, child()->myRect().width=%d sl=%d",
4918 // rect.width(), child->myRect().width(), m_scriptlevel_adjust);
4919
4920 ++m_scriptlevel_adjust;
4921 child->layout();
4922 }
4923
4924 // qWarning("MmlMtdNode::setMyRect(): rect.width()=%d, child()->myRect().width=%d sl=%d",
4925 // rect.width(), child->myRect().width(), m_scriptlevel_adjust);
4926 }
4927
4928 QRect mr = myRect();
4929 QRect cmr = child->myRect();
4930
4931 QPoint child_rel_origin;
4932
4933 switch ( columnalign() )
4934 {
4935 case ColAlignLeft:
4936 child_rel_origin.setX( 0 );
4937 break;
4938 case ColAlignCenter:
4939 child_rel_origin.setX( mr.left() + ( mr.width() - cmr.width() ) / 2 );
4940 break;
4941 case ColAlignRight:
4942 child_rel_origin.setX( mr.right() - cmr.width() );
4943 break;
4944 }
4945
4946 switch ( rowalign() )
4947 {
4948 case RowAlignTop:
4949 child_rel_origin.setY( mr.top() - cmr.top() );
4950 break;
4951 case RowAlignCenter:
4952 case RowAlignBaseline:
4953 child_rel_origin.setY( mr.top() - cmr.top() + ( mr.height() - cmr.height() ) / 2 );
4954 break;
4955 case RowAlignBottom:
4956 child_rel_origin.setY( mr.bottom() - cmr.bottom() );
4957 break;
4958 case RowAlignAxis:
4959 child_rel_origin.setY( 0 );
4960 break;
4961 }
4962
4963 child->setRelOrigin( child_rel_origin );
4964 }
4965
colNum()4966 uint QwtMmlMtdNode::colNum()
4967 {
4968 QwtMmlNode *syb = previousSibling();
4969
4970 uint i = 0;
4971 for ( ; syb != 0; syb = syb->previousSibling() )
4972 ++i;
4973
4974 return i;
4975 }
4976
rowNum()4977 uint QwtMmlMtdNode::rowNum()
4978 {
4979 QwtMmlNode *row = parent()->previousSibling();
4980
4981 uint i = 0;
4982 for ( ; row != 0; row = row->previousSibling() )
4983 ++i;
4984
4985 return i;
4986 }
4987
columnalign()4988 QwtMmlMtdNode::ColAlign QwtMmlMtdNode::columnalign()
4989 {
4990 QString val = explicitAttribute( "columnalign" );
4991 if ( !val.isNull() )
4992 return interpretColAlign( val, 0, 0 );
4993
4994 QwtMmlNode *node = parent(); // <mtr>
4995 if ( node == 0 )
4996 return ColAlignCenter;
4997
4998 uint colnum = colNum();
4999 val = node->explicitAttribute( "columnalign" );
5000 if ( !val.isNull() )
5001 return interpretColAlign( val, colnum, 0 );
5002
5003 node = node->parent(); // <mtable>
5004 if ( node == 0 )
5005 return ColAlignCenter;
5006
5007 val = node->explicitAttribute( "columnalign" );
5008 if ( !val.isNull() )
5009 return interpretColAlign( val, colnum, 0 );
5010
5011 return ColAlignCenter;
5012 }
5013
rowalign()5014 QwtMmlMtdNode::RowAlign QwtMmlMtdNode::rowalign()
5015 {
5016 QString val = explicitAttribute( "rowalign" );
5017 if ( !val.isNull() )
5018 return interpretRowAlign( val, 0, 0 );
5019
5020 QwtMmlNode *node = parent(); // <mtr>
5021 if ( node == 0 )
5022 return RowAlignAxis;
5023
5024 uint rownum = rowNum();
5025 val = node->explicitAttribute( "rowalign" );
5026 if ( !val.isNull() )
5027 return interpretRowAlign( val, rownum, 0 );
5028
5029 node = node->parent(); // <mtable>
5030 if ( node == 0 )
5031 return RowAlignAxis;
5032
5033 val = node->explicitAttribute( "rowalign" );
5034 if ( !val.isNull() )
5035 return interpretRowAlign( val, rownum, 0 );
5036
5037 return RowAlignAxis;
5038 }
5039
layoutSymbol()5040 void QwtMmlMoverNode::layoutSymbol()
5041 {
5042 QwtMmlNode *base = firstChild();
5043 Q_ASSERT( base != 0 );
5044 QwtMmlNode *over = base->nextSibling();
5045 Q_ASSERT( over != 0 );
5046
5047 QRect base_rect = base->myRect();
5048 QRect over_rect = over->myRect();
5049
5050 int spacing = ( int )( g_mfrac_spacing * ( over_rect.height()
5051 + base_rect.height() ) );
5052
5053 base->setRelOrigin( QPoint( -base_rect.width() / 2, 0 ) );
5054 over->setRelOrigin( QPoint( -over_rect.width() / 2,
5055 base_rect.top() - spacing - over_rect.bottom() ) );
5056 }
5057
scriptlevel(const QwtMmlNode * node) const5058 int QwtMmlMoverNode::scriptlevel( const QwtMmlNode *node ) const
5059 {
5060 QwtMmlNode *base = firstChild();
5061 Q_ASSERT( base != 0 );
5062 QwtMmlNode *over = base->nextSibling();
5063 Q_ASSERT( over != 0 );
5064
5065 int sl = QwtMmlNode::scriptlevel();
5066 if ( node != 0 && node == over )
5067 return sl + 1;
5068 else
5069 return sl;
5070 }
5071
layoutSymbol()5072 void QwtMmlMunderNode::layoutSymbol()
5073 {
5074 QwtMmlNode *base = firstChild();
5075 Q_ASSERT( base != 0 );
5076 QwtMmlNode *under = base->nextSibling();
5077 Q_ASSERT( under != 0 );
5078
5079 QRect base_rect = base->myRect();
5080 QRect under_rect = under->myRect();
5081
5082 int spacing = ( int )( g_mfrac_spacing * ( under_rect.height() + base_rect.height() ) );
5083
5084 base->setRelOrigin( QPoint( -base_rect.width() / 2, 0 ) );
5085 under->setRelOrigin( QPoint( -under_rect.width() / 2, base_rect.bottom() + spacing - under_rect.top() ) );
5086 }
5087
scriptlevel(const QwtMmlNode * node) const5088 int QwtMmlMunderNode::scriptlevel( const QwtMmlNode *node ) const
5089 {
5090 QwtMmlNode *base = firstChild();
5091 Q_ASSERT( base != 0 );
5092 QwtMmlNode *under = base->nextSibling();
5093 Q_ASSERT( under != 0 );
5094
5095 int sl = QwtMmlNode::scriptlevel();
5096 if ( node != 0 && node == under )
5097 return sl + 1;
5098 else
5099 return sl;
5100 }
5101
layoutSymbol()5102 void QwtMmlMunderoverNode::layoutSymbol()
5103 {
5104 QwtMmlNode *base = firstChild();
5105 Q_ASSERT( base != 0 );
5106 QwtMmlNode *under = base->nextSibling();
5107 Q_ASSERT( under != 0 );
5108 QwtMmlNode *over = under->nextSibling();
5109 Q_ASSERT( over != 0 );
5110
5111 QRect base_rect = base->myRect();
5112 QRect under_rect = under->myRect();
5113 QRect over_rect = over->myRect();
5114
5115 int spacing = ( int )( g_mfrac_spacing * ( base_rect.height()
5116 + under_rect.height()
5117 + over_rect.height() ) );
5118
5119 base->setRelOrigin( QPoint( -base_rect.width() / 2, 0 ) );
5120 under->setRelOrigin( QPoint( -under_rect.width() / 2, base_rect.bottom() + spacing - under_rect.top() ) );
5121 over->setRelOrigin( QPoint( -over_rect.width() / 2, base_rect.top() - spacing - under_rect.bottom() ) );
5122 }
5123
scriptlevel(const QwtMmlNode * node) const5124 int QwtMmlMunderoverNode::scriptlevel( const QwtMmlNode *node ) const
5125 {
5126 QwtMmlNode *base = firstChild();
5127 Q_ASSERT( base != 0 );
5128 QwtMmlNode *under = base->nextSibling();
5129 Q_ASSERT( under != 0 );
5130 QwtMmlNode *over = under->nextSibling();
5131 Q_ASSERT( over != 0 );
5132
5133 int sl = QwtMmlNode::scriptlevel();
5134 if ( node != 0 && ( node == under || node == over ) )
5135 return sl + 1;
5136 else
5137 return sl;
5138 }
5139
interpretSpacing(QString value,int base_value,bool * ok) const5140 int QwtMmlMpaddedNode::interpretSpacing( QString value, int base_value, bool *ok ) const
5141 {
5142 if ( ok != 0 )
5143 *ok = false;
5144
5145 value.replace( ' ', "" );
5146
5147 QString sign, factor_str, pseudo_unit;
5148 bool percent = false;
5149
5150 // extract the sign
5151 int idx = 0;
5152 if ( idx < value.length() && ( value.at( idx ) == '+' || value.at( idx ) == '-' ) )
5153 sign = value.at( idx++ );
5154
5155 // extract the factor
5156 while ( idx < value.length() && ( value.at( idx ).isDigit() || value.at( idx ) == '.' ) )
5157 factor_str.append( value.at( idx++ ) );
5158
5159 // extract the % sign
5160 if ( idx < value.length() && value.at( idx ) == '%' )
5161 {
5162 percent = true;
5163 ++idx;
5164 }
5165
5166 // extract the pseudo-unit
5167 pseudo_unit = value.mid( idx );
5168
5169 bool float_ok;
5170 double factor = factor_str.toFloat( &float_ok );
5171 if ( !float_ok || factor < 0 )
5172 {
5173 qWarning( "MmlMpaddedNode::interpretSpacing(): could not parse \"%s\"", value.toLatin1().data() );
5174 return 0;
5175 }
5176
5177 if ( percent )
5178 factor /= 100.0;
5179
5180 QRect cr;
5181 if ( firstChild() == 0 )
5182 cr = QRect( 0, 0, 0, 0 );
5183 else
5184 cr = firstChild()->myRect();
5185
5186 int unit_size;
5187
5188 if ( pseudo_unit.isEmpty() )
5189 unit_size = base_value;
5190 else if ( pseudo_unit == "width" )
5191 unit_size = cr.width();
5192 else if ( pseudo_unit == "height" )
5193 unit_size = -cr.top();
5194 else if ( pseudo_unit == "depth" )
5195 unit_size = cr.bottom();
5196 else
5197 {
5198 bool unit_ok;
5199 unit_size = QwtMmlNode::interpretSpacing( "1" + pseudo_unit, &unit_ok );
5200 if ( !unit_ok )
5201 {
5202 qWarning( "MmlMpaddedNode::interpretSpacing(): could not parse \"%s\"", value.toLatin1().data() );
5203 return 0;
5204 }
5205 }
5206
5207 if ( ok != 0 )
5208 *ok = true;
5209
5210 if ( sign.isNull() )
5211 return ( int )( factor * unit_size );
5212 else if ( sign == "+" )
5213 return base_value + ( int )( factor * unit_size );
5214 else // sign == "-"
5215 return base_value - ( int )( factor * unit_size );
5216 }
5217
lspace() const5218 int QwtMmlMpaddedNode::lspace() const
5219 {
5220 QString value = explicitAttribute( "lspace" );
5221
5222 if ( value.isNull() )
5223 return 0;
5224
5225 bool ok;
5226 int lspace = interpretSpacing( value, 0, &ok );
5227
5228 if ( ok )
5229 return lspace;
5230
5231 return 0;
5232 }
5233
width() const5234 int QwtMmlMpaddedNode::width() const
5235 {
5236 int child_width = 0;
5237 if ( firstChild() != 0 )
5238 child_width = firstChild()->myRect().width();
5239
5240 QString value = explicitAttribute( "width" );
5241 if ( value.isNull() )
5242 return child_width;
5243
5244 bool ok;
5245 int w = interpretSpacing( value, child_width, &ok );
5246 if ( ok )
5247 return w;
5248
5249 return child_width;
5250 }
5251
height() const5252 int QwtMmlMpaddedNode::height() const
5253 {
5254 QRect cr;
5255 if ( firstChild() == 0 )
5256 cr = QRect( 0, 0, 0, 0 );
5257 else
5258 cr = firstChild()->myRect();
5259
5260 QString value = explicitAttribute( "height" );
5261 if ( value.isNull() )
5262 return -cr.top();
5263
5264 bool ok;
5265 int h = interpretSpacing( value, -cr.top(), &ok );
5266 if ( ok )
5267 return h;
5268
5269 return -cr.top();
5270 }
5271
depth() const5272 int QwtMmlMpaddedNode::depth() const
5273 {
5274 QRect cr;
5275 if ( firstChild() == 0 )
5276 cr = QRect( 0, 0, 0, 0 );
5277 else
5278 cr = firstChild()->myRect();
5279
5280 QString value = explicitAttribute( "depth" );
5281 if ( value.isNull() )
5282 return cr.bottom();
5283
5284 bool ok;
5285 int h = interpretSpacing( value, cr.bottom(), &ok );
5286 if ( ok )
5287 return h;
5288
5289 return cr.bottom();
5290 }
5291
layoutSymbol()5292 void QwtMmlMpaddedNode::layoutSymbol()
5293 {
5294 QwtMmlNode *child = firstChild();
5295 if ( child == 0 )
5296 return;
5297
5298 child->setRelOrigin( QPoint( 0, 0 ) );
5299 }
5300
5301
symbolRect() const5302 QRect QwtMmlMpaddedNode::symbolRect() const
5303 {
5304 return QRect( -lspace(), -height(), lspace() + width(), height() + depth() );
5305 }
5306
5307 // *******************************************************************
5308 // Static helper functions
5309 // *******************************************************************
5310
entityDeclarations()5311 static QString entityDeclarations()
5312 {
5313 QString result = "<!DOCTYPE math [\n";
5314
5315 const QwtMmlEntitySpec *ent = g_xml_entity_data;
5316 for ( ; ent->name != 0; ++ent )
5317 {
5318 result += "\t<!ENTITY " + QString( ent->name ) + " \"" + ent->value + "\">\n";
5319 }
5320
5321 result += "]>\n";
5322
5323 return result;
5324 }
5325
interpretSpacing(QString value,int em,int ex,bool * ok)5326 static int interpretSpacing( QString value, int em, int ex, bool *ok )
5327 {
5328 if ( ok != 0 )
5329 *ok = true;
5330
5331 if ( value == "thin" )
5332 return 1;
5333
5334 if ( value == "medium" )
5335 return 2;
5336
5337 if ( value == "thick" )
5338 return 3;
5339
5340 struct HSpacingValue
5341 {
5342 const char *name;
5343 float factor;
5344 };
5345
5346 static const HSpacingValue g_h_spacing_data[] =
5347 {
5348 { "veryverythinmathspace", ( float ) 0.0555556 },
5349 { "verythinmathspace", ( float ) 0.111111 },
5350 { "thinmathspace", ( float ) 0.166667 },
5351 { "mediummathspace", ( float ) 0.222222 },
5352 { "thickmathspace", ( float ) 0.277778 },
5353 { "verythickmathspace", ( float ) 0.333333 },
5354 { "veryverythickmathspace", ( float ) 0.388889 },
5355 { 0, ( float ) 0 }
5356 };
5357
5358 const HSpacingValue *v = g_h_spacing_data;
5359 for ( ; v->name != 0; ++v )
5360 {
5361 if ( value == v->name )
5362 return ( int )( em * v->factor );
5363 }
5364
5365 if ( value.endsWith( "em" ) )
5366 {
5367 value.truncate( value.length() - 2 );
5368 bool float_ok;
5369 float factor = value.toFloat( &float_ok );
5370 if ( float_ok && factor >= 0 )
5371 return ( int )( em * factor );
5372 else
5373 {
5374 qWarning( "interpretSpacing(): could not parse \"%sem\"", value.toLatin1().data() );
5375 if ( ok != 0 )
5376 *ok = false;
5377 return 0;
5378 }
5379 }
5380
5381 if ( value.endsWith( "ex" ) )
5382 {
5383 value.truncate( value.length() - 2 );
5384 bool float_ok;
5385 float factor = value.toFloat( &float_ok );
5386 if ( float_ok && factor >= 0 )
5387 return ( int )( ex * factor );
5388 else
5389 {
5390 qWarning( "interpretSpacing(): could not parse \"%sex\"", value.toLatin1().data() );
5391 if ( ok != 0 )
5392 *ok = false;
5393 return 0;
5394 }
5395 }
5396
5397 if ( value.endsWith( "cm" ) )
5398 {
5399 value.truncate( value.length() - 2 );
5400 bool float_ok;
5401 float factor = value.toFloat( &float_ok );
5402 if ( float_ok && factor >= 0 )
5403 {
5404 Q_ASSERT( qApp->desktop() != 0 );
5405 QDesktopWidget *dw = qApp->desktop();
5406 Q_ASSERT( dw->width() != 0 );
5407 Q_ASSERT( dw->widthMM() != 0 );
5408 return ( int )( factor * 10 * dw->width() / dw->widthMM() );
5409 }
5410 else
5411 {
5412 qWarning( "interpretSpacing(): could not parse \"%scm\"", value.toLatin1().data() );
5413 if ( ok != 0 )
5414 *ok = false;
5415 return 0;
5416 }
5417 }
5418
5419 if ( value.endsWith( "mm" ) )
5420 {
5421 value.truncate( value.length() - 2 );
5422 bool float_ok;
5423 float factor = value.toFloat( &float_ok );
5424 if ( float_ok && factor >= 0 )
5425 {
5426 Q_ASSERT( qApp->desktop() != 0 );
5427 QDesktopWidget *dw = qApp->desktop();
5428 Q_ASSERT( dw->width() != 0 );
5429 Q_ASSERT( dw->widthMM() != 0 );
5430 return ( int )( factor * dw->width() / dw->widthMM() );
5431 }
5432 else
5433 {
5434 qWarning( "interpretSpacing(): could not parse \"%smm\"", value.toLatin1().data() );
5435 if ( ok != 0 )
5436 *ok = false;
5437 return 0;
5438 }
5439 }
5440
5441 if ( value.endsWith( "in" ) )
5442 {
5443 value.truncate( value.length() - 2 );
5444 bool float_ok;
5445 float factor = value.toFloat( &float_ok );
5446 if ( float_ok && factor >= 0 )
5447 {
5448 Q_ASSERT( qApp->desktop() != 0 );
5449 QDesktopWidget *dw = qApp->desktop();
5450 Q_ASSERT( dw->width() != 0 );
5451 Q_ASSERT( dw->widthMM() != 0 );
5452 return ( int )( factor * 10 * dw->width() / ( 2.54 * dw->widthMM() ) );
5453 }
5454 else
5455 {
5456 qWarning( "interpretSpacing(): could not parse \"%sin\"", value.toLatin1().data() );
5457 if ( ok != 0 )
5458 *ok = false;
5459 return 0;
5460 }
5461 }
5462
5463 if ( value.endsWith( "px" ) )
5464 {
5465 value.truncate( value.length() - 2 );
5466 bool float_ok;
5467 int i = ( int ) value.toFloat( &float_ok );
5468 if ( float_ok && i >= 0 )
5469 return i;
5470 else
5471 {
5472 qWarning( "interpretSpacing(): could not parse \"%spx\"", value.toLatin1().data() );
5473 if ( ok != 0 )
5474 *ok = false;
5475 return 0;
5476 }
5477 }
5478
5479 bool float_ok;
5480 int i = ( int )value.toFloat( &float_ok );
5481 if ( float_ok && i >= 0 )
5482 return i;
5483
5484 qWarning( "interpretSpacing(): could not parse \"%s\"", value.toLatin1().data() );
5485 if ( ok != 0 )
5486 *ok = false;
5487 return 0;
5488 }
5489
interpretPercentSpacing(QString value,int base,bool * ok)5490 static int interpretPercentSpacing( QString value, int base, bool *ok )
5491 {
5492 if ( !value.endsWith( "%" ) )
5493 {
5494 if ( ok != 0 )
5495 *ok = false;
5496 return 0;
5497 }
5498
5499 value.truncate( value.length() - 1 );
5500 bool float_ok;
5501 float factor = value.toFloat( &float_ok );
5502 if ( float_ok && factor >= 0 )
5503 {
5504 if ( ok != 0 )
5505 *ok = true;
5506 return ( int )( base * factor / 100.0 );
5507 }
5508
5509 qWarning( "interpretPercentSpacing(): could not parse \"%s%%\"", value.toLatin1().data() );
5510 if ( ok != 0 )
5511 *ok = false;
5512 return 0;
5513 }
5514
interpretPointSize(QString value,bool * ok)5515 static int interpretPointSize( QString value, bool *ok )
5516 {
5517 if ( !value.endsWith( "pt" ) )
5518 {
5519 if ( ok != 0 )
5520 *ok = false;
5521 return 0;
5522 }
5523
5524 value.truncate( value.length() - 2 );
5525 bool float_ok;
5526 int pt_size = ( int ) value.toFloat( &float_ok );
5527 if ( float_ok && pt_size > 0 )
5528 {
5529 if ( ok != 0 )
5530 *ok = true;
5531 return pt_size;
5532 }
5533
5534 qWarning( "interpretPointSize(): could not parse \"%spt\"", value.toLatin1().data() );
5535 if ( ok != 0 )
5536 *ok = false;
5537 return 0;
5538 }
5539
mmlFindNodeSpec(QwtMml::NodeType type)5540 static const QwtMmlNodeSpec *mmlFindNodeSpec( QwtMml::NodeType type )
5541 {
5542 const QwtMmlNodeSpec *spec = g_node_spec_data;
5543 for ( ; spec->type != QwtMml::NoNode; ++spec )
5544 {
5545 if ( type == spec->type ) return spec;
5546 }
5547 return 0;
5548 }
5549
mmlFindNodeSpec(const QString & tag)5550 static const QwtMmlNodeSpec *mmlFindNodeSpec( const QString &tag )
5551 {
5552 const QwtMmlNodeSpec *spec = g_node_spec_data;
5553 for ( ; spec->type != QwtMml::NoNode; ++spec )
5554 {
5555 if ( tag == spec->tag ) return spec;
5556 }
5557 return 0;
5558 }
5559
mmlCheckChildType(QwtMml::NodeType parent_type,QwtMml::NodeType child_type,QString * error_str)5560 static bool mmlCheckChildType( QwtMml::NodeType parent_type, QwtMml::NodeType child_type,
5561 QString *error_str )
5562 {
5563 if ( parent_type == QwtMml::UnknownNode || child_type == QwtMml::UnknownNode )
5564 return true;
5565
5566 const QwtMmlNodeSpec *child_spec = mmlFindNodeSpec( child_type );
5567 const QwtMmlNodeSpec *parent_spec = mmlFindNodeSpec( parent_type );
5568
5569 Q_ASSERT( parent_spec != 0 );
5570 Q_ASSERT( child_spec != 0 );
5571
5572 QString allowed_child_types( parent_spec->child_types );
5573 // null list means any child type is valid
5574 if ( allowed_child_types.isNull() )
5575 return true;
5576
5577 QString child_type_str = QString( " " ) + child_spec->type_str + " ";
5578 if ( !allowed_child_types.contains( child_type_str ) )
5579 {
5580 if ( error_str != 0 )
5581 *error_str = QString( "illegal child " )
5582 + child_spec->type_str
5583 + " for parent "
5584 + parent_spec->type_str;
5585 return false;
5586 }
5587
5588 return true;
5589 }
5590
mmlCheckAttributes(QwtMml::NodeType child_type,const QwtMmlAttributeMap & attr,QString * error_str)5591 static bool mmlCheckAttributes( QwtMml::NodeType child_type, const QwtMmlAttributeMap &attr,
5592 QString *error_str )
5593 {
5594 const QwtMmlNodeSpec *spec = mmlFindNodeSpec( child_type );
5595 Q_ASSERT( spec != 0 );
5596
5597 QString allowed_attr( spec->attributes );
5598 // empty list means any attr is valid
5599 if ( allowed_attr.isEmpty() )
5600 return true;
5601
5602 QwtMmlAttributeMap::const_iterator it = attr.begin(), end = attr.end();
5603 for ( ; it != end; ++it )
5604 {
5605 QString name = it.key();
5606
5607 if ( name.indexOf( ':' ) != -1 )
5608 continue;
5609
5610 QString padded_name = " " + name + " ";
5611 if ( !allowed_attr.contains( padded_name ) )
5612 {
5613 if ( error_str != 0 )
5614 *error_str = QString( "illegal attribute " )
5615 + name
5616 + " in "
5617 + spec->type_str;
5618 return false;
5619 }
5620 }
5621
5622 return true;
5623 }
5624
attributeIndex(const QString & name)5625 static int attributeIndex( const QString &name )
5626 {
5627 for ( unsigned i = 0; i < g_oper_spec_rows; ++i )
5628 {
5629 if ( name == g_oper_spec_names[i] )
5630 return i;
5631 }
5632 return -1;
5633 }
5634
decodeEntityValue(QString literal)5635 static QString decodeEntityValue( QString literal )
5636 {
5637 QString result;
5638
5639 while ( !literal.isEmpty() )
5640 {
5641
5642 if ( !literal.startsWith( "&#" ) )
5643 {
5644 qWarning() << "decodeEntityValue(): bad entity literal: \"" + literal + "\"";
5645 return QString();
5646 }
5647
5648 literal = literal.right( literal.length() - 2 );
5649
5650 int i = literal.indexOf( ';' );
5651 if ( i == -1 )
5652 {
5653 qWarning() << "decodeEntityValue(): bad entity literal: \"" + literal + "\"";
5654 return QString();
5655 }
5656
5657 QString char_code = literal.left( i );
5658 literal = literal.right( literal.length() - i - 1 );
5659
5660 if ( char_code.isEmpty() )
5661 {
5662 qWarning() << "decodeEntityValue(): bad entity literal: \"" + literal + "\"";
5663 return QString();
5664 }
5665
5666 if ( char_code.at( 0 ) == 'x' )
5667 {
5668 char_code = char_code.right( char_code.length() - 1 );
5669 bool ok;
5670 unsigned c = char_code.toUInt( &ok, 16 );
5671 if ( !ok )
5672 {
5673 qWarning() << "decodeEntityValue(): bad entity literal: \"" + literal + "\"";
5674 return QString();
5675 }
5676 result += QChar( c );
5677 }
5678 else
5679 {
5680 bool ok;
5681 unsigned c = char_code.toUInt( &ok, 10 );
5682 if ( !ok )
5683 {
5684 qWarning() << "decodeEntityValue(): bad entity literal: \"" + literal + "\"";
5685 return QString();
5686 }
5687 result += QChar( c );
5688 }
5689 }
5690
5691 return result;
5692 }
5693
searchEntitySpecData(const QString & value,const QwtMmlEntitySpec * from=0)5694 static const QwtMmlEntitySpec *searchEntitySpecData( const QString &value, const QwtMmlEntitySpec *from = 0 )
5695 {
5696 const QwtMmlEntitySpec *ent = from;
5697 if ( ent == 0 )
5698 ent = g_xml_entity_data;
5699 for ( ; ent->name != 0; ++ent )
5700 {
5701 QString ent_value = decodeEntityValue( ent->value );
5702 if ( value == ent_value )
5703 return ent;
5704 }
5705 return 0;
5706 }
5707
5708 struct OperSpecSearchResult
5709 {
OperSpecSearchResultOperSpecSearchResult5710 OperSpecSearchResult() { prefix_form = infix_form = postfix_form = 0; }
5711
5712 const QwtMmlOperSpec *prefix_form,
5713 *infix_form,
5714 *postfix_form;
5715
5716 const QwtMmlOperSpec *&getForm( QwtMml::FormType f );
haveFormOperSpecSearchResult5717 bool haveForm( QwtMml::FormType f )
5718 { return getForm( f ) != 0; }
addFormOperSpecSearchResult5719 void addForm( const QwtMmlOperSpec *spec )
5720 { getForm( spec->form ) = spec; }
5721 };
5722
getForm(QwtMml::FormType f)5723 const QwtMmlOperSpec *&OperSpecSearchResult::getForm( QwtMml::FormType f )
5724 {
5725 switch ( f )
5726 {
5727 case QwtMml::PrefixForm:
5728 return prefix_form;
5729 case QwtMml::InfixForm:
5730 return infix_form;
5731 case QwtMml::PostfixForm:
5732 return postfix_form;
5733 }
5734 return postfix_form; // just to avoid warning
5735 }
5736
5737 /*
5738 Searches g_oper_spec_data and returns any instance of operator name. There may
5739 be more instances, but since the list is sorted, they will be next to each other.
5740 */
searchOperSpecData(const QString & name)5741 static const QwtMmlOperSpec *searchOperSpecData( const QString &name )
5742 {
5743 const char *name_latin1 = name.toLatin1().data();
5744
5745 // binary search
5746 // establish invariant g_oper_spec_data[begin].name < name < g_oper_spec_data[end].name
5747
5748 int cmp = qstrcmp( name_latin1, g_oper_spec_data[0].name );
5749 if ( cmp < 0 )
5750 return 0;
5751
5752 if ( cmp == 0 )
5753 return g_oper_spec_data;
5754
5755 uint begin = 0;
5756 uint end = g_oper_spec_count;
5757
5758 // invariant holds
5759 while ( end - begin > 1 )
5760 {
5761 uint mid = ( begin + end ) / 2;
5762
5763 const QwtMmlOperSpec *spec = g_oper_spec_data + mid;
5764 int cmp = qstrcmp( name_latin1, spec->name );
5765 if ( cmp < 0 )
5766 end = mid;
5767 else if ( cmp > 0 )
5768 begin = mid;
5769 else
5770 return spec;
5771 }
5772
5773 return 0;
5774 }
5775
5776 /*
5777 This searches g_oper_spec_data until at least one name in name_list is found with FormType form,
5778 or until name_list is exhausted. The idea here is that if we don't find the operator in the
5779 specified form, we still want to use some other available form of that operator.
5780 */
_mmlFindOperSpec(const QStringList & name_list,QwtMml::FormType form)5781 static OperSpecSearchResult _mmlFindOperSpec( const QStringList &name_list, QwtMml::FormType form )
5782 {
5783 OperSpecSearchResult result;
5784
5785 QStringList::const_iterator it = name_list.begin();
5786 for ( ; it != name_list.end(); ++it )
5787 {
5788 const QString &name = *it;
5789
5790 const QwtMmlOperSpec *spec = searchOperSpecData( name );
5791
5792 if ( spec == 0 )
5793 continue;
5794
5795 const char *name_latin1 = name.toLatin1().data();
5796
5797 // backtrack to the first instance of name
5798 while ( spec > g_oper_spec_data && qstrcmp( ( spec - 1 )->name, name_latin1 ) == 0 )
5799 --spec;
5800
5801 // iterate over instances of name until the instances are exhausted or until we
5802 // find an instance in the specified form.
5803 do
5804 {
5805 result.addForm( spec++ );
5806 if ( result.haveForm( form ) )
5807 break;
5808 }
5809 while ( qstrcmp( spec->name, name_latin1 ) == 0 );
5810
5811 if ( result.haveForm( form ) )
5812 break;
5813 }
5814
5815 return result;
5816 }
5817
5818 /*
5819 text is a string between <mo> and </mo>. It can be a character ('+'), an
5820 entity reference ("∞") or a character reference ("∞"). Our
5821 job is to find an operator spec in the operator dictionary (g_oper_spec_data)
5822 that matches text. Things are further complicated by the fact, that many
5823 operators come in several forms (prefix, infix, postfix).
5824
5825 If available, this function returns an operator spec matching text in the specified
5826 form. If such operator is not available, returns an operator spec that matches
5827 text, but of some other form in the preference order specified by the MathML spec.
5828 If that's not available either, returns the default operator spec.
5829 */
mmlFindOperSpec(const QString & text,QwtMml::FormType form)5830 static const QwtMmlOperSpec *mmlFindOperSpec( const QString &text, QwtMml::FormType form )
5831 {
5832 QStringList name_list;
5833 name_list.append( text );
5834
5835 // First, just try to find text in the operator dictionary.
5836 OperSpecSearchResult result = _mmlFindOperSpec( name_list, form );
5837
5838 if ( !result.haveForm( form ) )
5839 {
5840 // Try to find other names for the operator represented by text.
5841
5842 const QwtMmlEntitySpec *ent = 0;
5843 for ( ;; )
5844 {
5845 ent = searchEntitySpecData( text, ent );
5846 if ( ent == 0 )
5847 break;
5848 name_list.append( '&' + QString( ent->name ) + ';' );
5849 ++ent;
5850 }
5851
5852 result = _mmlFindOperSpec( name_list, form );
5853 }
5854
5855 const QwtMmlOperSpec *spec = result.getForm( form );
5856 if ( spec != 0 )
5857 return spec;
5858
5859 spec = result.getForm( QwtMml::InfixForm );
5860 if ( spec != 0 )
5861 return spec;
5862
5863 spec = result.getForm( QwtMml::PostfixForm );
5864 if ( spec != 0 )
5865 return spec;
5866
5867 spec = result.getForm( QwtMml::PrefixForm );
5868 if ( spec != 0 )
5869 return spec;
5870
5871 return &g_oper_spec_defaults;
5872 }
5873
mmlDictAttribute(const QString & name,const QwtMmlOperSpec * spec)5874 static QString mmlDictAttribute( const QString &name, const QwtMmlOperSpec *spec )
5875 {
5876 int i = attributeIndex( name );
5877 if ( i == -1 )
5878 return QString();
5879 else
5880 return spec->attributes[i];
5881 }
5882
interpretMathVariant(const QString & value,bool * ok)5883 static uint interpretMathVariant( const QString &value, bool *ok )
5884 {
5885 struct MathVariantValue
5886 {
5887 const char *value;
5888 uint mv;
5889 };
5890
5891 static const MathVariantValue g_mv_data[] =
5892 {
5893 { "normal", QwtMml::NormalMV },
5894 { "bold", QwtMml::BoldMV },
5895 { "italic", QwtMml::ItalicMV },
5896 { "bold-italic", QwtMml::BoldMV | QwtMml::ItalicMV },
5897 { "double-struck", QwtMml::DoubleStruckMV },
5898 { "bold-fraktur", QwtMml::BoldMV | QwtMml::FrakturMV },
5899 { "script", QwtMml::ScriptMV },
5900 { "bold-script", QwtMml::BoldMV | QwtMml::ScriptMV },
5901 { "fraktur", QwtMml::FrakturMV },
5902 { "sans-serif", QwtMml::SansSerifMV },
5903 { "bold-sans-serif", QwtMml::BoldMV | QwtMml::SansSerifMV },
5904 { "sans-serif-italic", QwtMml::SansSerifMV | QwtMml::ItalicMV },
5905 { "sans-serif-bold-italic", QwtMml::SansSerifMV | QwtMml::ItalicMV | QwtMml::BoldMV },
5906 { "monospace", QwtMml::MonospaceMV },
5907 { 0, 0 }
5908 };
5909
5910 const MathVariantValue *v = g_mv_data;
5911 for ( ; v->value != 0; ++v )
5912 {
5913 if ( value == v->value )
5914 {
5915 if ( ok != 0 )
5916 *ok = true;
5917 return v->mv;
5918 }
5919 }
5920
5921 if ( ok != 0 )
5922 *ok = false;
5923
5924 qWarning( "interpretMathVariant(): could not parse value: \"%s\"", value.toLatin1().data() );
5925
5926 return QwtMml::NormalMV;
5927 }
5928
interpretForm(const QString & value,bool * ok)5929 static QwtMml::FormType interpretForm( const QString &value, bool *ok )
5930 {
5931 if ( ok != 0 )
5932 *ok = true;
5933
5934 if ( value == "prefix" )
5935 return QwtMml::PrefixForm;
5936 if ( value == "infix" )
5937 return QwtMml::InfixForm;
5938 if ( value == "postfix" )
5939 return QwtMml::PostfixForm;
5940
5941 if ( ok != 0 )
5942 *ok = false;
5943
5944 qWarning( "interpretForm(): could not parse value \"%s\"", value.toLatin1().data() );
5945 return QwtMml::InfixForm;
5946 }
5947
interpretColAlign(const QString & value_list,uint colnum,bool * ok)5948 static QwtMml::ColAlign interpretColAlign( const QString &value_list, uint colnum, bool *ok )
5949 {
5950 QString value = interpretListAttr( value_list, colnum, "center" );
5951
5952 if ( ok != 0 )
5953 *ok = true;
5954
5955 if ( value == "left" )
5956 return QwtMml::ColAlignLeft;
5957 if ( value == "right" )
5958 return QwtMml::ColAlignRight;
5959 if ( value == "center" )
5960 return QwtMml::ColAlignCenter;
5961
5962 if ( ok != 0 )
5963 *ok = false;
5964
5965 qWarning( "interpretColAlign(): could not parse value \"%s\"", value.toLatin1().data() );
5966 return QwtMml::ColAlignCenter;
5967 }
5968
interpretRowAlign(const QString & value_list,uint rownum,bool * ok)5969 static QwtMml::RowAlign interpretRowAlign( const QString &value_list, uint rownum, bool *ok )
5970 {
5971 QString value = interpretListAttr( value_list, rownum, "axis" );
5972
5973 if ( ok != 0 )
5974 *ok = true;
5975
5976 if ( value == "top" )
5977 return QwtMml::RowAlignTop;
5978 if ( value == "center" )
5979 return QwtMml::RowAlignCenter;
5980 if ( value == "bottom" )
5981 return QwtMml::RowAlignBottom;
5982 if ( value == "baseline" )
5983 return QwtMml::RowAlignBaseline;
5984 if ( value == "axis" )
5985 return QwtMml::RowAlignAxis;
5986
5987 if ( ok != 0 )
5988 *ok = false;
5989
5990 qWarning( "interpretRowAlign(): could not parse value \"%s\"", value.toLatin1().data() );
5991 return QwtMml::RowAlignAxis;
5992 }
5993
interpretListAttr(const QString & value_list,int idx,const QString & def)5994 static QString interpretListAttr( const QString &value_list, int idx, const QString &def )
5995 {
5996 QStringList l = value_list.split( ' ' );
5997
5998 if ( l.count() == 0 )
5999 return def;
6000
6001 if ( l.count() <= idx )
6002 return l[l.count() - 1];
6003 else
6004 return l[idx];
6005 }
6006
interpretFrameType(const QString & value_list,uint idx,bool * ok)6007 static QwtMml::FrameType interpretFrameType( const QString &value_list, uint idx, bool *ok )
6008 {
6009 if ( ok != 0 )
6010 *ok = true;
6011
6012 QString value = interpretListAttr( value_list, idx, "none" );
6013
6014 if ( value == "none" )
6015 return QwtMml::FrameNone;
6016 if ( value == "solid" )
6017 return QwtMml::FrameSolid;
6018 if ( value == "dashed" )
6019 return QwtMml::FrameDashed;
6020
6021 if ( ok != 0 )
6022 *ok = false;
6023
6024 qWarning( "interpretFrameType(): could not parse value \"%s\"", value.toLatin1().data() );
6025 return QwtMml::FrameNone;
6026 }
6027
6028
interpretFrameSpacing(const QString & value_list,int em,int ex,bool * ok)6029 static QwtMml::FrameSpacing interpretFrameSpacing( const QString &value_list, int em, int ex, bool *ok )
6030 {
6031 QwtMml::FrameSpacing fs;
6032
6033 QStringList l = value_list.split( ' ' );
6034 if ( l.count() != 2 )
6035 {
6036 qWarning( "interpretFrameSpacing: could not parse value \"%s\"", value_list.toLatin1().data() );
6037 if ( ok != 0 )
6038 *ok = false;
6039 return QwtMml::FrameSpacing( ( int )( 0.4 * em ), ( int )( 0.5 * ex ) );
6040 }
6041
6042 bool hor_ok, ver_ok;
6043 fs.m_hor = interpretSpacing( l[0], em, ex, &hor_ok );
6044 fs.m_ver = interpretSpacing( l[1], em, ex, &ver_ok );
6045
6046 if ( ok != 0 )
6047 *ok = hor_ok && ver_ok;
6048
6049 return fs;
6050 }
6051
interpretDepreciatedFontAttr(const QwtMmlAttributeMap & font_attr,QFont & fn,int em,int ex)6052 static QFont interpretDepreciatedFontAttr( const QwtMmlAttributeMap &font_attr, QFont &fn, int em, int ex )
6053 {
6054 if ( font_attr.contains( "fontsize" ) )
6055 {
6056 QString value = font_attr["fontsize"];
6057
6058 for ( ;; )
6059 {
6060
6061 bool ok;
6062 int ptsize = interpretPointSize( value, &ok );
6063 if ( ok )
6064 {
6065 fn.setPointSize( ptsize );
6066 break;
6067 }
6068
6069 ptsize = interpretPercentSpacing( value, fn.pointSize(), &ok );
6070 if ( ok )
6071 {
6072 fn.setPointSize( ptsize );
6073 break;
6074 }
6075
6076 int size = interpretSpacing( value, em, ex, &ok );
6077 if ( ok )
6078 {
6079 fn.setPixelSize( size );
6080 break;
6081 }
6082
6083 break;
6084 }
6085 }
6086
6087 if ( font_attr.contains( "fontweight" ) )
6088 {
6089 QString value = font_attr["fontweight"];
6090 if ( value == "normal" )
6091 fn.setBold( false );
6092 else if ( value == "bold" )
6093 fn.setBold( true );
6094 else
6095 qWarning( "interpretDepreciatedFontAttr(): could not parse fontweight \"%s\"", value.toLatin1().data() );
6096 }
6097
6098 if ( font_attr.contains( "fontstyle" ) )
6099 {
6100 QString value = font_attr["fontstyle"];
6101 if ( value == "normal" )
6102 fn.setItalic( false );
6103 else if ( value == "italic" )
6104 fn.setItalic( true );
6105 else
6106 qWarning( "interpretDepreciatedFontAttr(): could not parse fontstyle \"%s\"", value.toLatin1().data() );
6107 }
6108
6109 if ( font_attr.contains( "fontfamily" ) )
6110 {
6111 QString value = font_attr["fontfamily"];
6112 fn.setFamily( value );
6113 }
6114
6115 return fn;
6116 }
6117
interpretMathSize(QString value,QFont & fn,int em,int ex,bool * ok)6118 static QFont interpretMathSize( QString value, QFont &fn, int em, int ex, bool *ok )
6119 {
6120 if ( ok != 0 )
6121 *ok = true;
6122
6123 if ( value == "small" )
6124 {
6125 fn.setPointSize( ( int )( fn.pointSize() * 0.7 ) );
6126 return fn;
6127 }
6128
6129 if ( value == "normal" )
6130 return fn;
6131
6132 if ( value == "big" )
6133 {
6134 fn.setPointSize( ( int )( fn.pointSize() * 1.5 ) );
6135 return fn;
6136 }
6137
6138 bool size_ok;
6139
6140 int ptsize = interpretPointSize( value, &size_ok );
6141 if ( size_ok )
6142 {
6143 fn.setPointSize( ptsize );
6144 return fn;
6145 }
6146
6147 int size = interpretSpacing( value, em, ex, &size_ok );
6148 if ( size_ok )
6149 {
6150 fn.setPixelSize( size );
6151 return fn;
6152 }
6153
6154 if ( ok != 0 )
6155 *ok = false;
6156 qWarning( "interpretMathSize(): could not parse mathsize \"%s\"", value.toLatin1().data() );
6157 return fn;
6158 }
6159
6160 /*!
6161 \class QwtMathMLDocument
6162
6163 \brief The QwtMathMLDocument class renders mathematical formulas written in MathML 2.0.
6164 */
6165
6166 /*!
6167 Constructs an empty MML document.
6168 */
QwtMathMLDocument()6169 QwtMathMLDocument::QwtMathMLDocument()
6170 {
6171 m_doc = new QwtMmlDocument;
6172 }
6173
6174 /*!
6175 Destroys the MML document.
6176 */
~QwtMathMLDocument()6177 QwtMathMLDocument::~QwtMathMLDocument()
6178 {
6179 delete m_doc;
6180 }
6181
6182 /*!
6183 Clears the contents of this MML document.
6184 */
clear()6185 void QwtMathMLDocument::clear()
6186 {
6187 m_doc->clear();
6188 }
6189
6190 /*!
6191 Sets the MathML expression to be rendered. The expression is given
6192 in the string \a text. If the expression is successfully parsed,
6193 this method returns true; otherwise it returns false. If an error
6194 occured \a errorMsg is set to a diagnostic message, while \a
6195 errorLine and \a errorColumn contain the location of the error.
6196 Any of \a errorMsg, \a errorLine and \a errorColumn may be 0,
6197 in which case they are not set.
6198
6199 \a text should contain MathML 2.0 presentation markup elements enclosed
6200 in a <math> element.
6201 */
setContent(QString text,QString * errorMsg,int * errorLine,int * errorColumn)6202 bool QwtMathMLDocument::setContent( QString text, QString *errorMsg,
6203 int *errorLine, int *errorColumn )
6204 {
6205 return m_doc->setContent( text, errorMsg, errorLine, errorColumn );
6206 }
6207
6208 /*!
6209 Renders this MML document with the painter \a p at position \a pos.
6210 */
paint(QPainter * p,const QPoint & pos) const6211 void QwtMathMLDocument::paint( QPainter *p, const QPoint &pos ) const
6212 {
6213 m_doc->paint( p, pos );
6214 }
6215
6216 /*!
6217 Returns the size of this MML document, as rendered, in pixels.
6218 */
size() const6219 QSize QwtMathMLDocument::size() const
6220 {
6221 return m_doc->size();
6222 }
6223
6224 /*!
6225 Returns the name of the font used to render the font \a type.
6226
6227 \sa setFontName() setBaseFontPointSize() baseFontPointSize() QwtMathMLDocument::MmlFont
6228 */
fontName(QwtMathMLDocument::MmlFont type) const6229 QString QwtMathMLDocument::fontName( QwtMathMLDocument::MmlFont type ) const
6230 {
6231 return m_doc->fontName( type );
6232 }
6233
6234 /*!
6235 Sets the name of the font used to render the font \a type to \a name.
6236
6237 \sa fontName() setBaseFontPointSize() baseFontPointSize() QwtMathMLDocument::MmlFont
6238 */
setFontName(QwtMathMLDocument::MmlFont type,const QString & name)6239 void QwtMathMLDocument::setFontName( QwtMathMLDocument::MmlFont type, const QString &name )
6240 {
6241 m_doc->setFontName( type, name );
6242 }
6243
6244 /*!
6245 Returns the point size of the font used to render expressions
6246 whose scriptlevel is 0.
6247
6248 \sa setBaseFontPointSize() fontName() setFontName()
6249 */
baseFontPointSize() const6250 int QwtMathMLDocument::baseFontPointSize() const
6251 {
6252 return m_doc->baseFontPointSize();
6253 }
6254
6255 /*!
6256 Sets the point \a size of the font used to render expressions
6257 whose scriptlevel is 0.
6258
6259 \sa baseFontPointSize() fontName() setFontName()
6260 */
setBaseFontPointSize(int size)6261 void QwtMathMLDocument::setBaseFontPointSize( int size )
6262 {
6263 m_doc->setBaseFontPointSize( size );
6264 }
6265