1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: mathtype.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_starmath.hxx"
34 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
35 #include <mathtype.hxx>
37 #ifndef _TOOLS_DEBUG_H
38 #include <tools/debug.hxx>
41 #include <sfx2/docfile.hxx>
43 #define APPEND(str,ascii) str.AppendAscii(RTL_CONSTASCII_STRINGPARAM(ascii))
46 String aEmbelList
[21] =
55 "backwards prime (left of character)",
58 "diagonal slash through character",
61 "double-headed arrow",
62 "right single-barbed arrow",
63 "left single-barbed arrow",
64 "mid-height horizontal bar",
67 "over-arc, concave downward",
68 "over-arc, concave upward"
71 String aSelectorList
[49] =
75 "braces (curly brackets)",
78 "double vertical bars",
81 "left brace, left brace",
82 "right brace, right brace",
83 "right brace, left brace",
84 "left brace, right parenthesis",
85 "left parenthesis, right brace",
88 "subscript/superscript",
91 "left-pointing arrow",
92 "right-pointing arrow",
93 "left- and right-pointing arrow",
97 "single summation-style integral",
98 "double summation-style integral",
99 "triple summation-style integral",
100 "upper horizontal brace",
101 "lower horizontal brace",
103 "summation (integral-style limits)",
105 "product (integral-style limits)",
107 "coproduct (integral-style limits)",
109 "union (integral-style limits)",
111 "intersection (integral-style limits)",
115 "big integral-style operators",
116 "big summation-style operators",
117 "leading sub- and superscripts",
124 String aIntegralOpt
[2] =
126 "fixed-size integral",
127 "integral expands vertically to fit its contents"
130 String aFenceOpt
[3] =
132 "center fence on math axis",
133 "center fence on contents, place math axis of contents on math axis of containing line",
134 "center fence on contents, center contents on math axis of containing line"
137 String aTypeFaces
[12] =
165 static sal_Unicode
Convert(sal_Unicode nIn
)
167 //Find the best match in accepted unicode for our private area symbols
168 static sal_Unicode aStarMathPrivateToUnicode
[] =
170 0x2030, 0xF613, 0xF612, 0x002B, 0x003C, 0x003E, 0xE425, 0xE421, 0xE088, 0x2208,
171 0x0192, 0x2026, 0x2192, 0x221A, 0x221A, 0x221A, 0xE090, 0x005E, 0x02C7, 0x02D8,
172 0x00B4, 0x0060, 0x02DC, 0x00AF, 0x0362, 0xE099, 0xE09A, 0x20DB, 0xE09C, 0xE09D,
173 0x0028, 0x0029, 0x2220, 0x22AF, 0xE0A2, 0xE0A3, 0xE0A4, 0xE0A5, 0xE0A6, 0xE0A7,
174 0x002F, 0x005C, 0x274F, 0xE0AB, 0x0393, 0x0394, 0x0398, 0x039b, 0x039e, 0x03A0,
175 0x03a3, 0x03a5, 0x03a6, 0x03a8, 0x03A9, 0x03B1, 0x03B2, 0x03b3, 0x03b4, 0x03b5,
176 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
177 0x03c0, 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03b5,
178 0x03d1, 0x03d6, 0xE0D2, 0x03db, 0x2118, 0x2202, 0x2129, 0xE0D7, 0xE0D8, 0x22A4,
179 0xE0DA, 0x2190, 0x2191, 0x2193
181 if ((nIn
>= 0xE080) && (nIn
<= 0xE0DD))
182 nIn
= aStarMathPrivateToUnicode
[nIn
-0xE080];
184 //For whatever unicode glyph that equation editor doesn't ship with that
185 //we have a possible match we can munge it to.
198 void MathType::Init()
200 //These are the default MathType sizes
210 These are the default MathType italic/bold settings If mathtype is changed
211 from its defaults, there is nothing we can do, as this information is not
212 stored in the document
215 for(sal_uInt8 i
=1;i
<=11;i
++)
217 aFont
.nTface
= i
+128;
231 aUserStyles
.insert(aFont
);
236 /*ToDo replace with table rather than switch, returns
237 TRUE in the case that the char is just a char, and
238 FALSE if the character is an operator which must not be
239 placed inside the quote sequence designed to protect
240 against being parsed as a keyword
242 General solution required to force starmath to handle
243 unicode math chars the way it handles its own math
244 chars rathar than handle them as text as it will do
245 for the default case below, i.e. incorrect spacing
246 between math symbols and ordinary text e.g. 1=2 rather
249 sal_Bool
MathType::LookupChar(sal_Unicode nChar
,String
&rRet
,sal_uInt8 nVersion
,
253 const char *pC
= NULL
;
281 if ((nVersion
< 3) && (nTypeFace
== 0x86))
290 if ((nVersion
< 3) && (nTypeFace
== 0x81))
296 if ((nVersion
< 3) && (nTypeFace
== 0x84))
302 if ((nVersion
< 3) && (nTypeFace
== 0x84))
308 if ((nVersion
< 3) && (nTypeFace
== 0x84))
314 if ((nVersion
< 3) && (nTypeFace
== 0x84))
320 if ((nVersion
< 3) && (nTypeFace
== 0x84))
326 if ((nVersion
< 3) && (nTypeFace
== 0x84))
332 if ((nVersion
< 3) && (nTypeFace
== 0x82))
338 if ((nVersion
< 3) && (nTypeFace
== 0x86))
347 if ((nVersion
< 3) && (nTypeFace
== 0x86))
356 if ((nVersion
< 3) && (nTypeFace
== 0x86))
365 if ((nVersion
< 3) && (nTypeFace
== 0x85))
521 pC
= " intersection ";
644 case 0xeb01: //no space
645 case 0xeb08: //normal space
648 case 0xef04: //tiny space
649 case 0xef05: //tiny space
650 case 0xeb02: //small space
651 case 0xeb04: //medium space
654 case 0xeb05: //large space
666 rRet
.AppendAscii(pC
);
670 void MathTypeFont::AppendStyleToText(String
&rRet
)
672 const char *pC
= NULL
;
689 rRet
.AppendAscii(pC
);
692 void MathType::TypeFaceToString(String
&rTxt
,sal_uInt8 nFace
)
694 MathTypeFont
aFont(nFace
);
695 MathTypeFontSet::iterator aItr
= aUserStyles
.find(aFont
);
696 if (aItr
!= aUserStyles
.end())
697 aFont
.nStyle
= aItr
->nStyle
;
698 aFont
.AppendStyleToText(rTxt
);
701 int MathType::Parse(SotStorage
*pStor
)
703 SvStorageStreamRef xSrc
= pStor
->OpenSotStream(
704 String::CreateFromAscii("Equation Native"),
705 STREAM_STD_READ
| STREAM_NOCREATE
);
706 if ( (!xSrc
.Is()) || (SVSTREAM_OK
!= xSrc
->GetError()))
709 pS
->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
717 *pS
>> nProdSubVersion
;
719 if (nVersion
> 3) // allow only supported versions of MathType to be parsed
723 *pOut
<< "Format Version is " << int(nVersion
) << endl
;
724 *pOut
<< "Generating Platform is " << (nPlatform
? "Windows"
726 *pOut
<< "Generating Product is " << (nPlatform
? "Equation Editor"
727 : "Equation Editor") << endl
;
728 *pOut
<< "Prod Version is " << int(nProdVersion
) << "." <<
729 int(nProdSubVersion
) << endl
<< endl
;
732 int nRet
= HandleRecords();
733 //little crude hack to close ocassionally open expressions
734 //a sophisticated system to determine what expressions are
735 //opened is required, but this is as much work as rewriting
736 //starmaths internals.
739 #if OSL_DEBUG_LEVEL > 1
743 //sigh, theres no point! MathType (in some bizarre subvarient) pads
744 //the end of the formula with ENDs (0)'s
745 ULONG nEnd
= pS
->Tell();
746 DBG_ASSERT(nEnd
== pS
->Seek(STREAM_SEEK_TO_END
),
747 "Possibly unfully parsed formula");
753 static void lcl_PrependDummyTerm(String
&rRet
, xub_StrLen
&rTextStart
)
755 if ((rRet
.GetChar(rTextStart
) == '=') &&
756 ((rTextStart
== 0) ||
757 (rRet
.GetChar(rTextStart
-1) == '{'))
760 rRet
.InsertAscii(" {}",rTextStart
);
765 static void lcl_AppendDummyTerm(String
&rRet
)
767 sal_Bool bOk
=sal_False
;
768 for(int nI
=rRet
.Len()-1;nI
>= 0; nI
--)
770 xub_StrLen nIdx
= sal::static_int_cast
< xub_StrLen
>(nI
);
771 sal_Unicode nChar
= rRet
.GetChar(nIdx
);
774 if (rRet
.GetChar(nIdx
) != '{')
778 if (!bOk
) //No term, use dummy
782 void MathType::HandleNudge()
788 if (nXNudge
== 128 && nYNudge
== 128)
790 sal_uInt16 nXLongNudge
;
791 sal_uInt16 nYLongNudge
;
796 /*Fabously complicated as many tokens have to be reordered and generally
797 *moved around from mathtypes paradigm to starmaths.*/
798 int MathType::HandleRecords(int nLevel
,sal_uInt8 nSelector
,
799 sal_uInt8 nVariation
, int nMatrixRows
,int nMatrixCols
)
801 sal_uInt8 nTag
,nRecord
;
802 sal_uInt8 nTabType
,nTabStops
;
803 sal_uInt16 nTabOffset
;
806 int i
,nRet
=1,newline
=0;
807 sal_Bool bSilent
=FALSE
;
809 String sPush
,sMainTerm
;
810 int nSetSize
=0,nSetAlign
=0;
811 int nCurRow
=0,nCurCol
=0;
812 sal_Bool bOpenString
=FALSE
;
813 xub_StrLen nTextStart
= 0;
814 xub_StrLen nSubSupStartPos
= 0;
815 xub_StrLen nLastTemplateBracket
=STRING_NOTFOUND
;
822 /*MathType strings can of course include words which
823 *are StarMath keywords, the simplest solution is
824 to escape strings of greater than len 1 with double
825 quotes to avoid scanning the TokenTable for matches
827 Unfortunately it may turn out that the string gets
828 split during the handling of a character emblishment
829 so this special case must be handled in the
830 character handler case 2:
832 if ((nRecord
== CHAR
) && (!bIsSilent
) && (!bOpenString
))
835 nTextStart
= rRet
.Len();
837 else if ((nRecord
!= CHAR
) && (bOpenString
))
840 if ((rRet
.Len() - nTextStart
) > 1)
843 TypeFaceToString(aStr
,nTypeFace
);
845 rRet
.Insert(aStr
,nTextStart
);
852 sal_Unicode cChar
= 0;
853 xub_StrLen nI
= rRet
.Len()-1;
854 while (nI
&& ((cChar
= rRet
.GetChar(nI
)) == ' '))
856 if ((cChar
== '=') || (cChar
== '+') || (cChar
== '-'))
868 //if (xfLSPACE(nTag))
872 APPEND(rRet
,"\nnewline\n");
879 APPEND(rRet
," langle ");
880 else if (nVariation
==1)
881 APPEND(rRet
," \\langle ");
885 APPEND(rRet
," left (");
886 else if (nVariation
==1)
890 if ((nVariation
==0) || (nVariation
==1))
891 APPEND(rRet
," left lbrace ");
893 APPEND(rRet
," left none ");
897 APPEND(rRet
," left [");
898 else if (nVariation
==1)
907 APPEND(rRet
," lline ");
908 else if (nVariation
==1)
909 APPEND(rRet
," \\lline ");
913 APPEND(rRet
," ldline ");
914 else if (nVariation
==1)
915 APPEND(rRet
," \\ldline ");
918 if (nVariation
== 0 || nVariation
== 1)
919 APPEND(rRet
," left lfloor ");
920 else if (nVariation
==1)
921 APPEND(rRet
," left none ");
925 APPEND(rRet
," lceil ");
926 else if (nVariation
==1)
927 APPEND(rRet
," \\lceil ");
940 APPEND(rRet
," sqrt");
943 APPEND(rRet
," nroot");
956 APPEND(rRet
," over ");
960 nSubSupStartPos
= rRet
.Len();
961 if ((nVariation
== 0) ||
962 ((nVariation
== 2) && (nPart
==1)))
964 lcl_AppendDummyTerm(rRet
);
965 APPEND(rRet
," rSup");
967 else if ((nVariation
== 1) ||
968 ((nVariation
== 2) && (nPart
==0)))
970 lcl_AppendDummyTerm(rRet
);
971 APPEND(rRet
," rSub");
977 APPEND(rRet
," {underline ");
978 else if (nVariation
== 1)
979 APPEND(rRet
," {underline underline ");
984 APPEND(rRet
," {overline ");
985 else if (nVariation
== 1)
986 APPEND(rRet
," {overline overline ");
993 APPEND(rRet
," widevec ");//left arrow above
994 else if (nVariation
== 1)
995 APPEND(rRet
," widevec ");//left arrow below
1002 if (nVariation
== 0)
1003 APPEND(rRet
," widevec ");//right arrow above
1004 else if (nVariation
== 1)
1005 APPEND(rRet
," widevec ");//right arrow below
1012 if (nVariation
== 0)
1013 APPEND(rRet
," widevec ");//double arrow above
1014 else if (nVariation
== 1)
1015 APPEND(rRet
," widevec ");//double arrow below
1022 if ((nVariation
== 3) || (nVariation
== 4))
1023 APPEND(rRet
," lInt");
1025 APPEND(rRet
," Int");
1026 if ( (nVariation
!= 0) && (nVariation
!= 3))
1032 if (((nVariation
== 1) ||
1033 (nVariation
== 4)) && (nPart
==1))
1034 APPEND(rRet
," rSub");
1035 else if ((nVariation
== 2) && (nPart
==2))
1036 APPEND(rRet
," rSup");
1037 else if ((nVariation
== 2) && (nPart
==1))
1038 APPEND(rRet
," rSub");
1044 if ((nVariation
== 2) || (nVariation
== 3))
1045 APPEND(rRet
," llInt");
1047 APPEND(rRet
," iInt");
1048 if ( (nVariation
!= 0) && (nVariation
!= 2))
1054 if (((nVariation
== 1) ||
1055 (nVariation
== 3)) && (nPart
==1))
1056 APPEND(rRet
," rSub");
1062 if ((nVariation
== 2) || (nVariation
== 3))
1063 APPEND(rRet
," lllInt");
1065 APPEND(rRet
," iiInt");
1066 if ( (nVariation
!= 0) && (nVariation
!= 2))
1072 if (((nVariation
== 1) ||
1073 (nVariation
== 3)) && (nPart
==1))
1074 APPEND(rRet
," rSub");
1080 if (nVariation
== 2)
1081 APPEND(rRet
," lInt");
1083 APPEND(rRet
," Int");
1087 if (((nVariation
== 1) ||
1088 (nVariation
== 2)) && (nPart
==1))
1089 APPEND(rRet
," cSub");
1090 else if ((nVariation
== 0) && (nPart
==2))
1091 APPEND(rRet
," cSup");
1092 else if ((nVariation
== 0) && (nPart
==1))
1093 APPEND(rRet
," cSub");
1099 if (nVariation
== 0)
1100 APPEND(rRet
," llInt");
1102 APPEND(rRet
," iInt");
1107 APPEND(rRet
," cSub");
1113 if (nVariation
== 0)
1114 APPEND(rRet
," lllInt");
1116 APPEND(rRet
," iiInt");
1121 APPEND(rRet
," cSub");
1131 APPEND(rRet
," Sum");
1132 if (nVariation
!= 2)
1138 if ((nVariation
== 0) && (nPart
==1))
1139 APPEND(rRet
," cSub");
1140 else if ((nVariation
== 1) && (nPart
==2))
1141 APPEND(rRet
," cSup");
1142 else if ((nVariation
== 1) && (nPart
==1))
1143 APPEND(rRet
," cSub");
1149 APPEND(rRet
," Sum");
1153 if ((nVariation
== 0) && (nPart
==1))
1154 APPEND(rRet
," rSub");
1155 else if ((nVariation
== 1) && (nPart
==2))
1156 APPEND(rRet
," rSup");
1157 else if ((nVariation
== 1) && (nPart
==1))
1158 APPEND(rRet
," rSub");
1164 APPEND(rRet
," Prod");
1165 if (nVariation
!= 2)
1171 if ((nVariation
== 0) && (nPart
==1))
1172 APPEND(rRet
," cSub");
1173 else if ((nVariation
== 1) && (nPart
==2))
1174 APPEND(rRet
," cSup");
1175 else if ((nVariation
== 1) && (nPart
==1))
1176 APPEND(rRet
," cSub");
1182 APPEND(rRet
," Prod");
1186 if ((nVariation
== 0) && (nPart
==1))
1187 APPEND(rRet
," rSub");
1188 else if ((nVariation
== 1) && (nPart
==2))
1189 APPEND(rRet
," rSup");
1190 else if ((nVariation
== 1) && (nPart
==1))
1191 APPEND(rRet
," rSub");
1197 APPEND(rRet
," coProd");
1198 if (nVariation
!= 2)
1204 if ((nVariation
== 0) && (nPart
==1))
1205 APPEND(rRet
," cSub");
1206 else if ((nVariation
== 1) && (nPart
==2))
1207 APPEND(rRet
," cSup");
1208 else if ((nVariation
== 1) && (nPart
==1))
1209 APPEND(rRet
," cSub");
1215 APPEND(rRet
," coProd");
1219 if ((nVariation
== 0) && (nPart
==1))
1220 APPEND(rRet
," rSub");
1221 else if ((nVariation
== 1) && (nPart
==2))
1222 APPEND(rRet
," rSup");
1223 else if ((nVariation
== 1) && (nPart
==1))
1224 APPEND(rRet
," rSub");
1230 APPEND(rRet
," union"); //union
1231 if (nVariation
!= 2)
1237 if ((nVariation
== 0) && (nPart
==1))
1238 APPEND(rRet
," cSub");
1239 else if ((nVariation
== 1) && (nPart
==2))
1240 APPEND(rRet
," cSup");
1241 else if ((nVariation
== 1) && (nPart
==1))
1242 APPEND(rRet
," cSub");
1248 APPEND(rRet
," union"); //union
1252 if ((nVariation
== 0) && (nPart
==1))
1253 APPEND(rRet
," rSub");
1254 else if ((nVariation
== 1) && (nPart
==2))
1255 APPEND(rRet
," rSup");
1256 else if ((nVariation
== 1) && (nPart
==1))
1257 APPEND(rRet
," rSub");
1263 APPEND(rRet
," intersect"); //intersect
1264 if (nVariation
!= 2)
1270 if ((nVariation
== 0) && (nPart
==1))
1271 APPEND(rRet
," cSub");
1272 else if ((nVariation
== 1) && (nPart
==2))
1273 APPEND(rRet
," cSup");
1274 else if ((nVariation
== 1) && (nPart
==1))
1275 APPEND(rRet
," cSub");
1281 APPEND(rRet
," intersect"); //intersect
1285 if ((nVariation
== 0) && (nPart
==1))
1286 APPEND(rRet
," rSub");
1287 else if ((nVariation
== 1) && (nPart
==2))
1288 APPEND(rRet
," rSup");
1289 else if ((nVariation
== 1) && (nPart
==1))
1290 APPEND(rRet
," rSub");
1294 if ((nVariation
== 0) && (nPart
==1))
1295 APPEND(rRet
," cSup");
1296 else if ((nVariation
== 1) && (nPart
==1))
1297 APPEND(rRet
," cSub");
1298 else if ((nVariation
== 2) && (nPart
==1))
1299 APPEND(rRet
," cSub");
1300 else if ((nVariation
== 2) && (nPart
==2))
1301 APPEND(rRet
," cSup");
1305 if (nVariation
== 0)
1314 if (nVariation
== 0)
1317 APPEND(rRet
,"alignr ");
1320 APPEND(rRet
,"\\lline ");
1321 if (nVariation
== 1)
1322 APPEND(rRet
,"overline ");
1333 if ((nVariation
== 0) && (nPart
==0))
1334 APPEND(rRet
," rSup");
1335 else if ((nVariation
== 2) && (nPart
==1))
1336 APPEND(rRet
," rSup");
1337 else if ((nVariation
== 1) && (nPart
==0))
1338 APPEND(rRet
," rSub");
1339 else if ((nVariation
== 2) && (nPart
==0))
1340 APPEND(rRet
," rSub");
1349 if ((nVariation
== 0) && (nPart
==0))
1350 APPEND(rRet
," cSup");
1351 else if ((nVariation
== 2) && (nPart
==1))
1352 APPEND(rRet
," cSup");
1353 else if ((nVariation
== 1) && (nPart
==0))
1354 APPEND(rRet
," cSub");
1355 else if ((nVariation
== 2) && (nPart
==0))
1356 APPEND(rRet
," cSub");
1361 APPEND(rRet
,"\"\"");
1362 if ((nVariation
== 0)
1363 || ((nVariation
== 2) && (nPart
==1)))
1364 APPEND(rRet
," lSup");
1365 else if ((nVariation
== 1)
1366 || ((nVariation
== 2) && (nPart
==0)))
1367 APPEND(rRet
," lSub");
1374 APPEND(rRet
," langle ");
1376 else if (nVariation
==1)
1378 APPEND(rRet
," \\langle ");
1381 else if (nVariation
==2)
1383 APPEND(rRet
," \\lline ");
1388 if (nVariation
== 0)
1389 APPEND(rRet
," widevec ");//left below
1390 else if (nVariation
== 1)
1391 APPEND(rRet
," widevec ");//right below
1392 else if (nVariation
== 2)
1393 APPEND(rRet
," widevec ");//double headed below
1397 if (nVariation
== 0)
1398 APPEND(rRet
," widevec ");//left above
1399 else if (nVariation
== 1)
1400 APPEND(rRet
," widevec ");//right above
1401 else if (nVariation
== 2)
1402 APPEND(rRet
," widevec ");//double headed above
1408 sal_Int16 nOldCurSize
=nCurSize
;
1409 xub_StrLen nSizeStartPos
= rRet
.Len();
1410 HandleSize(nLSize
,nDSize
,nSetSize
);
1411 nRet
= HandleRecords(nLevel
+1);
1414 sal_Bool bOk
=sal_False
;
1415 xub_StrLen nI
= rRet
.SearchBackward('{');
1416 if (nI
!= STRING_NOTFOUND
)
1418 for(nI
=nI
+1;nI
<rRet
.Len();nI
++)
1419 if (rRet
.GetChar(nI
) != ' ')
1431 rRet
.Erase(nSizeStartPos
);
1433 nCurSize
=nOldCurSize
;
1437 HandleMatrixSeperator(nMatrixRows
,nMatrixCols
,
1444 APPEND(rRet
," rangle ");
1445 else if (nVariation
==2)
1446 APPEND(rRet
," \\rangle ");
1450 APPEND(rRet
," right )");
1451 else if (nVariation
==2)
1455 if ((nVariation
==0) || (nVariation
==2))
1456 APPEND(rRet
," right rbrace ");
1458 APPEND(rRet
," right none ");
1462 APPEND(rRet
," right ]");
1463 else if (nVariation
==2)
1468 APPEND(rRet
," rline ");
1469 else if (nVariation
==2)
1470 APPEND(rRet
," \\rline ");
1474 APPEND(rRet
," rdline ");
1475 else if (nVariation
==2)
1476 APPEND(rRet
," \\rdline ");
1479 if (nVariation
== 0 || nVariation
== 2)
1480 APPEND(rRet
," right rfloor ");
1481 else if (nVariation
==2)
1482 APPEND(rRet
," right none ");
1486 APPEND(rRet
," rceil ");
1487 else if (nVariation
==2)
1488 APPEND(rRet
," \\rceil ");
1500 if (nVariation
== 1)
1536 ((nVariation
== 2) || (nVariation
== 1)))
1539 sal_Bool bOk
=sal_False
;
1540 xub_StrLen nI
= rRet
.SearchBackward('{');
1541 if (nI
!= STRING_NOTFOUND
)
1543 for(nI
=nI
+1;nI
<rRet
.Len();nI
++)
1544 if (rRet
.GetChar(nI
) != ' ')
1556 rRet
.Erase(nSubSupStartPos
);
1562 ((nVariation
== 2) || (nVariation
== 1)))
1590 APPEND(rRet
,"overbrace");
1599 APPEND(rRet
,"underbrace");
1606 else if ((nPart
==1) &&
1607 ((nVariation
== 2) || (nVariation
== 1)))
1614 if (nVariation
== 0)
1625 APPEND(rRet
," over ");
1641 APPEND(rRet
,"slash");
1644 APPEND(rRet
,"wideslash");
1663 if (nVariation
!= 2)
1670 else if ((nPart
== 1) && (nVariation
== 0))
1677 else if ((nPart
== 1) && (nVariation
== 1))
1679 else if ((nPart
== 2) && (nVariation
== 1))
1692 if ((nVariation
!= 0) && (nVariation
!= 3))
1699 else if ((nPart
== 1) &&
1700 ((nVariation
== 1) || (nVariation
==4)))
1707 else if ((nPart
== 1) && (nVariation
== 2))
1709 else if ((nPart
== 2) && (nVariation
== 2))
1723 if ((nVariation
!= 0) && (nVariation
!= 2))
1730 else if ((nPart
== 1) &&
1731 ((nVariation
== 1) || (nVariation
==3)))
1748 else if ((nPart
== 1) &&
1749 ((nVariation
== 1) || (nVariation
==2)))
1756 else if ((nPart
== 1) && (nVariation
== 0))
1758 else if ((nPart
== 2) && (nVariation
== 0))
1776 else if (nPart
== 1)
1790 ((nVariation
== 0) || (nVariation
== 1)))
1796 else if ((nPart
== 0) && (nVariation
== 2))
1798 else if ((nPart
== 1) && (nVariation
== 2))
1804 else if ((nPart
== 2) || ((((nPart
== 1) &&
1805 (nVariation
== 0)) || (nVariation
== 1))))
1818 newline
--; //there is another term to arrive
1819 APPEND(rRet
," mline ");
1822 APPEND(rRet
," rangle ");
1824 else if (nVariation
==1)
1825 APPEND(rRet
," \\lline ");
1826 else if (nVariation
==2)
1827 APPEND(rRet
," \\rangle ");
1833 bSilent
= TRUE
; //Skip the optional brackets and/or
1834 //symbols that follow some of these
1835 //records. Foo Data.
1837 /*In matrices and piles we cannot seperate equation
1838 *lines with the newline keyword*/
1847 nRet
= HandleChar(nTextStart
,nSetSize
,nLevel
,nTag
,nSelector
,
1848 nVariation
,bSilent
);
1853 nRet
= HandleTemplate(nLevel
,nSelector
,nVariation
,
1854 nLastTemplateBracket
);
1859 nRet
= HandlePile(nSetAlign
,nLevel
,nSelector
,nVariation
);
1860 HandleMatrixSeperator(nMatrixRows
,nMatrixCols
,nCurCol
,nCurRow
);
1865 nRet
= HandleMatrix(nLevel
,nSelector
,nVariation
);
1866 HandleMatrixSeperator(nMatrixRows
,nMatrixCols
,nCurCol
,nCurRow
);
1871 HandleEmblishments();
1875 for (i
=0;i
<nTabStops
;i
++)
1880 DBG_ASSERT(FALSE
,"Not seen in the wild Equation Ruler Field");
1885 *pS
>> aFont
.nTface
;
1887 The typeface number is the negative (which makes it
1888 positive) of the typeface value (unbiased) that appears in
1889 CHAR records that might follow a given FONT record
1891 aFont
.nTface
= 128-aFont
.nTface
;
1892 *pS
>> aFont
.nStyle
;
1893 aUserStyles
.insert(aFont
);
1898 sFontName
.Append(ByteString::ConvertToUnicode(
1899 nChar8
,RTL_TEXTENCODING_MS_1252
));
1919 while (nRecord
!= END
&& !pS
->IsEof());
1928 /*Simply determine if we are at the end of a record or the end of a line,
1929 *with fiddley logic to see if we are in a matrix or a pile or neither
1931 Note we cannot tell until after the event that this is the last entry
1932 of a pile, so we must strip the last seperator of a pile after this
1933 is detected in the PILE handler
1935 void MathType::HandleMatrixSeperator(int nMatrixRows
,int nMatrixCols
,
1936 int &rCurCol
,int &rCurRow
)
1940 if (rCurCol
== nMatrixCols
-1)
1942 if (rCurRow
!= nMatrixRows
-1)
1943 APPEND(rRet
," {} ##\n");
1944 if (nMatrixRows
!=-1)
1952 APPEND(rRet
," {} # ");
1953 if (nMatrixRows
!=-1)
1961 /* set the alignment of the following term, but starmath currently
1962 * cannot handle vertical alignment */
1963 void MathType::HandleAlign(sal_uInt8 nHorAlign
, sal_uInt8
/*nVAlign*/, int &rSetAlign
)
1969 APPEND(rRet
,"alignl {");
1972 APPEND(rRet
,"alignc {");
1975 APPEND(rRet
,"alignr {");
1987 /* set size of text, complexity due to overuse of signedness as a flag
1988 * indicator by mathtype file format*/
1989 sal_Bool
MathType::HandleSize(sal_Int16 nLstSize
,sal_Int16 nDefSize
, int &rSetSize
)
1991 sal_Bool bRet
=FALSE
;
1994 if ((-nLstSize
/32 != nDefaultSize
) && (-nLstSize
/32 != nCurSize
))
2002 if (-nLstSize
/32 != nLastSize
)
2004 nLastSize
= nCurSize
;
2005 APPEND(rRet
," size ");
2006 rRet
+= String::CreateFromInt32(-nLstSize
/32);
2011 nCurSize
= -nLstSize
/32;
2016 /*sizetable should theoreticaly be filled with the default sizes
2017 *of the various font groupings matching starmaths equivalents
2018 in aTypeFaces, and a test would be done to see if the new font
2019 size would be the same as what starmath would have chosen for
2020 itself anyway in which case the size setting could be ignored*/
2021 nLstSize
= aSizeTable
[nLstSize
];
2022 nLstSize
= nLstSize
+ nDefSize
;
2023 //if (nLstSize != nDefaultSize)
2024 if (nLstSize
!= nCurSize
)
2032 if (nLstSize
!= nLastSize
)
2034 nLastSize
= nCurSize
;
2035 APPEND(rRet
," size ");
2036 rRet
+= String::CreateFromInt32(nLstSize
);
2041 nCurSize
= nLstSize
;
2047 int MathType::ConvertFromStarMath( SfxMedium
& rMedium
)
2052 SvStream
*pStream
= rMedium
.GetOutStream();
2055 SvStorageRef pStor
= new SotStorage( pStream
, FALSE
);
2057 SvGlobalName
aGName(0x0002ce02L
, 0x0000, 0x0000,0xc0,0x00,
2058 0x00,0x00,0x00,0x00,0x00,0x46 );
2059 pStor
->SetClass( aGName
, 0, C2S("Microsoft Equation 3.0"));
2061 static sal_uInt8 __READONLY_DATA aCompObj
[] = {
2062 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
2063 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0xCE, 0x02, 0x00,
2064 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
2065 0x00, 0x00, 0x00, 0x46, 0x17, 0x00, 0x00, 0x00,
2066 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
2067 0x74, 0x20, 0x45, 0x71, 0x75, 0x61, 0x74, 0x69,
2068 0x6F, 0x6E, 0x20, 0x33, 0x2E, 0x30, 0x00, 0x0C,
2069 0x00, 0x00, 0x00, 0x44, 0x53, 0x20, 0x45, 0x71,
2070 0x75, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x0B,
2071 0x00, 0x00, 0x00, 0x45, 0x71, 0x75, 0x61, 0x74,
2072 0x69, 0x6F, 0x6E, 0x2E, 0x33, 0x00, 0xF4, 0x39,
2073 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2074 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2076 SvStorageStreamRef
xStor( pStor
->OpenSotStream( C2S("\1CompObj")));
2077 xStor
->Write(aCompObj
,sizeof(aCompObj
));
2079 static sal_uInt8 __READONLY_DATA aOle
[] = {
2080 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
2081 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2082 0x00, 0x00, 0x00, 0x00
2084 SvStorageStreamRef
xStor2( pStor
->OpenSotStream( C2S("\1Ole")));
2085 xStor2
->Write(aOle
,sizeof(aOle
));
2089 SvStorageStreamRef xSrc
= pStor
->OpenSotStream(C2S("Equation Native"));
2090 if ( (!xSrc
.Is()) || (SVSTREAM_OK
!= xSrc
->GetError()))
2094 pS
->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
2096 pS
->SeekRel(EQNOLEFILEHDR_SIZE
); //Skip 28byte Header and fill it in later
2097 *pS
<< sal_uInt8(0x03);
2098 *pS
<< sal_uInt8(0x01);
2099 *pS
<< sal_uInt8(0x01);
2100 *pS
<< sal_uInt8(0x03);
2101 *pS
<< sal_uInt8(0x00);
2102 sal_uInt32 nSize
= pS
->Tell();
2103 nPendingAttributes
=0;
2106 *pS
<< sal_uInt8(END
);
2108 nSize
= pS
->Tell()-nSize
;
2110 EQNOLEFILEHDR
aHdr(nSize
+4+1);
2120 sal_uInt8
MathType::HandleNodes(SmNode
*pNode
,int nLevel
)
2122 sal_Bool bRet
=FALSE
;
2123 switch(pNode
->GetType())
2126 HandleAttributes(pNode
,nLevel
);
2129 HandleText(pNode
,nLevel
);
2131 case NVERTICAL_BRACE
:
2132 HandleVerticalBrace(pNode
,nLevel
);
2135 HandleBrace(pNode
,nLevel
);
2138 HandleOperator(pNode
,nLevel
);
2141 HandleFractions(pNode
,nLevel
);
2144 HandleRoot(pNode
,nLevel
);
2148 SmTextNode
*pText
=(SmTextNode
*)pNode
;
2149 //if the token str and the result text are the same then this
2150 //is to be seen as text, else assume its a mathchar
2151 if (pText
->GetText() == pText
->GetToken().aText
)
2152 HandleText(pText
,nLevel
);
2154 HandleMath(pText
,nLevel
);
2158 HandleMath(pNode
,nLevel
);
2161 HandleSubSupScript(pNode
,nLevel
);
2165 USHORT nSize
= pNode
->GetNumSubNodes();
2166 for (USHORT i
= 0; i
< nSize
; i
++)
2167 if (SmNode
*pTemp
= pNode
->GetSubNode(i
))
2168 HandleNodes(pTemp
,nLevel
+1);
2172 //Root Node, PILE equivalent, i.e. vertical stack
2173 HandleTable(pNode
,nLevel
);
2176 HandleSmMatrix((SmMatrixNode
*)pNode
,nLevel
);
2180 *pS
<< sal_uInt8(0x0a);
2181 *pS
<< sal_uInt8(LINE
);
2182 USHORT nSize
= pNode
->GetNumSubNodes();
2183 for (USHORT i
= 0; i
< nSize
; i
++)
2184 if (SmNode
*pTemp
= pNode
->GetSubNode(i
))
2185 HandleNodes(pTemp
,nLevel
+1);
2186 *pS
<< sal_uInt8(END
);
2190 HandleMAlign(pNode
,nLevel
);
2193 *pS
<< sal_uInt8(CHAR
);
2194 *pS
<< sal_uInt8(0x98);
2195 if (pNode
->GetToken().eType
== TSBLANK
)
2196 *pS
<< sal_uInt16(0xEB04);
2198 *pS
<< sal_uInt16(0xEB05);
2202 USHORT nSize
= pNode
->GetNumSubNodes();
2203 for (USHORT i
= 0; i
< nSize
; i
++)
2204 if (SmNode
*pTemp
= pNode
->GetSubNode(i
))
2205 HandleNodes(pTemp
,nLevel
+1);
2213 int MathType::StartTemplate(sal_uInt16 nSelector
,sal_uInt16 nVariation
)
2215 int nOldPending
=nPendingAttributes
;
2216 *pS
<< sal_uInt8(TMPL
); //Template
2217 *pS
<< sal_uInt8(nSelector
); //selector
2218 *pS
<< sal_uInt8(nVariation
); //variation
2219 *pS
<< sal_uInt8(0x00); //options
2220 *pS
<< sal_uInt8(LINE
);
2221 //theres just no way we can now handle any character
2222 //attributes (from mathtypes perspective) centered
2223 //over an expression but above template attribute
2224 //such as widevec and similiar constructs
2225 //we have to drop them
2226 nPendingAttributes
=0;
2230 void MathType::EndTemplate(int nOldPendingAttributes
)
2232 *pS
<< sal_uInt8(END
); //end line
2233 *pS
<< sal_uInt8(END
); //end template
2234 nPendingAttributes
=nOldPendingAttributes
;
2238 void MathType::HandleSmMatrix(SmMatrixNode
*pMatrix
,int nLevel
)
2240 *pS
<< sal_uInt8(MATRIX
);
2241 *pS
<< sal_uInt8(0x00); //vAlign ?
2242 *pS
<< sal_uInt8(0x00); //h_just
2243 *pS
<< sal_uInt8(0x00); //v_just
2244 *pS
<< sal_uInt8(pMatrix
->GetNumRows()); //v_just
2245 *pS
<< sal_uInt8(pMatrix
->GetNumCols()); //v_just
2246 int nBytes
=(pMatrix
->GetNumRows()+1)*2/8;
2247 if (((pMatrix
->GetNumRows()+1)*2)%8)
2249 for (USHORT j
= 0; j
< nBytes
; j
++)
2250 *pS
<< sal_uInt8(0x00); //row_parts
2251 nBytes
=(pMatrix
->GetNumCols()+1)*2/8;
2252 if (((pMatrix
->GetNumCols()+1)*2)%8)
2254 for (USHORT k
= 0; k
< nBytes
; k
++)
2255 *pS
<< sal_uInt8(0x00); //col_parts
2256 USHORT nSize
= pMatrix
->GetNumSubNodes();
2257 for (USHORT i
= 0; i
< nSize
; i
++)
2258 if (SmNode
*pTemp
= pMatrix
->GetSubNode(i
))
2260 *pS
<< sal_uInt8(LINE
); //line
2261 HandleNodes(pTemp
,nLevel
+1);
2262 *pS
<< sal_uInt8(END
); //end line
2264 *pS
<< sal_uInt8(END
);
2268 //Root Node, PILE equivalent, i.e. vertical stack
2269 void MathType::HandleTable(SmNode
*pNode
,int nLevel
)
2271 USHORT nSize
= pNode
->GetNumSubNodes();
2272 //The root of the starmath is a table, if
2273 //we convert this them each iteration of
2274 //conversion from starmath to mathtype will
2275 //add an extra unnecessary level to the
2276 //mathtype output stack which would grow
2277 //without bound in a multi step conversion
2280 *pS
<< sal_uInt8(0x0A); //initial size
2282 if ( nLevel
|| (nSize
>1))
2284 *pS
<< sal_uInt8(PILE
);
2285 *pS
<< sal_uInt8(nHAlign
); //vAlign ?
2286 *pS
<< sal_uInt8(0x01); //hAlign
2289 for (USHORT i
= 0; i
< nSize
; i
++)
2290 if (SmNode
*pTemp
= pNode
->GetSubNode(i
))
2292 *pS
<< sal_uInt8(LINE
);
2293 HandleNodes(pTemp
,nLevel
+1);
2294 *pS
<< sal_uInt8(END
);
2296 if (nLevel
|| (nSize
>1))
2297 *pS
<< sal_uInt8(END
);
2301 void MathType::HandleRoot(SmNode
*pNode
,int nLevel
)
2303 //USHORT nSize = pNode->GetNumSubNodes();
2305 *pS
<< sal_uInt8(TMPL
); //Template
2306 *pS
<< sal_uInt8(0x0D); //selector
2307 if (pNode
->GetSubNode(0))
2308 *pS
<< sal_uInt8(0x01); //variation
2310 *pS
<< sal_uInt8(0x00); //variation
2311 *pS
<< sal_uInt8(0x00); //options
2314 if (pTemp = pNode->GetSubNode(1))
2315 HandleNodes(pTemp,nLevel+1);
2317 if (NULL
!= (pTemp
= pNode
->GetSubNode(2)))
2319 *pS
<< sal_uInt8(LINE
); //line
2320 HandleNodes(pTemp
,nLevel
+1);
2321 *pS
<< sal_uInt8(END
);
2324 if (NULL
!= (pTemp
= pNode
->GetSubNode(0)))
2326 *pS
<< sal_uInt8(LINE
); //line
2327 HandleNodes(pTemp
,nLevel
+1);
2328 *pS
<< sal_uInt8(END
);
2331 *pS
<< sal_uInt8(LINE
|0x10); //dummy line
2335 *pS
<< sal_uInt8(END
);
2338 sal_uInt8
MathType::HandleCScript(SmNode
*pNode
,SmNode
*pContent
,int nLevel
,
2339 ULONG
*pPos
,sal_Bool bTest
)
2341 sal_uInt8 nVariation2
=0xff;
2343 if (bTest
&& pNode
->GetSubNode(CSUP
+1))
2346 if (pNode
->GetSubNode(CSUB
+1))
2349 else if (pNode
->GetSubNode(CSUB
+1))
2352 if (nVariation2
!=0xff)
2356 *pS
<< sal_uInt8(TMPL
); //Template
2357 *pS
<< sal_uInt8(0x2B); //selector
2359 *pS
<< sal_uInt8(0x00); //options
2363 *pS
<< sal_uInt8(LINE
); //line
2364 HandleNodes(pContent
,nLevel
+1);
2365 *pS
<< sal_uInt8(END
); //line
2368 *pS
<< sal_uInt8(LINE
|0x10);
2370 *pS
<< sal_uInt8(0x0B);
2373 if (NULL
!= (pTemp
= pNode
->GetSubNode(CSUB
+1)))
2375 *pS
<< sal_uInt8(LINE
); //line
2376 HandleNodes(pTemp
,nLevel
+1);
2377 *pS
<< sal_uInt8(END
); //line
2380 *pS
<< sal_uInt8(LINE
|0x10);
2381 if (bTest
&& NULL
!= (pTemp
= pNode
->GetSubNode(CSUP
+1)))
2383 *pS
<< sal_uInt8(LINE
); //line
2384 HandleNodes(pTemp
,nLevel
+1);
2385 *pS
<< sal_uInt8(END
); //line
2388 *pS
<< sal_uInt8(LINE
|0x10);
2396 Sub and Sup scripts and another problem area, StarMath
2397 can have all possible options used at the same time, whereas
2398 Mathtype cannot. The ordering of the nodes for each system
2399 is quite different as well leading to some complexity
2401 void MathType::HandleSubSupScript(SmNode
*pNode
,int nLevel
)
2403 //USHORT nSize = pNode->GetNumSubNodes();
2406 sal_uInt8 nVariation
=0xff;
2407 if (pNode
->GetSubNode(LSUP
+1))
2410 if (pNode
->GetSubNode(LSUB
+1))
2413 else if (NULL
!= (pTemp
= pNode
->GetSubNode(LSUB
+1)))
2416 if (nVariation
!=0xff)
2418 *pS
<< sal_uInt8(TMPL
); //Template
2419 *pS
<< sal_uInt8(0x2c); //selector
2421 *pS
<< sal_uInt8(0x00); //options
2422 *pS
<< sal_uInt8(0x0B);
2424 if (NULL
!= (pTemp
= pNode
->GetSubNode(LSUB
+1)))
2426 *pS
<< sal_uInt8(LINE
); //line
2427 HandleNodes(pTemp
,nLevel
+1);
2428 *pS
<< sal_uInt8(END
); //line
2431 *pS
<< sal_uInt8(LINE
|0x10);
2432 if (NULL
!= (pTemp
= pNode
->GetSubNode(LSUP
+1)))
2434 *pS
<< sal_uInt8(LINE
); //line
2435 HandleNodes(pTemp
,nLevel
+1);
2436 *pS
<< sal_uInt8(END
); //line
2439 *pS
<< sal_uInt8(LINE
|0x10);
2440 *pS
<< sal_uInt8(END
);
2445 sal_uInt8 nVariation2
=HandleCScript(pNode
,NULL
,nLevel
);
2447 if (NULL
!= (pTemp
= pNode
->GetSubNode(0)))
2449 // *pS << sal_uInt8(0x0A);
2450 // *pS << sal_uInt8(LINE);
2451 HandleNodes(pTemp
,nLevel
+1);
2452 // *pS << sal_uInt8(END);
2455 if (nVariation2
!= 0xff)
2456 *pS
<< sal_uInt8(END
);
2458 if (NULL
!= (pNode
->GetSubNode(RSUP
+1)))
2461 if (pNode
->GetSubNode(RSUB
+1))
2464 else if (NULL
!= (pTemp
= pNode
->GetSubNode(RSUB
+1)))
2467 if (nVariation
!=0xff)
2469 *pS
<< sal_uInt8(TMPL
); //Template
2470 *pS
<< sal_uInt8(0x0F); //selector
2472 *pS
<< sal_uInt8(0x00); //options
2473 *pS
<< sal_uInt8(0x0B);
2475 if (NULL
!= (pTemp
= pNode
->GetSubNode(RSUB
+1)))
2477 *pS
<< sal_uInt8(LINE
); //line
2478 HandleNodes(pTemp
,nLevel
+1);
2479 *pS
<< sal_uInt8(END
); //line
2482 *pS
<< sal_uInt8(LINE
|0x10);
2483 if (NULL
!= (pTemp
= pNode
->GetSubNode(RSUP
+1)))
2485 *pS
<< sal_uInt8(LINE
); //line
2486 HandleNodes(pTemp
,nLevel
+1);
2487 *pS
<< sal_uInt8(END
); //line
2490 *pS
<< sal_uInt8(LINE
|0x10);
2491 *pS
<< sal_uInt8(END
); //line
2494 //After subscript mathtype will keep the size of
2495 //normal text at the subscript size, sigh.
2496 *pS
<< sal_uInt8(0x0A);
2500 void MathType::HandleFractions(SmNode
*pNode
,int nLevel
)
2502 //USHORT nSize = pNode->GetNumSubNodes();
2504 *pS
<< sal_uInt8(TMPL
); //Template
2505 *pS
<< sal_uInt8(0x0E); //selector
2506 *pS
<< sal_uInt8(0x00); //variation
2507 *pS
<< sal_uInt8(0x00); //options
2509 *pS
<< sal_uInt8(0x0A);
2510 *pS
<< sal_uInt8(LINE
); //line
2511 if (NULL
!= (pTemp
= pNode
->GetSubNode(0)))
2512 HandleNodes(pTemp
,nLevel
+1);
2513 *pS
<< sal_uInt8(END
);
2515 *pS
<< sal_uInt8(0x0A);
2516 *pS
<< sal_uInt8(LINE
); //line
2517 if (NULL
!= (pTemp
= pNode
->GetSubNode(2)))
2518 HandleNodes(pTemp
,nLevel
+1);
2519 *pS
<< sal_uInt8(END
);
2521 *pS
<< sal_uInt8(END
);
2525 void MathType::HandleBrace(SmNode
*pNode
,int nLevel
)
2527 //USHORT nSize = pNode->GetNumSubNodes();
2529 SmNode
*pLeft
=pNode
->GetSubNode(0);
2530 SmNode
*pRight
=pNode
->GetSubNode(2);
2532 *pS
<< sal_uInt8(TMPL
); //Template
2534 sal_uInt8 nBSpec
=0x10;
2535 ULONG nLoc
= pS
->Tell();
2538 switch (pLeft
->GetToken().eType
)
2541 *pS
<< sal_uInt8(tmANGLE
); //selector
2542 *pS
<< sal_uInt8(0x00); //variation
2543 *pS
<< sal_uInt8(0x00); //options
2546 *pS
<< sal_uInt8(tmBRACE
); //selector
2547 *pS
<< sal_uInt8(0x00); //variation
2548 *pS
<< sal_uInt8(0x00); //options
2552 *pS
<< sal_uInt8(tmBRACK
); //selector
2553 *pS
<< sal_uInt8(0x00); //variation
2554 *pS
<< sal_uInt8(0x00); //options
2558 *pS
<< sal_uInt8(tmFLOOR
); //selector
2559 *pS
<< sal_uInt8(0x00); //variation
2560 *pS
<< sal_uInt8(0x00); //options
2563 *pS
<< sal_uInt8(tmBAR
); //selector
2564 *pS
<< sal_uInt8(0x00); //variation
2565 *pS
<< sal_uInt8(0x00); //options
2569 *pS
<< sal_uInt8(tmDBAR
); //selector
2570 *pS
<< sal_uInt8(0x00); //variation
2571 *pS
<< sal_uInt8(0x00); //options
2574 *pS
<< sal_uInt8(tmPAREN
); //selector
2575 *pS
<< sal_uInt8(0x00); //variation
2576 *pS
<< sal_uInt8(0x00); //options
2582 if (NULL
!= (pTemp
= pNode
->GetSubNode(1)))
2584 *pS
<< sal_uInt8(LINE
); //line
2585 HandleNodes(pTemp
,nLevel
+1);
2586 *pS
<< sal_uInt8(END
); //options
2590 HandleNodes(pLeft
,nLevel
+1);
2591 if (bIsReInterpBrace
)
2593 ULONG nLoc2
= pS
->Tell();
2595 *pS
<< sal_uInt8(0x2D);
2597 *pS
<< sal_uInt8(CHAR
);
2598 *pS
<< sal_uInt8(0x96);
2599 *pS
<< sal_uInt16(0xEC07);
2603 HandleNodes(pRight
,nLevel
+1);
2605 *pS
<< sal_uInt8(END
);
2609 void MathType::HandleVerticalBrace(SmNode
*pNode
,int nLevel
)
2612 *pS
<< sal_uInt8(TMPL
); //Template
2613 if (pNode
->GetToken().eType
== TUNDERBRACE
)
2614 *pS
<< sal_uInt8(tmLHBRACE
); //selector
2616 *pS
<< sal_uInt8(tmUHBRACE
); //selector
2617 *pS
<< sal_uInt8(0x01); //variation
2618 *pS
<< sal_uInt8(0x00); //options
2620 if (NULL
!= (pTemp
= pNode
->GetSubNode(0)))
2622 *pS
<< sal_uInt8(LINE
); //line
2623 HandleNodes(pTemp
,nLevel
+1);
2624 *pS
<< sal_uInt8(END
); //options
2627 if (NULL
!= (pTemp
= pNode
->GetSubNode(2)))
2629 *pS
<< sal_uInt8(LINE
); //line
2630 HandleNodes(pTemp
,nLevel
+1);
2631 *pS
<< sal_uInt8(END
); //options
2633 *pS
<< sal_uInt8(END
);
2636 void MathType::HandleOperator(SmNode
*pNode
,int nLevel
)
2638 //USHORT nSize = pNode->GetNumSubNodes();
2640 if (HandleLim(pNode
,nLevel
))
2644 sal_uInt8 nVariation
;
2646 switch (pNode
->GetToken().eType
)
2653 nVariation
=HandleCScript(pNode
->GetSubNode(0),
2654 pNode
->GetSubNode(1),nLevel
,&nPos
,0);
2657 nVariation
=HandleCScript(pNode
->GetSubNode(0),
2658 pNode
->GetSubNode(1),nLevel
,&nPos
);
2662 sal_uInt8 nOldVariation
=nVariation
;
2663 sal_uInt8 nIntVariation
=nVariation
;
2666 if (nVariation
!= 0xff)
2670 if (nVariation
== 2)
2675 else if (nVariation
== 0)
2677 else if (nVariation
== 1)
2685 *pS
<< sal_uInt8(TMPL
);
2686 switch(pNode
->GetToken().eType
)
2689 if (nOldVariation
!= 0xff)
2690 *pS
<< sal_uInt8(0x18); //selector
2692 *pS
<< sal_uInt8(0x15); //selector
2693 *pS
<< nIntVariation
; //variation
2696 if (nOldVariation
!= 0xff)
2698 *pS
<< sal_uInt8(0x19);
2699 *pS
<< sal_uInt8(0x01);
2703 *pS
<< sal_uInt8(0x16);
2704 *pS
<< sal_uInt8(0x00);
2708 if (nOldVariation
!= 0xff)
2710 *pS
<< sal_uInt8(0x1a);
2711 *pS
<< sal_uInt8(0x01);
2715 *pS
<< sal_uInt8(0x17);
2716 *pS
<< sal_uInt8(0x00);
2720 if (nOldVariation
!= 0xff)
2722 *pS
<< sal_uInt8(0x18);
2723 *pS
<< sal_uInt8(0x02);
2727 *pS
<< sal_uInt8(0x15);
2728 *pS
<< sal_uInt8(0x03);
2732 if (nOldVariation
!= 0xff)
2734 *pS
<< sal_uInt8(0x19);
2735 *pS
<< sal_uInt8(0x00);
2739 *pS
<< sal_uInt8(0x16);
2740 *pS
<< sal_uInt8(0x02);
2744 if (nOldVariation
!= 0xff)
2746 *pS
<< sal_uInt8(0x1a);
2747 *pS
<< sal_uInt8(0x00);
2751 *pS
<< sal_uInt8(0x17);
2752 *pS
<< sal_uInt8(0x02);
2757 *pS
<< sal_uInt8(0x1d);
2761 *pS
<< sal_uInt8(0x1f);
2765 *pS
<< sal_uInt8(0x21);
2769 *pS
<< sal_uInt8(0x00); //options
2775 *pS
<< sal_uInt8(LINE
); //line
2776 HandleNodes(pNode
->GetSubNode(1),nLevel
+1);
2777 *pS
<< sal_uInt8(END
); //line
2778 *pS
<< sal_uInt8(LINE
|0x10);
2779 *pS
<< sal_uInt8(LINE
|0x10);
2783 *pS
<< sal_uInt8(0x0D);
2784 switch(pNode
->GetToken().eType
)
2788 *pS
<< sal_uInt8(CHAR
);
2789 *pS
<< sal_uInt8(0x86);
2790 *pS
<< sal_uInt16(0x2211);
2793 *pS
<< sal_uInt8(CHAR
);
2794 *pS
<< sal_uInt8(0x86);
2795 *pS
<< sal_uInt16(0x220F);
2798 *pS
<< sal_uInt8(CHAR
);
2799 *pS
<< sal_uInt8(0x8B);
2800 *pS
<< sal_uInt16(0x2210);
2804 *pS
<< sal_uInt8(CHAR
);
2805 *pS
<< sal_uInt8(0x86);
2806 *pS
<< sal_uInt16(0x222B);
2809 *pS
<< sal_uInt8(CHAR
);
2810 *pS
<< sal_uInt8(0x86);
2811 *pS
<< sal_uInt16(0x222B);
2814 *pS
<< sal_uInt8(CHAR
);
2815 *pS
<< sal_uInt8(0x86);
2816 *pS
<< sal_uInt16(0x222B);
2819 *pS
<< sal_uInt8(END
);
2820 *pS
<< sal_uInt8(0x0A);
2824 int MathType::HandlePile(int &rSetAlign
,int nLevel
,sal_uInt8 nSelector
,
2825 sal_uInt8 nVariation
)
2830 HandleAlign(nHAlign
,nVAlign
,rSetAlign
);
2832 APPEND(rRet
," stack {\n");
2833 int nRet
= HandleRecords(nLevel
+1,nSelector
,nVariation
,-1,-1);
2834 rRet
.Erase(rRet
.Len()-3,2);
2845 int MathType::HandleMatrix(int nLevel
,sal_uInt8 nSelector
,
2846 sal_uInt8 nVariation
)
2848 sal_uInt8 nH_just
,nV_just
,nRows
,nCols
;
2854 int nBytes
= ((nRows
+1)*2)/8;
2855 if (((nRows
+1)*2)%8)
2857 pS
->SeekRel(nBytes
);
2858 nBytes
= ((nCols
+1)*2)/8;
2859 if (((nCols
+1)*2)%8)
2861 pS
->SeekRel(nBytes
);
2862 APPEND(rRet
," matrix {\n");
2863 int nRet
= HandleRecords(nLevel
+1,nSelector
,nVariation
,nRows
,nCols
);
2865 xub_StrLen nI
= rRet
.SearchBackward('#');
2866 if ((nI
!= STRING_NOTFOUND
) && (nI
> 0))
2867 if (rRet
.GetChar(nI
-1) != '#') //missing column
2870 APPEND(rRet
,"\n} ");
2874 int MathType::HandleTemplate(int nLevel
,sal_uInt8
&rSelector
,
2875 sal_uInt8
&rVariation
, xub_StrLen
&rLastTemplateBracket
)
2877 sal_uInt8 nOption
; //This appears utterly unused
2881 DBG_ASSERT(rSelector
< 48,"Selector out of range");
2882 if ((rSelector
>= 21) && (rSelector
<=26))
2884 DBG_ASSERT(nOption
< 2,"Option out of range");
2886 else if (/*(rSelector >= 0) &&*/ (rSelector
<=12))
2888 DBG_ASSERT(nOption
< 3,"Option out of range");
2891 //For the (broken) case where one subscript template ends, and there is
2892 //another one after it, mathtype handles it as if the second one was
2893 //inside the first one and renders it as sub of sub
2895 if ( (rSelector
== 0xf) && (rLastTemplateBracket
!= STRING_NOTFOUND
) )
2898 for (xub_StrLen nI
= rLastTemplateBracket
+1; nI
< rRet
.Len(); nI
++ )
2899 if (rRet
.GetChar(nI
) != ' ')
2907 int nRet
= HandleRecords(nLevel
+1,rSelector
,rVariation
);
2911 rRet
.Erase(rLastTemplateBracket
,1);
2913 rLastTemplateBracket
= STRING_NOTFOUND
;
2915 if (rSelector
== 0xf)
2916 rLastTemplateBracket
= rRet
.SearchBackward('}');
2918 rLastTemplateBracket
= STRING_NOTFOUND
;
2920 rSelector
= sal::static_int_cast
< sal_uInt8
>(-1);
2924 void MathType::HandleEmblishments()
2933 APPEND(rRet
," dot ");
2936 APPEND(rRet
," ddot ");
2939 APPEND(rRet
," dddot ");
2944 APPEND(sPost
," sup {}");
2945 nPostSup
= sPost
.Len();
2947 sPost
.InsertAscii(" ' ",nPostSup
-1);
2953 APPEND(sPost
," sup {}");
2954 nPostSup
= sPost
.Len();
2956 sPost
.InsertAscii(" '' ",nPostSup
-1);
2962 APPEND(sPost
," lsup {}");
2963 nPostlSup
= sPost
.Len();
2965 sPost
.InsertAscii(" ' ",nPostlSup
-1);
2969 APPEND(rRet
," tilde ");
2972 APPEND(rRet
," hat ");
2975 APPEND(rRet
," vec ");
2978 APPEND(rRet
," overstrike ");
2981 APPEND(rRet
," bar ");
2986 APPEND(sPost
," sup {}");
2987 nPostSup
= sPost
.Len();
2989 sPost
.InsertAscii(" ''' ",nPostSup
-1);
2993 APPEND(rRet
," breve ");
2996 DBG_ASSERT(nEmbel
< 21,"Embel out of range");
3004 void MathType::HandleSetSize()
3027 int MathType::HandleChar(xub_StrLen
&rTextStart
,int &rSetSize
,int nLevel
,
3028 sal_uInt8 nTag
,sal_uInt8 nSelector
,sal_uInt8 nVariation
, sal_Bool bSilent
)
3035 //This is a candidate for function recognition, whatever
3039 sal_uInt8 nOldTypeFace
= nTypeFace
;
3052 bad character, old mathtype < 3 has these
3059 //A bit tricky, the character emblishments for
3060 //mathtype can all be listed after eachother, in
3061 //starmath some must go before the character and some
3062 //must go after. In addition some of the emblishments
3063 //may repeated and in starmath some of these groups
3064 //must be gathered together. sPost is the portion that
3065 //follows the char and nPostSup and nPostlSup are the
3066 //indexes at which this class of emblishment is
3069 nPostSup
= nPostlSup
= 0;
3070 int nOriglen
=rRet
.Len()-rTextStart
;
3071 APPEND(rRet
," {"); // #i24340# make what would be "vec {A}_n" become "{vec {A}}_n"
3072 if ((!bSilent
) && ((nOriglen
) > 1))
3074 nRet
= HandleRecords(nLevel
+1,nSelector
,nVariation
);
3080 TypeFaceToString(aStr
,nOldTypeFace
);
3082 rRet
.Insert(aStr
,rTextStart
);
3085 TypeFaceToString(aStr
,nTypeFace
);
3091 rTextStart
= rRet
.Len();
3097 xub_StrLen nOldLen
= rRet
.Len();
3098 //nLastSize = nCurSize;
3100 HandleSize(nLSize
,nDSize
,rSetSize
) ||
3101 (nOldTypeFace
!= nTypeFace
)
3104 if ((nOldLen
- rTextStart
) > 1)
3106 rRet
.InsertAscii("\"",nOldLen
);
3108 TypeFaceToString(aStr
,nOldTypeFace
);
3110 rRet
.Insert(aStr
,rTextStart
);
3112 rTextStart
= rRet
.Len();
3114 nOldLen
= rRet
.Len();
3115 if (!LookupChar(nChar
,rRet
,nVersion
,nTypeFace
))
3117 if (nOldLen
- rTextStart
> 1)
3119 rRet
.InsertAscii("\"",nOldLen
);
3121 TypeFaceToString(aStr
,nOldTypeFace
);
3123 rRet
.Insert(aStr
,rTextStart
);
3125 rTextStart
= rRet
.Len();
3127 lcl_PrependDummyTerm(rRet
, rTextStart
);
3130 if ((xfEMBELL(nTag
)) && (!bSilent
))
3132 rRet
+= '}'; // #i24340# make what would be "vec {A}_n" become "{vec {A}}_n"
3135 rTextStart
= rRet
.Len();
3140 sal_Bool
MathType::HandleLim(SmNode
*pNode
,int nLevel
)
3143 //Special case for the "lim" option in StarMath
3144 if ((pNode
->GetToken().eType
== TLIM
)
3145 || (pNode
->GetToken().eType
== TLIMSUP
)
3146 || (pNode
->GetToken().eType
== TLIMINF
)
3149 if (pNode
->GetSubNode(1))
3151 sal_uInt8 nVariation2
=HandleCScript(pNode
->GetSubNode(0),NULL
,
3154 *pS
<< sal_uInt8(0x0A);
3155 *pS
<< sal_uInt8(LINE
); //line
3156 *pS
<< sal_uInt8(CHAR
|0x10);
3157 *pS
<< sal_uInt8(0x82);
3158 *pS
<< sal_uInt16('l');
3159 *pS
<< sal_uInt8(CHAR
|0x10);
3160 *pS
<< sal_uInt8(0x82);
3161 *pS
<< sal_uInt16('i');
3162 *pS
<< sal_uInt8(CHAR
|0x10);
3163 *pS
<< sal_uInt8(0x82);
3164 *pS
<< sal_uInt16('m');
3166 if (pNode
->GetToken().eType
== TLIMSUP
)
3168 *pS
<< sal_uInt8(CHAR
); //some space
3169 *pS
<< sal_uInt8(0x98);
3170 *pS
<< sal_uInt16(0xEB04);
3172 *pS
<< sal_uInt8(CHAR
|0x10);
3173 *pS
<< sal_uInt8(0x82);
3174 *pS
<< sal_uInt16('s');
3175 *pS
<< sal_uInt8(CHAR
|0x10);
3176 *pS
<< sal_uInt8(0x82);
3177 *pS
<< sal_uInt16('u');
3178 *pS
<< sal_uInt8(CHAR
|0x10);
3179 *pS
<< sal_uInt8(0x82);
3180 *pS
<< sal_uInt16('p');
3182 else if (pNode
->GetToken().eType
== TLIMINF
)
3184 *pS
<< sal_uInt8(CHAR
); //some space
3185 *pS
<< sal_uInt8(0x98);
3186 *pS
<< sal_uInt16(0xEB04);
3188 *pS
<< sal_uInt8(CHAR
|0x10);
3189 *pS
<< sal_uInt8(0x82);
3190 *pS
<< sal_uInt16('i');
3191 *pS
<< sal_uInt8(CHAR
|0x10);
3192 *pS
<< sal_uInt8(0x82);
3193 *pS
<< sal_uInt16('n');
3194 *pS
<< sal_uInt8(CHAR
|0x10);
3195 *pS
<< sal_uInt8(0x82);
3196 *pS
<< sal_uInt16('f');
3200 *pS
<< sal_uInt8(CHAR
); //some space
3201 *pS
<< sal_uInt8(0x98);
3202 *pS
<< sal_uInt16(0xEB04);
3204 if (nVariation2
!= 0xff)
3206 *pS
<< sal_uInt8(END
);
3207 *pS
<< sal_uInt8(END
);
3209 HandleNodes(pNode
->GetSubNode(1),nLevel
+1);
3210 //*pS << sal_uInt8(END); //options
3217 void MathType::HandleMAlign(SmNode
*pNode
,int nLevel
)
3219 sal_uInt8 nPushedHAlign
=nHAlign
;
3220 switch(pNode
->GetToken().eType
)
3232 USHORT nSize
= pNode
->GetNumSubNodes();
3233 for (USHORT i
= 0; i
< nSize
; i
++)
3234 if (SmNode
*pTemp
= pNode
->GetSubNode(i
))
3235 HandleNodes(pTemp
,nLevel
+1);
3236 nHAlign
=nPushedHAlign
;
3239 void MathType::HandleMath(SmNode
*pNode
, int /*nLevel*/)
3241 if (pNode
->GetToken().eType
== TMLINE
)
3243 *pS
<< sal_uInt8(END
);
3244 *pS
<< sal_uInt8(LINE
);
3248 SmMathSymbolNode
*pTemp
=(SmMathSymbolNode
*)pNode
;
3249 for(xub_StrLen i
=0;i
<pTemp
->GetText().Len();i
++)
3251 sal_Unicode nArse
= Convert(pTemp
->GetText().GetChar(i
));
3252 if ((nArse
== 0x2224) || (nArse
== 0x2288) || (nArse
== 0x2285) ||
3255 *pS
<< sal_uInt8(CHAR
|0x20);
3257 else if ((nPendingAttributes
) &&
3258 (i
== ((pTemp
->GetText().Len()+1)/2)-1))
3260 *pS
<< sal_uInt8(0x22);
3263 *pS
<< sal_uInt8(CHAR
); //char without formula recognition
3264 //The typeface seems to be MTEXTRA for unicode characters,
3265 //though how to determine when mathtype chooses one over
3266 //the other is unknown. This should do the trick
3269 if ( (nArse
== 0x2213) || (nArse
== 0x2218) ||
3270 (nArse
== 0x210F) || (
3271 (nArse
>= 0x22EE) && (nArse
<= 0x22FF)
3274 nBias
= 0xB; //typeface
3276 else if ((nArse
> 0x2000) || (nArse
== 0x00D7))
3277 nBias
= 0x6; //typeface
3278 else if (nArse
== 0x3d1)
3280 else if ((nArse
> 0xFF) && ((nArse
< 0x393) || (nArse
> 0x3c9)))
3281 nBias
= 0xB; //typeface
3282 else if ((nArse
== 0x2F) || (nArse
== 0x2225))
3283 nBias
= 0x2; //typeface
3285 nBias
= 0x3; //typeface
3287 *pS
<< sal_uInt8(nSpec
+nBias
+128); //typeface
3289 if (nArse
== 0x2224)
3291 *pS
<< sal_uInt16(0x7C);
3292 *pS
<< sal_uInt8(EMBEL
);
3293 *pS
<< sal_uInt8(0x0A);
3294 *pS
<< sal_uInt8(END
); //end embel
3295 *pS
<< sal_uInt8(END
); //end embel
3297 else if (nArse
== 0x2225)
3298 *pS
<< sal_uInt16(0xEC09);
3299 else if (nArse
== 0xE421)
3300 *pS
<< sal_uInt16(0x2265);
3301 else if (nArse
== 0x230A)
3302 *pS
<< sal_uInt16(0xF8F0);
3303 else if (nArse
== 0x230B)
3304 *pS
<< sal_uInt16(0xF8FB);
3305 else if (nArse
== 0xE425)
3306 *pS
<< sal_uInt16(0x2264);
3307 else if (nArse
== 0x226A)
3309 *pS
<< sal_uInt16(0x3C);
3310 *pS
<< sal_uInt8(CHAR
);
3311 *pS
<< sal_uInt8(0x98);
3312 *pS
<< sal_uInt16(0xEB01);
3313 *pS
<< sal_uInt8(CHAR
);
3314 *pS
<< sal_uInt8(0x86);
3315 *pS
<< sal_uInt16(0x3c);
3317 else if (nArse
== 0x2288)
3319 *pS
<< sal_uInt16(0x2286);
3320 *pS
<< sal_uInt8(EMBEL
);
3321 *pS
<< sal_uInt8(0x0A);
3322 *pS
<< sal_uInt8(END
); //end embel
3323 *pS
<< sal_uInt8(END
); //end embel
3325 else if (nArse
== 0x2289)
3327 *pS
<< sal_uInt16(0x2287);
3328 *pS
<< sal_uInt8(EMBEL
);
3329 *pS
<< sal_uInt8(0x0A);
3330 *pS
<< sal_uInt8(END
); //end embel
3331 *pS
<< sal_uInt8(END
); //end embel
3333 else if (nArse
== 0x2285)
3335 *pS
<< sal_uInt16(0x2283);
3336 *pS
<< sal_uInt8(EMBEL
);
3337 *pS
<< sal_uInt8(0x0A);
3338 *pS
<< sal_uInt8(END
); //end embel
3339 *pS
<< sal_uInt8(END
); //end embel
3344 nPendingAttributes
= 0;
3347 void MathType::HandleAttributes(SmNode
*pNode
,int nLevel
)
3349 int nOldPending
= 0;
3350 //USHORT nSize = pNode->GetNumSubNodes();
3352 SmTextNode
*pIsText
= 0;
3354 //SmTextNode *pTemp=(SmTextNode *)pNode;
3355 //for(int i=0;i<pTemp->GetText().Len();i++)
3357 if (NULL
!= (pTemp
= pNode
->GetSubNode(0)))
3359 pIsText
= (SmTextNode
*)pNode
->GetSubNode(1);
3361 switch (pTemp
->GetToken().eType
)
3364 //theres just no way we can now handle any character
3365 //attributes (from mathtypes perspective) centered
3366 //over an expression but above template attributes
3367 //such as widevec and similiar constructs
3368 //we have to drop them
3369 nOldPending
= StartTemplate(0x2f,0x01);
3371 case TCHECK
: //Not Exportable
3372 case TACUTE
: //Not Exportable
3373 case TGRAVE
: //Not Exportable
3374 case TCIRCLE
: //Not Exportable
3375 case TWIDETILDE
: //Not Exportable
3376 case TWIDEHAT
: //Not Exportable
3379 nOldPending
= StartTemplate(0x10);
3381 case TOVERLINE
: //If the next node is not text
3382 //or text with more than one char
3383 if ((pIsText
->GetToken().eType
!= TTEXT
) ||
3384 (pIsText
->GetText().Len() > 1))
3385 nOldPending
= StartTemplate(0x11);
3388 nPendingAttributes
++;
3394 HandleNodes(pIsText
,nLevel
+1);
3396 switch (pTemp
->GetToken().eType
)
3400 EndTemplate(nOldPending
);
3403 if ((pIsText
->GetToken().eType
!= TTEXT
) ||
3404 (pIsText
->GetText().Len() > 1))
3405 EndTemplate(nOldPending
);
3411 //if there was no suitable place to put the attribute,
3412 //then we have to just give up on it
3413 if (nPendingAttributes
)
3414 nPendingAttributes
--;
3417 if ((nInsertion
!= 0) && NULL
!= (pTemp
= pNode
->GetSubNode(0)))
3419 ULONG nPos
= pS
->Tell();
3421 pS
->Seek(nInsertion
);
3422 switch(pTemp
->GetToken().eType
)
3424 case TACUTE
: //Not Exportable
3425 case TGRAVE
: //Not Exportable
3426 case TCIRCLE
: //Not Exportable
3429 *pS
<< sal_uInt8(2);
3432 *pS
<< sal_uInt8(3);
3435 *pS
<< sal_uInt8(4);
3438 *pS
<< sal_uInt8(8);
3441 *pS
<< sal_uInt8(9);
3444 *pS
<< sal_uInt8(11);
3447 *pS
<< sal_uInt8(16);
3450 if ((pIsText
->GetToken().eType
== TTEXT
) &&
3451 (pIsText
->GetText().Len() == 1))
3452 *pS
<< sal_uInt8(17);
3455 *pS
<< sal_uInt8(20);
3463 *pS
<< sal_uInt8(17);
3466 *pS
<< sal_uInt8(0x2);
3474 void MathType::HandleText(SmNode
*pNode
, int /*nLevel*/)
3476 SmTextNode
*pTemp
=(SmTextNode
*)pNode
;
3477 for(xub_StrLen i
=0;i
<pTemp
->GetText().Len();i
++)
3479 if ((nPendingAttributes
) &&
3480 (i
== ((pTemp
->GetText().Len()+1)/2)-1))
3482 *pS
<< sal_uInt8(0x22); //char, with attributes right
3483 //after the character
3486 *pS
<< sal_uInt8(CHAR
);
3487 //*pS << sal_uInt8(CHAR|0x10); //char with formula recognition
3490 sal_uInt8 nFace
= 0x1;
3491 if (pNode
->GetFont().GetItalic() == ITALIC_NORMAL
)
3493 else if (pNode
->GetFont().GetWeight() == WEIGHT_BOLD
)
3495 *pS
<< sal_uInt8(nFace
+128); //typeface
3497 if ((pTemp
->GetText().GetChar(i
) >= '0') &&
3498 (pTemp
->GetText().GetChar(i
) <= '9'))
3499 *pS
<< sal_uInt8(0x8+128); //typeface
3501 *pS
<< sal_uInt8(0x3+128); //typeface
3503 sal_uInt16 nChar
= pTemp
->GetText().GetChar(i
);
3504 *pS
<< Convert(nChar
);
3506 //Mathtype can only have these sort of character
3507 //attributes on a single character, starmath can put them
3508 //anywhere, when the entity involved is a text run this is
3509 //a large effort to place the character attribute on the
3510 //central mathtype character so that it does pretty much
3511 //what the user probably has in mind. The attributes
3512 //filled in here are dummy ones which are replaced in the
3513 //ATTRIBUT handler if a suitable location for the
3514 //attributes was found here. Unfortunately it is
3515 //possible for starmath to place character attributes on
3516 //entities which cannot occur in mathtype e.g. a Summation
3517 //symbol so these attributes may be lost
3518 if ((nPendingAttributes
) &&
3519 (i
== ((pTemp
->GetText().Len()+1)/2)-1))
3521 *pS
<< sal_uInt8(EMBEL
);
3522 while (nPendingAttributes
)
3524 *pS
<< sal_uInt8(2);
3525 //wedge the attributes in here and clear
3527 nPendingAttributes
--;
3529 nInsertion
=pS
->Tell();
3530 *pS
<< sal_uInt8(END
); //end embel
3531 *pS
<< sal_uInt8(END
); //end embel
3536 /* vi:set tabstop=4 shiftwidth=4 expandtab: */