summaryrefslogtreecommitdiff
path: root/starmath/source/mathtype.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'starmath/source/mathtype.cxx')
-rw-r--r--starmath/source/mathtype.cxx3081
1 files changed, 3081 insertions, 0 deletions
diff --git a/starmath/source/mathtype.cxx b/starmath/source/mathtype.cxx
new file mode 100644
index 000000000000..181794883639
--- /dev/null
+++ b/starmath/source/mathtype.cxx
@@ -0,0 +1,3081 @@
+/*************************************************************************
+ *
+ * $RCSfile: mathtype.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:57:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef MATHTYPE_HXX
+#include <mathtype.hxx>
+#endif
+
+#ifndef _TOOLS_DEBUG_H
+#include <tools/debug.hxx>
+#endif
+
+#define APPEND(str,ascii) str.AppendAscii(RTL_CONSTASCII_STRINGPARAM(ascii))
+
+#if 0
+String aEmbelList[21] =
+{
+ " ",
+ " ",
+ "single dot",
+ "double dot",
+ "triple dot",
+ "single prime",
+ "double prime",
+ "backwards prime (left of character)",
+ "tilde",
+ "hat (circumflex)",
+ "diagonal slash through character",
+ "right arrow",
+ "left arrow",
+ "double-headed arrow",
+ "right single-barbed arrow",
+ "left single-barbed arrow",
+ "mid-height horizontal bar",
+ "over-bar",
+ "triple prime",
+ "over-arc, concave downward",
+ "over-arc, concave upward"
+};
+
+String aSelectorList[49] =
+{
+ "angle brackets",
+ "parentheses",
+ "braces (curly brackets)",
+ "square brackets",
+ "vertical bars",
+ "double vertical bars",
+ "floor brackets",
+ "ceiling brackets",
+ "left brace, left brace",
+ "right brace, right brace",
+ "right brace, left brace",
+ "left brace, right parenthesis",
+ "left parenthesis, right brace",
+ "radical",
+ "fractions",
+ "subscript/superscript",
+ "underbar",
+ "overbar",
+ "left-pointing arrow",
+ "right-pointing arrow",
+ "left- and right-pointing arrow",
+ "single integral",
+ "double integral",
+ "triple integral",
+ "single summation-style integral",
+ "double summation-style integral",
+ "triple summation-style integral",
+ "upper horizontal brace",
+ "lower horizontal brace",
+ "summation",
+ "summation (integral-style limits)",
+ "product",
+ "product (integral-style limits)",
+ "coproduct",
+ "coproduct (integral-style limits)",
+ "union",
+ "union (integral-style limits)",
+ "intersection",
+ "intersection (integral-style limits)",
+ "limit",
+ "long division",
+ "slash fractions",
+ "big integral-style operators",
+ "big summation-style operators",
+ "leading sub- and superscripts",
+ "Dirac delta",
+ "under arrow",
+ "over arrow",
+ "over arc"
+};
+
+String aIntegralOpt[2] =
+{
+ "fixed-size integral",
+ "integral expands vertically to fit its contents"
+};
+
+String aFenceOpt[3] =
+{
+ "center fence on math axis",
+ "center fence on contents, place math axis of contents on math axis of containing line",
+ "center fence on contents, center contents on math axis of containing line"
+};
+
+String aTypeFaces[12] =
+{
+ "",
+ "fnTEXT",
+ "fnFUNCTION",
+ "fnVARIABLE",
+ "fnLCGREEK",
+ "fnUCGREEK",
+ "fnSYMBOL",
+ "fnVECTOR",
+ "fnNUMBER",
+ "fnUSER1",
+ "fnUSER2",
+ "fnMTEXTRA"
+};
+
+String aSizes[7] =
+{
+ "full",
+ "subscript",
+ "sub-subscript",
+ "symbol",
+ "sub-symbol",
+ "user 1",
+ "user 2"
+};
+#endif
+
+/*This table is not fully complete and is pending on what decisions are
+ *made as regards the StarMath to Unicode stuff*/
+sal_Unicode aMathTypeTable[256] =
+{
+0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
+0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013,
+0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d,
+0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x2031, 0x0025, 0x0026, 0x221E,
+0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x2212, 0x002E, 0x002F, 0x2224, 0x21D2,
+0x21D0, 0x21D4, 0xffff, 0xffff, 0x2218, 0xffff, 0xffff, 0xffff, 0x003A, 0x003B,
+0x003C, 0x003D, 0x003E, 0x00BF, 0x2260, 0x002B, 0x2212, 0x002A, 0x00D7, 0x22C5,
+0x00F7, 0x00B1, 0x2213, 0x2295, 0x2296, 0x2297, 0x2298, 0x2299, 0x222A, 0x2229,
+0x003C, 0x003E, 0x2264, 0x2265, 0x2264, 0x2265, 0x226A, 0x226B, 0x007E, 0x2245,
+0x2248, 0xffff, 0x2261, 0x221D, 0x2202, 0x2282, 0x2283, 0x2286, 0x2287, 0x2284,
+0x2285, 0x2288, 0x2289, 0x2208, 0x2209, 0x2208, 0x2203, 0x220B, 0x2135, 0x2111,
+0x211C, 0x2118, 0x0192, 0x2221, 0x2222, 0x007C, 0x2225, 0x22A5, 0x2026, 0x22EF,
+0x22EE, 0x22F0, 0x22F1, 0x22B6, 0x22B7, 0x2192, 0x005C, 0x00AC, 0x222B, 0x222C,
+0x222D, 0x222E, 0x222F, 0x2230, 0x221A, 0x221A, 0x221A, 0x221A, 0x2210, 0x220F,
+0x2211, 0x2207, 0x2200, 0x2225, 0x005E, 0x02C7, 0x02D8, 0x00B4, 0x0060, 0x02DC,
+0x00AF, 0x2192, 0x02D9, 0x00A8, 0xffff, 0x02DA, 0x2227, 0x2228, 0x220D, 0x2205,
+0x007B, 0x007D, 0x0028, 0x0029, 0x2329, 0x232a, 0x005B, 0x005D, 0x2220, 0x221F,
+0xffff, 0x225C, 0x2254, 0x2255, 0x21B3, 0x2197, 0x2198, 0x2245, 0x301A, 0x301B,
+0xffff, 0xffff, 0xffff, 0xffff, 0x2112, 0x2130, 0x2131, 0xffff, 0xffff, 0x002F,
+0x005C, 0x274F, 0x2308, 0x230A, 0x2309, 0x230B, 0xffff, 0xffff, 0x0393, 0x0394,
+0x0398, 0x039B, 0x039E, 0x03A0, 0x03A3, 0x03A5, 0x03A6, 0x03A8, 0x0389, 0x03B1,
+0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB,
+0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6,
+0x03C7, 0x03C8, 0x03C9, 0x03B5, 0x03D1, 0xffff, 0x03F1, 0x03DB, 0x2118, 0xffff,
+0x2113, 0x2129, 0x2107, 0x2127, 0x210A, 0x22A4, 0x210F, 0x019B, 0x2190, 0x2191,
+0x2193, 0x2115, 0x2124, 0x211A, 0x211D, 0x2102
+};
+
+void EQNOLEFILEHDR::Read(SvStorageStream *pS)
+{
+ *pS >> nCBHdr;
+ *pS >> nVersion;
+ *pS >> nCf;
+ *pS >> nCBObject;
+ *pS >> nReserved1;
+ *pS >> nReserved2;
+ *pS >> nReserved3;
+ *pS >> nReserved4;
+}
+
+void EQNOLEFILEHDR::Write(SvStorageStream *pS)
+{
+ *pS << nCBHdr;
+ *pS << nVersion;
+ *pS << nCf;
+ *pS << nCBObject;
+ *pS << nReserved1;
+ *pS << nReserved2;
+ *pS << nReserved3;
+ *pS << nReserved4;
+}
+
+/*ToDo replace with table rather than switch, returns
+ TRUE in the case that the char is just a char, and
+ FALSE if the character is an operator which must not be
+ placed inside the quote sequence designed to protect
+ against being parsed as a keyword
+
+ General solution required to force starmath to handle
+ unicode math chars the way it handles its own math
+ chars rathar than handle them as text as it will do
+ for the default case below, i.e. incorrect spacing
+ between math symbols and ordinary text e.g. 1=2 rather
+ than 1 = 2
+ */
+BOOL MathType::LookupChar(sal_Unicode nChar)
+{
+ BOOL bRet=FALSE;
+ const char *pC = NULL;
+ switch(nChar)
+ {
+ case 0x00ac:
+ pC = " neg ";
+ break;
+ case 0x00b1:
+ pC = " +- ";
+ break;
+ case 0x0057:
+ if ((nVersion < 3) && (nTypeFace == 0x85))
+ pC = " %OMEGA ";
+ else
+ {
+ rRet.Append(nChar);
+ bRet=TRUE;
+ }
+ break;
+ case 0x00d7:
+ if (nVersion < 3)
+ pC = " cdot ";
+ else
+ pC = " times ";
+ break;
+ case 0x00f7:
+ pC = " div ";
+ break;
+ case 0x019b:
+ pC = " lambdabar ";
+ break;
+ case 0x2026:
+ pC = " dotslow ";
+ break;
+ case 0x2022:
+ pC = " cdot ";
+ break;
+ case 0x210f:
+ pC = " hbar ";
+ break;
+ case 0x2111:
+ pC = " Im ";
+ break;
+ case 0x2118:
+ pC = " wp ";
+ break;
+ case 0x211c:
+ pC = " Re ";
+ break;
+ case 0x2135:
+ pC = " aleph ";
+ break;
+ case 0x2190:
+ pC = " leftarrow ";
+ break;
+ case 0x2191:
+ pC = " uparrow ";
+ break;
+ case 0x2192:
+ pC = " rightarrow ";
+ break;
+ case 0x2193:
+ pC = " downarrow ";
+ break;
+ case 0x21d4:
+ pC = " dlrarrow ";
+ break;
+ case 0x2200:
+ pC = " forall ";
+ break;
+ case 0x2202:
+ pC = " partial ";
+ break;
+ case 0x2203:
+ pC = " exists ";
+ break;
+ case 0x2205:
+ pC = " emptyset ";
+ break;
+ case 0x2207:
+ pC = " nabla ";
+ break;
+ case 0x2208:
+ pC = " in ";
+ break;
+ case 0x2209:
+ pC = " notin ";
+ break;
+ case 0x220d:
+ pC = " owns ";
+ break;
+ case 0x220f:
+ pC = " prod ";
+ break;
+ case 0x2210:
+ pC = " coprod ";
+ break;
+ case 0x2211:
+ pC = " sum ";
+ break;
+ case 0x2212:
+ pC = " - ";
+ break;
+ case 0x2213:
+ pC = " -+ ";
+ break;
+ case 0x2217:
+ pC = " * ";
+ break;
+ case 0x2218:
+ pC = " circ ";
+ break;
+ case 0x221d:
+ pC = " prop ";
+ break;
+ case 0x221e:
+ pC = " infinity ";
+ break;
+ case 0x2227:
+ pC = " and ";
+ break;
+ case 0x2228:
+ pC = " or ";
+ break;
+ case 0x2229:
+ pC = " intersection ";
+ break;
+ case 0x222a:
+ pC = " union ";
+ break;
+ case 0x222b:
+ pC = " int ";
+ break;
+ case 0x2245:
+ pC = " simeq ";
+ break;
+ case 0x2248:
+ pC = " approx ";
+ break;
+ case 0x2260:
+ pC = " <> ";
+ break;
+ case 0x2261:
+ pC = " equiv ";
+ break;
+ case 0x2264:
+ pC = " <= ";
+ break;
+ case 0x2265:
+ pC = " >= ";
+ break;
+ case 0x2282:
+ pC = " subset ";
+ break;
+ case 0x2283:
+ pC = " supset ";
+ break;
+ case 0x2284:
+ pC = " nsubset ";
+ break;
+ case 0x2286:
+ pC = " subseteq ";
+ break;
+ case 0x2287:
+ pC = " supseteq ";
+ break;
+ case 0x227a:
+ case 0x227b:
+ case 0x22b2:
+ case 0x22b3:
+ rRet += ' ';
+ rRet.Append(nChar);
+ rRet += ' ';
+ break;
+ case 0x22a5:
+ pC = " ortho ";
+ break;
+ case 0x22c5:
+ pC = " cdot ";
+ break;
+ case 0x22ee:
+ pC = " dotsvert ";
+ break;
+ case 0x22ef:
+ pC = " dotsaxis ";
+ break;
+ case 0x22f0:
+ pC = " dotsup ";
+ break;
+ case 0x22f1:
+ pC = " dotsdown ";
+ break;
+ case 0xeb01: //no space
+ case 0xeb08: //normal space
+ bRet=TRUE;
+ break;
+ case 0xeb02: //small space
+ case 0xeb04: //medium space
+ rRet.Append('`');
+ break;
+ case 0xeb05: //large space
+ rRet.Append('~');
+ break;
+ case 0x3a9:
+ pC = " %OMEGA ";
+ break;
+ default:
+ rRet.Append(nChar);
+ bRet=TRUE;
+ break;
+ }
+ if (pC)
+ rRet.AppendAscii(pC);
+ return bRet;
+}
+
+int MathType::Parse(SvStorage *pStor)
+{
+ SvStorageStreamRef xSrc = pStor->OpenStream(
+ String::CreateFromAscii("Equation Native"),
+ STREAM_STD_READ | STREAM_NOCREATE);
+ if ( (!xSrc.Is()) || (SVSTREAM_OK != xSrc->GetError()))
+ return NULL;
+ pS = &xSrc;
+ pS->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ EQNOLEFILEHDR aHdr;
+ aHdr.Read(pS);
+ *pS >> nVersion;
+ *pS >> nPlatform;
+ *pS >> nProduct;
+ *pS >> nProdVersion;
+ *pS >> nProdSubVersion;
+
+#ifdef STANDALONE
+ *pOut << "Format Version is " << int(nVersion) << endl;
+ *pOut << "Generating Platform is " << (nPlatform ? "Windows"
+ : "Mac") << endl;
+ *pOut << "Generating Product is " << (nPlatform ? "Equation Editor"
+ : "Equation Editor") << endl;
+ *pOut << "Prod Version is " << int(nProdVersion) << "." <<
+ int(nProdSubVersion) << endl << endl;
+#endif
+
+ int nRet = HandleRecords();
+ //little crude hack to close ocassionally open expressions
+ //a sophisticated system to determine what expressions are
+ //opened is required, but this is as much work as rewriting
+ //starmaths internals.
+ APPEND(rRet,"{}");
+
+ //sanity check
+ ULONG nEnd = pS->Tell();
+ if (nEnd != pS->Seek(STREAM_SEEK_TO_END))
+ return 0;
+ return nRet;
+}
+
+/*Fabously complicated as many tokens have to be reordered and generally
+ *moved around from mathtypes paradigm to starmaths.*/
+int MathType::HandleRecords(int nLevel,BYTE nSelector,
+ BYTE nVariation, int nMatrixRows,int nMatrixCols)
+{
+ BYTE nTag,nRecord;
+ BYTE nTabType,nTabStops;
+ BYTE nTface,nStyle;
+ UINT16 nTabOffset;
+ sal_Char nChar8;
+ String sFontName;
+ int i,nRet=1,newline=0;
+ BOOL bSilent=FALSE;
+ int nPart=0;
+ String sPush,sMainTerm;
+ int nSetSize=0,nSetAlign=0;
+ int nCurRow=0,nCurCol=0;
+ BOOL bOpenString=FALSE;
+ xub_StrLen nTextStart;
+
+ do
+ {
+ *pS >> nTag;
+ nRecord = nTag&0x0F;
+
+ /*MathType strings can of course include words which
+ *are StarMath keywords, the simplest solution is
+ to escape strings of greater than len 1 with double
+ quotes to avoid scanning the TokenTable for matches
+
+ Unfortunately it may turn out that the string gets
+ split during the handling of a character emblishment
+ so this special case must be handled in the
+ character handler case 2:
+ */
+ if ((nRecord == CHAR) && (!bSilent) && (!bOpenString))
+ {
+ bOpenString=TRUE;
+ nTextStart = rRet.Len();
+ }
+ else if ((nRecord != CHAR) && (bOpenString))
+ {
+ bOpenString=FALSE;
+ if ((rRet.Len() - nTextStart) > 1)
+ {
+ rRet.InsertAscii(" ital \"",nTextStart);
+ rRet += '\"';
+ }
+ }
+
+ switch(nRecord)
+ {
+ case LINE:
+ {
+ //if (xfLMOVE(nTag))
+ //if (xfLSPACE(nTag))
+ //if (xfRULER(nTag))
+
+ if (newline>0)
+ APPEND(rRet,"\nnewline\n");
+ if (!(xfNULL(nTag)))
+ {
+ switch (nSelector)
+ {
+ case 0x0:
+ if (nVariation==0)
+ APPEND(rRet," langle ");
+ else if (nVariation==1)
+ APPEND(rRet," \\langle ");
+ break;
+ case 0x1:
+ if (nVariation==0)
+ APPEND(rRet," left (");
+ else if (nVariation==1)
+ APPEND(rRet,"\\(");
+ break;
+ case 0x2:
+ if (nVariation==0)
+ APPEND(rRet," lbrace ");
+ else if (nVariation==1)
+ APPEND(rRet," \\lbrace ");
+ break;
+ case 0x3:
+ if (nVariation==0)
+ APPEND(rRet," left [");
+ else if (nVariation==1)
+ APPEND(rRet,"\\[");
+ break;
+ case 0x8:
+ case 0xb:
+ APPEND(rRet," \\[");
+ break;
+ case 0x4:
+ if (nVariation==0)
+ APPEND(rRet," lline ");
+ else if (nVariation==1)
+ APPEND(rRet," \\lline ");
+ break;
+ case 0x5:
+ if (nVariation==0)
+ APPEND(rRet," ldline ");
+ else if (nVariation==1)
+ APPEND(rRet," \\ldline ");
+ break;
+ case 0x6:
+ if (nVariation==0)
+ APPEND(rRet," lfloor ");
+ else if (nVariation==1)
+ APPEND(rRet," \\lfloor ");
+ break;
+ case 0x7:
+ if (nVariation==0)
+ APPEND(rRet," lceil ");
+ else if (nVariation==1)
+ APPEND(rRet," \\lceil ");
+ break;
+ case 0x9:
+ case 0xa:
+ APPEND(rRet," \\]");
+ break;
+ case 0xc:
+ APPEND(rRet," \\(");
+ break;
+ case 0xd:
+ if (nPart == 0)
+ {
+ if (nVariation == 0)
+ APPEND(rRet," sqrt");
+ else
+ {
+ APPEND(rRet," nroot");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ APPEND(rRet," {");
+ break;
+ case 0xe:
+ if (nPart == 0)
+ APPEND(rRet," { ");
+
+
+ if (nPart == 1)
+ APPEND(rRet," over ");
+ APPEND(rRet," {");
+ break;
+ case 0xf:
+ if ((nVariation == 0) ||
+ ((nVariation == 2) && (nPart==1)))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 1) ||
+ ((nVariation == 2) && (nPart==0)))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x10:
+ if (nVariation == 0)
+ APPEND(rRet," underline ");
+ else if (nVariation == 1)
+ APPEND(rRet," underline underline ");
+ APPEND(rRet," {");
+ break;
+ case 0x11:
+ if (nVariation == 0)
+ APPEND(rRet," overline ");
+ else if (nVariation == 1)
+ APPEND(rRet," overline overline ");
+ APPEND(rRet," {");
+ break;
+ case 0x12:
+ if (nPart == 0)
+ {
+ if (nVariation == 0)
+ APPEND(rRet," widevec ");//left arrow above
+ else if (nVariation == 1)
+ APPEND(rRet," widevec ");//left arrow below
+ APPEND(rRet," {");
+ }
+ break;
+ case 0x13:
+ if (nPart == 0)
+ {
+ if (nVariation == 0)
+ APPEND(rRet," widevec ");//right arrow above
+ else if (nVariation == 1)
+ APPEND(rRet," widevec ");//right arrow below
+ APPEND(rRet," {");
+ }
+ break;
+ case 0x14:
+ if (nPart == 0)
+ {
+ if (nVariation == 0)
+ APPEND(rRet," widevec ");//double arrow above
+ else if (nVariation == 1)
+ APPEND(rRet," widevec ");//double arrow below
+ APPEND(rRet," {");
+ }
+ break;
+ case 0x15:
+ if (nPart == 0)
+ {
+ if ((nVariation == 3) || (nVariation == 4))
+ APPEND(rRet," lInt");
+ else
+ APPEND(rRet," Int");
+ if ( (nVariation != 0) && (nVariation != 3))
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if (((nVariation == 1) ||
+ (nVariation == 4)) && (nPart==1))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 2) && (nPart==2))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 2) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x16:
+ if (nPart == 0)
+ {
+ if ((nVariation == 2) || (nVariation == 3))
+ APPEND(rRet," llInt");
+ else
+ APPEND(rRet," iInt");
+ if ( (nVariation != 0) && (nVariation != 2))
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if (((nVariation == 1) ||
+ (nVariation == 3)) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x17:
+ if (nPart == 0)
+ {
+ if ((nVariation == 2) || (nVariation == 3))
+ APPEND(rRet," lllInt");
+ else
+ APPEND(rRet," iiInt");
+ if ( (nVariation != 0) && (nVariation != 2))
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if (((nVariation == 1) ||
+ (nVariation == 3)) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x18:
+ if (nPart == 0)
+ {
+ if (nVariation == 2)
+ APPEND(rRet," lInt");
+ else
+ APPEND(rRet," Int");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if (((nVariation == 1) ||
+ (nVariation == 2)) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 0) && (nPart==2))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x19:
+ if (nPart == 0)
+ {
+ if (nVariation == 0)
+ APPEND(rRet," llInt");
+ else
+ APPEND(rRet," iInt");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if (nPart==1)
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x1a:
+ if (nPart == 0)
+ {
+ if (nVariation == 0)
+ APPEND(rRet," lllInt");
+ else
+ APPEND(rRet," iiInt");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if (nPart==1)
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x1b:
+ case 0x1c:
+ APPEND(rRet," {");
+ break;
+ case 0x1d:
+ if (nPart == 0)
+ {
+ APPEND(rRet," Sum");
+ if (nVariation != 2)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x1e:
+ if (nPart == 0)
+ {
+ APPEND(rRet," Sum");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x1f:
+ if (nPart == 0)
+ {
+ APPEND(rRet," Prod");
+ if (nVariation != 2)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x20:
+ if (nPart == 0)
+ {
+ APPEND(rRet," Prod");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x21:
+ if (nPart == 0)
+ {
+ APPEND(rRet," coProd");
+ if (nVariation != 2)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x22:
+ if (nPart == 0)
+ {
+ APPEND(rRet," coProd");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x23:
+ if (nPart == 0)
+ {
+ APPEND(rRet," union"); //union
+ if (nVariation != 2)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x24:
+ if (nPart == 0)
+ {
+ APPEND(rRet," union"); //union
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x25:
+ if (nPart == 0)
+ {
+ APPEND(rRet," intersect"); //intersect
+ if (nVariation != 2)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x26:
+ if (nPart == 0)
+ {
+ APPEND(rRet," intersect"); //intersect
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x27:
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 2) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 2) && (nPart==2))
+ APPEND(rRet," cSup");
+ APPEND(rRet," {");
+ break;
+ case 0x28:
+ if (nVariation == 0)
+ {
+ if (nPart == 0)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ APPEND(rRet," {");
+ if (nVariation == 0)
+ {
+ if (nPart == 1)
+ APPEND(rRet,"alignr ");
+ }
+ if (nPart == 0)
+ APPEND(rRet,"\\lline ");
+ if (nVariation == 1)
+ APPEND(rRet,"overline ");
+ break;
+ case 0x29:
+ APPEND(rRet," {");
+ break;
+ case 0x2a:
+ if (nPart == 0)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==0))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 2) && (nPart==1))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 1) && (nPart==0))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 2) && (nPart==0))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x2b:
+ if (nPart == 0)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==0))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 2) && (nPart==1))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==0))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 2) && (nPart==0))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x2c:
+ if (nPart == 0)
+ APPEND(rRet,"\"\"");
+ if ((nVariation == 0)
+ || ((nVariation == 2) && (nPart==1)))
+ APPEND(rRet," lSup");
+ else if ((nVariation == 1)
+ || ((nVariation == 2) && (nPart==0)))
+ APPEND(rRet," lSub");
+ APPEND(rRet," {");
+ break;
+ case 0x2d:
+ if (nVariation==0)
+ {
+ if (nPart == 0)
+ APPEND(rRet," langle ");
+ }
+ else if (nVariation==1)
+ {
+ APPEND(rRet," \\langle ");
+ newline--;
+ }
+ else if (nVariation==2)
+ {
+ APPEND(rRet," \\lline ");
+ newline--;
+ }
+ break;
+ case 0x2e:
+ if (nVariation == 0)
+ APPEND(rRet," widevec ");//left below
+ else if (nVariation == 1)
+ APPEND(rRet," widevec ");//right below
+ else if (nVariation == 2)
+ APPEND(rRet," widevec ");//double headed below
+ APPEND(rRet," {");
+ break;
+ case 0x2f:
+ if (nVariation == 0)
+ APPEND(rRet," widevec ");//left above
+ else if (nVariation == 1)
+ APPEND(rRet," widevec ");//right above
+ else if (nVariation == 2)
+ APPEND(rRet," widevec ");//double headed above
+ APPEND(rRet," {");
+ break;
+ default:
+ break;
+ }
+ int nOldCurSize=nCurSize;
+ HandleSize(nLSize,nDSize,nSetSize);
+ nRet = HandleRecords(nLevel+1,nSelector,nVariation);
+ while (nSetSize)
+ {
+ APPEND(rRet,"} ");
+ nSetSize--;
+ nCurSize=nOldCurSize;
+ }
+
+
+ HandleMatrixSeperator(nMatrixRows,nMatrixCols,
+ nCurCol,nCurRow);
+
+ switch (nSelector)
+ {
+ case 0x0:
+ if (nVariation==0)
+ APPEND(rRet," rangle ");
+ else if (nVariation==2)
+ APPEND(rRet," \\rangle ");
+ break;
+ case 0x1:
+ if (nVariation==0)
+ APPEND(rRet," right )");
+ else if (nVariation==2)
+ APPEND(rRet,"\\)");
+ break;
+ case 0x2:
+ if (nVariation==0)
+ APPEND(rRet," rbrace ");
+ else if (nVariation==2)
+ APPEND(rRet," \\rbrace ");
+ break;
+ case 0x3:
+ if (nVariation==0)
+ APPEND(rRet," right ]");
+ else if (nVariation==2)
+ APPEND(rRet,"\\]");
+ break;
+ case 0x4:
+ if (nVariation==0)
+ APPEND(rRet," rline ");
+ else if (nVariation==2)
+ APPEND(rRet," \\rline ");
+ break;
+ case 0x5:
+ if (nVariation==0)
+ APPEND(rRet," rdline ");
+ else if (nVariation==2)
+ APPEND(rRet," \\rdline ");
+ break;
+ case 0x6:
+ if (nVariation==0)
+ APPEND(rRet," rfloor ");
+ else if (nVariation==2)
+ APPEND(rRet," \\rfloor ");
+ break;
+ case 0x7:
+ if (nVariation==0)
+ APPEND(rRet," rceil ");
+ else if (nVariation==2)
+ APPEND(rRet," \\rceil ");
+ break;
+ case 0x8:
+ case 0xa:
+ APPEND(rRet,"\\[");
+ break;
+ case 0x9:
+ case 0xc:
+ APPEND(rRet,"\\]");
+ break;
+ case 0xd:
+ APPEND(rRet,"} ");
+ if (nVariation == 1)
+ {
+ if (nPart == 0)
+ {
+ newline--;
+ sMainTerm = rRet;
+ rRet.Erase();
+ }
+ else
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ }
+ }
+ else
+ {
+ if (nPart == 0)
+ newline--;
+ }
+ nPart++;
+ break;
+ case 0xb:
+ APPEND(rRet,"\\)");
+ break;
+ case 0xe:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ newline--;
+ else
+ APPEND(rRet,"} ");
+ nPart++;
+ break;
+ case 0xf:
+ case 0x2c:
+ if ((nPart == 0) &&
+ ((nVariation == 2) || (nVariation == 1)))
+ newline--;
+ APPEND(rRet,"} ");
+ nPart++;
+ break;
+ case 0x10:
+ case 0x11:
+ case 0x2e:
+ case 0x2f:
+ APPEND(rRet,"} ");
+ break;
+ case 0x12:
+ case 0x13:
+ case 0x14:
+ if (nPart == 0)
+ {
+ newline--;
+ APPEND(rRet,"} ");
+ }
+ nPart++;
+ break;
+ case 0x1b:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ newline--;
+ APPEND(rRet,"overbrace");
+ }
+ nPart++;
+ break;
+ case 0x1c:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ newline--;
+ APPEND(rRet,"underbrace");
+ }
+ nPart++;
+ break;
+ case 0x27:
+ if (nPart==0)
+ newline--;
+ else if ((nPart==1) &&
+ ((nVariation == 2) || (nVariation == 1)))
+ newline--;
+ APPEND(rRet,"} ");
+ nPart++;
+ break;
+ case 0x28:
+ APPEND(rRet,"} ");
+ if (nVariation == 0)
+ {
+ if (nPart == 0)
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ }
+ else
+ {
+ sPush += rRet;
+ rRet = sPush;
+ APPEND(rRet," over ");
+ rRet += sMainTerm;
+ }
+ }
+ if (nPart == 0)
+ newline--;
+ nPart++;
+ break;
+ case 0x29:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ newline--;
+ switch (nVariation)
+ {
+ case 1:
+ APPEND(rRet,"slash");
+ break;
+ default:
+ APPEND(rRet,"wideslash");
+ break;
+ }
+ }
+ nPart++;
+ break;
+ case 0x1d:
+ case 0x1e:
+ case 0x1f:
+ case 0x20:
+ case 0x21:
+ case 0x22:
+ case 0x23:
+ case 0x24:
+ case 0x25:
+ case 0x26:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ if (nVariation != 2)
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ }
+ newline--;
+ }
+ else if ((nPart == 1) && (nVariation == 0))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ else if ((nPart == 1) && (nVariation == 1))
+ newline--;
+ else if ((nPart == 2) && (nVariation == 1))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ nPart++;
+ break;
+ case 0x15:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ if ((nVariation != 0) && (nVariation != 3))
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ }
+ newline--;
+ }
+ else if ((nPart == 1) &&
+ ((nVariation == 1) || (nVariation==4)))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ else if ((nPart == 1) && (nVariation == 2))
+ newline--;
+ else if ((nPart == 2) && (nVariation == 2))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ nPart++;
+ break;
+ case 0x16:
+ case 0x17:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ if ((nVariation != 0) && (nVariation != 2))
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ }
+ newline--;
+ }
+ else if ((nPart == 1) &&
+ ((nVariation == 1) || (nVariation==3)))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ nPart++;
+ break;
+ case 0x18:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ newline--;
+ }
+ else if ((nPart == 1) &&
+ ((nVariation == 1) || (nVariation==2)))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ else if ((nPart == 1) && (nVariation == 0))
+ newline--;
+ else if ((nPart == 2) && (nVariation == 0))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ nPart++;
+ break;
+ case 0x19:
+ case 0x1a:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ newline--;
+ }
+ else if (nPart == 1)
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ nPart++;
+ break;
+ case 0x2a:
+ case 0x2b:
+ APPEND(rRet,"} ");
+
+ if ((nPart == 0) &&
+ ((nVariation == 0) || (nVariation == 1)))
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ newline--;
+ }
+ else if ((nPart == 0) && (nVariation == 2))
+ newline--;
+ else if ((nPart == 1) && (nVariation == 2))
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ newline--;
+ }
+ else if ((nPart == 2) || (((nPart == 1) &&
+ (nVariation == 0) || (nVariation == 1))))
+ {
+ sPush+=rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ }
+ nPart++;
+ break;
+ case 0x2d:
+ if (nVariation==0)
+ {
+ if (nPart == 0)
+ {
+ newline--; //there is another term to arrive
+ APPEND(rRet," mline ");
+ }
+ else
+ APPEND(rRet," rangle ");
+ }
+ else if (nVariation==1)
+ APPEND(rRet," \\lline ");
+ else if (nVariation==2)
+ APPEND(rRet," \\rangle ");
+ nPart++;
+ break;
+ default:
+ break;
+ }
+ bSilent = TRUE; //Skip the optional brackets and/or
+ //symbols that follow some of these
+ //records. Foo Data.
+
+ /*In matrices and piles we cannot seperate equation
+ *lines with the newline keyword*/
+ if (nMatrixCols==0)
+ newline++;
+ }
+ }
+ break;
+ case CHAR:
+ nRet = HandleChar(nTextStart,nSetSize,nLevel,nTag,nSelector,
+ nVariation,bSilent);
+ break;
+ case TMPL:
+ nRet = HandleTemplate(nLevel,nSelector,nVariation);
+ break;
+ case PILE:
+ nRet = HandlePile(nSetAlign,nLevel,nSelector,nVariation);
+ HandleMatrixSeperator(nMatrixRows,nMatrixCols,nCurCol,nCurRow);
+ break;
+ case MATRIX:
+ nRet = HandleMatrix(nLevel,nSelector,nVariation);
+ HandleMatrixSeperator(nMatrixRows,nMatrixCols,nCurCol,nCurRow);
+ break;
+ case EMBEL:
+ HandleEmblishments();
+ break;
+ case RULER:
+ *pS >> nTabStops;
+ for (i=0;i<nTabStops;i++)
+ {
+ *pS >> nTabType;
+ *pS >> nTabOffset;
+ }
+ DBG_ASSERT(FALSE,"Not seen in the wild Equation Ruler Field")
+ break;
+ case FONT:
+ *pS >> nTface;
+ *pS >> nStyle;
+ sFontName.Erase();
+ do
+ {
+ *pS >> nChar8;
+ sFontName.Append(ByteString::ConvertToUnicode(
+ nChar8,RTL_TEXTENCODING_MS_1252));
+ }
+ while(nChar8);
+ break;
+ case SIZE:
+ HandleSetSize();
+ break;
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ nLSize=nRecord-10;
+ break;
+ case END:
+ default:
+ break;
+ }
+ }
+ while (nRecord != END);
+ while (nSetSize)
+ {
+ rRet += '}';
+ nSetSize--;
+ }
+ return nRet;
+}
+
+/*Simply determine if we are at the end of a record or the end of a line,
+ *with fiddley logic to see if we are in a matrix or a pile or neither
+
+ Note we cannot tell until after the event that this is the last entry
+ of a pile, so we must strip the last seperator of a pile after this
+ is detected in the PILE handler
+ */
+void MathType::HandleMatrixSeperator(int nMatrixRows,int nMatrixCols,
+ int &rCurCol,int &rCurRow)
+{
+ if (nMatrixRows!=0)
+ {
+ if (rCurCol == nMatrixCols-1)
+ {
+ if (rCurRow != nMatrixRows-1)
+ APPEND(rRet," {} ##\n");
+ if (nMatrixRows!=-1)
+ {
+ rCurCol=0;
+ rCurRow++;
+ }
+ }
+ else
+ {
+ APPEND(rRet," {} # ");
+ if (nMatrixRows!=-1)
+ rCurCol++;
+ else
+ rRet += '\n';
+ }
+ }
+}
+
+/* set the alignment of the following term, but starmath currently
+ * cannot handle vertical alignment */
+void MathType::HandleAlign(BYTE nHAlign,BYTE nVAlign,int &rSetAlign)
+{
+ switch(nHAlign)
+ {
+ case 1:
+ default:
+ APPEND(rRet,"alignl {");
+ break;
+ case 2:
+ APPEND(rRet,"alignc {");
+ break;
+ case 3:
+ APPEND(rRet,"alignr {");
+ break;
+ }
+#if 0
+ switch(nVAlign)
+ {
+ }
+ rSetAlign+=2;
+#endif
+ rSetAlign++;
+}
+
+/* set size of text, complexity due to overuse of signedness as a flag
+ * indicator by mathtype file format*/
+BOOL MathType::HandleSize(INT16 nLSize,INT16 nDSize, int &rSetSize)
+{
+ BOOL bRet=FALSE;
+ if (nLSize < 0)
+ {
+ if ((-nLSize/32 != nDefaultSize) && (-nLSize/32 != nCurSize))
+ {
+ if (rSetSize)
+ {
+ rSetSize--;
+ rRet += '}';
+ bRet=TRUE;
+ }
+ if (-nLSize/32 != nLastSize)
+ {
+ nLastSize = nCurSize;
+ APPEND(rRet," size ");
+ rRet += String::CreateFromInt32(-nLSize/32);
+ rRet += '{';
+ bRet=TRUE;
+ rSetSize++;
+ }
+ nCurSize = -nLSize/32;
+ }
+ }
+ else
+ {
+ /*sizetable should theoreticaly be filled with the default sizes
+ *of the various font groupings matching starmaths equivalents
+ in aTypeFaces, and a test would be done to see if the new font
+ size would be the same as what starmath would have chosen for
+ itself anyway in which case the size setting could be ignored*/
+ nLSize = aSizeTable[nLSize];
+ nLSize += nDSize;
+ //if (nLSize != nDefaultSize)
+ if (nLSize != nCurSize)
+ {
+ if (rSetSize)
+ {
+ rSetSize--;
+ rRet += '}';
+ bRet=TRUE;
+ }
+ if (nLSize != nLastSize)
+ {
+ nLastSize = nCurSize;
+ APPEND(rRet," size ");
+ rRet += String::CreateFromInt32(nLSize);
+ rRet += '{';
+ bRet=TRUE;
+ rSetSize++;
+ }
+ nCurSize = nLSize;
+ }
+ }
+ return bRet;
+}
+
+int MathType::ConvertFromStarMath(SvStorage *pStor)
+{
+ if (!pTree)
+ return 0;
+
+ SvGlobalName aGName(0x0002ce02L, 0x0000, 0x0000,0xc0,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x46 );
+ pStor->SetClass( aGName, 0, C2S("Microsoft Equation 3.0"));
+
+ static BYTE __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0xCE, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x17, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x45, 0x71, 0x75, 0x61, 0x74, 0x69,
+ 0x6F, 0x6E, 0x20, 0x33, 0x2E, 0x30, 0x00, 0x0C,
+ 0x00, 0x00, 0x00, 0x44, 0x53, 0x20, 0x45, 0x71,
+ 0x75, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x0B,
+ 0x00, 0x00, 0x00, 0x45, 0x71, 0x75, 0x61, 0x74,
+ 0x69, 0x6F, 0x6E, 0x2E, 0x33, 0x00, 0xF4, 0x39,
+ 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ SvStorageStreamRef xStor( pStor->OpenStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+
+ static BYTE __READONLY_DATA aOle[] = {
+ 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+ };
+ SvStorageStreamRef xStor2( pStor->OpenStream( C2S("\1Ole")));
+ xStor2->Write(aOle,sizeof(aOle));
+ xStor.Clear();
+ xStor2.Clear();
+
+ SvStorageStreamRef xSrc = pStor->OpenStream(C2S("Equation Native"));
+ if ( (!xSrc.Is()) || (SVSTREAM_OK != xSrc->GetError()))
+ return NULL;
+
+ pS = &xSrc;
+ pS->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ pS->SeekRel(EQNOLEFILEHDR_SIZE); //Skip 28byte Header and fill it in later
+ *pS << BYTE(0x03);
+ *pS << BYTE(0x01);
+ *pS << BYTE(0x01);
+ *pS << BYTE(0x03);
+ *pS << BYTE(0x00);
+ UINT32 nSize = pS->Tell();
+ nPendingAttributes=0;
+
+ HandleNodes(pTree);
+ *pS << BYTE(END);
+
+ nSize = pS->Tell()-nSize;
+ pS->Seek(0);
+ EQNOLEFILEHDR aHdr(nSize+4+1);
+ aHdr.Write(pS);
+ return 1;
+}
+
+
+BYTE MathType::HandleNodes(SmNode *pNode,int nLevel)
+{
+ BOOL bRet=FALSE;
+ switch(pNode->GetType())
+ {
+ case NATTRIBUT:
+ HandleAttributes(pNode,nLevel);
+ break;
+ case NTEXT:
+ HandleText(pNode,nLevel);
+ break;
+ case NVERTICAL_BRACE:
+ HandleVerticalBrace(pNode,nLevel);
+ break;
+ case NBRACE:
+ HandleBrace(pNode,nLevel);
+ break;
+ case NOPER:
+ HandleOperator(pNode,nLevel);
+ break;
+ case NBINVER:
+ HandleFractions(pNode,nLevel);
+ break;
+ case NROOT:
+ HandleRoot(pNode,nLevel);
+ break;
+ case NSPECIAL:
+ {
+ SmTextNode *pText=(SmTextNode *)pNode;
+ //if the token str and the result text are the same then this
+ //is to be seen as text, else assume its a mathchar
+ if (pText->GetText() == pText->GetToken().aText)
+ HandleText(pText,nLevel);
+ else
+ HandleMath(pText,nLevel);
+ }
+ break;
+ case NMATH:
+ HandleMath(pNode,nLevel);
+ break;
+ case NSUBSUP:
+ HandleSubSupScript(pNode,nLevel);
+ break;
+ case NEXPRESSION:
+ {
+ USHORT nSize = pNode->GetNumSubNodes();
+ for (USHORT i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ HandleNodes(pTemp,nLevel+1);
+ }
+ break;
+ case NTABLE:
+ //Root Node, PILE equivalent, i.e. vertical stack
+ HandleTable(pNode,nLevel);
+ break;
+ case NMATRIX:
+ HandleSmMatrix((SmMatrixNode *)pNode,nLevel);
+ break;
+ case NLINE:
+ {
+ *pS << BYTE(0x0a);
+ *pS << BYTE(LINE);
+ USHORT nSize = pNode->GetNumSubNodes();
+ for (USHORT i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END);
+ }
+ break;
+ case NALIGN:
+ HandleMAlign(pNode,nLevel);
+ break;
+ case NBLANK:
+ *pS << BYTE(CHAR);
+ *pS << BYTE(0x98);
+ if (pNode->GetToken().eType == TSBLANK)
+ *pS << USHORT(0xEB04);
+ else
+ *pS << USHORT(0xEB05);
+ break;
+
+ break;
+ default:
+ {
+ USHORT nSize = pNode->GetNumSubNodes();
+ for (USHORT i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ HandleNodes(pTemp,nLevel+1);
+ }
+ break;
+ }
+ return bRet;
+}
+
+
+int MathType::StartTemplate(UINT16 nSelector,UINT16 nVariation)
+{
+ int nOldPending=nPendingAttributes;
+ *pS << BYTE(TMPL); //Template
+ *pS << BYTE(nSelector); //selector
+ *pS << BYTE(nVariation); //variation
+ *pS << BYTE(0x00); //options
+ *pS << BYTE(LINE);
+ //theres just no way we can now handle any character
+ //attributes (from mathtypes perspective) centered
+ //over an expression but above template attribute
+ //such as widevec and similiar constructs
+ //we have to drop them
+ nPendingAttributes=0;
+ return nOldPending;
+}
+
+void MathType::EndTemplate(int nOldPendingAttributes)
+{
+ *pS << BYTE(END); //end line
+ *pS << BYTE(END); //end template
+ nPendingAttributes=nOldPendingAttributes;
+}
+
+
+void MathType::HandleSmMatrix(SmMatrixNode *pMatrix,int nLevel)
+{
+ *pS << BYTE(MATRIX);
+ *pS << BYTE(0x00); //vAlign ?
+ *pS << BYTE(0x00); //h_just
+ *pS << BYTE(0x00); //v_just
+ *pS << BYTE(pMatrix->GetNumRows()); //v_just
+ *pS << BYTE(pMatrix->GetNumCols()); //v_just
+ int nBytes=(pMatrix->GetNumRows()+1)*2/8;
+ if (((pMatrix->GetNumRows()+1)*2)%8)
+ nBytes++;
+ for (USHORT j = 0; j < nBytes; j++)
+ *pS << BYTE(0x00); //row_parts
+ nBytes=(pMatrix->GetNumCols()+1)*2/8;
+ if (((pMatrix->GetNumCols()+1)*2)%8)
+ nBytes++;
+ for (USHORT k = 0; k < nBytes; k++)
+ *pS << BYTE(0x00); //col_parts
+ USHORT nSize = pMatrix->GetNumSubNodes();
+ for (USHORT i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pMatrix->GetSubNode(i))
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END); //end line
+ }
+ *pS << BYTE(END);
+}
+
+
+//Root Node, PILE equivalent, i.e. vertical stack
+void MathType::HandleTable(SmNode *pNode,int nLevel)
+{
+ USHORT nSize = pNode->GetNumSubNodes();
+ //The root of the starmath is a table, if
+ //we convert this them each iteration of
+ //conversion from starmath to mathtype will
+ //add an extra unnecessary level to the
+ //mathtype output stack which would grow
+ //without bound in a multi step conversion
+
+ if (nLevel == 0)
+ *pS << BYTE(0x0A); //initial size
+
+ if ( nLevel || (nSize >1))
+ {
+ *pS << BYTE(PILE);
+ *pS << BYTE(nHAlign); //vAlign ?
+ *pS << BYTE(0x01); //hAlign
+ }
+
+ for (USHORT i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ {
+ *pS << BYTE(LINE);
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END);
+ }
+ if (nLevel || (nSize>1))
+ *pS << BYTE(END);
+}
+
+
+void MathType::HandleRoot(SmNode *pNode,int nLevel)
+{
+ USHORT nSize = pNode->GetNumSubNodes();
+ SmNode *pTemp;
+ *pS << BYTE(TMPL); //Template
+ *pS << BYTE(0x0D); //selector
+ if (pNode->GetSubNode(0))
+ *pS << BYTE(0x01); //variation
+ else
+ *pS << BYTE(0x00); //variation
+ *pS << BYTE(0x00); //options
+
+ /*
+ if (pTemp = pNode->GetSubNode(1))
+ HandleNodes(pTemp,nLevel+1);
+ */
+ if (pTemp = pNode->GetSubNode(2))
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END);
+ }
+
+ if (pTemp = pNode->GetSubNode(0))
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END);
+ }
+ else
+ *pS << BYTE(LINE|0x10); //dummy line
+
+
+
+ *pS << BYTE(END);
+}
+
+BYTE MathType::HandleCScript(SmNode *pNode,SmNode *pContent,int nLevel,ULONG *pPos,BOOL bTest)
+{
+ BYTE nVariation2=0xff;
+
+ if (bTest && pNode->GetSubNode(CSUP+1))
+ {
+ nVariation2=0;
+ if (pNode->GetSubNode(CSUB+1))
+ nVariation2=2;
+ }
+ else if (pNode->GetSubNode(CSUB+1))
+ nVariation2=1;
+
+ if (nVariation2!=0xff)
+ {
+ if (pPos)
+ *pPos = pS->Tell();
+ *pS << BYTE(TMPL); //Template
+ *pS << BYTE(0x2B); //selector
+ *pS << nVariation2;
+ *pS << BYTE(0x00); //options
+
+ if (pContent)
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pContent,nLevel+1);
+ *pS << BYTE(END); //line
+ }
+ else
+ *pS << BYTE(LINE|0x10);
+
+ *pS << BYTE(0x0B);
+
+ SmNode *pTemp;
+ if (pTemp = pNode->GetSubNode(CSUB+1))
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END); //line
+ }
+ else
+ *pS << BYTE(LINE|0x10);
+ if (bTest && (pTemp = pNode->GetSubNode(CSUP+1)))
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END); //line
+ }
+ else
+ *pS << BYTE(LINE|0x10);
+ }
+ return nVariation2;
+}
+
+
+
+/*
+ Sub and Sup scripts and another problem area, StarMath
+ can have all possible options used at the same time, whereas
+ Mathtype cannot. The ordering of the nodes for each system
+ is quite different as well leading to some complexity
+ */
+void MathType::HandleSubSupScript(SmNode *pNode,int nLevel)
+{
+ USHORT nSize = pNode->GetNumSubNodes();
+ ULONG nRSUpos=0,nCSUpos=0;
+ SmNode *pTemp;
+
+
+ BYTE nVariation=0xff;
+ if (pNode->GetSubNode(LSUP+1))
+ {
+ nVariation=0;
+ if (pNode->GetSubNode(LSUB+1))
+ nVariation=2;
+ }
+ else if (pTemp = pNode->GetSubNode(LSUB+1))
+ nVariation=1;
+
+ if (nVariation!=0xff)
+ {
+ *pS << BYTE(TMPL); //Template
+ *pS << BYTE(0x2c); //selector
+ *pS << nVariation;
+ *pS << BYTE(0x00); //options
+ *pS << BYTE(0x0B);
+
+ if (pTemp = pNode->GetSubNode(LSUB+1))
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END); //line
+ }
+ else
+ *pS << BYTE(LINE|0x10);
+ if (pTemp = pNode->GetSubNode(LSUP+1))
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END); //line
+ }
+ else
+ *pS << BYTE(LINE|0x10);
+ *pS << BYTE(END);
+ nVariation=0xff;
+ }
+
+
+ BYTE nVariation2=HandleCScript(pNode,NULL,nLevel);
+
+ if (pTemp = pNode->GetSubNode(0))
+ {
+ *pS << BYTE(0x0A);
+ *pS << BYTE(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END);
+ }
+
+ if (nVariation2 != 0xff)
+ *pS << BYTE(END);
+
+ if (pNode->GetSubNode(RSUP+1))
+ {
+ nVariation=0;
+ if (pNode->GetSubNode(RSUB+1))
+ nVariation=2;
+ }
+ else if (pTemp = pNode->GetSubNode(RSUB+1))
+ nVariation=1;
+
+ if (nVariation!=0xff)
+ {
+ *pS << BYTE(TMPL); //Template
+ *pS << BYTE(0x0F); //selector
+ *pS << nVariation;
+ *pS << BYTE(0x00); //options
+ *pS << BYTE(0x0B);
+
+ if (pTemp = pNode->GetSubNode(RSUB+1))
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END); //line
+ }
+ else
+ *pS << BYTE(LINE|0x10);
+ if (pTemp = pNode->GetSubNode(RSUP+1))
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END); //line
+ }
+ else
+ *pS << BYTE(LINE|0x10);
+ *pS << BYTE(END); //line
+ }
+
+ //After subscript mathtype will keep the size of
+ //normal text at the subscript size, sigh.
+ *pS << BYTE(0x0A);
+}
+
+
+void MathType::HandleFractions(SmNode *pNode,int nLevel)
+{
+ USHORT nSize = pNode->GetNumSubNodes();
+ SmNode *pTemp;
+ *pS << BYTE(TMPL); //Template
+ *pS << BYTE(0x0E); //selector
+ *pS << BYTE(0x00); //variation
+ *pS << BYTE(0x00); //options
+
+ *pS << BYTE(0x0A);
+ *pS << BYTE(LINE); //line
+ if (pTemp = pNode->GetSubNode(0))
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END);
+
+ *pS << BYTE(0x0A);
+ *pS << BYTE(LINE); //line
+ if (pTemp = pNode->GetSubNode(2))
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END);
+
+ *pS << BYTE(END);
+}
+
+
+void MathType::HandleBrace(SmNode *pNode,int nLevel)
+{
+ USHORT nSize = pNode->GetNumSubNodes();
+ SmNode *pTemp;
+ SmNode *pLeft=pNode->GetSubNode(0);
+ SmNode *pRight=pNode->GetSubNode(2);
+
+ *pS << BYTE(TMPL); //Template
+ bReInterpBrace=0;
+ BYTE nBSpec=0x10;
+ ULONG nLoc = pS->Tell();
+ if (pLeft)
+ {
+ switch (pLeft->GetToken().eType)
+ {
+ case TLANGLE:
+ *pS << BYTE(tmANGLE); //selector
+ *pS << BYTE(0x00); //variation
+ *pS << BYTE(0x00); //options
+ break;
+ case TLBRACE:
+ *pS << BYTE(tmBRACE); //selector
+ *pS << BYTE(0x00); //variation
+ *pS << BYTE(0x00); //options
+ nBSpec+=3;
+ break;
+ case TLBRACKET:
+ *pS << BYTE(tmBRACK); //selector
+ *pS << BYTE(0x00); //variation
+ *pS << BYTE(0x00); //options
+ nBSpec+=3;
+ break;
+ case TLLINE:
+ *pS << BYTE(tmBAR); //selector
+ *pS << BYTE(0x00); //variation
+ *pS << BYTE(0x00); //options
+ nBSpec+=3;
+ break;
+ case TLDLINE:
+ *pS << BYTE(tmDBAR); //selector
+ *pS << BYTE(0x00); //variation
+ *pS << BYTE(0x00); //options
+ break;
+ default:
+ *pS << BYTE(tmPAREN); //selector
+ *pS << BYTE(0x00); //variation
+ *pS << BYTE(0x00); //options
+ nBSpec+=3;
+ break;
+ }
+ }
+
+ if (pTemp = pNode->GetSubNode(1))
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END); //options
+ }
+ nSpec=nBSpec;
+ if (pLeft)
+ HandleNodes(pLeft,nLevel+1);
+ if (bReInterpBrace)
+ {
+ ULONG nLoc2 = pS->Tell();
+ pS->Seek(nLoc);
+ *pS << BYTE(0x2D);
+ pS->Seek(nLoc2);
+ *pS << BYTE(CHAR);
+ *pS << BYTE(0x96);
+ *pS << USHORT(0xEC07);
+ bReInterpBrace=0;
+ }
+ if (pRight)
+ HandleNodes(pRight,nLevel+1);
+ nSpec=0x0;
+ *pS << BYTE(END);
+}
+
+
+void MathType::HandleVerticalBrace(SmNode *pNode,int nLevel)
+{
+ SmNode *pTemp;
+ *pS << BYTE(TMPL); //Template
+ if (pNode->GetToken().eType == TUNDERBRACE)
+ *pS << BYTE(tmLHBRACE); //selector
+ else
+ *pS << BYTE(tmUHBRACE); //selector
+ *pS << BYTE(0x01); //variation
+ *pS << BYTE(0x00); //options
+
+ if (pTemp = pNode->GetSubNode(0))
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END); //options
+ }
+
+ if (pTemp = pNode->GetSubNode(2))
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << BYTE(END); //options
+ }
+ *pS << BYTE(END);
+}
+
+void MathType::HandleOperator(SmNode *pNode,int nLevel)
+{
+ USHORT nSize = pNode->GetNumSubNodes();
+
+ if (HandleLim(pNode,nLevel))
+ return;
+
+ ULONG nPos;
+ BYTE nVariation;
+
+ switch (pNode->GetToken().eType)
+ {
+ case TIINT:
+ case TIIINT:
+ case TLINT:
+ case TLLINT:
+ case TLLLINT:
+ nVariation=HandleCScript(pNode->GetSubNode(0),
+ pNode->GetSubNode(1),nLevel,&nPos,0);
+ break;
+ default:
+ nVariation=HandleCScript(pNode->GetSubNode(0),
+ pNode->GetSubNode(1),nLevel,&nPos);
+ break;
+ }
+
+ BYTE nOldVariation=nVariation;
+ BYTE nIntVariation=nVariation;
+
+ ULONG nPos2=0;
+ if (nVariation != 0xff)
+ {
+ nPos2 = pS->Tell();
+ pS->Seek(nPos);
+ if (nVariation == 2)
+ {
+ nIntVariation=0;
+ nVariation = 1;
+ }
+ else if (nVariation == 0)
+ nVariation = 1;
+ else if (nVariation == 1)
+ nVariation = 0;
+ }
+ else
+ {
+ nVariation = 2;
+ nIntVariation=0;
+ }
+ *pS << BYTE(TMPL);
+ switch(pNode->GetToken().eType)
+ {
+ case TINT:
+ if (nOldVariation != 0xff)
+ *pS << BYTE(0x18); //selector
+ else
+ *pS << BYTE(0x15); //selector
+ *pS << nIntVariation; //variation
+ break;
+ case TIINT:
+ if (nOldVariation != 0xff)
+ {
+ *pS << BYTE(0x19);
+ *pS << BYTE(0x01);
+ }
+ else
+ {
+ *pS << BYTE(0x16);
+ *pS << BYTE(0x00);
+ }
+ break;
+ case TIIINT:
+ if (nOldVariation != 0xff)
+ {
+ *pS << BYTE(0x1a);
+ *pS << BYTE(0x01);
+ }
+ else
+ {
+ *pS << BYTE(0x17);
+ *pS << BYTE(0x00);
+ }
+ break;
+ case TLINT:
+ if (nOldVariation != 0xff)
+ {
+ *pS << BYTE(0x18);
+ *pS << BYTE(0x02);
+ }
+ else
+ {
+ *pS << BYTE(0x15);
+ *pS << BYTE(0x03);
+ }
+ break;
+ case TLLINT:
+ if (nOldVariation != 0xff)
+ {
+ *pS << BYTE(0x19);
+ *pS << BYTE(0x00);
+ }
+ else
+ {
+ *pS << BYTE(0x16);
+ *pS << BYTE(0x02);
+ }
+ break;
+ case TLLLINT:
+ if (nOldVariation != 0xff)
+ {
+ *pS << BYTE(0x1a);
+ *pS << BYTE(0x00);
+ }
+ else
+ {
+ *pS << BYTE(0x17);
+ *pS << BYTE(0x02);
+ }
+ break;
+ case TSUM:
+ default:
+ *pS << BYTE(0x1d);
+ *pS << nVariation;
+ break;
+ case TPROD:
+ *pS << BYTE(0x1f);
+ *pS << nVariation;
+ break;
+ case TCOPROD:
+ *pS << BYTE(0x21);
+ *pS << nVariation;
+ break;
+ }
+ *pS << BYTE(0x00); //options
+
+ if (nPos2)
+ pS->Seek(nPos2);
+ else
+ {
+ *pS << BYTE(LINE); //line
+ HandleNodes(pNode->GetSubNode(1),nLevel+1);
+ *pS << BYTE(END); //line
+ *pS << BYTE(LINE|0x10);
+ *pS << BYTE(LINE|0x10);
+ }
+
+
+ *pS << BYTE(0x0D);
+ switch(pNode->GetToken().eType)
+ {
+ case TSUM:
+ default:
+ *pS << BYTE(CHAR);
+ *pS << BYTE(0x86);
+ *pS << USHORT(0x2211);
+ break;
+ case TPROD:
+ *pS << BYTE(CHAR);
+ *pS << BYTE(0x86);
+ *pS << USHORT(0x220F);
+ break;
+ case TCOPROD:
+ *pS << BYTE(CHAR);
+ *pS << BYTE(0x8B);
+ *pS << USHORT(0x2210);
+ break;
+ case TIIINT:
+ case TLLLINT:
+ *pS << BYTE(CHAR);
+ *pS << BYTE(0x86);
+ *pS << USHORT(0x222B);
+ case TIINT:
+ case TLLINT:
+ *pS << BYTE(CHAR);
+ *pS << BYTE(0x86);
+ *pS << USHORT(0x222B);
+ case TINT:
+ case TLINT:
+ *pS << BYTE(CHAR);
+ *pS << BYTE(0x86);
+ *pS << USHORT(0x222B);
+ break;
+ }
+ *pS << BYTE(END);
+ *pS << BYTE(0x0A);
+}
+
+
+int MathType::HandlePile(int &rSetAlign,int nLevel,BYTE nSelector,
+ BYTE nVariation)
+{
+ //if (xfLMOVE(nTag))
+ *pS >> nHAlign;
+ *pS >> nVAlign;
+
+ HandleAlign(nHAlign,nVAlign,rSetAlign);
+
+ APPEND(rRet," stack {\n");
+ int nRet = HandleRecords(nLevel+1,nSelector,nVariation,-1,-1);
+ rRet.Erase(rRet.Len()-3,2);
+ APPEND(rRet,"} ");
+
+ while (rSetAlign)
+ {
+ APPEND(rRet,"} ");
+ rSetAlign--;
+ }
+ return nRet;
+}
+
+int MathType::HandleMatrix(int nLevel,BYTE nSelector,
+ BYTE nVariation)
+{
+ BYTE nH_just,nV_just;
+ int nRows,nCols;
+ //if (xfLMOVE(nTag))
+ *pS >> nVAlign;
+ *pS >> nH_just;
+ *pS >> nV_just;
+ *pS >> nRows;
+ *pS >> nCols;
+ int nBytes = ((nRows+1)*2)/8;
+ if (((nRows+1)*2)%8)
+ nBytes++;
+ pS->SeekRel(nBytes);
+ nBytes = ((nCols+1)*2)/8;
+ if (((nCols+1)*2)%8)
+ nBytes++;
+ pS->SeekRel(nBytes);
+ APPEND(rRet," matrix {\n");
+ int nRet = HandleRecords(nLevel+1,nSelector,nVariation,nRows,nCols);
+ APPEND(rRet,"\n} ");
+ return nRet;
+}
+
+int MathType::HandleTemplate(int nLevel,BYTE &rSelector,BYTE &rVariation)
+{
+ BYTE nOption; //This appears utterly unused
+ //if (xfLMOVE(nTag))
+ *pS >> rSelector;
+ *pS >> rVariation;
+ *pS >> nOption;
+ DBG_ASSERT(rSelector < 48,"Selector out of range")
+ if ((rSelector >= 21) && (rSelector <=26))
+ {
+ DBG_ASSERT(nOption < 2,"Option out of range");
+ }
+ else if ((rSelector >= 0) && (rSelector <=12))
+ {
+ DBG_ASSERT(nOption < 3,"Option out of range");
+ }
+ //suborderlist
+ int nRet = HandleRecords(nLevel+1,rSelector,rVariation);
+ rSelector = -1;
+ return nRet;
+}
+
+void MathType::HandleEmblishments()
+{
+ BYTE nEmbel;
+ //if (xfLMOVE(nTag))
+ do
+ {
+ *pS >> nEmbel;
+ switch (nEmbel)
+ {
+ case 0x02:
+ APPEND(rRet," dot ");
+ break;
+ case 0x03:
+ APPEND(rRet," ddot ");
+ break;
+ case 0x04:
+ APPEND(rRet," dddot ");
+ break;
+ case 0x05:
+ if (nPostSup == 0)
+ {
+ APPEND(sPost," sup {}");
+ nPostSup = sPost.Len();
+ }
+ sPost.InsertAscii(" ' ",nPostSup-1);
+ nPostSup += 3;
+ break;
+ case 0x06:
+ if (nPostSup == 0)
+ {
+ APPEND(sPost," sup {}");
+ nPostSup = sPost.Len();
+ }
+ sPost.InsertAscii(" '' ",nPostSup-1);
+ nPostSup += 4;
+ break;
+ case 0x07:
+ if (nPostlSup == 0)
+ {
+ APPEND(sPost," lsup {}");
+ nPostlSup = sPost.Len();
+ }
+ sPost.InsertAscii(" ' ",nPostlSup-1);
+ nPostlSup += 3;
+ break;
+ case 0x08:
+ APPEND(rRet," tilde ");
+ break;
+ case 0x09:
+ APPEND(rRet," hat ");
+ break;
+ case 0x0b:
+ APPEND(rRet," vec ");
+ break;
+ case 0x10:
+ APPEND(rRet," overstrike ");
+ break;
+ case 0x11:
+ APPEND(rRet," bar ");
+ break;
+ case 0x12:
+ if (nPostSup == 0)
+ {
+ APPEND(sPost," sup {}");
+ nPostSup = sPost.Len();
+ }
+ sPost.InsertAscii(" ''' ",nPostSup-1);
+ nPostSup += 5;
+ break;
+ case 0x14:
+ APPEND(rRet," breve ");
+ break;
+ default:
+ DBG_ASSERT(nEmbel < 21,"Embel out of range")
+ break;
+ }
+ }while (nEmbel);
+}
+
+void MathType::HandleSetSize()
+{
+ BYTE nTemp;
+ *pS >> nTemp;
+ switch (nTemp)
+ {
+ case 101:
+ *pS >> nLSize;
+ nLSize = -nLSize;
+ break;
+ case 100:
+ *pS >> nTemp;
+ nLSize = nTemp;
+ *pS >> nDSize;
+ break;
+ default:
+ nLSize = nTemp;
+ *pS >> nTemp;
+ nDSize = nTemp-128;
+ break;
+ }
+}
+
+int MathType::HandleChar(xub_StrLen &rTextStart,int &rSetSize,int nLevel,
+ BYTE nTag,BYTE nSelector,BYTE nVariation, BOOL bSilent)
+{
+ sal_Unicode nChar;
+ int nRet=1;
+
+ if (xfAUTO(nTag))
+ {
+ //This is a candidate for function recognition, whatever
+ //that is!
+ }
+ //if (xfLMODE(nTag))
+
+ *pS >> nTypeFace;
+ if (nVersion < 3)
+ {
+ BYTE nChar8;
+ *pS >> nChar8;
+ nChar = nChar8;
+ }
+ else
+ *pS >> nChar;
+
+ if (xfEMBELL(nTag))
+ {
+ //A bit tricky, the character emblishments for
+ //mathtype can all be listed after eachother, in
+ //starmath some must go before the character and some
+ //must go after. In addition some of the emblishments
+ //may repeated and in starmath some of these groups
+ //must be gathered together. sPost is the portion that
+ //follows the char and nPostSup and nPostlSup are the
+ //indexes at which this class of emblishment is
+ //collated together
+ sPost.Erase();
+ nPostSup = nPostlSup = 0;
+ int nOriglen=rRet.Len()-rTextStart;
+ if ((!bSilent) && ((nOriglen) > 1))
+ rRet += '\"';
+ nRet = HandleRecords(nLevel+1,nSelector,nVariation);
+ if (!bSilent)
+ {
+ if (nOriglen > 1)
+ {
+ rRet.InsertAscii(" ital \"",rTextStart);
+ APPEND(rRet," ital {");
+ }
+ else
+ APPEND(rRet," {");
+ }
+ }
+
+ if (!bSilent)
+ {
+ int nOldLen = rRet.Len();
+ //nLastSize = nCurSize;
+ if (HandleSize(nLSize,nDSize,rSetSize))
+ {
+ if ((nOldLen - rTextStart) > 1)
+ {
+ rRet.InsertAscii("\"",nOldLen);
+ rRet.InsertAscii(" ital \"",rTextStart);
+ }
+ rTextStart = rRet.Len();
+ }
+ nOldLen = rRet.Len();
+ if (!LookupChar(nChar))
+ {
+ if (nOldLen - rTextStart > 1)
+ {
+ rRet.InsertAscii("\"",nOldLen);
+ rRet.InsertAscii(" ital \"",rTextStart);
+ }
+ rTextStart = rRet.Len();
+ }
+ }
+
+ if ((xfEMBELL(nTag)) && (!bSilent))
+ {
+ rRet += '}';
+ rRet += sPost;
+ rTextStart = rRet.Len();
+ }
+ return nRet;
+}
+
+BOOL MathType::HandleLim(SmNode *pNode,int nLevel)
+{
+ BOOL bRet=0;
+ //Special case for the "lim" option in StarMath
+ if ((pNode->GetToken().eType == TLIM)
+ || (pNode->GetToken().eType == TLIMSUP)
+ || (pNode->GetToken().eType == TLIMINF)
+ )
+ {
+ if (pNode->GetSubNode(1))
+ {
+ BYTE nVariation2=HandleCScript(pNode->GetSubNode(0),NULL,nLevel);
+
+ *pS << BYTE(0x0A);
+ *pS << BYTE(LINE); //line
+ *pS << BYTE(CHAR|0x10);
+ *pS << BYTE(0x82);
+ *pS << USHORT('l');
+ *pS << BYTE(CHAR|0x10);
+ *pS << BYTE(0x82);
+ *pS << USHORT('i');
+ *pS << BYTE(CHAR|0x10);
+ *pS << BYTE(0x82);
+ *pS << USHORT('m');
+
+ if (pNode->GetToken().eType == TLIMSUP)
+ {
+ *pS << BYTE(CHAR); //some space
+ *pS << BYTE(0x98);
+ *pS << USHORT(0xEB04);
+
+ *pS << BYTE(CHAR|0x10);
+ *pS << BYTE(0x82);
+ *pS << USHORT('s');
+ *pS << BYTE(CHAR|0x10);
+ *pS << BYTE(0x82);
+ *pS << USHORT('u');
+ *pS << BYTE(CHAR|0x10);
+ *pS << BYTE(0x82);
+ *pS << USHORT('p');
+ }
+ else if (pNode->GetToken().eType == TLIMINF)
+ {
+ *pS << BYTE(CHAR); //some space
+ *pS << BYTE(0x98);
+ *pS << USHORT(0xEB04);
+
+ *pS << BYTE(CHAR|0x10);
+ *pS << BYTE(0x82);
+ *pS << USHORT('i');
+ *pS << BYTE(CHAR|0x10);
+ *pS << BYTE(0x82);
+ *pS << USHORT('n');
+ *pS << BYTE(CHAR|0x10);
+ *pS << BYTE(0x82);
+ *pS << USHORT('f');
+ }
+
+
+ *pS << BYTE(CHAR); //some space
+ *pS << BYTE(0x98);
+ *pS << USHORT(0xEB04);
+
+ if (nVariation2 != 0xff)
+ {
+ *pS << BYTE(END);
+ *pS << BYTE(END);
+ }
+ HandleNodes(pNode->GetSubNode(1),nLevel+1);
+ //*pS << BYTE(END); //options
+ bRet = 1;
+ }
+ }
+ return bRet;
+}
+
+void MathType::HandleMAlign(SmNode *pNode,int nLevel)
+{
+ BYTE nPushedHAlign=nHAlign;
+ switch(pNode->GetToken().eType)
+ {
+ case TALIGNC:
+ nHAlign=2;
+ break;
+ case TALIGNR:
+ nHAlign=3;
+ break;
+ default:
+ nHAlign=1;
+ break;
+ }
+ USHORT nSize = pNode->GetNumSubNodes();
+ for (USHORT i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ HandleNodes(pTemp,nLevel+1);
+ nHAlign=nPushedHAlign;
+}
+
+void MathType::HandleMath(SmNode *pNode,int nLevel)
+{
+ if (pNode->GetToken().eType == TMLINE)
+ {
+ *pS << BYTE(END);
+ *pS << BYTE(LINE);
+ bReInterpBrace=1;
+ return;
+ }
+ SmMathSymbolNode *pTemp=(SmMathSymbolNode *)pNode;
+ for(int i=0;i<pTemp->GetText().Len();i++)
+ {
+ //Convert StarMath to Unicode. Provisional Table
+ //until unicode font designers come back with
+ //something complete
+
+ USHORT nArse = aMathTypeTable[pTemp->GetText().GetChar(i)&0x00FF];
+ if ((nArse == 0x2224) || (nArse == 0x2288) || (nArse == 0x2285) || (nArse == 0x2289))
+ *pS << BYTE(CHAR|0x20);
+ else
+ *pS << BYTE(CHAR); //char without formula recognition
+ //The typeface seems to be MTEXTRA for unicode characters,
+ //though how to determine when mathtype chooses one over
+ //the other is unknown. This should do the trick
+ //nevertheless.
+ BYTE nBias;
+ if ( (nArse == 0x2213) || (nArse == 0x2218) ||
+ (nArse == 0x210F) || (
+ (nArse >= 0x22EE) && (nArse <= 0x22FF)
+ ))
+ {
+ nBias = 0xB; //typeface
+ }
+ else if ((nArse > 0x2000) || (nArse == 0x00D7))
+ nBias = 0x6; //typeface
+ else if (nArse == 0x3d1)
+ nBias = 0x4;
+ else if ((nArse > 0xFF) && ((nArse < 0x393) || (nArse > 0x3c9)))
+ nBias = 0xB; //typeface
+ else if ((nArse == 0x2F) || (nArse == 0x2225))
+ nBias = 0x2; //typeface
+ else
+ nBias = 0x3; //typeface
+
+ *pS << BYTE(nSpec+nBias+128); //typeface
+
+ if (nArse == 0x2224)
+ {
+ *pS << USHORT(0x7C);
+ *pS << BYTE(EMBEL);
+ *pS << BYTE(0x0A);
+ *pS << BYTE(END); //end embel
+ *pS << BYTE(END); //end embel
+ }
+ else if (nArse == 0x2225)
+ *pS << USHORT(0xEC09);
+ else if (nArse == 0x226A)
+ {
+ *pS << USHORT(0x3C);
+ *pS << BYTE(CHAR);
+ *pS << BYTE(0x98);
+ *pS << USHORT(0xEB01);
+ *pS << BYTE(CHAR);
+ *pS << BYTE(0x86);
+ *pS << USHORT(0x3c);
+ }
+ else if (nArse == 0x2288)
+ {
+ *pS << USHORT(0x2286);
+ *pS << BYTE(EMBEL);
+ *pS << BYTE(0x0A);
+ *pS << BYTE(END); //end embel
+ *pS << BYTE(END); //end embel
+ }
+ else if (nArse == 0x2289)
+ {
+ *pS << USHORT(0x2287);
+ *pS << BYTE(EMBEL);
+ *pS << BYTE(0x0A);
+ *pS << BYTE(END); //end embel
+ *pS << BYTE(END); //end embel
+ }
+ else if (nArse == 0x2285)
+ {
+ *pS << USHORT(0x2283);
+ *pS << BYTE(EMBEL);
+ *pS << BYTE(0x0A);
+ *pS << BYTE(END); //end embel
+ *pS << BYTE(END); //end embel
+ }
+ else
+ {
+ //Convert StarMath to Unicode. Provisional Table
+ //until unicode font designers come back with
+ //something complete
+ *pS << nArse;
+ }
+
+ }
+}
+
+void MathType::HandleAttributes(SmNode *pNode,int nLevel)
+{
+ int nOldPending;
+ USHORT nSize = pNode->GetNumSubNodes();
+ SmNode *pTemp;
+ SmTextNode *pIsText;
+
+ //SmTextNode *pTemp=(SmTextNode *)pNode;
+ //for(int i=0;i<pTemp->GetText().Len();i++)
+
+ if (pTemp = pNode->GetSubNode(0))
+ {
+ pIsText = (SmTextNode *)pNode->GetSubNode(1);
+
+ switch (pTemp->GetToken().eType)
+ {
+ case TWIDEVEC:
+ //theres just no way we can now handle any character
+ //attributes (from mathtypes perspective) centered
+ //over an expression but above template attributes
+ //such as widevec and similiar constructs
+ //we have to drop them
+ nOldPending = StartTemplate(0x2f,0x01);
+ break;
+ case TCHECK: //Not Exportable
+ case TACUTE: //Not Exportable
+ case TGRAVE: //Not Exportable
+ case TCIRCLE: //Not Exportable
+ case TWIDETILDE: //Not Exportable
+ case TWIDEHAT: //Not Exportable
+ break;
+ case TUNDERLINE:
+ nOldPending = StartTemplate(0x10);
+ break;
+ case TOVERLINE: //If the next node is not text
+ //or text with more than one char
+ if ((pIsText->GetToken().eType != NTEXT) ||
+ (pIsText->GetText().Len() > 1))
+ nOldPending = StartTemplate(0x11);
+ break;
+ default:
+ nPendingAttributes++;
+ break;
+ }
+ }
+
+ if (pIsText)
+ HandleNodes(pIsText,nLevel+1);
+
+ switch (pTemp->GetToken().eType)
+ {
+ case TWIDEVEC:
+ case TUNDERLINE:
+ EndTemplate(nOldPending);
+ break;
+ case TOVERLINE:
+ if ((pIsText->GetToken().eType != NTEXT) ||
+ (pIsText->GetText().Len() > 1))
+ EndTemplate(nOldPending);
+ break;
+ default:
+ break;
+ }
+
+ //if there was no suitable place to put the attribute,
+ //then we have to just give up on it
+ if (nPendingAttributes)
+ nPendingAttributes--;
+ else
+ {
+ if ((nInsertion != 0) && (pTemp = pNode->GetSubNode(0)))
+ {
+ ULONG nPos = pS->Tell();
+ nInsertion--;
+ pS->Seek(nInsertion);
+ switch(pTemp->GetToken().eType)
+ {
+ case TACUTE: //Not Exportable
+ case TGRAVE: //Not Exportable
+ case TCIRCLE: //Not Exportable
+ break;
+ case TCDOT:
+ *pS << BYTE(2);
+ break;
+ case TDDOT:
+ *pS << BYTE(3);
+ break;
+ case TDDDOT:
+ *pS << BYTE(4);
+ break;
+ case TTILDE:
+ *pS << BYTE(8);
+ break;
+ case THAT:
+ *pS << BYTE(9);
+ break;
+ case TVEC:
+ *pS << BYTE(11);
+ break;
+ case TOVERSTRIKE:
+ *pS << BYTE(16);
+ break;
+ case TOVERLINE:
+ if ((pIsText->GetToken().eType == NTEXT) &&
+ (pIsText->GetText().Len() == 1))
+ *pS << BYTE(17);
+ break;
+ case TBREVE:
+ *pS << BYTE(20);
+ break;
+ case TWIDEVEC:
+ case TUNDERLINE:
+ case TWIDETILDE:
+ case TWIDEHAT:
+ break;
+ case TBAR:
+ *pS << BYTE(17);
+ break;
+ default:
+ *pS << BYTE(0x2);
+ break;
+ }
+ pS->Seek(nPos);
+ }
+ }
+}
+
+void MathType::HandleText(SmNode *pNode,int nLevel)
+{
+ SmTextNode *pTemp=(SmTextNode *)pNode;
+ for(int i=0;i<pTemp->GetText().Len();i++)
+ {
+ if ((nPendingAttributes) &&
+ (i == ((pTemp->GetText().Len()+1)/2)-1))
+ {
+ *pS << BYTE(0x22); //char, with attributes right
+ //after the character
+ }
+ else
+ *pS << BYTE(CHAR);
+ //*pS << BYTE(CHAR|0x10); //char with formula recognition
+
+ if ((pTemp->GetText().GetChar(i) >= '0') &&
+ (pTemp->GetText().GetChar(i) <= '9'))
+ *pS << BYTE(0x8+128); //typeface
+ else
+ *pS << BYTE(0x3+128); //typeface
+ *pS << USHORT(pTemp->GetText().GetChar(i));
+
+ //Mathtype can only have these sort of character
+ //attributes on a single character, starmath can put them
+ //anywhere, when the entity involved is a text run this is
+ //a large effort to place the character attribute on the
+ //central mathtype character so that it does pretty much
+ //what the user probably has in mind. The attributes
+ //filled in here are dummy ones which are replaced in the
+ //ATTRIBUT handler if a suitable location for the
+ //attributes was found here. Unfortunately it is
+ //possible for starmath to place character attributes on
+ //entities which cannot occur in mathtype e.g. a Summation
+ //symbol so these attributes may be lost
+ if ((nPendingAttributes) &&
+ (i == ((pTemp->GetText().Len()+1)/2)-1))
+ {
+ *pS << BYTE(EMBEL);
+ while (nPendingAttributes)
+ {
+ *pS << BYTE(2);
+ //wedge the attributes in here and clear
+ //the pending stack
+ nPendingAttributes--;
+ }
+ nInsertion=pS->Tell();
+ *pS << BYTE(END); //end embel
+ *pS << BYTE(END); //end embel
+ }
+ }
+}
+