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