Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <mathtype.hxx>
22 : #include <osl/diagnose.h>
23 : #include <sfx2/docfile.hxx>
24 :
25 0 : void MathType::Init()
26 : {
27 : //These are the default MathType sizes
28 0 : aSizeTable[0]=12;
29 0 : aSizeTable[1]=8;
30 0 : aSizeTable[2]=6;
31 0 : aSizeTable[3]=24;
32 0 : aSizeTable[4]=10;
33 0 : aSizeTable[5]=12;
34 0 : aSizeTable[6]=12;
35 :
36 : /*
37 : These are the default MathType italic/bold settings If mathtype is changed
38 : from its defaults, there is nothing we can do, as this information is not
39 : stored in the document
40 : */
41 0 : MathTypeFont aFont;
42 0 : for(sal_uInt8 i=1;i<=11;i++)
43 : {
44 0 : aFont.nTface = i+128;
45 0 : switch (i)
46 : {
47 : default:
48 0 : aFont.nStyle=0;
49 0 : break;
50 : case 3:
51 : case 4:
52 0 : aFont.nStyle=1;
53 0 : break;
54 : case 7:
55 0 : aFont.nStyle=2;
56 0 : break;
57 : }
58 0 : aUserStyles.insert(aFont);
59 : }
60 0 : }
61 :
62 :
63 : /*ToDo replace with table rather than switch, returns
64 : sal_True in the case that the char is just a char, and
65 : sal_False if the character is an operator which must not be
66 : placed inside the quote sequence designed to protect
67 : against being parsed as a keyword
68 :
69 : General solution required to force starmath to handle
70 : unicode math chars the way it handles its own math
71 : chars rathar than handle them as text as it will do
72 : for the default case below, i.e. incorrect spacing
73 : between math symbols and ordinary text e.g. 1=2 rather
74 : than 1 = 2
75 : */
76 0 : sal_Bool MathType::LookupChar(sal_Unicode nChar,OUString &rRet,sal_uInt8 nVersion,
77 : sal_uInt8 nTypeFace)
78 : {
79 0 : bool bRet=false;
80 0 : const char *pC = NULL;
81 0 : switch(nChar)
82 : {
83 : case 0x0000:
84 0 : pC = " none ";
85 0 : break;
86 : case 0x00ac:
87 0 : pC = " neg ";
88 0 : break;
89 : case 0x00b1:
90 0 : pC = " +- ";
91 0 : break;
92 : case '(':
93 0 : pC = " \\( ";
94 0 : break;
95 : case ')':
96 0 : pC = " \\) ";
97 0 : break;
98 : case '[':
99 0 : pC = " \\[ ";
100 0 : break;
101 : case ']':
102 0 : pC = " \\] ";
103 0 : break;
104 : case '.':
105 0 : pC = " \".\" ";
106 0 : break;
107 : case 0xae:
108 0 : if ((nVersion < 3) && (nTypeFace == 0x86))
109 0 : pC = " rightarrow ";
110 : else
111 : {
112 0 : rRet += OUString( nChar );
113 0 : bRet=true;
114 : }
115 0 : break;
116 : case 0x00fb:
117 0 : if ((nVersion < 3) && (nTypeFace == 0x81))
118 0 : nChar = 0xDF;
119 0 : rRet += OUString( nChar );
120 0 : bRet=true;
121 0 : break;
122 : case 'a':
123 0 : if ((nVersion < 3) && (nTypeFace == 0x84))
124 0 : nChar = 0x3b1;
125 0 : rRet += OUString( nChar );
126 0 : bRet=true;
127 0 : break;
128 : case 'b':
129 0 : if ((nVersion < 3) && (nTypeFace == 0x84))
130 0 : nChar = 0x3b2;
131 0 : rRet += OUString( nChar );
132 0 : bRet=true;
133 0 : break;
134 : case 'l':
135 0 : if ((nVersion < 3) && (nTypeFace == 0x84))
136 0 : nChar = 0x3bb;
137 0 : rRet += OUString( nChar );
138 0 : bRet=true;
139 0 : break;
140 : case 'n':
141 0 : if ((nVersion < 3) && (nTypeFace == 0x84))
142 0 : nChar = 0x3bd;
143 0 : rRet += OUString( nChar );
144 0 : bRet=true;
145 0 : break;
146 : case 'r':
147 0 : if ((nVersion < 3) && (nTypeFace == 0x84))
148 0 : nChar = 0x3c1;
149 0 : rRet += OUString( nChar );
150 0 : bRet=true;
151 0 : break;
152 : case 'D':
153 0 : if ((nVersion < 3) && (nTypeFace == 0x84))
154 0 : nChar = 0x394;
155 0 : rRet += OUString( nChar );
156 0 : bRet=true;
157 0 : break;
158 : case 0xa9:
159 0 : if ((nVersion < 3) && (nTypeFace == 0x82))
160 0 : nChar = '\'';
161 0 : rRet += OUString( nChar );
162 0 : bRet=true;
163 0 : break;
164 : case 0x00f1:
165 0 : if ((nVersion < 3) && (nTypeFace == 0x86))
166 0 : pC = " \\rangle ";
167 : else
168 : {
169 0 : rRet += OUString( nChar );
170 0 : bRet=true;
171 : }
172 0 : break;
173 : case 0x00a3:
174 0 : if ((nVersion < 3) && (nTypeFace == 0x86))
175 0 : pC = " <= ";
176 : else
177 : {
178 0 : rRet += OUString( nChar );
179 0 : bRet=true;
180 : }
181 0 : break;
182 : case 0x00de:
183 0 : if ((nVersion < 3) && (nTypeFace == 0x86))
184 0 : pC = " drarrow ";
185 : else
186 : {
187 0 : rRet += OUString( nChar );
188 0 : bRet=true;
189 : }
190 0 : break;
191 : case 0x0057:
192 0 : if ((nVersion < 3) && (nTypeFace == 0x85))
193 0 : pC = " %OMEGA ";
194 : else
195 : {
196 0 : rRet += OUString( nChar );
197 0 : bRet=true;
198 : }
199 0 : break;
200 : case 0x007b:
201 0 : pC = " lbrace ";
202 0 : break;
203 : case 0x007c:
204 0 : pC = " \\lline ";
205 0 : break;
206 : case 0x007d:
207 0 : pC = " rbrace ";
208 0 : break;
209 : case 0x007e:
210 0 : pC = " \"~\" ";
211 0 : break;
212 : case 0x2224:
213 0 : pC = " ndivides ";
214 0 : break;
215 : case 0x2225:
216 0 : pC = " parallel ";
217 0 : break;
218 : case 0x00d7:
219 0 : if (nVersion < 3)
220 0 : pC = " cdot ";
221 : else
222 0 : pC = " times ";
223 0 : break;
224 : case 0x00f7:
225 0 : pC = " div ";
226 0 : break;
227 : case 0x019b:
228 0 : pC = " lambdabar ";
229 0 : break;
230 : case 0x2026:
231 0 : pC = " dotslow ";
232 0 : break;
233 : case 0x2022:
234 0 : pC = " cdot ";
235 0 : break;
236 : case 0x2102:
237 0 : pC = " setC ";
238 0 : break;
239 : case 0x210f:
240 0 : pC = " hbar ";
241 0 : break;
242 : case 0x2111:
243 0 : pC = " Im ";
244 0 : break;
245 : case 0x2115:
246 0 : pC = " setN ";
247 0 : break;
248 : case 0x2118:
249 0 : pC = " wp ";
250 0 : break;
251 : case 0x211a:
252 0 : pC = " setQ ";
253 0 : break;
254 : case 0x211c:
255 0 : pC = " Re ";
256 0 : break;
257 : case 0x211d:
258 0 : pC = " setR ";
259 0 : break;
260 : case 0x2124:
261 0 : pC = " setZ ";
262 0 : break;
263 : case 0x2135:
264 0 : pC = " aleph ";
265 0 : break;
266 : case 0x2190:
267 0 : pC = " leftarrow ";
268 0 : break;
269 : case 0x2191:
270 0 : pC = " uparrow ";
271 0 : break;
272 : case 0x2192:
273 0 : pC = " rightarrow ";
274 0 : break;
275 : case 0x0362:
276 0 : pC = " widevec ";
277 0 : break;
278 : case 0x2193:
279 0 : pC = " downarrow ";
280 0 : break;
281 : case 0x21d0:
282 0 : pC = " dlarrow ";
283 0 : break;
284 : case 0x21d2:
285 0 : pC = " drarrow ";
286 0 : break;
287 : case 0x21d4:
288 0 : pC = " dlrarrow ";
289 0 : break;
290 : case 0x2200:
291 0 : pC = " forall ";
292 0 : break;
293 : case 0x2202:
294 0 : pC = " partial ";
295 0 : break;
296 : case 0x2203:
297 0 : pC = " exists ";
298 0 : break;
299 : case 0x2204:
300 0 : pC = " notexists ";
301 0 : break;
302 : case 0x2205:
303 0 : pC = " emptyset ";
304 0 : break;
305 : case 0x2207:
306 0 : pC = " nabla ";
307 0 : break;
308 : case 0x2208:
309 0 : pC = " in ";
310 0 : break;
311 : case 0x2209:
312 0 : pC = " notin ";
313 0 : break;
314 : case 0x220d:
315 0 : pC = " owns ";
316 0 : break;
317 : case 0x220f:
318 0 : pC = " prod ";
319 0 : break;
320 : case 0x2210:
321 0 : pC = " coprod ";
322 0 : break;
323 : case 0x2211:
324 0 : pC = " sum ";
325 0 : break;
326 : case 0x2212:
327 0 : pC = " - ";
328 0 : break;
329 : case 0x2213:
330 0 : pC = " -+ ";
331 0 : break;
332 : case 0x2217:
333 0 : pC = " * ";
334 0 : break;
335 : case 0x2218:
336 0 : pC = " circ ";
337 0 : break;
338 : case 0x221d:
339 0 : pC = " prop ";
340 0 : break;
341 : case 0x221e:
342 0 : pC = " infinity ";
343 0 : break;
344 : case 0x2227:
345 0 : pC = " and ";
346 0 : break;
347 : case 0x2228:
348 0 : pC = " or ";
349 0 : break;
350 : case 0x2229:
351 0 : pC = " intersection ";
352 0 : break;
353 : case 0x222a:
354 0 : pC = " union ";
355 0 : break;
356 : case 0x222b:
357 0 : pC = " int ";
358 0 : break;
359 : case 0x222c:
360 0 : pC = " iint ";
361 0 : break;
362 : case 0x222d:
363 0 : pC = " iiint ";
364 0 : break;
365 : case 0x222e:
366 0 : pC = " lint ";
367 0 : break;
368 : case 0x222f:
369 0 : pC = " llint ";
370 0 : break;
371 : case 0x2230:
372 0 : pC = " lllint ";
373 0 : break;
374 : case 0x2245:
375 0 : pC = " simeq ";
376 0 : break;
377 : case 0x2248:
378 0 : pC = " approx ";
379 0 : break;
380 : case 0x2260:
381 0 : pC = " <> ";
382 0 : break;
383 : case 0x2261:
384 0 : pC = " equiv ";
385 0 : break;
386 : case 0x2264:
387 0 : pC = " <= ";
388 0 : break;
389 : case 0x2265:
390 0 : pC = " >= ";
391 0 : break;
392 :
393 : case 0x227A:
394 0 : pC = " prec ";
395 0 : break;
396 : case 0x227B:
397 0 : pC = " succ ";
398 0 : break;
399 : case 0x227C:
400 0 : pC = " preccurlyeq ";
401 0 : break;
402 : case 0x227D:
403 0 : pC = " succcurlyeq ";
404 0 : break;
405 : case 0x227E:
406 0 : pC = " precsim ";
407 0 : break;
408 : case 0x227F:
409 0 : pC = " succsim ";
410 0 : break;
411 : case 0x2280:
412 0 : pC = " nprec ";
413 0 : break;
414 : case 0x2281:
415 0 : pC = " nsucc ";
416 0 : break;
417 :
418 : case 0x2282:
419 0 : pC = " subset ";
420 0 : break;
421 : case 0x2283:
422 0 : pC = " supset ";
423 0 : break;
424 : case 0x2284:
425 0 : pC = " nsubset ";
426 0 : break;
427 : case 0x2285:
428 0 : pC = " nsupset ";
429 0 : break;
430 : case 0x2286:
431 0 : pC = " subseteq ";
432 0 : break;
433 : case 0x2287:
434 0 : pC = " supseteq ";
435 0 : break;
436 : case 0x2288:
437 0 : pC = " nsubseteq ";
438 0 : break;
439 : case 0x2289:
440 0 : pC = " nsupseteq ";
441 0 : break;
442 : case 0x22b2:
443 : case 0x22b3:
444 0 : rRet += " " + OUString( nChar ) + " ";
445 0 : break;
446 : case 0x22a5:
447 0 : pC = " ortho ";
448 0 : break;
449 : case 0x22c5:
450 0 : pC = " cdot ";
451 0 : break;
452 : case 0x22ee:
453 0 : pC = " dotsvert ";
454 0 : break;
455 : case 0x22ef:
456 0 : pC = " dotsaxis ";
457 0 : break;
458 : case 0x22f0:
459 0 : pC = " dotsup ";
460 0 : break;
461 : case 0x22f1:
462 0 : pC = " dotsdown ";
463 0 : break;
464 : case MS_LANGLE:
465 : case MS_LMATHANGLE:
466 0 : pC = " langle ";
467 0 : break;
468 : case MS_RANGLE:
469 : case MS_RMATHANGLE:
470 0 : pC = " rangle ";
471 0 : break;
472 : case 0x301a:
473 0 : pC = " ldbracket ";
474 0 : break;
475 : case 0x301b:
476 0 : pC = " rdbracket ";
477 0 : break;
478 : case 0xe083:
479 0 : rRet += "+";
480 0 : bRet=true;
481 0 : break;
482 : case '^':
483 : case 0xe091:
484 0 : pC = " widehat ";
485 0 : break;
486 : case 0xe096:
487 0 : pC = " widetilde ";
488 0 : break;
489 : case 0xe098:
490 0 : pC = " widevec ";
491 0 : break;
492 : case 0xE421:
493 0 : pC = " geslant ";
494 0 : break;
495 : case 0xE425:
496 0 : pC = " leslant ";
497 0 : break;
498 : case 0xeb01: //no space
499 : case 0xeb08: //normal space
500 0 : bRet=true;
501 0 : break;
502 : case 0xef04: //tiny space
503 : case 0xef05: //tiny space
504 : case 0xeb02: //small space
505 : case 0xeb04: //medium space
506 0 : rRet += "`";
507 0 : break;
508 : case 0xeb05: //large space
509 0 : rRet += "~";
510 0 : break;
511 : case 0x3a9:
512 0 : pC = " %OMEGA ";
513 0 : break;
514 : default:
515 0 : rRet += OUString( nChar );
516 0 : bRet=true;
517 0 : break;
518 : }
519 0 : if (pC)
520 0 : rRet += OUString::createFromAscii( pC );
521 0 : return bRet;
522 : }
523 :
524 0 : void MathTypeFont::AppendStyleToText(OUString &rRet)
525 : {
526 0 : const char *pC = NULL;
527 0 : switch (nStyle)
528 : {
529 : default:
530 : case 0:
531 0 : break;
532 : case 1:
533 0 : pC = " ital ";
534 0 : break;
535 : case 2:
536 0 : pC = " bold ";
537 0 : break;
538 : case 3:
539 0 : pC = " bold italic";
540 0 : break;
541 : }
542 0 : if (pC)
543 0 : rRet += OUString::createFromAscii( pC );
544 0 : }
545 :
546 0 : void MathType::TypeFaceToString(OUString &rTxt,sal_uInt8 nFace)
547 : {
548 0 : MathTypeFont aFont(nFace);
549 0 : MathTypeFontSet::iterator aItr = aUserStyles.find(aFont);
550 0 : if (aItr != aUserStyles.end())
551 0 : aFont.nStyle = aItr->nStyle;
552 0 : aFont.AppendStyleToText(rTxt);
553 0 : }
554 :
555 0 : int MathType::Parse(SotStorage *pStor)
556 : {
557 : SvStorageStreamRef xSrc = pStor->OpenSotStream(
558 : OUString("Equation Native"),
559 0 : STREAM_STD_READ | STREAM_NOCREATE);
560 0 : if ( (!xSrc.Is()) || (SVSTREAM_OK != xSrc->GetError()))
561 0 : return 0;
562 0 : pS = &xSrc;
563 0 : pS->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
564 :
565 0 : EQNOLEFILEHDR aHdr;
566 0 : aHdr.Read(pS);
567 0 : pS->ReadUChar( nVersion );
568 0 : pS->ReadUChar( nPlatform );
569 0 : pS->ReadUChar( nProduct );
570 0 : pS->ReadUChar( nProdVersion );
571 0 : pS->ReadUChar( nProdSubVersion );
572 :
573 0 : if (nVersion > 3) // allow only supported versions of MathType to be parsed
574 0 : return 0;
575 :
576 : #ifdef STANDALONE
577 : *pOut << "Format Version is " << int(nVersion) << endl;
578 : *pOut << "Generating Platform is " << (nPlatform ? "Windows"
579 : : "Mac") << endl;
580 : *pOut << "Generating Product is " << (nPlatform ? "Equation Editor"
581 : : "Equation Editor") << endl;
582 : *pOut << "Prod Version is " << int(nProdVersion) << "." <<
583 : int(nProdSubVersion) << endl << endl;
584 : #endif
585 :
586 0 : int nRet = HandleRecords();
587 : //little crude hack to close ocassionally open expressions
588 : //a sophisticated system to determine what expressions are
589 : //opened is required, but this is as much work as rewriting
590 : //starmaths internals.
591 0 : rRet += "{}";
592 :
593 : #if OSL_DEBUG_LEVEL > 1
594 : # ifdef CAOLAN
595 : //sanity check
596 :
597 : //sigh, theres no point! MathType (in some bizarre subvarient) pads
598 : //the end of the formula with ENDs (0)'s
599 : sal_uLong nEnd = pS->Tell();
600 : OSL_ENSURE(nEnd == pS->Seek(STREAM_SEEK_TO_END),
601 : "Possibly unfully parsed formula");
602 : # endif
603 : #endif
604 0 : return nRet;
605 : }
606 :
607 0 : static void lcl_PrependDummyTerm(OUString &rRet, sal_Int32 &rTextStart)
608 : {
609 0 : if ((rTextStart < rRet.getLength()) &&
610 0 : (rRet[rTextStart] == '=') &&
611 0 : ((rTextStart == 0) || (rRet[ rTextStart-1 ] == '{'))
612 : )
613 : {
614 0 : rRet = rRet.replaceAt(rTextStart,0," {}");
615 0 : rTextStart+=3;
616 : }
617 0 : }
618 :
619 0 : static void lcl_AppendDummyTerm(OUString &rRet)
620 : {
621 0 : bool bOk=false;
622 0 : for(int nI=rRet.getLength()-1;nI >= 0; nI--)
623 : {
624 0 : sal_Int32 nIdx = sal::static_int_cast< sal_Int32 >(nI);
625 0 : sal_Unicode nChar = rRet[nIdx];
626 0 : if (nChar == ' ')
627 0 : continue;
628 0 : if (rRet[nIdx] != '{')
629 0 : bOk=true;
630 0 : break;
631 : }
632 0 : if (!bOk) //No term, use dummy
633 0 : rRet += " {}";
634 0 : }
635 :
636 0 : void MathType::HandleNudge()
637 : {
638 : sal_uInt8 nXNudge;
639 0 : pS->ReadUChar( nXNudge );
640 : sal_uInt8 nYNudge;
641 0 : pS->ReadUChar( nYNudge );
642 0 : if (nXNudge == 128 && nYNudge == 128)
643 : {
644 : sal_uInt16 nXLongNudge;
645 : sal_uInt16 nYLongNudge;
646 0 : pS->ReadUInt16( nXLongNudge );
647 0 : pS->ReadUInt16( nYLongNudge );
648 : }
649 0 : }
650 : /*Fabously complicated as many tokens have to be reordered and generally
651 : *moved around from mathtypes paradigm to starmaths.*/
652 0 : int MathType::HandleRecords(int nLevel,sal_uInt8 nSelector,
653 : sal_uInt8 nVariation, int nMatrixRows,int nMatrixCols)
654 : {
655 : sal_uInt8 nTag,nRecord;
656 : sal_uInt8 nTabType,nTabStops;
657 : sal_uInt16 nTabOffset;
658 0 : int i,nRet=1,newline=0;
659 0 : bool bSilent=false;
660 0 : int nPart=0;
661 0 : OUString sPush,sMainTerm;
662 0 : int nSetSize=0,nSetAlign=0;
663 0 : int nCurRow=0,nCurCol=0;
664 0 : bool bOpenString=false;
665 0 : sal_Int32 nTextStart = 0;
666 0 : sal_Int32 nSubSupStartPos = 0;
667 0 : sal_Int32 nLastTemplateBracket=-1;
668 :
669 0 : do
670 : {
671 0 : nTag = 0;
672 0 : pS->ReadUChar( nTag );
673 0 : nRecord = nTag&0x0F;
674 :
675 : /*MathType strings can of course include words which
676 : *are StarMath keywords, the simplest solution is
677 : to escape strings of greater than len 1 with double
678 : quotes to avoid scanning the TokenTable for matches
679 :
680 : Unfortunately it may turn out that the string gets
681 : split during the handling of a character emblishment
682 : so this special case must be handled in the
683 : character handler case 2:
684 : */
685 0 : if ((nRecord == CHAR) && (!bIsSilent) && (!bOpenString))
686 : {
687 0 : bOpenString=true;
688 0 : nTextStart = rRet.getLength();
689 : }
690 0 : else if ((nRecord != CHAR) && (bOpenString))
691 : {
692 0 : bOpenString=false;
693 0 : if ((rRet.getLength() - nTextStart) > 1)
694 : {
695 0 : OUString aStr;
696 0 : TypeFaceToString(aStr,nTypeFace);
697 0 : aStr += "\"";
698 0 : rRet = rRet.replaceAt(nTextStart,0,aStr);
699 0 : rRet += "\"";
700 : }
701 0 : else if (nRecord == END && !rRet.isEmpty())
702 : {
703 0 : sal_Unicode cChar = 0;
704 0 : sal_Int32 nI = rRet.getLength()-1;
705 0 : while (nI && ((cChar = rRet[nI]) == ' '))
706 0 : --nI;
707 0 : if ((cChar == '=') || (cChar == '+') || (cChar == '-'))
708 0 : rRet += "{}";
709 : }
710 : }
711 :
712 0 : switch(nRecord)
713 : {
714 : case LINE:
715 : {
716 0 : if (xfLMOVE(nTag))
717 0 : HandleNudge();
718 :
719 0 : if (newline>0)
720 0 : rRet += "\nnewline\n";
721 0 : if (!(xfNULL(nTag)))
722 : {
723 0 : switch (nSelector)
724 : {
725 : case 0x0:
726 0 : if (nVariation==0)
727 0 : rRet += " langle ";
728 0 : else if (nVariation==1)
729 0 : rRet += " \\langle ";
730 0 : break;
731 : case 0x1:
732 0 : if (nVariation==0)
733 0 : rRet += " left (";
734 0 : else if (nVariation==1)
735 0 : rRet += "\\(";
736 0 : break;
737 : case 0x2:
738 0 : if ((nVariation==0) || (nVariation==1))
739 0 : rRet += " left lbrace ";
740 : else
741 0 : rRet += " left none ";
742 0 : break;
743 : case 0x3:
744 0 : if (nVariation==0)
745 0 : rRet += " left [";
746 0 : else if (nVariation==1)
747 0 : rRet += "\\[";
748 0 : break;
749 : case 0x8:
750 : case 0xb:
751 0 : rRet += " \\[";
752 0 : break;
753 : case 0x4:
754 0 : if (nVariation==0)
755 0 : rRet += " lline ";
756 0 : else if (nVariation==1)
757 0 : rRet += " \\lline ";
758 0 : break;
759 : case 0x5:
760 0 : if (nVariation==0)
761 0 : rRet += " ldline ";
762 0 : else if (nVariation==1)
763 0 : rRet += " \\ldline ";
764 0 : break;
765 : case 0x6:
766 0 : if (nVariation == 0 || nVariation == 1)
767 0 : rRet += " left lfloor ";
768 0 : else if (nVariation==1)
769 0 : rRet += " left none ";
770 0 : break;
771 : case 0x7:
772 0 : if (nVariation==0)
773 0 : rRet += " lceil ";
774 0 : else if (nVariation==1)
775 0 : rRet += " \\lceil ";
776 0 : break;
777 : case 0x9:
778 : case 0xa:
779 0 : rRet += " \\]";
780 0 : break;
781 : case 0xc:
782 0 : rRet += " \\(";
783 0 : break;
784 : case 0xd:
785 0 : if (nPart == 0)
786 : {
787 0 : if (nVariation == 0)
788 0 : rRet += " sqrt";
789 : else
790 : {
791 0 : rRet += " nroot";
792 0 : sPush = rRet;
793 0 : rRet = OUString();
794 : }
795 : }
796 0 : rRet += " {";
797 0 : break;
798 : case 0xe:
799 0 : if (nPart == 0)
800 0 : rRet += " { ";
801 :
802 :
803 0 : if (nPart == 1)
804 0 : rRet += " over ";
805 0 : rRet += " {";
806 0 : break;
807 : case 0xf:
808 0 : nSubSupStartPos = rRet.getLength();
809 0 : if ((nVariation == 0) ||
810 0 : ((nVariation == 2) && (nPart==1)))
811 : {
812 0 : lcl_AppendDummyTerm(rRet);
813 0 : rRet += " rSup";
814 : }
815 0 : else if ((nVariation == 1) ||
816 0 : ((nVariation == 2) && (nPart==0)))
817 : {
818 0 : lcl_AppendDummyTerm(rRet);
819 0 : rRet += " rSub";
820 : }
821 0 : rRet += " {";
822 0 : break;
823 : case 0x10:
824 0 : if (nVariation == 0)
825 0 : rRet += " {underline ";
826 0 : else if (nVariation == 1)
827 0 : rRet += " {underline underline ";
828 0 : rRet += " {";
829 0 : break;
830 : case 0x11:
831 0 : if (nVariation == 0)
832 0 : rRet += " {overline ";
833 0 : else if (nVariation == 1)
834 0 : rRet += " {overline overline ";
835 0 : rRet += " {";
836 0 : break;
837 : case 0x12:
838 0 : if (nPart == 0)
839 : {
840 0 : if (nVariation == 0)
841 0 : rRet += " widevec ";//left arrow above
842 0 : else if (nVariation == 1)
843 0 : rRet += " widevec ";//left arrow below
844 0 : rRet += " {";
845 : }
846 0 : break;
847 : case 0x13:
848 0 : if (nPart == 0)
849 : {
850 0 : if (nVariation == 0)
851 0 : rRet += " widevec ";//right arrow above
852 0 : else if (nVariation == 1)
853 0 : rRet += " widevec ";//right arrow below
854 0 : rRet += " {";
855 : }
856 0 : break;
857 : case 0x14:
858 0 : if (nPart == 0)
859 : {
860 0 : if (nVariation == 0)
861 0 : rRet += " widevec ";//double arrow above
862 0 : else if (nVariation == 1)
863 0 : rRet += " widevec ";//double arrow below
864 0 : rRet += " {";
865 : }
866 0 : break;
867 : case 0x15:
868 0 : if (nPart == 0)
869 : {
870 0 : if ((nVariation == 3) || (nVariation == 4))
871 0 : rRet += " lInt";
872 : else
873 0 : rRet += " Int";
874 0 : if ( (nVariation != 0) && (nVariation != 3))
875 : {
876 0 : sPush = rRet;
877 0 : rRet = OUString();
878 : }
879 : }
880 0 : if (((nVariation == 1) ||
881 0 : (nVariation == 4)) && (nPart==1))
882 0 : rRet += " rSub";
883 0 : else if ((nVariation == 2) && (nPart==2))
884 0 : rRet += " rSup";
885 0 : else if ((nVariation == 2) && (nPart==1))
886 0 : rRet += " rSub";
887 0 : rRet += " {";
888 0 : break;
889 : case 0x16:
890 0 : if (nPart == 0)
891 : {
892 0 : if ((nVariation == 2) || (nVariation == 3))
893 0 : rRet += " llInt";
894 : else
895 0 : rRet += " iInt";
896 0 : if ( (nVariation != 0) && (nVariation != 2))
897 : {
898 0 : sPush = rRet;
899 0 : rRet = OUString();
900 : }
901 : }
902 0 : if (((nVariation == 1) ||
903 0 : (nVariation == 3)) && (nPart==1))
904 0 : rRet += " rSub";
905 0 : rRet += " {";
906 0 : break;
907 : case 0x17:
908 0 : if (nPart == 0)
909 : {
910 0 : if ((nVariation == 2) || (nVariation == 3))
911 0 : rRet += " lllInt";
912 : else
913 0 : rRet += " iiInt";
914 0 : if ( (nVariation != 0) && (nVariation != 2))
915 : {
916 0 : sPush = rRet;
917 0 : rRet = OUString();
918 : }
919 : }
920 0 : if (((nVariation == 1) ||
921 0 : (nVariation == 3)) && (nPart==1))
922 0 : rRet += " rSub";
923 0 : rRet += " {";
924 0 : break;
925 : case 0x18:
926 0 : if (nPart == 0)
927 : {
928 0 : if (nVariation == 2)
929 0 : rRet += " lInt";
930 : else
931 0 : rRet += " Int";
932 0 : sPush = rRet;
933 0 : rRet = OUString();
934 : }
935 0 : if (((nVariation == 1) ||
936 0 : (nVariation == 2)) && (nPart==1))
937 0 : rRet += " cSub";
938 0 : else if ((nVariation == 0) && (nPart==2))
939 0 : rRet += " cSup";
940 0 : else if ((nVariation == 0) && (nPart==1))
941 0 : rRet += " cSub";
942 0 : rRet += " {";
943 0 : break;
944 : case 0x19:
945 0 : if (nPart == 0)
946 : {
947 0 : if (nVariation == 0)
948 0 : rRet += " llInt";
949 : else
950 0 : rRet += " iInt";
951 0 : sPush = rRet;
952 0 : rRet = OUString();
953 : }
954 0 : if (nPart==1)
955 0 : rRet += " cSub";
956 0 : rRet += " {";
957 0 : break;
958 : case 0x1a:
959 0 : if (nPart == 0)
960 : {
961 0 : if (nVariation == 0)
962 0 : rRet += " lllInt";
963 : else
964 0 : rRet += " iiInt";
965 0 : sPush = rRet;
966 0 : rRet = OUString();
967 : }
968 0 : if (nPart==1)
969 0 : rRet += " cSub";
970 0 : rRet += " {";
971 0 : break;
972 : case 0x1b:
973 : case 0x1c:
974 0 : rRet += " {";
975 0 : break;
976 : case 0x1d:
977 0 : if (nPart == 0)
978 : {
979 0 : rRet += " Sum";
980 0 : if (nVariation != 2)
981 : {
982 0 : sPush = rRet;
983 0 : rRet = OUString();
984 : }
985 : }
986 0 : if ((nVariation == 0) && (nPart==1))
987 0 : rRet += " cSub";
988 0 : else if ((nVariation == 1) && (nPart==2))
989 0 : rRet += " cSup";
990 0 : else if ((nVariation == 1) && (nPart==1))
991 0 : rRet += " cSub";
992 0 : rRet += " {";
993 0 : break;
994 : case 0x1e:
995 0 : if (nPart == 0)
996 : {
997 0 : rRet += " Sum";
998 0 : sPush = rRet;
999 0 : rRet = OUString();
1000 : }
1001 0 : if ((nVariation == 0) && (nPart==1))
1002 0 : rRet += " rSub";
1003 0 : else if ((nVariation == 1) && (nPart==2))
1004 0 : rRet += " rSup";
1005 0 : else if ((nVariation == 1) && (nPart==1))
1006 0 : rRet += " rSub";
1007 0 : rRet += " {";
1008 0 : break;
1009 : case 0x1f:
1010 0 : if (nPart == 0)
1011 : {
1012 0 : rRet += " Prod";
1013 0 : if (nVariation != 2)
1014 : {
1015 0 : sPush = rRet;
1016 0 : rRet = OUString();
1017 : }
1018 : }
1019 0 : if ((nVariation == 0) && (nPart==1))
1020 0 : rRet += " cSub";
1021 0 : else if ((nVariation == 1) && (nPart==2))
1022 0 : rRet += " cSup";
1023 0 : else if ((nVariation == 1) && (nPart==1))
1024 0 : rRet += " cSub";
1025 0 : rRet += " {";
1026 0 : break;
1027 : case 0x20:
1028 0 : if (nPart == 0)
1029 : {
1030 0 : rRet += " Prod";
1031 0 : sPush = rRet;
1032 0 : rRet = OUString();
1033 : }
1034 0 : if ((nVariation == 0) && (nPart==1))
1035 0 : rRet += " rSub";
1036 0 : else if ((nVariation == 1) && (nPart==2))
1037 0 : rRet += " rSup";
1038 0 : else if ((nVariation == 1) && (nPart==1))
1039 0 : rRet += " rSub";
1040 0 : rRet += " {";
1041 0 : break;
1042 : case 0x21:
1043 0 : if (nPart == 0)
1044 : {
1045 0 : rRet += " coProd";
1046 0 : if (nVariation != 2)
1047 : {
1048 0 : sPush = rRet;
1049 0 : rRet = OUString();
1050 : }
1051 : }
1052 0 : if ((nVariation == 0) && (nPart==1))
1053 0 : rRet += " cSub";
1054 0 : else if ((nVariation == 1) && (nPart==2))
1055 0 : rRet += " cSup";
1056 0 : else if ((nVariation == 1) && (nPart==1))
1057 0 : rRet += " cSub";
1058 0 : rRet += " {";
1059 0 : break;
1060 : case 0x22:
1061 0 : if (nPart == 0)
1062 : {
1063 0 : rRet += " coProd";
1064 0 : sPush = rRet;
1065 0 : rRet = OUString();
1066 : }
1067 0 : if ((nVariation == 0) && (nPart==1))
1068 0 : rRet += " rSub";
1069 0 : else if ((nVariation == 1) && (nPart==2))
1070 0 : rRet += " rSup";
1071 0 : else if ((nVariation == 1) && (nPart==1))
1072 0 : rRet += " rSub";
1073 0 : rRet += " {";
1074 0 : break;
1075 : case 0x23:
1076 0 : if (nPart == 0)
1077 : {
1078 0 : rRet += " union"; //union
1079 0 : if (nVariation != 2)
1080 : {
1081 0 : sPush = rRet;
1082 0 : rRet = OUString();
1083 : }
1084 : }
1085 0 : if ((nVariation == 0) && (nPart==1))
1086 0 : rRet += " cSub";
1087 0 : else if ((nVariation == 1) && (nPart==2))
1088 0 : rRet += " cSup";
1089 0 : else if ((nVariation == 1) && (nPart==1))
1090 0 : rRet += " cSub";
1091 0 : rRet += " {";
1092 0 : break;
1093 : case 0x24:
1094 0 : if (nPart == 0)
1095 : {
1096 0 : rRet += " union"; //union
1097 0 : sPush = rRet;
1098 0 : rRet = OUString();
1099 : }
1100 0 : if ((nVariation == 0) && (nPart==1))
1101 0 : rRet += " rSub";
1102 0 : else if ((nVariation == 1) && (nPart==2))
1103 0 : rRet += " rSup";
1104 0 : else if ((nVariation == 1) && (nPart==1))
1105 0 : rRet += " rSub";
1106 0 : rRet += " {";
1107 0 : break;
1108 : case 0x25:
1109 0 : if (nPart == 0)
1110 : {
1111 0 : rRet += " intersect"; //intersect
1112 0 : if (nVariation != 2)
1113 : {
1114 0 : sPush = rRet;
1115 0 : rRet = OUString();
1116 : }
1117 : }
1118 0 : if ((nVariation == 0) && (nPart==1))
1119 0 : rRet += " cSub";
1120 0 : else if ((nVariation == 1) && (nPart==2))
1121 0 : rRet += " cSup";
1122 0 : else if ((nVariation == 1) && (nPart==1))
1123 0 : rRet += " cSub";
1124 0 : rRet += " {";
1125 0 : break;
1126 : case 0x26:
1127 0 : if (nPart == 0)
1128 : {
1129 0 : rRet += " intersect"; //intersect
1130 0 : sPush = rRet;
1131 0 : rRet = OUString();
1132 : }
1133 0 : if ((nVariation == 0) && (nPart==1))
1134 0 : rRet += " rSub";
1135 0 : else if ((nVariation == 1) && (nPart==2))
1136 0 : rRet += " rSup";
1137 0 : else if ((nVariation == 1) && (nPart==1))
1138 0 : rRet += " rSub";
1139 0 : rRet += " {";
1140 0 : break;
1141 : case 0x27:
1142 0 : if ((nVariation == 0) && (nPart==1))
1143 0 : rRet += " cSup";
1144 0 : else if ((nVariation == 1) && (nPart==1))
1145 0 : rRet += " cSub";
1146 0 : else if ((nVariation == 2) && (nPart==1))
1147 0 : rRet += " cSub";
1148 0 : else if ((nVariation == 2) && (nPart==2))
1149 0 : rRet += " cSup";
1150 0 : rRet += " {";
1151 0 : break;
1152 : case 0x28:
1153 0 : if (nVariation == 0)
1154 : {
1155 0 : if (nPart == 0)
1156 : {
1157 0 : sPush = rRet;
1158 0 : rRet = OUString();
1159 : }
1160 : }
1161 0 : rRet += " {";
1162 0 : if (nVariation == 0)
1163 : {
1164 0 : if (nPart == 1)
1165 0 : rRet += "alignr ";
1166 : }
1167 0 : if (nPart == 0)
1168 0 : rRet += "\\lline ";
1169 0 : if (nVariation == 1)
1170 0 : rRet += "overline ";
1171 0 : break;
1172 : case 0x29:
1173 0 : rRet += " {";
1174 0 : break;
1175 : case 0x2a:
1176 0 : if (nPart == 0)
1177 : {
1178 0 : sPush = rRet;
1179 0 : rRet = OUString();
1180 : }
1181 0 : if ((nVariation == 0) && (nPart==0))
1182 0 : rRet += " rSup";
1183 0 : else if ((nVariation == 2) && (nPart==1))
1184 0 : rRet += " rSup";
1185 0 : else if ((nVariation == 1) && (nPart==0))
1186 0 : rRet += " rSub";
1187 0 : else if ((nVariation == 2) && (nPart==0))
1188 0 : rRet += " rSub";
1189 0 : rRet += " {";
1190 0 : break;
1191 : case 0x2b:
1192 0 : if (nPart == 0)
1193 : {
1194 0 : sPush = rRet;
1195 0 : rRet = OUString();
1196 : }
1197 0 : if ((nVariation == 0) && (nPart==0))
1198 0 : rRet += " cSup";
1199 0 : else if ((nVariation == 2) && (nPart==1))
1200 0 : rRet += " cSup";
1201 0 : else if ((nVariation == 1) && (nPart==0))
1202 0 : rRet += " cSub";
1203 0 : else if ((nVariation == 2) && (nPart==0))
1204 0 : rRet += " cSub";
1205 0 : rRet += " {";
1206 0 : break;
1207 : case 0x2c:
1208 0 : if (nPart == 0)
1209 0 : rRet += "\"\"";
1210 0 : if ((nVariation == 0)
1211 0 : || ((nVariation == 2) && (nPart==1)))
1212 0 : rRet += " lSup";
1213 0 : else if ((nVariation == 1)
1214 0 : || ((nVariation == 2) && (nPart==0)))
1215 0 : rRet += " lSub";
1216 0 : rRet += " {";
1217 0 : break;
1218 : case 0x2d:
1219 0 : if (nVariation==0)
1220 : {
1221 0 : if (nPart == 0)
1222 0 : rRet += " langle ";
1223 : }
1224 0 : else if (nVariation==1)
1225 : {
1226 0 : rRet += " \\langle ";
1227 0 : newline--;
1228 : }
1229 0 : else if (nVariation==2)
1230 : {
1231 0 : rRet += " \\lline ";
1232 0 : newline--;
1233 : }
1234 0 : break;
1235 : case 0x2e:
1236 0 : if (nVariation == 0)
1237 0 : rRet += " widevec ";//left below
1238 0 : else if (nVariation == 1)
1239 0 : rRet += " widevec ";//right below
1240 0 : else if (nVariation == 2)
1241 0 : rRet += " widevec ";//double headed below
1242 0 : rRet += " {";
1243 0 : break;
1244 : case 0x2f:
1245 0 : if (nVariation == 0)
1246 0 : rRet += " widevec ";//left above
1247 0 : else if (nVariation == 1)
1248 0 : rRet += " widevec ";//right above
1249 0 : else if (nVariation == 2)
1250 0 : rRet += " widevec ";//double headed above
1251 0 : rRet += " {";
1252 0 : break;
1253 : default:
1254 0 : break;
1255 : }
1256 0 : sal_Int16 nOldCurSize=nCurSize;
1257 0 : sal_Int32 nSizeStartPos = rRet.getLength();
1258 0 : HandleSize(nLSize,nDSize,nSetSize);
1259 0 : nRet = HandleRecords(nLevel+1);
1260 0 : while (nSetSize)
1261 : {
1262 0 : bool bOk=false;
1263 0 : sal_Int32 nI = rRet.lastIndexOf('{');
1264 0 : if (nI != -1)
1265 : {
1266 0 : for(nI=nI+1;nI<rRet.getLength();nI++)
1267 0 : if (rRet[nI] != ' ')
1268 : {
1269 0 : bOk=true;
1270 0 : break;
1271 : }
1272 : }
1273 : else
1274 0 : bOk=true;
1275 :
1276 0 : if (bOk)
1277 0 : rRet += "} ";
1278 : else
1279 0 : rRet = rRet.replaceAt( nSizeStartPos, rRet.getLength(), "" );
1280 0 : nSetSize--;
1281 0 : nCurSize=nOldCurSize;
1282 : }
1283 :
1284 :
1285 : HandleMatrixSeparator(nMatrixRows,nMatrixCols,
1286 0 : nCurCol,nCurRow);
1287 :
1288 0 : switch (nSelector)
1289 : {
1290 : case 0x0:
1291 0 : if (nVariation==0)
1292 0 : rRet += " rangle ";
1293 0 : else if (nVariation==2)
1294 0 : rRet += " \\rangle ";
1295 0 : break;
1296 : case 0x1:
1297 0 : if (nVariation==0)
1298 0 : rRet += " right )";
1299 0 : else if (nVariation==2)
1300 0 : rRet += "\\)";
1301 0 : break;
1302 : case 0x2:
1303 0 : if ((nVariation==0) || (nVariation==2))
1304 0 : rRet += " right rbrace ";
1305 : else
1306 0 : rRet += " right none ";
1307 0 : break;
1308 : case 0x3:
1309 0 : if (nVariation==0)
1310 0 : rRet += " right ]";
1311 0 : else if (nVariation==2)
1312 0 : rRet += "\\]";
1313 0 : break;
1314 : case 0x4:
1315 0 : if (nVariation==0)
1316 0 : rRet += " rline ";
1317 0 : else if (nVariation==2)
1318 0 : rRet += " \\rline ";
1319 0 : break;
1320 : case 0x5:
1321 0 : if (nVariation==0)
1322 0 : rRet += " rdline ";
1323 0 : else if (nVariation==2)
1324 0 : rRet += " \\rdline ";
1325 0 : break;
1326 : case 0x6:
1327 0 : if (nVariation == 0 || nVariation == 2)
1328 0 : rRet += " right rfloor ";
1329 0 : else if (nVariation==2)
1330 0 : rRet += " right none ";
1331 0 : break;
1332 : case 0x7:
1333 0 : if (nVariation==0)
1334 0 : rRet += " rceil ";
1335 0 : else if (nVariation==2)
1336 0 : rRet += " \\rceil ";
1337 0 : break;
1338 : case 0x8:
1339 : case 0xa:
1340 0 : rRet += "\\[";
1341 0 : break;
1342 : case 0x9:
1343 : case 0xc:
1344 0 : rRet += "\\]";
1345 0 : break;
1346 : case 0xd:
1347 0 : rRet += "} ";
1348 0 : if (nVariation == 1)
1349 : {
1350 0 : if (nPart == 0)
1351 : {
1352 0 : newline--;
1353 0 : sMainTerm = rRet;
1354 0 : rRet = OUString();
1355 : }
1356 : else
1357 : {
1358 0 : sPush += rRet;
1359 0 : rRet = sPush;
1360 0 : rRet += sMainTerm;
1361 : }
1362 : }
1363 : else
1364 : {
1365 0 : if (nPart == 0)
1366 0 : newline--;
1367 : }
1368 0 : nPart++;
1369 0 : break;
1370 : case 0xb:
1371 0 : rRet += "\\)";
1372 0 : break;
1373 : case 0xe:
1374 0 : rRet += "} ";
1375 0 : if (nPart == 0)
1376 0 : newline--;
1377 : else
1378 0 : rRet += "} ";
1379 0 : nPart++;
1380 0 : break;
1381 : case 0xf:
1382 : {
1383 0 : if ((nPart == 0) &&
1384 0 : ((nVariation == 2) || (nVariation == 1)))
1385 0 : newline--;
1386 :
1387 0 : bool bOk=false;
1388 0 : sal_Int32 nI = rRet.lastIndexOf('{');
1389 0 : if (nI != -1)
1390 : {
1391 0 : for(nI=nI+1;nI<rRet.getLength();nI++)
1392 0 : if (rRet[nI] != ' ')
1393 : {
1394 0 : bOk=true;
1395 0 : break;
1396 : }
1397 : }
1398 : else
1399 0 : bOk=true;
1400 :
1401 0 : if (bOk)
1402 0 : rRet += "} ";
1403 : else
1404 0 : rRet = rRet.replaceAt(nSubSupStartPos, rRet.getLength(), "");
1405 0 : nPart++;
1406 : }
1407 0 : break;
1408 : case 0x2c:
1409 0 : if ((nPart == 0) &&
1410 0 : ((nVariation == 2) || (nVariation == 1)))
1411 0 : newline--;
1412 0 : rRet += "} ";
1413 0 : nPart++;
1414 0 : break;
1415 : case 0x2e:
1416 : case 0x2f:
1417 0 : rRet += "} ";
1418 0 : break;
1419 : case 0x10:
1420 : case 0x11:
1421 0 : rRet += "}} ";
1422 0 : break;
1423 : case 0x12:
1424 : case 0x13:
1425 : case 0x14:
1426 0 : if (nPart == 0)
1427 : {
1428 0 : newline--;
1429 0 : rRet += "} ";
1430 : }
1431 0 : nPart++;
1432 0 : break;
1433 : case 0x1b:
1434 0 : rRet += "} ";
1435 0 : if (nPart == 0)
1436 : {
1437 0 : newline--;
1438 0 : rRet += "overbrace";
1439 : }
1440 0 : nPart++;
1441 0 : break;
1442 : case 0x1c:
1443 0 : rRet += "} ";
1444 0 : if (nPart == 0)
1445 : {
1446 0 : newline--;
1447 0 : rRet += "underbrace";
1448 : }
1449 0 : nPart++;
1450 0 : break;
1451 : case 0x27:
1452 0 : if (nPart==0)
1453 0 : newline--;
1454 0 : else if ((nPart==1) &&
1455 0 : ((nVariation == 2) || (nVariation == 1)))
1456 0 : newline--;
1457 0 : rRet += "} ";
1458 0 : nPart++;
1459 0 : break;
1460 : case 0x28:
1461 0 : rRet += "} ";
1462 0 : if (nVariation == 0)
1463 : {
1464 0 : if (nPart == 0)
1465 : {
1466 0 : sMainTerm = rRet;
1467 0 : rRet = OUString();
1468 : }
1469 : else
1470 : {
1471 0 : sPush += rRet;
1472 0 : rRet = sPush;
1473 0 : rRet += " over ";
1474 0 : rRet += sMainTerm;
1475 : }
1476 : }
1477 0 : if (nPart == 0)
1478 0 : newline--;
1479 0 : nPart++;
1480 0 : break;
1481 : case 0x29:
1482 0 : rRet += "} ";
1483 0 : if (nPart == 0)
1484 : {
1485 0 : newline--;
1486 0 : switch (nVariation)
1487 : {
1488 : case 1:
1489 0 : rRet += "slash";
1490 0 : break;
1491 : default:
1492 0 : rRet += "wideslash";
1493 0 : break;
1494 : }
1495 : }
1496 0 : nPart++;
1497 0 : break;
1498 : case 0x1d:
1499 : case 0x1e:
1500 : case 0x1f:
1501 : case 0x20:
1502 : case 0x21:
1503 : case 0x22:
1504 : case 0x23:
1505 : case 0x24:
1506 : case 0x25:
1507 : case 0x26:
1508 0 : rRet += "} ";
1509 0 : if (nPart == 0)
1510 : {
1511 0 : if (nVariation != 2)
1512 : {
1513 0 : sMainTerm = rRet;
1514 0 : rRet = OUString();
1515 : }
1516 0 : newline--;
1517 : }
1518 0 : else if ((nPart == 1) && (nVariation == 0))
1519 : {
1520 0 : sPush += rRet;
1521 0 : rRet = sPush;
1522 0 : rRet += sMainTerm;
1523 0 : newline--;
1524 : }
1525 0 : else if ((nPart == 1) && (nVariation == 1))
1526 0 : newline--;
1527 0 : else if ((nPart == 2) && (nVariation == 1))
1528 : {
1529 0 : sPush += rRet;
1530 0 : rRet = sPush;
1531 0 : rRet += sMainTerm;
1532 0 : newline--;
1533 : }
1534 0 : nPart++;
1535 0 : break;
1536 : case 0x15:
1537 0 : rRet += "} ";
1538 0 : if (nPart == 0)
1539 : {
1540 0 : if ((nVariation != 0) && (nVariation != 3))
1541 : {
1542 0 : sMainTerm = rRet;
1543 0 : rRet = OUString();
1544 : }
1545 0 : newline--;
1546 : }
1547 0 : else if ((nPart == 1) &&
1548 0 : ((nVariation == 1) || (nVariation==4)))
1549 : {
1550 0 : sPush += rRet;
1551 0 : rRet = sPush;
1552 0 : rRet += sMainTerm;
1553 0 : newline--;
1554 : }
1555 0 : else if ((nPart == 1) && (nVariation == 2))
1556 0 : newline--;
1557 0 : else if ((nPart == 2) && (nVariation == 2))
1558 : {
1559 0 : sPush += rRet;
1560 0 : rRet = sPush;
1561 0 : rRet += sMainTerm;
1562 0 : newline--;
1563 : }
1564 0 : nPart++;
1565 0 : break;
1566 : case 0x16:
1567 : case 0x17:
1568 0 : rRet += "} ";
1569 0 : if (nPart == 0)
1570 : {
1571 0 : if ((nVariation != 0) && (nVariation != 2))
1572 : {
1573 0 : sMainTerm = rRet;
1574 0 : rRet = OUString();
1575 : }
1576 0 : newline--;
1577 : }
1578 0 : else if ((nPart == 1) &&
1579 0 : ((nVariation == 1) || (nVariation==3)))
1580 : {
1581 0 : sPush += rRet;
1582 0 : rRet = sPush;
1583 0 : rRet += sMainTerm;
1584 0 : newline--;
1585 : }
1586 0 : nPart++;
1587 0 : break;
1588 : case 0x18:
1589 0 : rRet += "} ";
1590 0 : if (nPart == 0)
1591 : {
1592 0 : sMainTerm = rRet;
1593 0 : rRet = OUString();
1594 0 : newline--;
1595 : }
1596 0 : else if ((nPart == 1) &&
1597 0 : ((nVariation == 1) || (nVariation==2)))
1598 : {
1599 0 : sPush += rRet;
1600 0 : rRet = sPush;
1601 0 : rRet += sMainTerm;
1602 0 : newline--;
1603 : }
1604 0 : else if ((nPart == 1) && (nVariation == 0))
1605 0 : newline--;
1606 0 : else if ((nPart == 2) && (nVariation == 0))
1607 : {
1608 0 : sPush += rRet;
1609 0 : rRet = sPush;
1610 0 : rRet += sMainTerm;
1611 0 : newline--;
1612 : }
1613 0 : nPart++;
1614 0 : break;
1615 : case 0x19:
1616 : case 0x1a:
1617 0 : rRet += "} ";
1618 0 : if (nPart == 0)
1619 : {
1620 0 : sMainTerm = rRet;
1621 0 : rRet = OUString();
1622 0 : newline--;
1623 : }
1624 0 : else if (nPart == 1)
1625 : {
1626 0 : sPush += rRet;
1627 0 : rRet = sPush;
1628 0 : rRet += sMainTerm;
1629 0 : newline--;
1630 : }
1631 0 : nPart++;
1632 0 : break;
1633 : case 0x2a:
1634 : case 0x2b:
1635 0 : rRet += "} ";
1636 :
1637 0 : if ((nPart == 0) &&
1638 0 : ((nVariation == 0) || (nVariation == 1)))
1639 : {
1640 0 : sMainTerm = rRet;
1641 0 : rRet = OUString();
1642 0 : newline--;
1643 : }
1644 0 : else if ((nPart == 0) && (nVariation == 2))
1645 0 : newline--;
1646 0 : else if ((nPart == 1) && (nVariation == 2))
1647 : {
1648 0 : sMainTerm = rRet;
1649 0 : rRet = OUString();
1650 0 : newline--;
1651 : }
1652 0 : else if ((nPart == 2) || ((((nPart == 1) &&
1653 0 : (nVariation == 0)) || (nVariation == 1))))
1654 : {
1655 0 : sPush+=rRet;
1656 0 : rRet = sPush;
1657 0 : rRet += sMainTerm;
1658 : }
1659 0 : nPart++;
1660 0 : break;
1661 : case 0x2d:
1662 0 : if (nVariation==0)
1663 : {
1664 0 : if (nPart == 0)
1665 : {
1666 0 : newline--; //there is another term to arrive
1667 0 : rRet += " mline ";
1668 : }
1669 : else
1670 0 : rRet += " rangle ";
1671 : }
1672 0 : else if (nVariation==1)
1673 0 : rRet += " \\lline ";
1674 0 : else if (nVariation==2)
1675 0 : rRet += " \\rangle ";
1676 0 : nPart++;
1677 0 : break;
1678 : default:
1679 0 : break;
1680 : }
1681 0 : bSilent = true; //Skip the optional brackets and/or
1682 : //symbols that follow some of these
1683 : //records. Foo Data.
1684 :
1685 : /*In matrices and piles we cannot separate equation
1686 : *lines with the newline keyword*/
1687 0 : if (nMatrixCols==0)
1688 0 : newline++;
1689 : }
1690 : }
1691 0 : break;
1692 : case CHAR:
1693 0 : if (xfLMOVE(nTag))
1694 0 : HandleNudge();
1695 : nRet = HandleChar(nTextStart,nSetSize,nLevel,nTag,nSelector,
1696 0 : nVariation,bSilent);
1697 0 : break;
1698 : case TMPL:
1699 0 : if (xfLMOVE(nTag))
1700 0 : HandleNudge();
1701 : nRet = HandleTemplate(nLevel,nSelector,nVariation,
1702 0 : nLastTemplateBracket);
1703 0 : break;
1704 : case PILE:
1705 0 : if (xfLMOVE(nTag))
1706 0 : HandleNudge();
1707 0 : nRet = HandlePile(nSetAlign,nLevel,nSelector,nVariation);
1708 0 : HandleMatrixSeparator(nMatrixRows,nMatrixCols,nCurCol,nCurRow);
1709 0 : break;
1710 : case MATRIX:
1711 0 : if (xfLMOVE(nTag))
1712 0 : HandleNudge();
1713 0 : nRet = HandleMatrix(nLevel,nSelector,nVariation);
1714 0 : HandleMatrixSeparator(nMatrixRows,nMatrixCols,nCurCol,nCurRow);
1715 0 : break;
1716 : case EMBEL:
1717 0 : if (xfLMOVE(nTag))
1718 0 : HandleNudge();
1719 0 : HandleEmblishments();
1720 0 : break;
1721 : case RULER:
1722 0 : pS->ReadUChar( nTabStops );
1723 0 : for (i=0;i<nTabStops;i++)
1724 : {
1725 0 : pS->ReadUChar( nTabType );
1726 0 : pS->ReadUInt16( nTabOffset );
1727 : }
1728 : SAL_WARN("starmath", "Not seen in the wild Equation Ruler Field");
1729 0 : break;
1730 : case FONT:
1731 : {
1732 0 : MathTypeFont aFont;
1733 0 : pS->ReadUChar( aFont.nTface );
1734 : /*
1735 : The typeface number is the negative (which makes it
1736 : positive) of the typeface value (unbiased) that appears in
1737 : CHAR records that might follow a given FONT record
1738 : */
1739 0 : aFont.nTface = 128-aFont.nTface;
1740 0 : pS->ReadUChar( aFont.nStyle );
1741 0 : aUserStyles.insert(aFont);
1742 0 : std::vector<sal_Char> aSeq;
1743 : while(true)
1744 : {
1745 0 : sal_Char nChar8(0);
1746 0 : pS->ReadChar( nChar8 );
1747 0 : if (nChar8 == 0)
1748 0 : break;
1749 0 : aSeq.push_back(nChar8);
1750 0 : }
1751 : // Do nothing to the font name now in aSeq!?
1752 : }
1753 0 : break;
1754 : case SIZE:
1755 0 : HandleSetSize();
1756 0 : break;
1757 : case 10:
1758 : case 11:
1759 : case 12:
1760 : case 13:
1761 : case 14:
1762 0 : nLSize=nRecord-10;
1763 0 : break;
1764 : case END:
1765 : default:
1766 0 : break;
1767 : }
1768 : }
1769 0 : while (nRecord != END && !pS->IsEof());
1770 0 : while (nSetSize)
1771 : {
1772 0 : rRet += "}";
1773 0 : nSetSize--;
1774 : }
1775 0 : return nRet;
1776 : }
1777 :
1778 : /*Simply determine if we are at the end of a record or the end of a line,
1779 : *with fiddley logic to see if we are in a matrix or a pile or neither
1780 :
1781 : Note we cannot tell until after the event that this is the last entry
1782 : of a pile, so we must strip the last separator of a pile after this
1783 : is detected in the PILE handler
1784 : */
1785 0 : void MathType::HandleMatrixSeparator(int nMatrixRows,int nMatrixCols,
1786 : int &rCurCol,int &rCurRow)
1787 : {
1788 0 : if (nMatrixRows!=0)
1789 : {
1790 0 : if (rCurCol == nMatrixCols-1)
1791 : {
1792 0 : if (rCurRow != nMatrixRows-1)
1793 0 : rRet += " {} ##\n";
1794 0 : if (nMatrixRows!=-1)
1795 : {
1796 0 : rCurCol=0;
1797 0 : rCurRow++;
1798 : }
1799 : }
1800 : else
1801 : {
1802 0 : rRet += " {} # ";
1803 0 : if (nMatrixRows!=-1)
1804 0 : rCurCol++;
1805 : else
1806 0 : rRet += "\n";
1807 : }
1808 : }
1809 0 : }
1810 :
1811 : /* set the alignment of the following term, but starmath currently
1812 : * cannot handle vertical alignment */
1813 0 : void MathType::HandleAlign(sal_uInt8 nHorAlign, sal_uInt8 /*nVAlign*/, int &rSetAlign)
1814 : {
1815 0 : switch(nHorAlign)
1816 : {
1817 : case 1:
1818 : default:
1819 0 : rRet += "alignl {";
1820 0 : break;
1821 : case 2:
1822 0 : rRet += "alignc {";
1823 0 : break;
1824 : case 3:
1825 0 : rRet += "alignr {";
1826 0 : break;
1827 : }
1828 0 : rSetAlign++;
1829 0 : }
1830 :
1831 : /* set size of text, complexity due to overuse of signedness as a flag
1832 : * indicator by mathtype file format*/
1833 0 : sal_Bool MathType::HandleSize(sal_Int16 nLstSize,sal_Int16 nDefSize, int &rSetSize)
1834 : {
1835 0 : bool bRet=false;
1836 0 : if (nLstSize < 0)
1837 : {
1838 0 : if ((-nLstSize/32 != nDefaultSize) && (-nLstSize/32 != nCurSize))
1839 : {
1840 0 : if (rSetSize)
1841 : {
1842 0 : rSetSize--;
1843 0 : rRet += "}";
1844 0 : bRet=true;
1845 : }
1846 0 : if (-nLstSize/32 != nLastSize)
1847 : {
1848 0 : nLastSize = nCurSize;
1849 0 : rRet += " size ";
1850 0 : rRet += OUString::number(-nLstSize/32);
1851 0 : rRet += "{";
1852 0 : bRet=true;
1853 0 : rSetSize++;
1854 : }
1855 0 : nCurSize = -nLstSize/32;
1856 : }
1857 : }
1858 : else
1859 : {
1860 : /*sizetable should theoreticaly be filled with the default sizes
1861 : *of the various font groupings matching starmaths equivalents
1862 : in aTypeFaces, and a test would be done to see if the new font
1863 : size would be the same as what starmath would have chosen for
1864 : itself anyway in which case the size setting could be ignored*/
1865 0 : nLstSize = aSizeTable[nLstSize];
1866 0 : nLstSize = nLstSize + nDefSize;
1867 0 : if (nLstSize != nCurSize)
1868 : {
1869 0 : if (rSetSize)
1870 : {
1871 0 : rSetSize--;
1872 0 : rRet += "}";
1873 0 : bRet=true;
1874 : }
1875 0 : if (nLstSize != nLastSize)
1876 : {
1877 0 : nLastSize = nCurSize;
1878 0 : rRet += " size ";
1879 0 : rRet += OUString::number(nLstSize);
1880 0 : rRet += "{";
1881 0 : bRet=true;
1882 0 : rSetSize++;
1883 : }
1884 0 : nCurSize = nLstSize;
1885 : }
1886 : }
1887 0 : return bRet;
1888 : }
1889 :
1890 0 : int MathType::ConvertFromStarMath( SfxMedium& rMedium )
1891 : {
1892 0 : if (!pTree)
1893 0 : return 0;
1894 :
1895 0 : SvStream *pStream = rMedium.GetOutStream();
1896 0 : if ( pStream )
1897 : {
1898 0 : SvStorageRef pStor = new SotStorage( pStream, false );
1899 :
1900 : SvGlobalName aGName(0x0002ce02L, 0x0000, 0x0000,0xc0,0x00,
1901 0 : 0x00,0x00,0x00,0x00,0x00,0x46 );
1902 0 : pStor->SetClass( aGName, 0, OUString("Microsoft Equation 3.0"));
1903 :
1904 : static sal_uInt8 const aCompObj[] = {
1905 : 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
1906 : 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0xCE, 0x02, 0x00,
1907 : 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
1908 : 0x00, 0x00, 0x00, 0x46, 0x17, 0x00, 0x00, 0x00,
1909 : 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
1910 : 0x74, 0x20, 0x45, 0x71, 0x75, 0x61, 0x74, 0x69,
1911 : 0x6F, 0x6E, 0x20, 0x33, 0x2E, 0x30, 0x00, 0x0C,
1912 : 0x00, 0x00, 0x00, 0x44, 0x53, 0x20, 0x45, 0x71,
1913 : 0x75, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x0B,
1914 : 0x00, 0x00, 0x00, 0x45, 0x71, 0x75, 0x61, 0x74,
1915 : 0x69, 0x6F, 0x6E, 0x2E, 0x33, 0x00, 0xF4, 0x39,
1916 : 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1917 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1918 : };
1919 0 : SvStorageStreamRef xStor( pStor->OpenSotStream(OUString("\1CompObj")));
1920 0 : xStor->Write(aCompObj,sizeof(aCompObj));
1921 :
1922 : static sal_uInt8 const aOle[] = {
1923 : 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
1924 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1925 : 0x00, 0x00, 0x00, 0x00
1926 : };
1927 0 : SvStorageStreamRef xStor2( pStor->OpenSotStream(OUString("\1Ole")));
1928 0 : xStor2->Write(aOle,sizeof(aOle));
1929 0 : xStor.Clear();
1930 0 : xStor2.Clear();
1931 :
1932 0 : SvStorageStreamRef xSrc = pStor->OpenSotStream(OUString("Equation Native"));
1933 0 : if ( (!xSrc.Is()) || (SVSTREAM_OK != xSrc->GetError()))
1934 0 : return 0;
1935 :
1936 0 : pS = &xSrc;
1937 0 : pS->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
1938 :
1939 0 : pS->SeekRel(EQNOLEFILEHDR_SIZE); //Skip 28byte Header and fill it in later
1940 0 : pS->WriteUChar( sal_uInt8(0x03) );
1941 0 : pS->WriteUChar( sal_uInt8(0x01) );
1942 0 : pS->WriteUChar( sal_uInt8(0x01) );
1943 0 : pS->WriteUChar( sal_uInt8(0x03) );
1944 0 : pS->WriteUChar( sal_uInt8(0x00) );
1945 0 : sal_uInt32 nSize = pS->Tell();
1946 0 : nPendingAttributes=0;
1947 :
1948 0 : HandleNodes(pTree);
1949 0 : pS->WriteUChar( sal_uInt8(END) );
1950 :
1951 0 : nSize = pS->Tell()-nSize;
1952 0 : pS->Seek(0);
1953 0 : EQNOLEFILEHDR aHdr(nSize+4+1);
1954 0 : aHdr.Write(pS);
1955 :
1956 0 : pStor->Commit();
1957 : }
1958 :
1959 0 : return 1;
1960 : }
1961 :
1962 :
1963 0 : sal_uInt8 MathType::HandleNodes(SmNode *pNode,int nLevel)
1964 : {
1965 0 : bool bRet=false;
1966 0 : switch(pNode->GetType())
1967 : {
1968 : case NATTRIBUT:
1969 0 : HandleAttributes(pNode,nLevel);
1970 0 : break;
1971 : case NTEXT:
1972 0 : HandleText(pNode,nLevel);
1973 0 : break;
1974 : case NVERTICAL_BRACE:
1975 0 : HandleVerticalBrace(pNode,nLevel);
1976 0 : break;
1977 : case NBRACE:
1978 0 : HandleBrace(pNode,nLevel);
1979 0 : break;
1980 : case NOPER:
1981 0 : HandleOperator(pNode,nLevel);
1982 0 : break;
1983 : case NBINVER:
1984 0 : HandleFractions(pNode,nLevel);
1985 0 : break;
1986 : case NROOT:
1987 0 : HandleRoot(pNode,nLevel);
1988 0 : break;
1989 : case NSPECIAL:
1990 : {
1991 0 : SmTextNode *pText=(SmTextNode *)pNode;
1992 : //if the token str and the result text are the same then this
1993 : //is to be seen as text, else assume it's a mathchar
1994 0 : if (pText->GetText() == pText->GetToken().aText)
1995 0 : HandleText(pText,nLevel);
1996 : else
1997 0 : HandleMath(pText,nLevel);
1998 : }
1999 0 : break;
2000 : case NMATH:
2001 : case NMATHIDENT:
2002 0 : HandleMath(pNode,nLevel);
2003 0 : break;
2004 : case NSUBSUP:
2005 0 : HandleSubSupScript(pNode,nLevel);
2006 0 : break;
2007 : case NEXPRESSION:
2008 : {
2009 0 : sal_uInt16 nSize = pNode->GetNumSubNodes();
2010 0 : for (sal_uInt16 i = 0; i < nSize; i++)
2011 0 : if (SmNode *pTemp = pNode->GetSubNode(i))
2012 0 : HandleNodes(pTemp,nLevel+1);
2013 : }
2014 0 : break;
2015 : case NTABLE:
2016 : //Root Node, PILE equivalent, i.e. vertical stack
2017 0 : HandleTable(pNode,nLevel);
2018 0 : break;
2019 : case NMATRIX:
2020 0 : HandleSmMatrix((SmMatrixNode *)pNode,nLevel);
2021 0 : break;
2022 : case NLINE:
2023 : {
2024 0 : pS->WriteUChar( sal_uInt8(0x0a) );
2025 0 : pS->WriteUChar( sal_uInt8(LINE) );
2026 0 : sal_uInt16 nSize = pNode->GetNumSubNodes();
2027 0 : for (sal_uInt16 i = 0; i < nSize; i++)
2028 0 : if (SmNode *pTemp = pNode->GetSubNode(i))
2029 0 : HandleNodes(pTemp,nLevel+1);
2030 0 : pS->WriteUChar( sal_uInt8(END) );
2031 : }
2032 0 : break;
2033 : case NALIGN:
2034 0 : HandleMAlign(pNode,nLevel);
2035 0 : break;
2036 : case NBLANK:
2037 0 : pS->WriteUChar( sal_uInt8(CHAR) );
2038 0 : pS->WriteUChar( sal_uInt8(0x98) );
2039 0 : if (pNode->GetToken().eType == TSBLANK)
2040 0 : pS->WriteUInt16( sal_uInt16(0xEB04) );
2041 : else
2042 0 : pS->WriteUInt16( sal_uInt16(0xEB05) );
2043 0 : break;
2044 : default:
2045 : {
2046 0 : sal_uInt16 nSize = pNode->GetNumSubNodes();
2047 0 : for (sal_uInt16 i = 0; i < nSize; i++)
2048 0 : if (SmNode *pTemp = pNode->GetSubNode(i))
2049 0 : HandleNodes(pTemp,nLevel+1);
2050 : }
2051 0 : break;
2052 : }
2053 0 : return bRet;
2054 : }
2055 :
2056 :
2057 0 : int MathType::StartTemplate(sal_uInt16 nSelector,sal_uInt16 nVariation)
2058 : {
2059 0 : int nOldPending=nPendingAttributes;
2060 0 : pS->WriteUChar( sal_uInt8(TMPL) ); //Template
2061 0 : pS->WriteUChar( sal_uInt8(nSelector) ); //selector
2062 0 : pS->WriteUChar( sal_uInt8(nVariation) ); //variation
2063 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2064 0 : pS->WriteUChar( sal_uInt8(LINE) );
2065 : //theres just no way we can now handle any character
2066 : //attributes (from mathtypes perspective) centered
2067 : //over an expression but above template attribute
2068 : //such as widevec and similar constructs
2069 : //we have to drop them
2070 0 : nPendingAttributes=0;
2071 0 : return nOldPending;
2072 : }
2073 :
2074 0 : void MathType::EndTemplate(int nOldPendingAttributes)
2075 : {
2076 0 : pS->WriteUChar( sal_uInt8(END) ); //end line
2077 0 : pS->WriteUChar( sal_uInt8(END) ); //end template
2078 0 : nPendingAttributes=nOldPendingAttributes;
2079 0 : }
2080 :
2081 :
2082 0 : void MathType::HandleSmMatrix(SmMatrixNode *pMatrix,int nLevel)
2083 : {
2084 0 : pS->WriteUChar( sal_uInt8(MATRIX) );
2085 0 : pS->WriteUChar( sal_uInt8(0x00) ); //vAlign ?
2086 0 : pS->WriteUChar( sal_uInt8(0x00) ); //h_just
2087 0 : pS->WriteUChar( sal_uInt8(0x00) ); //v_just
2088 0 : pS->WriteUChar( sal_uInt8(pMatrix->GetNumRows()) ); //v_just
2089 0 : pS->WriteUChar( sal_uInt8(pMatrix->GetNumCols()) ); //v_just
2090 0 : int nBytes=(pMatrix->GetNumRows()+1)*2/8;
2091 0 : if (((pMatrix->GetNumRows()+1)*2)%8)
2092 0 : nBytes++;
2093 0 : for (sal_uInt16 j = 0; j < nBytes; j++)
2094 0 : pS->WriteUChar( sal_uInt8(0x00) ); //row_parts
2095 0 : nBytes=(pMatrix->GetNumCols()+1)*2/8;
2096 0 : if (((pMatrix->GetNumCols()+1)*2)%8)
2097 0 : nBytes++;
2098 0 : for (sal_uInt16 k = 0; k < nBytes; k++)
2099 0 : pS->WriteUChar( sal_uInt8(0x00) ); //col_parts
2100 0 : sal_uInt16 nSize = pMatrix->GetNumSubNodes();
2101 0 : for (sal_uInt16 i = 0; i < nSize; i++)
2102 0 : if (SmNode *pTemp = pMatrix->GetSubNode(i))
2103 : {
2104 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2105 0 : HandleNodes(pTemp,nLevel+1);
2106 0 : pS->WriteUChar( sal_uInt8(END) ); //end line
2107 : }
2108 0 : pS->WriteUChar( sal_uInt8(END) );
2109 0 : }
2110 :
2111 :
2112 : //Root Node, PILE equivalent, i.e. vertical stack
2113 0 : void MathType::HandleTable(SmNode *pNode,int nLevel)
2114 : {
2115 0 : sal_uInt16 nSize = pNode->GetNumSubNodes();
2116 : //The root of the starmath is a table, if
2117 : //we convert this them each iteration of
2118 : //conversion from starmath to mathtype will
2119 : //add an extra unnecessary level to the
2120 : //mathtype output stack which would grow
2121 : //without bound in a multi step conversion
2122 :
2123 0 : if (nLevel == 0)
2124 0 : pS->WriteUChar( sal_uInt8(0x0A) ); //initial size
2125 :
2126 0 : if ( nLevel || (nSize >1))
2127 : {
2128 0 : pS->WriteUChar( sal_uInt8(PILE) );
2129 0 : pS->WriteUChar( sal_uInt8(nHAlign) ); //vAlign ?
2130 0 : pS->WriteUChar( sal_uInt8(0x01) ); //hAlign
2131 : }
2132 :
2133 0 : for (sal_uInt16 i = 0; i < nSize; i++)
2134 0 : if (SmNode *pTemp = pNode->GetSubNode(i))
2135 : {
2136 0 : pS->WriteUChar( sal_uInt8(LINE) );
2137 0 : HandleNodes(pTemp,nLevel+1);
2138 0 : pS->WriteUChar( sal_uInt8(END) );
2139 : }
2140 0 : if (nLevel || (nSize>1))
2141 0 : pS->WriteUChar( sal_uInt8(END) );
2142 0 : }
2143 :
2144 :
2145 0 : void MathType::HandleRoot(SmNode *pNode,int nLevel)
2146 : {
2147 : SmNode *pTemp;
2148 0 : pS->WriteUChar( sal_uInt8(TMPL) ); //Template
2149 0 : pS->WriteUChar( sal_uInt8(0x0D) ); //selector
2150 0 : if (pNode->GetSubNode(0))
2151 0 : pS->WriteUChar( sal_uInt8(0x01) ); //variation
2152 : else
2153 0 : pS->WriteUChar( sal_uInt8(0x00) ); //variation
2154 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2155 :
2156 0 : if (NULL != (pTemp = pNode->GetSubNode(2)))
2157 : {
2158 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2159 0 : HandleNodes(pTemp,nLevel+1);
2160 0 : pS->WriteUChar( sal_uInt8(END) );
2161 : }
2162 :
2163 0 : if (NULL != (pTemp = pNode->GetSubNode(0)))
2164 : {
2165 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2166 0 : HandleNodes(pTemp,nLevel+1);
2167 0 : pS->WriteUChar( sal_uInt8(END) );
2168 : }
2169 : else
2170 0 : pS->WriteUChar( sal_uInt8(LINE|0x10) ); //dummy line
2171 :
2172 :
2173 :
2174 0 : pS->WriteUChar( sal_uInt8(END) );
2175 0 : }
2176 :
2177 0 : sal_uInt8 MathType::HandleCScript(SmNode *pNode,SmNode *pContent,int nLevel,
2178 : sal_uLong *pPos,sal_Bool bTest)
2179 : {
2180 0 : sal_uInt8 nVariation2=0xff;
2181 :
2182 0 : if (bTest && pNode->GetSubNode(CSUP+1))
2183 : {
2184 0 : nVariation2=0;
2185 0 : if (pNode->GetSubNode(CSUB+1))
2186 0 : nVariation2=2;
2187 : }
2188 0 : else if (pNode->GetSubNode(CSUB+1))
2189 0 : nVariation2=1;
2190 :
2191 0 : if (nVariation2!=0xff)
2192 : {
2193 0 : if (pPos)
2194 0 : *pPos = pS->Tell();
2195 0 : pS->WriteUChar( sal_uInt8(TMPL) ); //Template
2196 0 : pS->WriteUChar( sal_uInt8(0x2B) ); //selector
2197 0 : pS->WriteUChar( nVariation2 );
2198 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2199 :
2200 0 : if (pContent)
2201 : {
2202 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2203 0 : HandleNodes(pContent,nLevel+1);
2204 0 : pS->WriteUChar( sal_uInt8(END) ); //line
2205 : }
2206 : else
2207 0 : pS->WriteUChar( sal_uInt8(LINE|0x10) );
2208 :
2209 0 : pS->WriteUChar( sal_uInt8(0x0B) );
2210 :
2211 : SmNode *pTemp;
2212 0 : if (NULL != (pTemp = pNode->GetSubNode(CSUB+1)))
2213 : {
2214 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2215 0 : HandleNodes(pTemp,nLevel+1);
2216 0 : pS->WriteUChar( sal_uInt8(END) ); //line
2217 : }
2218 : else
2219 0 : pS->WriteUChar( sal_uInt8(LINE|0x10) );
2220 0 : if (bTest && NULL != (pTemp = pNode->GetSubNode(CSUP+1)))
2221 : {
2222 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2223 0 : HandleNodes(pTemp,nLevel+1);
2224 0 : pS->WriteUChar( sal_uInt8(END) ); //line
2225 : }
2226 : else
2227 0 : pS->WriteUChar( sal_uInt8(LINE|0x10) );
2228 : }
2229 0 : return nVariation2;
2230 : }
2231 :
2232 :
2233 :
2234 : /*
2235 : Sub and Sup scripts and another problem area, StarMath
2236 : can have all possible options used at the same time, whereas
2237 : Mathtype cannot. The ordering of the nodes for each system
2238 : is quite different as well leading to some complexity
2239 : */
2240 0 : void MathType::HandleSubSupScript(SmNode *pNode,int nLevel)
2241 : {
2242 0 : sal_uInt8 nVariation=0xff;
2243 0 : if (pNode->GetSubNode(LSUP+1))
2244 : {
2245 0 : nVariation=0;
2246 0 : if (pNode->GetSubNode(LSUB+1))
2247 0 : nVariation=2;
2248 : }
2249 0 : else if ( NULL != pNode->GetSubNode(LSUB+1) )
2250 0 : nVariation=1;
2251 :
2252 : SmNode *pTemp;
2253 0 : if (nVariation!=0xff)
2254 : {
2255 0 : pS->WriteUChar( sal_uInt8(TMPL) ); //Template
2256 0 : pS->WriteUChar( sal_uInt8(0x2c) ); //selector
2257 0 : pS->WriteUChar( nVariation );
2258 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2259 0 : pS->WriteUChar( sal_uInt8(0x0B) );
2260 :
2261 0 : if (NULL != (pTemp = pNode->GetSubNode(LSUB+1)))
2262 : {
2263 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2264 0 : HandleNodes(pTemp,nLevel+1);
2265 0 : pS->WriteUChar( sal_uInt8(END) ); //line
2266 : }
2267 : else
2268 0 : pS->WriteUChar( sal_uInt8(LINE|0x10) );
2269 0 : if (NULL != (pTemp = pNode->GetSubNode(LSUP+1)))
2270 : {
2271 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2272 0 : HandleNodes(pTemp,nLevel+1);
2273 0 : pS->WriteUChar( sal_uInt8(END) ); //line
2274 : }
2275 : else
2276 0 : pS->WriteUChar( sal_uInt8(LINE|0x10) );
2277 0 : pS->WriteUChar( sal_uInt8(END) );
2278 0 : nVariation=0xff;
2279 : }
2280 :
2281 :
2282 0 : sal_uInt8 nVariation2=HandleCScript(pNode,NULL,nLevel);
2283 :
2284 0 : if (NULL != (pTemp = pNode->GetSubNode(0)))
2285 : {
2286 0 : HandleNodes(pTemp,nLevel+1);
2287 : }
2288 :
2289 0 : if (nVariation2 != 0xff)
2290 0 : pS->WriteUChar( sal_uInt8(END) );
2291 :
2292 0 : if (NULL != (pNode->GetSubNode(RSUP+1)))
2293 : {
2294 0 : nVariation=0;
2295 0 : if (pNode->GetSubNode(RSUB+1))
2296 0 : nVariation=2;
2297 : }
2298 0 : else if (NULL != (pTemp = pNode->GetSubNode(RSUB+1)))
2299 0 : nVariation=1;
2300 :
2301 0 : if (nVariation!=0xff)
2302 : {
2303 0 : pS->WriteUChar( sal_uInt8(TMPL) ); //Template
2304 0 : pS->WriteUChar( sal_uInt8(0x0F) ); //selector
2305 0 : pS->WriteUChar( nVariation );
2306 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2307 0 : pS->WriteUChar( sal_uInt8(0x0B) );
2308 :
2309 0 : if (NULL != (pTemp = pNode->GetSubNode(RSUB+1)))
2310 : {
2311 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2312 0 : HandleNodes(pTemp,nLevel+1);
2313 0 : pS->WriteUChar( sal_uInt8(END) ); //line
2314 : }
2315 : else
2316 0 : pS->WriteUChar( sal_uInt8(LINE|0x10) );
2317 0 : if (NULL != (pTemp = pNode->GetSubNode(RSUP+1)))
2318 : {
2319 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2320 0 : HandleNodes(pTemp,nLevel+1);
2321 0 : pS->WriteUChar( sal_uInt8(END) ); //line
2322 : }
2323 : else
2324 0 : pS->WriteUChar( sal_uInt8(LINE|0x10) );
2325 0 : pS->WriteUChar( sal_uInt8(END) ); //line
2326 : }
2327 :
2328 : //After subscript mathtype will keep the size of
2329 : //normal text at the subscript size, sigh.
2330 0 : pS->WriteUChar( sal_uInt8(0x0A) );
2331 0 : }
2332 :
2333 :
2334 0 : void MathType::HandleFractions(SmNode *pNode,int nLevel)
2335 : {
2336 : SmNode *pTemp;
2337 0 : pS->WriteUChar( sal_uInt8(TMPL) ); //Template
2338 0 : pS->WriteUChar( sal_uInt8(0x0E) ); //selector
2339 0 : pS->WriteUChar( sal_uInt8(0x00) ); //variation
2340 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2341 :
2342 0 : pS->WriteUChar( sal_uInt8(0x0A) );
2343 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2344 0 : if (NULL != (pTemp = pNode->GetSubNode(0)))
2345 0 : HandleNodes(pTemp,nLevel+1);
2346 0 : pS->WriteUChar( sal_uInt8(END) );
2347 :
2348 0 : pS->WriteUChar( sal_uInt8(0x0A) );
2349 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2350 0 : if (NULL != (pTemp = pNode->GetSubNode(2)))
2351 0 : HandleNodes(pTemp,nLevel+1);
2352 0 : pS->WriteUChar( sal_uInt8(END) );
2353 :
2354 0 : pS->WriteUChar( sal_uInt8(END) );
2355 0 : }
2356 :
2357 :
2358 0 : void MathType::HandleBrace(SmNode *pNode,int nLevel)
2359 : {
2360 : SmNode *pTemp;
2361 0 : SmNode *pLeft=pNode->GetSubNode(0);
2362 0 : SmNode *pRight=pNode->GetSubNode(2);
2363 :
2364 0 : pS->WriteUChar( sal_uInt8(TMPL) ); //Template
2365 0 : bIsReInterpBrace=0;
2366 0 : sal_uInt8 nBSpec=0x10;
2367 0 : sal_uLong nLoc = pS->Tell();
2368 0 : if (pLeft)
2369 : {
2370 0 : switch (pLeft->GetToken().eType)
2371 : {
2372 : case TLANGLE:
2373 0 : pS->WriteUChar( sal_uInt8(tmANGLE) ); //selector
2374 0 : pS->WriteUChar( sal_uInt8(0x00) ); //variation
2375 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2376 0 : break;
2377 : case TLBRACE:
2378 0 : pS->WriteUChar( sal_uInt8(tmBRACE) ); //selector
2379 0 : pS->WriteUChar( sal_uInt8(0x00) ); //variation
2380 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2381 0 : nBSpec+=3;
2382 0 : break;
2383 : case TLBRACKET:
2384 0 : pS->WriteUChar( sal_uInt8(tmBRACK) ); //selector
2385 0 : pS->WriteUChar( sal_uInt8(0x00) ); //variation
2386 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2387 0 : nBSpec+=3;
2388 0 : break;
2389 : case TLFLOOR:
2390 0 : pS->WriteUChar( sal_uInt8(tmFLOOR) ); //selector
2391 0 : pS->WriteUChar( sal_uInt8(0x00) ); //variation
2392 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2393 0 : break;
2394 : case TLLINE:
2395 0 : pS->WriteUChar( sal_uInt8(tmBAR) ); //selector
2396 0 : pS->WriteUChar( sal_uInt8(0x00) ); //variation
2397 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2398 0 : nBSpec+=3;
2399 0 : break;
2400 : case TLDLINE:
2401 0 : pS->WriteUChar( sal_uInt8(tmDBAR) ); //selector
2402 0 : pS->WriteUChar( sal_uInt8(0x00) ); //variation
2403 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2404 0 : break;
2405 : default:
2406 0 : pS->WriteUChar( sal_uInt8(tmPAREN) ); //selector
2407 0 : pS->WriteUChar( sal_uInt8(0x00) ); //variation
2408 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2409 0 : nBSpec+=3;
2410 0 : break;
2411 : }
2412 : }
2413 :
2414 0 : if (NULL != (pTemp = pNode->GetSubNode(1)))
2415 : {
2416 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2417 0 : HandleNodes(pTemp,nLevel+1);
2418 0 : pS->WriteUChar( sal_uInt8(END) ); //options
2419 : }
2420 0 : nSpec=nBSpec;
2421 0 : if (pLeft)
2422 0 : HandleNodes(pLeft,nLevel+1);
2423 0 : if (bIsReInterpBrace)
2424 : {
2425 0 : sal_uLong nLoc2 = pS->Tell();
2426 0 : pS->Seek(nLoc);
2427 0 : pS->WriteUChar( sal_uInt8(0x2D) );
2428 0 : pS->Seek(nLoc2);
2429 0 : pS->WriteUChar( sal_uInt8(CHAR) );
2430 0 : pS->WriteUChar( sal_uInt8(0x96) );
2431 0 : pS->WriteUInt16( sal_uInt16(0xEC07) );
2432 0 : bIsReInterpBrace=0;
2433 : }
2434 0 : if (pRight)
2435 0 : HandleNodes(pRight,nLevel+1);
2436 0 : nSpec=0x0;
2437 0 : pS->WriteUChar( sal_uInt8(END) );
2438 0 : }
2439 :
2440 :
2441 0 : void MathType::HandleVerticalBrace(SmNode *pNode,int nLevel)
2442 : {
2443 : SmNode *pTemp;
2444 0 : pS->WriteUChar( sal_uInt8(TMPL) ); //Template
2445 0 : if (pNode->GetToken().eType == TUNDERBRACE)
2446 0 : pS->WriteUChar( sal_uInt8(tmLHBRACE) ); //selector
2447 : else
2448 0 : pS->WriteUChar( sal_uInt8(tmUHBRACE) ); //selector
2449 0 : pS->WriteUChar( sal_uInt8(0x01) ); //variation
2450 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2451 :
2452 0 : if (NULL != (pTemp = pNode->GetSubNode(0)))
2453 : {
2454 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2455 0 : HandleNodes(pTemp,nLevel+1);
2456 0 : pS->WriteUChar( sal_uInt8(END) ); //options
2457 : }
2458 :
2459 0 : if (NULL != (pTemp = pNode->GetSubNode(2)))
2460 : {
2461 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2462 0 : HandleNodes(pTemp,nLevel+1);
2463 0 : pS->WriteUChar( sal_uInt8(END) ); //options
2464 : }
2465 0 : pS->WriteUChar( sal_uInt8(END) );
2466 0 : }
2467 :
2468 0 : void MathType::HandleOperator(SmNode *pNode,int nLevel)
2469 : {
2470 0 : if (HandleLim(pNode,nLevel))
2471 0 : return;
2472 :
2473 : sal_uLong nPos;
2474 : sal_uInt8 nVariation;
2475 :
2476 0 : switch (pNode->GetToken().eType)
2477 : {
2478 : case TIINT:
2479 : case TIIINT:
2480 : case TLINT:
2481 : case TLLINT:
2482 : case TLLLINT:
2483 0 : nVariation=HandleCScript(pNode->GetSubNode(0),
2484 0 : pNode->GetSubNode(1),nLevel,&nPos,0);
2485 0 : break;
2486 : default:
2487 0 : nVariation=HandleCScript(pNode->GetSubNode(0),
2488 0 : pNode->GetSubNode(1),nLevel,&nPos);
2489 0 : break;
2490 : }
2491 :
2492 0 : sal_uInt8 nOldVariation=nVariation;
2493 0 : sal_uInt8 nIntVariation=nVariation;
2494 :
2495 0 : sal_uLong nPos2=0;
2496 0 : if (nVariation != 0xff)
2497 : {
2498 0 : nPos2 = pS->Tell();
2499 0 : pS->Seek(nPos);
2500 0 : if (nVariation == 2)
2501 : {
2502 0 : nIntVariation=0;
2503 0 : nVariation = 1;
2504 : }
2505 0 : else if (nVariation == 0)
2506 0 : nVariation = 1;
2507 0 : else if (nVariation == 1)
2508 0 : nVariation = 0;
2509 : }
2510 : else
2511 : {
2512 0 : nVariation = 2;
2513 0 : nIntVariation=0;
2514 : }
2515 0 : pS->WriteUChar( sal_uInt8(TMPL) );
2516 0 : switch(pNode->GetToken().eType)
2517 : {
2518 : case TINT:
2519 : case TINTD:
2520 0 : if (nOldVariation != 0xff)
2521 0 : pS->WriteUChar( sal_uInt8(0x18) ); //selector
2522 : else
2523 0 : pS->WriteUChar( sal_uInt8(0x15) ); //selector
2524 0 : pS->WriteUChar( nIntVariation ); //variation
2525 0 : break;
2526 : case TIINT:
2527 0 : if (nOldVariation != 0xff)
2528 : {
2529 0 : pS->WriteUChar( sal_uInt8(0x19) );
2530 0 : pS->WriteUChar( sal_uInt8(0x01) );
2531 : }
2532 : else
2533 : {
2534 0 : pS->WriteUChar( sal_uInt8(0x16) );
2535 0 : pS->WriteUChar( sal_uInt8(0x00) );
2536 : }
2537 0 : break;
2538 : case TIIINT:
2539 0 : if (nOldVariation != 0xff)
2540 : {
2541 0 : pS->WriteUChar( sal_uInt8(0x1a) );
2542 0 : pS->WriteUChar( sal_uInt8(0x01) );
2543 : }
2544 : else
2545 : {
2546 0 : pS->WriteUChar( sal_uInt8(0x17) );
2547 0 : pS->WriteUChar( sal_uInt8(0x00) );
2548 : }
2549 0 : break;
2550 : case TLINT:
2551 0 : if (nOldVariation != 0xff)
2552 : {
2553 0 : pS->WriteUChar( sal_uInt8(0x18) );
2554 0 : pS->WriteUChar( sal_uInt8(0x02) );
2555 : }
2556 : else
2557 : {
2558 0 : pS->WriteUChar( sal_uInt8(0x15) );
2559 0 : pS->WriteUChar( sal_uInt8(0x03) );
2560 : }
2561 0 : break;
2562 : case TLLINT:
2563 0 : if (nOldVariation != 0xff)
2564 : {
2565 0 : pS->WriteUChar( sal_uInt8(0x19) );
2566 0 : pS->WriteUChar( sal_uInt8(0x00) );
2567 : }
2568 : else
2569 : {
2570 0 : pS->WriteUChar( sal_uInt8(0x16) );
2571 0 : pS->WriteUChar( sal_uInt8(0x02) );
2572 : }
2573 0 : break;
2574 : case TLLLINT:
2575 0 : if (nOldVariation != 0xff)
2576 : {
2577 0 : pS->WriteUChar( sal_uInt8(0x1a) );
2578 0 : pS->WriteUChar( sal_uInt8(0x00) );
2579 : }
2580 : else
2581 : {
2582 0 : pS->WriteUChar( sal_uInt8(0x17) );
2583 0 : pS->WriteUChar( sal_uInt8(0x02) );
2584 : }
2585 0 : break;
2586 : case TSUM:
2587 : default:
2588 0 : pS->WriteUChar( sal_uInt8(0x1d) );
2589 0 : pS->WriteUChar( nVariation );
2590 0 : break;
2591 : case TPROD:
2592 0 : pS->WriteUChar( sal_uInt8(0x1f) );
2593 0 : pS->WriteUChar( nVariation );
2594 0 : break;
2595 : case TCOPROD:
2596 0 : pS->WriteUChar( sal_uInt8(0x21) );
2597 0 : pS->WriteUChar( nVariation );
2598 0 : break;
2599 : }
2600 0 : pS->WriteUChar( sal_uInt8(0x00) ); //options
2601 :
2602 0 : if (nPos2)
2603 0 : pS->Seek(nPos2);
2604 : else
2605 : {
2606 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2607 0 : HandleNodes(pNode->GetSubNode(1),nLevel+1);
2608 0 : pS->WriteUChar( sal_uInt8(END) ); //line
2609 0 : pS->WriteUChar( sal_uInt8(LINE|0x10) );
2610 0 : pS->WriteUChar( sal_uInt8(LINE|0x10) );
2611 : }
2612 :
2613 :
2614 0 : pS->WriteUChar( sal_uInt8(0x0D) );
2615 0 : switch(pNode->GetToken().eType)
2616 : {
2617 : case TSUM:
2618 : default:
2619 0 : pS->WriteUChar( sal_uInt8(CHAR) );
2620 0 : pS->WriteUChar( sal_uInt8(0x86) );
2621 0 : pS->WriteUInt16( sal_uInt16(0x2211) );
2622 0 : break;
2623 : case TPROD:
2624 0 : pS->WriteUChar( sal_uInt8(CHAR) );
2625 0 : pS->WriteUChar( sal_uInt8(0x86) );
2626 0 : pS->WriteUInt16( sal_uInt16(0x220F) );
2627 0 : break;
2628 : case TCOPROD:
2629 0 : pS->WriteUChar( sal_uInt8(CHAR) );
2630 0 : pS->WriteUChar( sal_uInt8(0x8B) );
2631 0 : pS->WriteUInt16( sal_uInt16(0x2210) );
2632 0 : break;
2633 : case TIIINT:
2634 : case TLLLINT:
2635 0 : pS->WriteUChar( sal_uInt8(CHAR) );
2636 0 : pS->WriteUChar( sal_uInt8(0x86) );
2637 0 : pS->WriteUInt16( sal_uInt16(0x222B) );
2638 : case TIINT:
2639 : case TLLINT:
2640 0 : pS->WriteUChar( sal_uInt8(CHAR) );
2641 0 : pS->WriteUChar( sal_uInt8(0x86) );
2642 0 : pS->WriteUInt16( sal_uInt16(0x222B) );
2643 : case TINT:
2644 : case TINTD:
2645 : case TLINT:
2646 0 : pS->WriteUChar( sal_uInt8(CHAR) );
2647 0 : pS->WriteUChar( sal_uInt8(0x86) );
2648 0 : pS->WriteUInt16( sal_uInt16(0x222B) );
2649 0 : break;
2650 : }
2651 0 : pS->WriteUChar( sal_uInt8(END) );
2652 0 : pS->WriteUChar( sal_uInt8(0x0A) );
2653 : }
2654 :
2655 :
2656 0 : int MathType::HandlePile(int &rSetAlign,int nLevel,sal_uInt8 nSelector,
2657 : sal_uInt8 nVariation)
2658 : {
2659 0 : pS->ReadUChar( nHAlign );
2660 0 : pS->ReadUChar( nVAlign );
2661 :
2662 0 : HandleAlign(nHAlign,nVAlign,rSetAlign);
2663 :
2664 0 : rRet += " stack {\n";
2665 0 : int nRet = HandleRecords(nLevel+1,nSelector,nVariation,-1,-1);
2666 0 : rRet = rRet.replaceAt(rRet.getLength()-3,2,"");
2667 0 : rRet += "} ";
2668 :
2669 0 : while (rSetAlign)
2670 : {
2671 0 : rRet += "} ";
2672 0 : rSetAlign--;
2673 : }
2674 0 : return nRet;
2675 : }
2676 :
2677 0 : int MathType::HandleMatrix(int nLevel,sal_uInt8 nSelector,
2678 : sal_uInt8 nVariation)
2679 : {
2680 : sal_uInt8 nH_just,nV_just,nRows,nCols;
2681 0 : pS->ReadUChar( nVAlign );
2682 0 : pS->ReadUChar( nH_just );
2683 0 : pS->ReadUChar( nV_just );
2684 0 : pS->ReadUChar( nRows );
2685 0 : pS->ReadUChar( nCols );
2686 0 : int nBytes = ((nRows+1)*2)/8;
2687 0 : if (((nRows+1)*2)%8)
2688 0 : nBytes++;
2689 0 : pS->SeekRel(nBytes);
2690 0 : nBytes = ((nCols+1)*2)/8;
2691 0 : if (((nCols+1)*2)%8)
2692 0 : nBytes++;
2693 0 : pS->SeekRel(nBytes);
2694 0 : rRet += " matrix {\n";
2695 0 : int nRet = HandleRecords(nLevel+1,nSelector,nVariation,nRows,nCols);
2696 :
2697 0 : sal_Int32 nI = rRet.lastIndexOf('#');
2698 0 : if (nI > 0)
2699 0 : if (rRet[nI-1] != '#') //missing column
2700 0 : rRet += "{}";
2701 :
2702 0 : rRet += "\n} ";
2703 0 : return nRet;
2704 : }
2705 :
2706 0 : int MathType::HandleTemplate(int nLevel,sal_uInt8 &rSelector,
2707 : sal_uInt8 &rVariation, sal_Int32 &rLastTemplateBracket)
2708 : {
2709 : sal_uInt8 nOption; //This appears utterly unused
2710 0 : pS->ReadUChar( rSelector );
2711 0 : pS->ReadUChar( rVariation );
2712 0 : pS->ReadUChar( nOption );
2713 : OSL_ENSURE(rSelector < 48,"Selector out of range");
2714 0 : if ((rSelector >= 21) && (rSelector <=26))
2715 : {
2716 : OSL_ENSURE(nOption < 2,"Option out of range");
2717 : }
2718 0 : else if (/*(rSelector >= 0) &&*/ (rSelector <=12))
2719 : {
2720 : OSL_ENSURE(nOption < 3,"Option out of range");
2721 : }
2722 :
2723 : //For the (broken) case where one subscript template ends, and there is
2724 : //another one after it, mathtype handles it as if the second one was
2725 : //inside the first one and renders it as sub of sub
2726 0 : bool bRemove=false;
2727 0 : if ( (rSelector == 0xf) && (rLastTemplateBracket != -1) )
2728 : {
2729 0 : bRemove=true;
2730 0 : for (sal_Int32 nI = rLastTemplateBracket+1; nI < rRet.getLength(); nI++ )
2731 0 : if (rRet[nI] != ' ')
2732 : {
2733 0 : bRemove=false;
2734 0 : break;
2735 : }
2736 : }
2737 :
2738 : //suborderlist
2739 0 : int nRet = HandleRecords(nLevel+1,rSelector,rVariation);
2740 :
2741 0 : if (bRemove)
2742 : {
2743 0 : rRet = rRet.replaceAt(rLastTemplateBracket,1,"");
2744 0 : rRet += "} ";
2745 0 : rLastTemplateBracket = -1;
2746 : }
2747 0 : if (rSelector == 0xf)
2748 0 : rLastTemplateBracket = rRet.lastIndexOf('}');
2749 : else
2750 0 : rLastTemplateBracket = -1;
2751 :
2752 0 : rSelector = sal::static_int_cast< sal_uInt8 >(-1);
2753 0 : return nRet;
2754 : }
2755 :
2756 0 : void MathType::HandleEmblishments()
2757 : {
2758 : sal_uInt8 nEmbel;
2759 0 : do
2760 : {
2761 0 : pS->ReadUChar( nEmbel );
2762 0 : switch (nEmbel)
2763 : {
2764 : case 0x02:
2765 0 : rRet += " dot ";
2766 0 : break;
2767 : case 0x03:
2768 0 : rRet += " ddot ";
2769 0 : break;
2770 : case 0x04:
2771 0 : rRet += " dddot ";
2772 0 : break;
2773 : case 0x05:
2774 0 : if (!nPostSup)
2775 : {
2776 0 : sPost += " sup {}";
2777 0 : nPostSup = sPost.getLength();
2778 : }
2779 0 : sPost = sPost.replaceAt(nPostSup-1,0," ' ");
2780 0 : nPostSup += 3;
2781 0 : break;
2782 : case 0x06:
2783 0 : if (!nPostSup)
2784 : {
2785 0 : sPost += " sup {}";
2786 0 : nPostSup = sPost.getLength();
2787 : }
2788 0 : sPost = sPost.replaceAt(nPostSup-1,0," '' ");
2789 0 : nPostSup += 4;
2790 0 : break;
2791 : case 0x07:
2792 0 : if (!nPostlSup)
2793 : {
2794 0 : sPost += " lsup {}";
2795 0 : nPostlSup = sPost.getLength();
2796 : }
2797 0 : sPost = sPost.replaceAt(nPostlSup-1,0," ' ");
2798 0 : nPostlSup += 3;
2799 0 : break;
2800 : case 0x08:
2801 0 : rRet += " tilde ";
2802 0 : break;
2803 : case 0x09:
2804 0 : rRet += " hat ";
2805 0 : break;
2806 : case 0x0b:
2807 0 : rRet += " vec ";
2808 0 : break;
2809 : case 0x10:
2810 0 : rRet += " overstrike ";
2811 0 : break;
2812 : case 0x11:
2813 0 : rRet += " bar ";
2814 0 : break;
2815 : case 0x12:
2816 0 : if (!nPostSup)
2817 : {
2818 0 : sPost += " sup {}";
2819 0 : nPostSup = sPost.getLength();
2820 : }
2821 0 : sPost = sPost.replaceAt(nPostSup-1,0," ''' ");
2822 0 : nPostSup += 5;
2823 0 : break;
2824 : case 0x14:
2825 0 : rRet += " breve ";
2826 0 : break;
2827 : default:
2828 : OSL_ENSURE(nEmbel < 21,"Embel out of range");
2829 0 : break;
2830 : }
2831 0 : if (nVersion < 3)
2832 0 : break;
2833 : }while (nEmbel);
2834 0 : }
2835 :
2836 0 : void MathType::HandleSetSize()
2837 : {
2838 : sal_uInt8 nTemp;
2839 0 : pS->ReadUChar( nTemp );
2840 0 : switch (nTemp)
2841 : {
2842 : case 101:
2843 0 : pS->ReadInt16( nLSize );
2844 0 : nLSize = -nLSize;
2845 0 : break;
2846 : case 100:
2847 0 : pS->ReadUChar( nTemp );
2848 0 : nLSize = nTemp;
2849 0 : pS->ReadInt16( nDSize );
2850 0 : break;
2851 : default:
2852 0 : nLSize = nTemp;
2853 0 : pS->ReadUChar( nTemp );
2854 0 : nDSize = nTemp-128;
2855 0 : break;
2856 : }
2857 0 : }
2858 :
2859 0 : int MathType::HandleChar(sal_Int32 &rTextStart,int &rSetSize,int nLevel,
2860 : sal_uInt8 nTag,sal_uInt8 nSelector,sal_uInt8 nVariation, sal_Bool bSilent)
2861 : {
2862 : sal_Unicode nChar;
2863 0 : int nRet=1;
2864 :
2865 0 : if (xfAUTO(nTag))
2866 : {
2867 : //This is a candidate for function recognition, whatever
2868 : //that is!
2869 : }
2870 :
2871 0 : sal_uInt8 nOldTypeFace = nTypeFace;
2872 0 : pS->ReadUChar( nTypeFace );
2873 0 : if (nVersion < 3)
2874 : {
2875 : sal_uInt8 nChar8;
2876 0 : pS->ReadUChar( nChar8 );
2877 0 : nChar = nChar8;
2878 : }
2879 : else
2880 0 : pS->ReadUInt16( nChar );
2881 :
2882 : /*
2883 : bad character, old mathtype < 3 has these
2884 : */
2885 0 : if (nChar < 0x20)
2886 0 : return nRet;
2887 :
2888 0 : if (xfEMBELL(nTag))
2889 : {
2890 : //A bit tricky, the character emblishments for
2891 : //mathtype can all be listed after eachother, in
2892 : //starmath some must go before the character and some
2893 : //must go after. In addition some of the emblishments
2894 : //may repeated and in starmath some of these groups
2895 : //must be gathered together. sPost is the portion that
2896 : //follows the char and nPostSup and nPostlSup are the
2897 : //indexes at which this class of emblishment is
2898 : //collated together
2899 0 : sPost = OUString();
2900 0 : nPostSup = nPostlSup = 0;
2901 0 : int nOriglen=rRet.getLength()-rTextStart;
2902 0 : rRet += " {"; // #i24340# make what would be "vec {A}_n" become "{vec {A}}_n"
2903 0 : if ((!bSilent) && ((nOriglen) > 1))
2904 0 : rRet += "\"";
2905 0 : nRet = HandleRecords(nLevel+1,nSelector,nVariation);
2906 0 : if (!bSilent)
2907 : {
2908 0 : if (nOriglen > 1)
2909 : {
2910 0 : OUString aStr;
2911 0 : TypeFaceToString(aStr,nOldTypeFace);
2912 0 : aStr += "\"";
2913 0 : rRet = rRet.replaceAt(rTextStart,0,aStr);
2914 :
2915 0 : aStr = OUString();
2916 0 : TypeFaceToString(aStr,nTypeFace);
2917 0 : rRet += aStr + "{";
2918 : }
2919 : else
2920 0 : rRet += " {";
2921 0 : rTextStart = rRet.getLength();
2922 : }
2923 : }
2924 :
2925 0 : if (!bSilent)
2926 : {
2927 0 : sal_Int32 nOldLen = rRet.getLength();
2928 0 : if (
2929 0 : HandleSize(nLSize,nDSize,rSetSize) ||
2930 0 : (nOldTypeFace != nTypeFace)
2931 : )
2932 : {
2933 0 : if ((nOldLen - rTextStart) > 1)
2934 : {
2935 0 : rRet = rRet.replaceAt(nOldLen, 0, "\"");
2936 0 : OUString aStr;
2937 0 : TypeFaceToString(aStr,nOldTypeFace);
2938 0 : aStr += "\"";
2939 0 : rRet = rRet.replaceAt(rTextStart,0,aStr);
2940 : }
2941 0 : rTextStart = rRet.getLength();
2942 : }
2943 0 : nOldLen = rRet.getLength();
2944 0 : if (!LookupChar(nChar,rRet,nVersion,nTypeFace))
2945 : {
2946 0 : if (nOldLen - rTextStart > 1)
2947 : {
2948 0 : rRet = rRet.replaceAt(nOldLen,0,"\"");
2949 0 : OUString aStr;
2950 0 : TypeFaceToString(aStr,nOldTypeFace);
2951 0 : aStr += "\"";
2952 0 : rRet = rRet.replaceAt(rTextStart, 0, aStr);
2953 : }
2954 0 : rTextStart = rRet.getLength();
2955 : }
2956 0 : lcl_PrependDummyTerm(rRet, rTextStart);
2957 : }
2958 :
2959 0 : if ((xfEMBELL(nTag)) && (!bSilent))
2960 : {
2961 0 : rRet += "}}" + sPost; // #i24340# make what would be "vec {A}_n" become "{vec {A}}_n"
2962 0 : rTextStart = rRet.getLength();
2963 : }
2964 0 : return nRet;
2965 : }
2966 :
2967 0 : sal_Bool MathType::HandleLim(SmNode *pNode,int nLevel)
2968 : {
2969 0 : bool bRet=false;
2970 : //Special case for the "lim" option in StarMath
2971 0 : if ((pNode->GetToken().eType == TLIM)
2972 0 : || (pNode->GetToken().eType == TLIMSUP)
2973 0 : || (pNode->GetToken().eType == TLIMINF)
2974 : )
2975 : {
2976 0 : if (pNode->GetSubNode(1))
2977 : {
2978 0 : sal_uInt8 nVariation2=HandleCScript(pNode->GetSubNode(0),NULL,
2979 0 : nLevel);
2980 :
2981 0 : pS->WriteUChar( sal_uInt8(0x0A) );
2982 0 : pS->WriteUChar( sal_uInt8(LINE) ); //line
2983 0 : pS->WriteUChar( sal_uInt8(CHAR|0x10) );
2984 0 : pS->WriteUChar( sal_uInt8(0x82) );
2985 0 : pS->WriteUInt16( sal_uInt16('l') );
2986 0 : pS->WriteUChar( sal_uInt8(CHAR|0x10) );
2987 0 : pS->WriteUChar( sal_uInt8(0x82) );
2988 0 : pS->WriteUInt16( sal_uInt16('i') );
2989 0 : pS->WriteUChar( sal_uInt8(CHAR|0x10) );
2990 0 : pS->WriteUChar( sal_uInt8(0x82) );
2991 0 : pS->WriteUInt16( sal_uInt16('m') );
2992 :
2993 0 : if (pNode->GetToken().eType == TLIMSUP)
2994 : {
2995 0 : pS->WriteUChar( sal_uInt8(CHAR) ); //some space
2996 0 : pS->WriteUChar( sal_uInt8(0x98) );
2997 0 : pS->WriteUInt16( sal_uInt16(0xEB04) );
2998 :
2999 0 : pS->WriteUChar( sal_uInt8(CHAR|0x10) );
3000 0 : pS->WriteUChar( sal_uInt8(0x82) );
3001 0 : pS->WriteUInt16( sal_uInt16('s') );
3002 0 : pS->WriteUChar( sal_uInt8(CHAR|0x10) );
3003 0 : pS->WriteUChar( sal_uInt8(0x82) );
3004 0 : pS->WriteUInt16( sal_uInt16('u') );
3005 0 : pS->WriteUChar( sal_uInt8(CHAR|0x10) );
3006 0 : pS->WriteUChar( sal_uInt8(0x82) );
3007 0 : pS->WriteUInt16( sal_uInt16('p') );
3008 : }
3009 0 : else if (pNode->GetToken().eType == TLIMINF)
3010 : {
3011 0 : pS->WriteUChar( sal_uInt8(CHAR) ); //some space
3012 0 : pS->WriteUChar( sal_uInt8(0x98) );
3013 0 : pS->WriteUInt16( sal_uInt16(0xEB04) );
3014 :
3015 0 : pS->WriteUChar( sal_uInt8(CHAR|0x10) );
3016 0 : pS->WriteUChar( sal_uInt8(0x82) );
3017 0 : pS->WriteUInt16( sal_uInt16('i') );
3018 0 : pS->WriteUChar( sal_uInt8(CHAR|0x10) );
3019 0 : pS->WriteUChar( sal_uInt8(0x82) );
3020 0 : pS->WriteUInt16( sal_uInt16('n') );
3021 0 : pS->WriteUChar( sal_uInt8(CHAR|0x10) );
3022 0 : pS->WriteUChar( sal_uInt8(0x82) );
3023 0 : pS->WriteUInt16( sal_uInt16('f') );
3024 : }
3025 :
3026 :
3027 0 : pS->WriteUChar( sal_uInt8(CHAR) ); //some space
3028 0 : pS->WriteUChar( sal_uInt8(0x98) );
3029 0 : pS->WriteUInt16( sal_uInt16(0xEB04) );
3030 :
3031 0 : if (nVariation2 != 0xff)
3032 : {
3033 0 : pS->WriteUChar( sal_uInt8(END) );
3034 0 : pS->WriteUChar( sal_uInt8(END) );
3035 : }
3036 0 : HandleNodes(pNode->GetSubNode(1),nLevel+1);
3037 : //*pS << sal_uInt8(END); //options
3038 0 : bRet = true;
3039 : }
3040 : }
3041 0 : return bRet;
3042 : }
3043 :
3044 0 : void MathType::HandleMAlign(SmNode *pNode,int nLevel)
3045 : {
3046 0 : sal_uInt8 nPushedHAlign=nHAlign;
3047 0 : switch(pNode->GetToken().eType)
3048 : {
3049 : case TALIGNC:
3050 0 : nHAlign=2;
3051 0 : break;
3052 : case TALIGNR:
3053 0 : nHAlign=3;
3054 0 : break;
3055 : default:
3056 0 : nHAlign=1;
3057 0 : break;
3058 : }
3059 0 : sal_uInt16 nSize = pNode->GetNumSubNodes();
3060 0 : for (sal_uInt16 i = 0; i < nSize; i++)
3061 0 : if (SmNode *pTemp = pNode->GetSubNode(i))
3062 0 : HandleNodes(pTemp,nLevel+1);
3063 0 : nHAlign=nPushedHAlign;
3064 0 : }
3065 :
3066 0 : void MathType::HandleMath(SmNode *pNode, int /*nLevel*/)
3067 : {
3068 0 : if (pNode->GetToken().eType == TMLINE)
3069 : {
3070 0 : pS->WriteUChar( sal_uInt8(END) );
3071 0 : pS->WriteUChar( sal_uInt8(LINE) );
3072 0 : bIsReInterpBrace=1;
3073 0 : return;
3074 : }
3075 0 : SmMathSymbolNode *pTemp=(SmMathSymbolNode *)pNode;
3076 0 : for(sal_Int32 i=0;i<pTemp->GetText().getLength();i++)
3077 : {
3078 0 : sal_Unicode nArse = SmTextNode::ConvertSymbolToUnicode(pTemp->GetText()[i]);
3079 0 : if ((nArse == 0x2224) || (nArse == 0x2288) || (nArse == 0x2285) ||
3080 : (nArse == 0x2289))
3081 : {
3082 0 : pS->WriteUChar( sal_uInt8(CHAR|0x20) );
3083 : }
3084 0 : else if ((nPendingAttributes) &&
3085 0 : (i == ((pTemp->GetText().getLength()+1)/2)-1))
3086 : {
3087 0 : pS->WriteUChar( sal_uInt8(0x22) );
3088 : }
3089 : else
3090 0 : pS->WriteUChar( sal_uInt8(CHAR) ); //char without formula recognition
3091 : //The typeface seems to be MTEXTRA for unicode characters,
3092 : //though how to determine when mathtype chooses one over
3093 : //the other is unknown. This should do the trick
3094 : //nevertheless.
3095 : sal_uInt8 nBias;
3096 0 : if ( (nArse == 0x2213) || (nArse == 0x2218) ||
3097 0 : (nArse == 0x210F) || (
3098 0 : (nArse >= 0x22EE) && (nArse <= 0x22FF)
3099 : ))
3100 : {
3101 0 : nBias = 0xB; //typeface
3102 : }
3103 0 : else if ((nArse > 0x2000) || (nArse == 0x00D7))
3104 0 : nBias = 0x6; //typeface
3105 0 : else if (nArse == 0x3d1)
3106 0 : nBias = 0x4;
3107 0 : else if ((nArse > 0xFF) && ((nArse < 0x393) || (nArse > 0x3c9)))
3108 0 : nBias = 0xB; //typeface
3109 0 : else if ((nArse == 0x2F) || (nArse == 0x2225))
3110 0 : nBias = 0x2; //typeface
3111 : else
3112 0 : nBias = 0x3; //typeface
3113 :
3114 0 : pS->WriteUChar( sal_uInt8(nSpec+nBias+128) ); //typeface
3115 :
3116 0 : if (nArse == 0x2224)
3117 : {
3118 0 : pS->WriteUInt16( sal_uInt16(0x7C) );
3119 0 : pS->WriteUChar( sal_uInt8(EMBEL) );
3120 0 : pS->WriteUChar( sal_uInt8(0x0A) );
3121 0 : pS->WriteUChar( sal_uInt8(END) ); //end embel
3122 0 : pS->WriteUChar( sal_uInt8(END) ); //end embel
3123 : }
3124 0 : else if (nArse == 0x2225)
3125 0 : pS->WriteUInt16( sal_uInt16(0xEC09) );
3126 0 : else if (nArse == 0xE421)
3127 0 : pS->WriteUInt16( sal_uInt16(0x2265) );
3128 0 : else if (nArse == 0x230A)
3129 0 : pS->WriteUInt16( sal_uInt16(0xF8F0) );
3130 0 : else if (nArse == 0x230B)
3131 0 : pS->WriteUInt16( sal_uInt16(0xF8FB) );
3132 0 : else if (nArse == 0xE425)
3133 0 : pS->WriteUInt16( sal_uInt16(0x2264) );
3134 0 : else if (nArse == 0x226A)
3135 : {
3136 0 : pS->WriteUInt16( sal_uInt16(0x3C) );
3137 0 : pS->WriteUChar( sal_uInt8(CHAR) );
3138 0 : pS->WriteUChar( sal_uInt8(0x98) );
3139 0 : pS->WriteUInt16( sal_uInt16(0xEB01) );
3140 0 : pS->WriteUChar( sal_uInt8(CHAR) );
3141 0 : pS->WriteUChar( sal_uInt8(0x86) );
3142 0 : pS->WriteUInt16( sal_uInt16(0x3c) );
3143 : }
3144 0 : else if (nArse == 0x2288)
3145 : {
3146 0 : pS->WriteUInt16( sal_uInt16(0x2286) );
3147 0 : pS->WriteUChar( sal_uInt8(EMBEL) );
3148 0 : pS->WriteUChar( sal_uInt8(0x0A) );
3149 0 : pS->WriteUChar( sal_uInt8(END) ); //end embel
3150 0 : pS->WriteUChar( sal_uInt8(END) ); //end embel
3151 : }
3152 0 : else if (nArse == 0x2289)
3153 : {
3154 0 : pS->WriteUInt16( sal_uInt16(0x2287) );
3155 0 : pS->WriteUChar( sal_uInt8(EMBEL) );
3156 0 : pS->WriteUChar( sal_uInt8(0x0A) );
3157 0 : pS->WriteUChar( sal_uInt8(END) ); //end embel
3158 0 : pS->WriteUChar( sal_uInt8(END) ); //end embel
3159 : }
3160 0 : else if (nArse == 0x2285)
3161 : {
3162 0 : pS->WriteUInt16( sal_uInt16(0x2283) );
3163 0 : pS->WriteUChar( sal_uInt8(EMBEL) );
3164 0 : pS->WriteUChar( sal_uInt8(0x0A) );
3165 0 : pS->WriteUChar( sal_uInt8(END) ); //end embel
3166 0 : pS->WriteUChar( sal_uInt8(END) ); //end embel
3167 : }
3168 : else
3169 0 : pS->WriteUInt16( nArse );
3170 : }
3171 0 : nPendingAttributes = 0;
3172 : }
3173 :
3174 0 : void MathType::HandleAttributes(SmNode *pNode,int nLevel)
3175 : {
3176 0 : int nOldPending = 0;
3177 0 : SmNode *pTemp = 0;
3178 0 : SmTextNode *pIsText = 0;
3179 :
3180 0 : if (NULL != (pTemp = pNode->GetSubNode(0)))
3181 : {
3182 0 : pIsText = (SmTextNode *)pNode->GetSubNode(1);
3183 :
3184 0 : switch (pTemp->GetToken().eType)
3185 : {
3186 : case TWIDEVEC:
3187 : //theres just no way we can now handle any character
3188 : //attributes (from mathtypes perspective) centered
3189 : //over an expression but above template attributes
3190 : //such as widevec and similar constructs
3191 : //we have to drop them
3192 0 : nOldPending = StartTemplate(0x2f,0x01);
3193 0 : break;
3194 : case TCHECK: //Not Exportable
3195 : case TACUTE: //Not Exportable
3196 : case TGRAVE: //Not Exportable
3197 : case TCIRCLE: //Not Exportable
3198 : case TWIDETILDE: //Not Exportable
3199 : case TWIDEHAT: //Not Exportable
3200 0 : break;
3201 : case TUNDERLINE:
3202 0 : nOldPending = StartTemplate(0x10);
3203 0 : break;
3204 : case TOVERLINE: //If the next node is not text
3205 : //or text with more than one char
3206 0 : if ((pIsText->GetToken().eType != TTEXT) ||
3207 0 : (pIsText->GetText().getLength() > 1))
3208 0 : nOldPending = StartTemplate(0x11);
3209 0 : break;
3210 : default:
3211 0 : nPendingAttributes++;
3212 0 : break;
3213 : }
3214 : }
3215 :
3216 0 : if (pIsText)
3217 0 : HandleNodes(pIsText,nLevel+1);
3218 :
3219 0 : switch (pTemp->GetToken().eType)
3220 : {
3221 : case TWIDEVEC:
3222 : case TUNDERLINE:
3223 0 : EndTemplate(nOldPending);
3224 0 : break;
3225 : case TOVERLINE:
3226 0 : if ((pIsText->GetToken().eType != TTEXT) ||
3227 0 : (pIsText->GetText().getLength() > 1))
3228 0 : EndTemplate(nOldPending);
3229 0 : break;
3230 : default:
3231 0 : break;
3232 : }
3233 :
3234 : //if there was no suitable place to put the attribute,
3235 : //then we have to just give up on it
3236 0 : if (nPendingAttributes)
3237 0 : nPendingAttributes--;
3238 : else
3239 : {
3240 0 : if ((nInsertion != 0) && NULL != (pTemp = pNode->GetSubNode(0)))
3241 : {
3242 0 : sal_uLong nPos = pS->Tell();
3243 0 : nInsertion--;
3244 0 : pS->Seek(nInsertion);
3245 0 : switch(pTemp->GetToken().eType)
3246 : {
3247 : case TACUTE: //Not Exportable
3248 : case TGRAVE: //Not Exportable
3249 : case TCIRCLE: //Not Exportable
3250 0 : break;
3251 : case TCDOT:
3252 0 : pS->WriteUChar( sal_uInt8(2) );
3253 0 : break;
3254 : case TDDOT:
3255 0 : pS->WriteUChar( sal_uInt8(3) );
3256 0 : break;
3257 : case TDDDOT:
3258 0 : pS->WriteUChar( sal_uInt8(4) );
3259 0 : break;
3260 : case TTILDE:
3261 0 : pS->WriteUChar( sal_uInt8(8) );
3262 0 : break;
3263 : case THAT:
3264 0 : pS->WriteUChar( sal_uInt8(9) );
3265 0 : break;
3266 : case TVEC:
3267 0 : pS->WriteUChar( sal_uInt8(11) );
3268 0 : break;
3269 : case TOVERSTRIKE:
3270 0 : pS->WriteUChar( sal_uInt8(16) );
3271 0 : break;
3272 : case TOVERLINE:
3273 0 : if ((pIsText->GetToken().eType == TTEXT) &&
3274 0 : (pIsText->GetText().getLength() == 1))
3275 0 : pS->WriteUChar( sal_uInt8(17) );
3276 0 : break;
3277 : case TBREVE:
3278 0 : pS->WriteUChar( sal_uInt8(20) );
3279 0 : break;
3280 : case TWIDEVEC:
3281 : case TUNDERLINE:
3282 : case TWIDETILDE:
3283 : case TWIDEHAT:
3284 0 : break;
3285 : case TBAR:
3286 0 : pS->WriteUChar( sal_uInt8(17) );
3287 0 : break;
3288 : default:
3289 0 : pS->WriteUChar( sal_uInt8(0x2) );
3290 0 : break;
3291 : }
3292 0 : pS->Seek(nPos);
3293 : }
3294 : }
3295 0 : }
3296 :
3297 0 : void MathType::HandleText(SmNode *pNode, int /*nLevel*/)
3298 : {
3299 0 : SmTextNode *pTemp=(SmTextNode *)pNode;
3300 0 : for(sal_Int32 i=0;i<pTemp->GetText().getLength();i++)
3301 : {
3302 0 : if ((nPendingAttributes) &&
3303 0 : (i == ((pTemp->GetText().getLength()+1)/2)-1))
3304 : {
3305 0 : pS->WriteUChar( sal_uInt8(0x22) ); //char, with attributes right
3306 : //after the character
3307 : }
3308 : else
3309 0 : pS->WriteUChar( sal_uInt8(CHAR) );
3310 :
3311 0 : sal_uInt8 nFace = 0x1;
3312 0 : if (pNode->GetFont().GetItalic() == ITALIC_NORMAL)
3313 0 : nFace = 0x3;
3314 0 : else if (pNode->GetFont().GetWeight() == WEIGHT_BOLD)
3315 0 : nFace = 0x7;
3316 0 : pS->WriteUChar( sal_uInt8(nFace+128) ); //typeface
3317 0 : sal_uInt16 nChar = pTemp->GetText()[i];
3318 0 : pS->WriteUInt16( SmTextNode::ConvertSymbolToUnicode(nChar) );
3319 :
3320 : //Mathtype can only have these sort of character
3321 : //attributes on a single character, starmath can put them
3322 : //anywhere, when the entity involved is a text run this is
3323 : //a large effort to place the character attribute on the
3324 : //central mathtype character so that it does pretty much
3325 : //what the user probably has in mind. The attributes
3326 : //filled in here are dummy ones which are replaced in the
3327 : //ATTRIBUT handler if a suitable location for the
3328 : //attributes was found here. Unfortunately it is
3329 : //possible for starmath to place character attributes on
3330 : //entities which cannot occur in mathtype e.g. a Summation
3331 : //symbol so these attributes may be lost
3332 0 : if ((nPendingAttributes) &&
3333 0 : (i == ((pTemp->GetText().getLength()+1)/2)-1))
3334 : {
3335 0 : pS->WriteUChar( sal_uInt8(EMBEL) );
3336 0 : while (nPendingAttributes)
3337 : {
3338 0 : pS->WriteUChar( sal_uInt8(2) );
3339 : //wedge the attributes in here and clear
3340 : //the pending stack
3341 0 : nPendingAttributes--;
3342 : }
3343 0 : nInsertion=pS->Tell();
3344 0 : pS->WriteUChar( sal_uInt8(END) ); //end embel
3345 0 : pS->WriteUChar( sal_uInt8(END) ); //end embel
3346 : }
3347 : }
3348 0 : }
3349 :
3350 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|