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