diff options
Diffstat (limited to 'starmath/source/mathtype.cxx')
-rw-r--r-- | starmath/source/mathtype.cxx | 3374 |
1 files changed, 0 insertions, 3374 deletions
diff --git a/starmath/source/mathtype.cxx b/starmath/source/mathtype.cxx deleted file mode 100644 index 4a3cf8700b..0000000000 --- a/starmath/source/mathtype.cxx +++ /dev/null @@ -1,3374 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org 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 version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_starmath.hxx" - -#include <mathtype.hxx> -#include <osl/diagnose.h> -#include <sfx2/docfile.hxx> - -#define APPEND(str,ascii) str.AppendAscii(RTL_CONSTASCII_STRINGPARAM(ascii)) - -static sal_Unicode Convert(sal_Unicode nIn) -{ - //Find the best match in accepted unicode for our private area symbols - static sal_Unicode aStarMathPrivateToUnicode[] = - { - 0x2030, 0xF613, 0xF612, 0x002B, 0x003C, 0x003E, 0xE425, 0xE421, 0xE088, 0x2208, - 0x0192, 0x2026, 0x2192, 0x221A, 0x221A, 0x221A, 0xE090, 0x005E, 0x02C7, 0x02D8, - 0x00B4, 0x0060, 0x02DC, 0x00AF, 0x0362, 0xE099, 0xE09A, 0x20DB, 0xE09C, 0xE09D, - 0x0028, 0x0029, 0x2220, 0x22AF, 0xE0A2, 0xE0A3, 0xE0A4, 0xE0A5, 0xE0A6, 0xE0A7, - 0x002F, 0x005C, 0x274F, 0xE0AB, 0x0393, 0x0394, 0x0398, 0x039b, 0x039e, 0x03A0, - 0x03a3, 0x03a5, 0x03a6, 0x03a8, 0x03A9, 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, 0x03d6, 0xE0D2, 0x03db, 0x2118, 0x2202, 0x2129, 0xE0D7, 0xE0D8, 0x22A4, - 0xE0DA, 0x2190, 0x2191, 0x2193 - }; - if ((nIn >= 0xE080) && (nIn <= 0xE0DD)) - nIn = aStarMathPrivateToUnicode[nIn-0xE080]; - - //For whatever unicode glyph that equation editor doesn't ship with that - //we have a possible match we can munge it to. - switch (nIn) - { - case 0x2223: - nIn = '|'; - break; - default: - break; - } - - return nIn; -} - -void MathType::Init() -{ - //These are the default MathType sizes - aSizeTable[0]=12; - aSizeTable[1]=8; - aSizeTable[2]=6; - aSizeTable[3]=24; - aSizeTable[4]=10; - aSizeTable[5]=12; - aSizeTable[6]=12; - - /* - These are the default MathType italic/bold settings If mathtype is changed - from its defaults, there is nothing we can do, as this information is not - stored in the document - */ - MathTypeFont aFont; - for(sal_uInt8 i=1;i<=11;i++) - { - aFont.nTface = i+128; - switch (i) - { - default: - aFont.nStyle=0; - break; - case 3: - case 4: - aFont.nStyle=1; - break; - case 7: - aFont.nStyle=2; - break; - } - aUserStyles.insert(aFont); - } -} - - -/*ToDo replace with table rather than switch, returns - sal_True in the case that the char is just a char, and - sal_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 - */ -sal_Bool MathType::LookupChar(sal_Unicode nChar,String &rRet,sal_uInt8 nVersion, - sal_uInt8 nTypeFace) -{ - bool bRet=false; - const char *pC = NULL; - switch(nChar) - { - case 0x0000: - pC = " none "; - break; - case 0x00ac: - pC = " neg "; - break; - case 0x00b1: - pC = " +- "; - break; - case '(': - pC = " \\( "; - break; - case ')': - pC = " \\) "; - break; - case '[': - pC = " \\[ "; - break; - case ']': - pC = " \\] "; - break; - case '.': - pC = " \".\" "; - break; - case 0xae: - if ((nVersion < 3) && (nTypeFace == 0x86)) - pC = " rightarrow "; - else - { - rRet.Append(nChar); - bRet=true; - } - break; - case 0x00fb: - if ((nVersion < 3) && (nTypeFace == 0x81)) - nChar = 0xDF; - rRet.Append(nChar); - bRet=true; - break; - case 'a': - if ((nVersion < 3) && (nTypeFace == 0x84)) - nChar = 0x3b1; - rRet.Append(nChar); - bRet=true; - break; - case 'b': - if ((nVersion < 3) && (nTypeFace == 0x84)) - nChar = 0x3b2; - rRet.Append(nChar); - bRet=true; - break; - case 'l': - if ((nVersion < 3) && (nTypeFace == 0x84)) - nChar = 0x3bb; - rRet.Append(nChar); - bRet=true; - break; - case 'n': - if ((nVersion < 3) && (nTypeFace == 0x84)) - nChar = 0x3bd; - rRet.Append(nChar); - bRet=true; - break; - case 'r': - if ((nVersion < 3) && (nTypeFace == 0x84)) - nChar = 0x3c1; - rRet.Append(nChar); - bRet=true; - break; - case 'D': - if ((nVersion < 3) && (nTypeFace == 0x84)) - nChar = 0x394; - rRet.Append(nChar); - bRet=true; - break; - case 0xa9: - if ((nVersion < 3) && (nTypeFace == 0x82)) - nChar = '\''; - rRet.Append(nChar); - bRet=true; - break; - case 0x00f1: - if ((nVersion < 3) && (nTypeFace == 0x86)) - pC = " \\rangle "; - else - { - rRet.Append(nChar); - bRet=true; - } - break; - case 0x00a3: - if ((nVersion < 3) && (nTypeFace == 0x86)) - pC = " <= "; - else - { - rRet.Append(nChar); - bRet=true; - } - break; - case 0x00de: - if ((nVersion < 3) && (nTypeFace == 0x86)) - pC = " drarrow "; - else - { - rRet.Append(nChar); - bRet=true; - } - break; - case 0x0057: - if ((nVersion < 3) && (nTypeFace == 0x85)) - pC = " %OMEGA "; - else - { - rRet.Append(nChar); - bRet=true; - } - break; - case 0x007b: - pC = " lbrace "; - break; - case 0x007c: - pC = " \\lline "; - break; - case 0x007d: - pC = " rbrace "; - break; - case 0x007e: - pC = " \"~\" "; - break; - case 0x2224: - pC = " ndivides "; - break; - case 0x2225: - pC = " parallel "; - 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 0x2102: - pC = " setC "; - break; - case 0x210f: - pC = " hbar "; - break; - case 0x2111: - pC = " Im "; - break; - case 0x2115: - pC = " setN "; - break; - case 0x2118: - pC = " wp "; - break; - case 0x211a: - pC = " setQ "; - break; - case 0x211c: - pC = " Re "; - break; - case 0x211d: - pC = " setR "; - break; - case 0x2124: - pC = " setZ "; - break; - case 0x2135: - pC = " aleph "; - break; - case 0x2190: - pC = " leftarrow "; - break; - case 0x2191: - pC = " uparrow "; - break; - case 0x2192: - pC = " rightarrow "; - break; - case 0x0362: - pC = " widevec "; - break; - case 0x2193: - pC = " downarrow "; - break; - case 0x21d0: - pC = " dlarrow "; - break; - case 0x21d2: - pC = " drarrow "; - 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 0x222c: - pC = " iint "; - break; - case 0x222d: - pC = " iiint "; - break; - case 0x222e: - pC = " lint "; - break; - case 0x222f: - pC = " llint "; - break; - case 0x2230: - pC = " lllint "; - 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 0x2285: - pC = " nsupset "; - break; - case 0x2286: - pC = " subseteq "; - break; - case 0x2287: - pC = " supseteq "; - break; - case 0x2288: - pC = " nsubseteq "; - break; - case 0x2289: - pC = " nsupseteq "; - 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 0x2329: - pC = " langle "; - break; - case 0x232a: - pC = " rangle "; - break; - case 0x301a: - pC = " ldbracket "; - break; - case 0x301b: - pC = " rdbracket "; - break; - case 0xe083: - rRet.Append('+'); - bRet=true; - break; - case '^': - case 0xe091: - pC = " widehat "; - break; - case 0xe096: - pC = " widetilde "; - break; - case 0xe098: - pC = " widevec "; - break; - case 0xE421: - pC = " geslant "; - break; - case 0xE425: - pC = " leslant "; - break; - case 0xeb01: //no space - case 0xeb08: //normal space - bRet=true; - break; - case 0xef04: //tiny space - case 0xef05: //tiny space - 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; -} - -void MathTypeFont::AppendStyleToText(String &rRet) -{ - const char *pC = NULL; - switch (nStyle) - { - default: - case 0: - break; - case 1: - pC = " ital "; - break; - case 2: - pC = " bold "; - break; - case 3: - pC = " bold italic"; - break; - } - if (pC) - rRet.AppendAscii(pC); -} - -void MathType::TypeFaceToString(String &rTxt,sal_uInt8 nFace) -{ - MathTypeFont aFont(nFace); - MathTypeFontSet::iterator aItr = aUserStyles.find(aFont); - if (aItr != aUserStyles.end()) - aFont.nStyle = aItr->nStyle; - aFont.AppendStyleToText(rTxt); -} - -int MathType::Parse(SotStorage *pStor) -{ - SvStorageStreamRef xSrc = pStor->OpenSotStream( - String::CreateFromAscii("Equation Native"), - STREAM_STD_READ | STREAM_NOCREATE); - if ( (!xSrc.Is()) || (SVSTREAM_OK != xSrc->GetError())) - return 0; - pS = &xSrc; - pS->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - - EQNOLEFILEHDR aHdr; - aHdr.Read(pS); - *pS >> nVersion; - *pS >> nPlatform; - *pS >> nProduct; - *pS >> nProdVersion; - *pS >> nProdSubVersion; - - if (nVersion > 3) // allow only supported versions of MathType to be parsed - return 0; - -#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,"{}"); - -#if OSL_DEBUG_LEVEL > 1 -# ifdef CAOLAN - //sanity check - - //sigh, theres no point! MathType (in some bizarre subvarient) pads - //the end of the formula with ENDs (0)'s - sal_uLong nEnd = pS->Tell(); - OSL_ENSURE(nEnd == pS->Seek(STREAM_SEEK_TO_END), - "Possibly unfully parsed formula"); -# endif -#endif - return nRet; -} - -static void lcl_PrependDummyTerm(String &rRet, xub_StrLen &rTextStart) -{ - if ((rRet.GetChar(rTextStart) == '=') && - ((rTextStart == 0) || - (rRet.GetChar(rTextStart-1) == '{')) - ) - { - rRet.InsertAscii(" {}",rTextStart); - rTextStart+=3; - } -} - -static void lcl_AppendDummyTerm(String &rRet) -{ - bool bOk=false; - for(int nI=rRet.Len()-1;nI >= 0; nI--) - { - xub_StrLen nIdx = sal::static_int_cast< xub_StrLen >(nI); - sal_Unicode nChar = rRet.GetChar(nIdx); - if (nChar == ' ') - continue; - if (rRet.GetChar(nIdx) != '{') - bOk=true; - break; - } - if (!bOk) //No term, use dummy - APPEND(rRet," {}"); -} - -void MathType::HandleNudge() -{ - sal_uInt8 nXNudge; - *pS >> nXNudge; - sal_uInt8 nYNudge; - *pS >> nYNudge; - if (nXNudge == 128 && nYNudge == 128) - { - sal_uInt16 nXLongNudge; - sal_uInt16 nYLongNudge; - *pS >> nXLongNudge; - *pS >> nYLongNudge; - } -} -/*Fabously complicated as many tokens have to be reordered and generally - *moved around from mathtypes paradigm to starmaths.*/ -int MathType::HandleRecords(int nLevel,sal_uInt8 nSelector, - sal_uInt8 nVariation, int nMatrixRows,int nMatrixCols) -{ - sal_uInt8 nTag,nRecord; - sal_uInt8 nTabType,nTabStops; - sal_uInt16 nTabOffset; - 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 = 0; - xub_StrLen nSubSupStartPos = 0; - xub_StrLen nLastTemplateBracket=STRING_NOTFOUND; - - 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) && (!bIsSilent) && (!bOpenString)) - { - bOpenString=true; - nTextStart = rRet.Len(); - } - else if ((nRecord != CHAR) && (bOpenString)) - { - bOpenString=false; - if ((rRet.Len() - nTextStart) > 1) - { - String aStr; - TypeFaceToString(aStr,nTypeFace); - aStr += '\"'; - rRet.Insert(aStr,nTextStart); - rRet += '\"'; - } - else - { - if (nRecord == END) - { - sal_Unicode cChar = 0; - xub_StrLen nI = rRet.Len()-1; - while (nI && ((cChar = rRet.GetChar(nI)) == ' ')) - --nI; - if ((cChar == '=') || (cChar == '+') || (cChar == '-')) - APPEND(rRet,"{}"); - } - } - } - - switch(nRecord) - { - case LINE: - { - if (xfLMOVE(nTag)) - HandleNudge(); - - 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) || (nVariation==1)) - APPEND(rRet," left lbrace "); - else - APPEND(rRet," left none "); - 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 || nVariation == 1) - APPEND(rRet," left lfloor "); - else if (nVariation==1) - APPEND(rRet," left none "); - 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: - nSubSupStartPos = rRet.Len(); - if ((nVariation == 0) || - ((nVariation == 2) && (nPart==1))) - { - lcl_AppendDummyTerm(rRet); - APPEND(rRet," rSup"); - } - else if ((nVariation == 1) || - ((nVariation == 2) && (nPart==0))) - { - lcl_AppendDummyTerm(rRet); - 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; - } - sal_Int16 nOldCurSize=nCurSize; - xub_StrLen nSizeStartPos = rRet.Len(); - HandleSize(nLSize,nDSize,nSetSize); - nRet = HandleRecords(nLevel+1); - while (nSetSize) - { - bool bOk=false; - xub_StrLen nI = rRet.SearchBackward('{'); - if (nI != STRING_NOTFOUND) - { - for(nI=nI+1;nI<rRet.Len();nI++) - if (rRet.GetChar(nI) != ' ') - { - bOk=true; - break; - } - } - else - bOk=true; - - if (bOk) - APPEND(rRet,"} "); - else - rRet.Erase(nSizeStartPos); - 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) || (nVariation==2)) - APPEND(rRet," right rbrace "); - else - APPEND(rRet," right none "); - 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 || nVariation == 2) - APPEND(rRet," right rfloor "); - else if (nVariation==2) - APPEND(rRet," right none "); - 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: - { - if ((nPart == 0) && - ((nVariation == 2) || (nVariation == 1))) - newline--; - - bool bOk=false; - xub_StrLen nI = rRet.SearchBackward('{'); - if (nI != STRING_NOTFOUND) - { - for(nI=nI+1;nI<rRet.Len();nI++) - if (rRet.GetChar(nI) != ' ') - { - bOk=true; - break; - } - } - else - bOk=true; - - if (bOk) - APPEND(rRet,"} "); - else - rRet.Erase(nSubSupStartPos); - nPart++; - } - break; - case 0x2c: - if ((nPart == 0) && - ((nVariation == 2) || (nVariation == 1))) - newline--; - APPEND(rRet,"} "); - nPart++; - break; - case 0x2e: - case 0x2f: - APPEND(rRet,"} "); - break; - case 0x10: - case 0x11: - 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: - if (xfLMOVE(nTag)) - HandleNudge(); - nRet = HandleChar(nTextStart,nSetSize,nLevel,nTag,nSelector, - nVariation,bSilent); - break; - case TMPL: - if (xfLMOVE(nTag)) - HandleNudge(); - nRet = HandleTemplate(nLevel,nSelector,nVariation, - nLastTemplateBracket); - break; - case PILE: - if (xfLMOVE(nTag)) - HandleNudge(); - nRet = HandlePile(nSetAlign,nLevel,nSelector,nVariation); - HandleMatrixSeperator(nMatrixRows,nMatrixCols,nCurCol,nCurRow); - break; - case MATRIX: - if (xfLMOVE(nTag)) - HandleNudge(); - nRet = HandleMatrix(nLevel,nSelector,nVariation); - HandleMatrixSeperator(nMatrixRows,nMatrixCols,nCurCol,nCurRow); - break; - case EMBEL: - if (xfLMOVE(nTag)) - HandleNudge(); - HandleEmblishments(); - break; - case RULER: - *pS >> nTabStops; - for (i=0;i<nTabStops;i++) - { - *pS >> nTabType; - *pS >> nTabOffset; - } - OSL_FAIL("Not seen in the wild Equation Ruler Field"); - break; - case FONT: - { - MathTypeFont aFont; - *pS >> aFont.nTface; - /* - The typeface number is the negative (which makes it - positive) of the typeface value (unbiased) that appears in - CHAR records that might follow a given FONT record - */ - aFont.nTface = 128-aFont.nTface; - *pS >> aFont.nStyle; - aUserStyles.insert(aFont); - std::vector<sal_Char> aSeq; - while(1) - { - sal_Char nChar8(0); - *pS >> nChar8; - if (nChar8 == 0) - break; - aSeq.push_back(nChar8); - } - sFontName = rtl::OUString(&aSeq[0], aSeq.size(), - RTL_TEXTENCODING_MS_1252); - } - 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 && !pS->IsEof()); - 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(sal_uInt8 nHorAlign, sal_uInt8 /*nVAlign*/, int &rSetAlign) -{ - switch(nHorAlign) - { - case 1: - default: - APPEND(rRet,"alignl {"); - break; - case 2: - APPEND(rRet,"alignc {"); - break; - case 3: - APPEND(rRet,"alignr {"); - break; - } - rSetAlign++; -} - -/* set size of text, complexity due to overuse of signedness as a flag - * indicator by mathtype file format*/ -sal_Bool MathType::HandleSize(sal_Int16 nLstSize,sal_Int16 nDefSize, int &rSetSize) -{ - bool bRet=false; - if (nLstSize < 0) - { - if ((-nLstSize/32 != nDefaultSize) && (-nLstSize/32 != nCurSize)) - { - if (rSetSize) - { - rSetSize--; - rRet += '}'; - bRet=true; - } - if (-nLstSize/32 != nLastSize) - { - nLastSize = nCurSize; - APPEND(rRet," size "); - rRet += String::CreateFromInt32(-nLstSize/32); - rRet += '{'; - bRet=true; - rSetSize++; - } - nCurSize = -nLstSize/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*/ - nLstSize = aSizeTable[nLstSize]; - nLstSize = nLstSize + nDefSize; - if (nLstSize != nCurSize) - { - if (rSetSize) - { - rSetSize--; - rRet += '}'; - bRet=true; - } - if (nLstSize != nLastSize) - { - nLastSize = nCurSize; - APPEND(rRet," size "); - rRet += String::CreateFromInt32(nLstSize); - rRet += '{'; - bRet=true; - rSetSize++; - } - nCurSize = nLstSize; - } - } - return bRet; -} - -int MathType::ConvertFromStarMath( SfxMedium& rMedium ) -{ - if (!pTree) - return 0; - - SvStream *pStream = rMedium.GetOutStream(); - if ( pStream ) - { - SvStorageRef pStor = new SotStorage( pStream, false ); - - SvGlobalName aGName(0x0002ce02L, 0x0000, 0x0000,0xc0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x46 ); - pStor->SetClass( aGName, 0, C2S("Microsoft Equation 3.0")); - - static sal_uInt8 const 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->OpenSotStream( C2S("\1CompObj"))); - xStor->Write(aCompObj,sizeof(aCompObj)); - - static sal_uInt8 const aOle[] = { - 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - SvStorageStreamRef xStor2( pStor->OpenSotStream( C2S("\1Ole"))); - xStor2->Write(aOle,sizeof(aOle)); - xStor.Clear(); - xStor2.Clear(); - - SvStorageStreamRef xSrc = pStor->OpenSotStream(C2S("Equation Native")); - if ( (!xSrc.Is()) || (SVSTREAM_OK != xSrc->GetError())) - return 0; - - pS = &xSrc; - pS->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - - pS->SeekRel(EQNOLEFILEHDR_SIZE); //Skip 28byte Header and fill it in later - *pS << sal_uInt8(0x03); - *pS << sal_uInt8(0x01); - *pS << sal_uInt8(0x01); - *pS << sal_uInt8(0x03); - *pS << sal_uInt8(0x00); - sal_uInt32 nSize = pS->Tell(); - nPendingAttributes=0; - - HandleNodes(pTree); - *pS << sal_uInt8(END); - - nSize = pS->Tell()-nSize; - pS->Seek(0); - EQNOLEFILEHDR aHdr(nSize+4+1); - aHdr.Write(pS); - - pStor->Commit(); - } - - return 1; -} - - -sal_uInt8 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: - { - sal_uInt16 nSize = pNode->GetNumSubNodes(); - for (sal_uInt16 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 << sal_uInt8(0x0a); - *pS << sal_uInt8(LINE); - sal_uInt16 nSize = pNode->GetNumSubNodes(); - for (sal_uInt16 i = 0; i < nSize; i++) - if (SmNode *pTemp = pNode->GetSubNode(i)) - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); - } - break; - case NALIGN: - HandleMAlign(pNode,nLevel); - break; - case NBLANK: - *pS << sal_uInt8(CHAR); - *pS << sal_uInt8(0x98); - if (pNode->GetToken().eType == TSBLANK) - *pS << sal_uInt16(0xEB04); - else - *pS << sal_uInt16(0xEB05); - break; - default: - { - sal_uInt16 nSize = pNode->GetNumSubNodes(); - for (sal_uInt16 i = 0; i < nSize; i++) - if (SmNode *pTemp = pNode->GetSubNode(i)) - HandleNodes(pTemp,nLevel+1); - } - break; - } - return bRet; -} - - -int MathType::StartTemplate(sal_uInt16 nSelector,sal_uInt16 nVariation) -{ - int nOldPending=nPendingAttributes; - *pS << sal_uInt8(TMPL); //Template - *pS << sal_uInt8(nSelector); //selector - *pS << sal_uInt8(nVariation); //variation - *pS << sal_uInt8(0x00); //options - *pS << sal_uInt8(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 << sal_uInt8(END); //end line - *pS << sal_uInt8(END); //end template - nPendingAttributes=nOldPendingAttributes; -} - - -void MathType::HandleSmMatrix(SmMatrixNode *pMatrix,int nLevel) -{ - *pS << sal_uInt8(MATRIX); - *pS << sal_uInt8(0x00); //vAlign ? - *pS << sal_uInt8(0x00); //h_just - *pS << sal_uInt8(0x00); //v_just - *pS << sal_uInt8(pMatrix->GetNumRows()); //v_just - *pS << sal_uInt8(pMatrix->GetNumCols()); //v_just - int nBytes=(pMatrix->GetNumRows()+1)*2/8; - if (((pMatrix->GetNumRows()+1)*2)%8) - nBytes++; - for (sal_uInt16 j = 0; j < nBytes; j++) - *pS << sal_uInt8(0x00); //row_parts - nBytes=(pMatrix->GetNumCols()+1)*2/8; - if (((pMatrix->GetNumCols()+1)*2)%8) - nBytes++; - for (sal_uInt16 k = 0; k < nBytes; k++) - *pS << sal_uInt8(0x00); //col_parts - sal_uInt16 nSize = pMatrix->GetNumSubNodes(); - for (sal_uInt16 i = 0; i < nSize; i++) - if (SmNode *pTemp = pMatrix->GetSubNode(i)) - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); //end line - } - *pS << sal_uInt8(END); -} - - -//Root Node, PILE equivalent, i.e. vertical stack -void MathType::HandleTable(SmNode *pNode,int nLevel) -{ - sal_uInt16 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 << sal_uInt8(0x0A); //initial size - - if ( nLevel || (nSize >1)) - { - *pS << sal_uInt8(PILE); - *pS << sal_uInt8(nHAlign); //vAlign ? - *pS << sal_uInt8(0x01); //hAlign - } - - for (sal_uInt16 i = 0; i < nSize; i++) - if (SmNode *pTemp = pNode->GetSubNode(i)) - { - *pS << sal_uInt8(LINE); - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); - } - if (nLevel || (nSize>1)) - *pS << sal_uInt8(END); -} - - -void MathType::HandleRoot(SmNode *pNode,int nLevel) -{ - SmNode *pTemp; - *pS << sal_uInt8(TMPL); //Template - *pS << sal_uInt8(0x0D); //selector - if (pNode->GetSubNode(0)) - *pS << sal_uInt8(0x01); //variation - else - *pS << sal_uInt8(0x00); //variation - *pS << sal_uInt8(0x00); //options - - if (NULL != (pTemp = pNode->GetSubNode(2))) - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); - } - - if (NULL != (pTemp = pNode->GetSubNode(0))) - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); - } - else - *pS << sal_uInt8(LINE|0x10); //dummy line - - - - *pS << sal_uInt8(END); -} - -sal_uInt8 MathType::HandleCScript(SmNode *pNode,SmNode *pContent,int nLevel, - sal_uLong *pPos,sal_Bool bTest) -{ - sal_uInt8 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 << sal_uInt8(TMPL); //Template - *pS << sal_uInt8(0x2B); //selector - *pS << nVariation2; - *pS << sal_uInt8(0x00); //options - - if (pContent) - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pContent,nLevel+1); - *pS << sal_uInt8(END); //line - } - else - *pS << sal_uInt8(LINE|0x10); - - *pS << sal_uInt8(0x0B); - - SmNode *pTemp; - if (NULL != (pTemp = pNode->GetSubNode(CSUB+1))) - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); //line - } - else - *pS << sal_uInt8(LINE|0x10); - if (bTest && NULL != (pTemp = pNode->GetSubNode(CSUP+1))) - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); //line - } - else - *pS << sal_uInt8(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) -{ - SmNode *pTemp; - - sal_uInt8 nVariation=0xff; - if (pNode->GetSubNode(LSUP+1)) - { - nVariation=0; - if (pNode->GetSubNode(LSUB+1)) - nVariation=2; - } - else if (NULL != (pTemp = pNode->GetSubNode(LSUB+1))) - nVariation=1; - - if (nVariation!=0xff) - { - *pS << sal_uInt8(TMPL); //Template - *pS << sal_uInt8(0x2c); //selector - *pS << nVariation; - *pS << sal_uInt8(0x00); //options - *pS << sal_uInt8(0x0B); - - if (NULL != (pTemp = pNode->GetSubNode(LSUB+1))) - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); //line - } - else - *pS << sal_uInt8(LINE|0x10); - if (NULL != (pTemp = pNode->GetSubNode(LSUP+1))) - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); //line - } - else - *pS << sal_uInt8(LINE|0x10); - *pS << sal_uInt8(END); - nVariation=0xff; - } - - - sal_uInt8 nVariation2=HandleCScript(pNode,NULL,nLevel); - - if (NULL != (pTemp = pNode->GetSubNode(0))) - { - HandleNodes(pTemp,nLevel+1); - } - - if (nVariation2 != 0xff) - *pS << sal_uInt8(END); - - if (NULL != (pNode->GetSubNode(RSUP+1))) - { - nVariation=0; - if (pNode->GetSubNode(RSUB+1)) - nVariation=2; - } - else if (NULL != (pTemp = pNode->GetSubNode(RSUB+1))) - nVariation=1; - - if (nVariation!=0xff) - { - *pS << sal_uInt8(TMPL); //Template - *pS << sal_uInt8(0x0F); //selector - *pS << nVariation; - *pS << sal_uInt8(0x00); //options - *pS << sal_uInt8(0x0B); - - if (NULL != (pTemp = pNode->GetSubNode(RSUB+1))) - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); //line - } - else - *pS << sal_uInt8(LINE|0x10); - if (NULL != (pTemp = pNode->GetSubNode(RSUP+1))) - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); //line - } - else - *pS << sal_uInt8(LINE|0x10); - *pS << sal_uInt8(END); //line - } - - //After subscript mathtype will keep the size of - //normal text at the subscript size, sigh. - *pS << sal_uInt8(0x0A); -} - - -void MathType::HandleFractions(SmNode *pNode,int nLevel) -{ - SmNode *pTemp; - *pS << sal_uInt8(TMPL); //Template - *pS << sal_uInt8(0x0E); //selector - *pS << sal_uInt8(0x00); //variation - *pS << sal_uInt8(0x00); //options - - *pS << sal_uInt8(0x0A); - *pS << sal_uInt8(LINE); //line - if (NULL != (pTemp = pNode->GetSubNode(0))) - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); - - *pS << sal_uInt8(0x0A); - *pS << sal_uInt8(LINE); //line - if (NULL != (pTemp = pNode->GetSubNode(2))) - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); - - *pS << sal_uInt8(END); -} - - -void MathType::HandleBrace(SmNode *pNode,int nLevel) -{ - SmNode *pTemp; - SmNode *pLeft=pNode->GetSubNode(0); - SmNode *pRight=pNode->GetSubNode(2); - - *pS << sal_uInt8(TMPL); //Template - bIsReInterpBrace=0; - sal_uInt8 nBSpec=0x10; - sal_uLong nLoc = pS->Tell(); - if (pLeft) - { - switch (pLeft->GetToken().eType) - { - case TLANGLE: - *pS << sal_uInt8(tmANGLE); //selector - *pS << sal_uInt8(0x00); //variation - *pS << sal_uInt8(0x00); //options - break; - case TLBRACE: - *pS << sal_uInt8(tmBRACE); //selector - *pS << sal_uInt8(0x00); //variation - *pS << sal_uInt8(0x00); //options - nBSpec+=3; - break; - case TLBRACKET: - *pS << sal_uInt8(tmBRACK); //selector - *pS << sal_uInt8(0x00); //variation - *pS << sal_uInt8(0x00); //options - nBSpec+=3; - break; - case TLFLOOR: - *pS << sal_uInt8(tmFLOOR); //selector - *pS << sal_uInt8(0x00); //variation - *pS << sal_uInt8(0x00); //options - break; - case TLLINE: - *pS << sal_uInt8(tmBAR); //selector - *pS << sal_uInt8(0x00); //variation - *pS << sal_uInt8(0x00); //options - nBSpec+=3; - break; - case TLDLINE: - *pS << sal_uInt8(tmDBAR); //selector - *pS << sal_uInt8(0x00); //variation - *pS << sal_uInt8(0x00); //options - break; - default: - *pS << sal_uInt8(tmPAREN); //selector - *pS << sal_uInt8(0x00); //variation - *pS << sal_uInt8(0x00); //options - nBSpec+=3; - break; - } - } - - if (NULL != (pTemp = pNode->GetSubNode(1))) - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); //options - } - nSpec=nBSpec; - if (pLeft) - HandleNodes(pLeft,nLevel+1); - if (bIsReInterpBrace) - { - sal_uLong nLoc2 = pS->Tell(); - pS->Seek(nLoc); - *pS << sal_uInt8(0x2D); - pS->Seek(nLoc2); - *pS << sal_uInt8(CHAR); - *pS << sal_uInt8(0x96); - *pS << sal_uInt16(0xEC07); - bIsReInterpBrace=0; - } - if (pRight) - HandleNodes(pRight,nLevel+1); - nSpec=0x0; - *pS << sal_uInt8(END); -} - - -void MathType::HandleVerticalBrace(SmNode *pNode,int nLevel) -{ - SmNode *pTemp; - *pS << sal_uInt8(TMPL); //Template - if (pNode->GetToken().eType == TUNDERBRACE) - *pS << sal_uInt8(tmLHBRACE); //selector - else - *pS << sal_uInt8(tmUHBRACE); //selector - *pS << sal_uInt8(0x01); //variation - *pS << sal_uInt8(0x00); //options - - if (NULL != (pTemp = pNode->GetSubNode(0))) - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); //options - } - - if (NULL != (pTemp = pNode->GetSubNode(2))) - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pTemp,nLevel+1); - *pS << sal_uInt8(END); //options - } - *pS << sal_uInt8(END); -} - -void MathType::HandleOperator(SmNode *pNode,int nLevel) -{ - if (HandleLim(pNode,nLevel)) - return; - - sal_uLong nPos; - sal_uInt8 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; - } - - sal_uInt8 nOldVariation=nVariation; - sal_uInt8 nIntVariation=nVariation; - - sal_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 << sal_uInt8(TMPL); - switch(pNode->GetToken().eType) - { - case TINT: - if (nOldVariation != 0xff) - *pS << sal_uInt8(0x18); //selector - else - *pS << sal_uInt8(0x15); //selector - *pS << nIntVariation; //variation - break; - case TIINT: - if (nOldVariation != 0xff) - { - *pS << sal_uInt8(0x19); - *pS << sal_uInt8(0x01); - } - else - { - *pS << sal_uInt8(0x16); - *pS << sal_uInt8(0x00); - } - break; - case TIIINT: - if (nOldVariation != 0xff) - { - *pS << sal_uInt8(0x1a); - *pS << sal_uInt8(0x01); - } - else - { - *pS << sal_uInt8(0x17); - *pS << sal_uInt8(0x00); - } - break; - case TLINT: - if (nOldVariation != 0xff) - { - *pS << sal_uInt8(0x18); - *pS << sal_uInt8(0x02); - } - else - { - *pS << sal_uInt8(0x15); - *pS << sal_uInt8(0x03); - } - break; - case TLLINT: - if (nOldVariation != 0xff) - { - *pS << sal_uInt8(0x19); - *pS << sal_uInt8(0x00); - } - else - { - *pS << sal_uInt8(0x16); - *pS << sal_uInt8(0x02); - } - break; - case TLLLINT: - if (nOldVariation != 0xff) - { - *pS << sal_uInt8(0x1a); - *pS << sal_uInt8(0x00); - } - else - { - *pS << sal_uInt8(0x17); - *pS << sal_uInt8(0x02); - } - break; - case TSUM: - default: - *pS << sal_uInt8(0x1d); - *pS << nVariation; - break; - case TPROD: - *pS << sal_uInt8(0x1f); - *pS << nVariation; - break; - case TCOPROD: - *pS << sal_uInt8(0x21); - *pS << nVariation; - break; - } - *pS << sal_uInt8(0x00); //options - - if (nPos2) - pS->Seek(nPos2); - else - { - *pS << sal_uInt8(LINE); //line - HandleNodes(pNode->GetSubNode(1),nLevel+1); - *pS << sal_uInt8(END); //line - *pS << sal_uInt8(LINE|0x10); - *pS << sal_uInt8(LINE|0x10); - } - - - *pS << sal_uInt8(0x0D); - switch(pNode->GetToken().eType) - { - case TSUM: - default: - *pS << sal_uInt8(CHAR); - *pS << sal_uInt8(0x86); - *pS << sal_uInt16(0x2211); - break; - case TPROD: - *pS << sal_uInt8(CHAR); - *pS << sal_uInt8(0x86); - *pS << sal_uInt16(0x220F); - break; - case TCOPROD: - *pS << sal_uInt8(CHAR); - *pS << sal_uInt8(0x8B); - *pS << sal_uInt16(0x2210); - break; - case TIIINT: - case TLLLINT: - *pS << sal_uInt8(CHAR); - *pS << sal_uInt8(0x86); - *pS << sal_uInt16(0x222B); - case TIINT: - case TLLINT: - *pS << sal_uInt8(CHAR); - *pS << sal_uInt8(0x86); - *pS << sal_uInt16(0x222B); - case TINT: - case TLINT: - *pS << sal_uInt8(CHAR); - *pS << sal_uInt8(0x86); - *pS << sal_uInt16(0x222B); - break; - } - *pS << sal_uInt8(END); - *pS << sal_uInt8(0x0A); -} - - -int MathType::HandlePile(int &rSetAlign,int nLevel,sal_uInt8 nSelector, - sal_uInt8 nVariation) -{ - *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,sal_uInt8 nSelector, - sal_uInt8 nVariation) -{ - sal_uInt8 nH_just,nV_just,nRows,nCols; - *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); - - xub_StrLen nI = rRet.SearchBackward('#'); - if ((nI != STRING_NOTFOUND) && (nI > 0)) - if (rRet.GetChar(nI-1) != '#') //missing column - APPEND(rRet,"{}"); - - APPEND(rRet,"\n} "); - return nRet; -} - -int MathType::HandleTemplate(int nLevel,sal_uInt8 &rSelector, - sal_uInt8 &rVariation, xub_StrLen &rLastTemplateBracket) -{ - sal_uInt8 nOption; //This appears utterly unused - *pS >> rSelector; - *pS >> rVariation; - *pS >> nOption; - OSL_ENSURE(rSelector < 48,"Selector out of range"); - if ((rSelector >= 21) && (rSelector <=26)) - { - OSL_ENSURE(nOption < 2,"Option out of range"); - } - else if (/*(rSelector >= 0) &&*/ (rSelector <=12)) - { - OSL_ENSURE(nOption < 3,"Option out of range"); - } - - //For the (broken) case where one subscript template ends, and there is - //another one after it, mathtype handles it as if the second one was - //inside the first one and renders it as sub of sub - bool bRemove=false; - if ( (rSelector == 0xf) && (rLastTemplateBracket != STRING_NOTFOUND) ) - { - bRemove=true; - for (xub_StrLen nI = rLastTemplateBracket+1; nI < rRet.Len(); nI++ ) - if (rRet.GetChar(nI) != ' ') - { - bRemove=false; - break; - } - } - - //suborderlist - int nRet = HandleRecords(nLevel+1,rSelector,rVariation); - - if (bRemove) - { - rRet.Erase(rLastTemplateBracket,1); - APPEND(rRet,"} "); - rLastTemplateBracket = STRING_NOTFOUND; - } - if (rSelector == 0xf) - rLastTemplateBracket = rRet.SearchBackward('}'); - else - rLastTemplateBracket = STRING_NOTFOUND; - - rSelector = sal::static_int_cast< sal_uInt8 >(-1); - return nRet; -} - -void MathType::HandleEmblishments() -{ - sal_uInt8 nEmbel; - 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: - OSL_ENSURE(nEmbel < 21,"Embel out of range"); - break; - } - if (nVersion < 3) - break; - }while (nEmbel); -} - -void MathType::HandleSetSize() -{ - sal_uInt8 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, - sal_uInt8 nTag,sal_uInt8 nSelector,sal_uInt8 nVariation, sal_Bool bSilent) -{ - sal_Unicode nChar; - int nRet=1; - - if (xfAUTO(nTag)) - { - //This is a candidate for function recognition, whatever - //that is! - } - - sal_uInt8 nOldTypeFace = nTypeFace; - *pS >> nTypeFace; - if (nVersion < 3) - { - sal_uInt8 nChar8; - *pS >> nChar8; - nChar = nChar8; - } - else - *pS >> nChar; - - /* - bad character, old mathtype < 3 has these - */ - if (nChar < 0x20) - return nRet; - - 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; - APPEND(rRet," {"); // #i24340# make what would be "vec {A}_n" become "{vec {A}}_n" - if ((!bSilent) && ((nOriglen) > 1)) - rRet += '\"'; - nRet = HandleRecords(nLevel+1,nSelector,nVariation); - if (!bSilent) - { - if (nOriglen > 1) - { - String aStr; - TypeFaceToString(aStr,nOldTypeFace); - aStr += '\"'; - rRet.Insert(aStr,rTextStart); - - aStr.Erase(); - TypeFaceToString(aStr,nTypeFace); - rRet.Append(aStr); - rRet += '{'; - } - else - APPEND(rRet," {"); - rTextStart = rRet.Len(); - } - } - - if (!bSilent) - { - xub_StrLen nOldLen = rRet.Len(); - if ( - HandleSize(nLSize,nDSize,rSetSize) || - (nOldTypeFace != nTypeFace) - ) - { - if ((nOldLen - rTextStart) > 1) - { - rRet.InsertAscii("\"",nOldLen); - String aStr; - TypeFaceToString(aStr,nOldTypeFace); - aStr += '\"'; - rRet.Insert(aStr,rTextStart); - } - rTextStart = rRet.Len(); - } - nOldLen = rRet.Len(); - if (!LookupChar(nChar,rRet,nVersion,nTypeFace)) - { - if (nOldLen - rTextStart > 1) - { - rRet.InsertAscii("\"",nOldLen); - String aStr; - TypeFaceToString(aStr,nOldTypeFace); - aStr += '\"'; - rRet.Insert(aStr,rTextStart); - } - rTextStart = rRet.Len(); - } - lcl_PrependDummyTerm(rRet, rTextStart); - } - - if ((xfEMBELL(nTag)) && (!bSilent)) - { - rRet += '}'; // #i24340# make what would be "vec {A}_n" become "{vec {A}}_n" - rRet += '}'; - rRet += sPost; - rTextStart = rRet.Len(); - } - return nRet; -} - -sal_Bool MathType::HandleLim(SmNode *pNode,int nLevel) -{ - bool bRet=false; - //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)) - { - sal_uInt8 nVariation2=HandleCScript(pNode->GetSubNode(0),NULL, - nLevel); - - *pS << sal_uInt8(0x0A); - *pS << sal_uInt8(LINE); //line - *pS << sal_uInt8(CHAR|0x10); - *pS << sal_uInt8(0x82); - *pS << sal_uInt16('l'); - *pS << sal_uInt8(CHAR|0x10); - *pS << sal_uInt8(0x82); - *pS << sal_uInt16('i'); - *pS << sal_uInt8(CHAR|0x10); - *pS << sal_uInt8(0x82); - *pS << sal_uInt16('m'); - - if (pNode->GetToken().eType == TLIMSUP) - { - *pS << sal_uInt8(CHAR); //some space - *pS << sal_uInt8(0x98); - *pS << sal_uInt16(0xEB04); - - *pS << sal_uInt8(CHAR|0x10); - *pS << sal_uInt8(0x82); - *pS << sal_uInt16('s'); - *pS << sal_uInt8(CHAR|0x10); - *pS << sal_uInt8(0x82); - *pS << sal_uInt16('u'); - *pS << sal_uInt8(CHAR|0x10); - *pS << sal_uInt8(0x82); - *pS << sal_uInt16('p'); - } - else if (pNode->GetToken().eType == TLIMINF) - { - *pS << sal_uInt8(CHAR); //some space - *pS << sal_uInt8(0x98); - *pS << sal_uInt16(0xEB04); - - *pS << sal_uInt8(CHAR|0x10); - *pS << sal_uInt8(0x82); - *pS << sal_uInt16('i'); - *pS << sal_uInt8(CHAR|0x10); - *pS << sal_uInt8(0x82); - *pS << sal_uInt16('n'); - *pS << sal_uInt8(CHAR|0x10); - *pS << sal_uInt8(0x82); - *pS << sal_uInt16('f'); - } - - - *pS << sal_uInt8(CHAR); //some space - *pS << sal_uInt8(0x98); - *pS << sal_uInt16(0xEB04); - - if (nVariation2 != 0xff) - { - *pS << sal_uInt8(END); - *pS << sal_uInt8(END); - } - HandleNodes(pNode->GetSubNode(1),nLevel+1); - //*pS << sal_uInt8(END); //options - bRet = true; - } - } - return bRet; -} - -void MathType::HandleMAlign(SmNode *pNode,int nLevel) -{ - sal_uInt8 nPushedHAlign=nHAlign; - switch(pNode->GetToken().eType) - { - case TALIGNC: - nHAlign=2; - break; - case TALIGNR: - nHAlign=3; - break; - default: - nHAlign=1; - break; - } - sal_uInt16 nSize = pNode->GetNumSubNodes(); - for (sal_uInt16 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 << sal_uInt8(END); - *pS << sal_uInt8(LINE); - bIsReInterpBrace=1; - return; - } - SmMathSymbolNode *pTemp=(SmMathSymbolNode *)pNode; - for(xub_StrLen i=0;i<pTemp->GetText().Len();i++) - { - sal_Unicode nArse = Convert(pTemp->GetText().GetChar(i)); - if ((nArse == 0x2224) || (nArse == 0x2288) || (nArse == 0x2285) || - (nArse == 0x2289)) - { - *pS << sal_uInt8(CHAR|0x20); - } - else if ((nPendingAttributes) && - (i == ((pTemp->GetText().Len()+1)/2)-1)) - { - *pS << sal_uInt8(0x22); - } - else - *pS << sal_uInt8(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. - sal_uInt8 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 << sal_uInt8(nSpec+nBias+128); //typeface - - if (nArse == 0x2224) - { - *pS << sal_uInt16(0x7C); - *pS << sal_uInt8(EMBEL); - *pS << sal_uInt8(0x0A); - *pS << sal_uInt8(END); //end embel - *pS << sal_uInt8(END); //end embel - } - else if (nArse == 0x2225) - *pS << sal_uInt16(0xEC09); - else if (nArse == 0xE421) - *pS << sal_uInt16(0x2265); - else if (nArse == 0x230A) - *pS << sal_uInt16(0xF8F0); - else if (nArse == 0x230B) - *pS << sal_uInt16(0xF8FB); - else if (nArse == 0xE425) - *pS << sal_uInt16(0x2264); - else if (nArse == 0x226A) - { - *pS << sal_uInt16(0x3C); - *pS << sal_uInt8(CHAR); - *pS << sal_uInt8(0x98); - *pS << sal_uInt16(0xEB01); - *pS << sal_uInt8(CHAR); - *pS << sal_uInt8(0x86); - *pS << sal_uInt16(0x3c); - } - else if (nArse == 0x2288) - { - *pS << sal_uInt16(0x2286); - *pS << sal_uInt8(EMBEL); - *pS << sal_uInt8(0x0A); - *pS << sal_uInt8(END); //end embel - *pS << sal_uInt8(END); //end embel - } - else if (nArse == 0x2289) - { - *pS << sal_uInt16(0x2287); - *pS << sal_uInt8(EMBEL); - *pS << sal_uInt8(0x0A); - *pS << sal_uInt8(END); //end embel - *pS << sal_uInt8(END); //end embel - } - else if (nArse == 0x2285) - { - *pS << sal_uInt16(0x2283); - *pS << sal_uInt8(EMBEL); - *pS << sal_uInt8(0x0A); - *pS << sal_uInt8(END); //end embel - *pS << sal_uInt8(END); //end embel - } - else - *pS << nArse; - } - nPendingAttributes = 0; -} - -void MathType::HandleAttributes(SmNode *pNode,int nLevel) -{ - int nOldPending = 0; - SmNode *pTemp = 0; - SmTextNode *pIsText = 0; - - if (NULL != (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 != TTEXT) || - (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 != TTEXT) || - (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) && NULL != (pTemp = pNode->GetSubNode(0))) - { - sal_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 << sal_uInt8(2); - break; - case TDDOT: - *pS << sal_uInt8(3); - break; - case TDDDOT: - *pS << sal_uInt8(4); - break; - case TTILDE: - *pS << sal_uInt8(8); - break; - case THAT: - *pS << sal_uInt8(9); - break; - case TVEC: - *pS << sal_uInt8(11); - break; - case TOVERSTRIKE: - *pS << sal_uInt8(16); - break; - case TOVERLINE: - if ((pIsText->GetToken().eType == TTEXT) && - (pIsText->GetText().Len() == 1)) - *pS << sal_uInt8(17); - break; - case TBREVE: - *pS << sal_uInt8(20); - break; - case TWIDEVEC: - case TUNDERLINE: - case TWIDETILDE: - case TWIDEHAT: - break; - case TBAR: - *pS << sal_uInt8(17); - break; - default: - *pS << sal_uInt8(0x2); - break; - } - pS->Seek(nPos); - } - } -} - -void MathType::HandleText(SmNode *pNode, int /*nLevel*/) -{ - SmTextNode *pTemp=(SmTextNode *)pNode; - for(xub_StrLen i=0;i<pTemp->GetText().Len();i++) - { - if ((nPendingAttributes) && - (i == ((pTemp->GetText().Len()+1)/2)-1)) - { - *pS << sal_uInt8(0x22); //char, with attributes right - //after the character - } - else - *pS << sal_uInt8(CHAR); - - sal_uInt8 nFace = 0x1; - if (pNode->GetFont().GetItalic() == ITALIC_NORMAL) - nFace = 0x3; - else if (pNode->GetFont().GetWeight() == WEIGHT_BOLD) - nFace = 0x7; - *pS << sal_uInt8(nFace+128); //typeface - sal_uInt16 nChar = pTemp->GetText().GetChar(i); - *pS << Convert(nChar); - - //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 << sal_uInt8(EMBEL); - while (nPendingAttributes) - { - *pS << sal_uInt8(2); - //wedge the attributes in here and clear - //the pending stack - nPendingAttributes--; - } - nInsertion=pS->Tell(); - *pS << sal_uInt8(END); //end embel - *pS << sal_uInt8(END); //end embel - } - } -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |