[Libreoffice-commits] core.git: 4 commits - i18npool/inc i18npool/source include/oox oox/inc oox/source sd/qa starmath/qa starmath/source writerfilter/source

Michael Stahl mstahl at redhat.com
Thu Jan 21 10:45:19 PST 2016


 i18npool/inc/cclass_unicode.hxx                                   |   26 -
 i18npool/source/characterclassification/cclass_unicode_parser.cxx |  137 +++++-----
 include/oox/mathml/import.hxx                                     |   11 
 oox/inc/drawingml/textparagraph.hxx                               |   13 
 oox/source/core/xmlfilterbase.cxx                                 |    4 
 oox/source/drawingml/shape.cxx                                    |   51 +++
 oox/source/drawingml/textbodycontext.cxx                          |    5 
 oox/source/drawingml/textparagraph.cxx                            |   10 
 oox/source/mathml/import.cxx                                      |   92 ++++++
 sd/qa/unit/data/pptx/Math.pptx                                    |binary
 sd/qa/unit/export-tests.cxx                                       |   54 +++
 starmath/qa/cppunit/test_nodetotextvisitors.cxx                   |   26 +
 starmath/source/ooxmlexport.cxx                                   |    6 
 writerfilter/source/dmapper/DomainMapper_Impl.cxx                 |    1 
 14 files changed, 348 insertions(+), 88 deletions(-)

New commits:
commit 9486dd0692e08b3770bee8f3be2292263c6e5d26
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu Jan 21 19:00:26 2016 +0100

    i18npool: why not document the state transitions
    
    Change-Id: Ica5789dab22a49efb9e2da3a795e13aa7e2c4339

diff --git a/i18npool/inc/cclass_unicode.hxx b/i18npool/inc/cclass_unicode.hxx
index e88530a..cbcb6f9 100644
--- a/i18npool/inc/cclass_unicode.hxx
+++ b/i18npool/inc/cclass_unicode.hxx
@@ -75,16 +75,16 @@ private:
 
     enum ScanState
     {
-        ssGetChar,
-        ssGetValue,
-        ssGetWord,
-        ssGetWordFirstChar,
-        ssGetString,
-        ssGetBool,
-        ssRewindFromValue,
-        ssIgnoreLeadingInRewind,
-        ssStopBack,
-        ssBounce,
+        ssGetChar, // initial state; -> ssBounce, ssGetValue, ssRewindFromValue, ssGetWord, ssGetWordFirstChar, ssGetString, ssGetBool, ssStop
+        ssGetValue, // -> ssBounce, ssRewindFromValue, ssStopBack, ssGetWord
+        ssGetWord, // -> ssBounce, ssStop, ssStopBack
+        ssGetWordFirstChar, // -> ssBounce, ssGetWord, ssStop, ssStopBack
+        ssGetString, // -> ssBounce, ssStop
+        ssGetBool, // -> ssBounce, ssStop, ssStopBack
+        ssRewindFromValue, // -> ssBounce, ssGetValue, ssGetWord, ssGetWordFirstChar, ssGetString, ssGetBool, ssStop, ssIgnoreLeadingInRewind
+        ssIgnoreLeadingInRewind, // -> ssBounce, ssGetValue, ssRewindFromValue, ssGetWord, ssGetWordFirstChar, ssGetString, ssGetBool, ssStop
+        ssStopBack, // -> ssStop
+        ssBounce, // -> ssStopBack
         ssStop
     };
 
commit 331a0a347e2ed238ff41c8cd7815b946cc95ac0f
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu Jan 21 18:20:12 2016 +0100

    starmath: fix OOXML export of non-BMP Unicode
    
    Change-Id: Iafaeb9ea2e96ee6d8cc96174731ba3845c230b5e

diff --git a/sd/qa/unit/data/pptx/Math.pptx b/sd/qa/unit/data/pptx/Math.pptx
new file mode 100644
index 0000000..fef2067
Binary files /dev/null and b/sd/qa/unit/data/pptx/Math.pptx differ
diff --git a/sd/qa/unit/export-tests.cxx b/sd/qa/unit/export-tests.cxx
index 2f9550a..211cff2 100644
--- a/sd/qa/unit/export-tests.cxx
+++ b/sd/qa/unit/export-tests.cxx
@@ -142,6 +142,7 @@ public:
     void testTdf91378();
     void testBnc822341();
     void testMathObject();
+    void testMathObjectPPT2010();
     void testTdf80224();
     void testTdf92527();
 
@@ -182,6 +183,7 @@ public:
 
     CPPUNIT_TEST(testBnc822341);
     CPPUNIT_TEST(testMathObject);
+    CPPUNIT_TEST(testMathObjectPPT2010);
     CPPUNIT_TEST(testTdf80224);
 
     CPPUNIT_TEST(testExportTransitionsPPTX);
@@ -1202,6 +1204,33 @@ void SdExportTest::testMathObject()
     xDocShRef->DoClose();
 }
 
+void SdExportTest::testMathObjectPPT2010()
+{
+    // Check import / export of math object
+    ::sd::DrawDocShellRef xDocShRef = loadURL(getURLFromSrc("sd/qa/unit/data/pptx/Math.pptx"), PPTX);
+    utl::TempFile tempFile1;
+    xDocShRef = saveAndReload(xDocShRef, PPTX, &tempFile1);
+
+    // Export an MS specific ole object (imported from a PPTX document)
+    {
+        xmlDocPtr pXmlDocContent = parseExport(tempFile1, "ppt/slides/slide1.xml");
+        assertXPath(pXmlDocContent,
+            "/p:sld/p:cSld/p:spTree/mc:AlternateContent/mc:Choice",
+            "Requires",
+            "a14");
+        assertXPathContent(pXmlDocContent,
+            "/p:sld/p:cSld/p:spTree/mc:AlternateContent/mc:Choice/p:sp/p:txBody/a:p/a14:m/m:oMath/m:sSup/m:e/m:r[1]/m:t",
+            OUString::fromUtf8("\xf0\x9d\x91\x8e")); // non-BMP char
+
+        const SdrPage *pPage = GetPage(1, xDocShRef);
+        const SdrObject* pObj = dynamic_cast<SdrObject*>(pPage->GetObj(0));
+        CPPUNIT_ASSERT_MESSAGE("no object", pObj != nullptr);
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(OBJ_OLE2), pObj->GetObjIdentifier());
+    }
+
+    xDocShRef->DoClose();
+}
+
 void SdExportTest::testBulletMarginAndIndentation()
 {
     ::sd::DrawDocShellRef xDocShRef = loadURL( getURLFromSrc("/sd/qa/unit/data/pptx/bulletMarginAndIndent.pptx"), PPTX );
diff --git a/starmath/source/ooxmlexport.cxx b/starmath/source/ooxmlexport.cxx
index 277fb25..63f7cd4 100644
--- a/starmath/source/ooxmlexport.cxx
+++ b/starmath/source/ooxmlexport.cxx
@@ -75,6 +75,7 @@ void SmOoxmlExport::HandleText( const SmNode* pNode, int /*nLevel*/)
     m_pSerializer->startElementNS( XML_m, XML_t, FSNS( XML_xml, XML_space ), "preserve", FSEND );
     const SmTextNode* pTemp = static_cast<const SmTextNode* >(pNode);
     SAL_INFO( "starmath.ooxml", "Text:" << OUStringToOString( pTemp->GetText(), RTL_TEXTENCODING_UTF8 ).getStr());
+    OUStringBuffer buf(pTemp->GetText());
     for(sal_Int32 i=0;i<pTemp->GetText().getLength();i++)
     {
 #if 0
@@ -94,9 +95,7 @@ void SmOoxmlExport::HandleText( const SmNode* pNode, int /*nLevel*/)
             nFace = 0x7;
         *pS << sal_uInt8(nFace+128); //typeface
 #endif
-        sal_uInt16 nChar = pTemp->GetText()[i];
-        m_pSerializer->writeEscaped( OUString( SmTextNode::ConvertSymbolToUnicode(nChar)));
-
+        buf[i] = SmTextNode::ConvertSymbolToUnicode(buf[i]);
 #if 0
         //Mathtype can only have these sort of character
         //attributes on a single character, starmath can put them
@@ -127,6 +126,7 @@ void SmOoxmlExport::HandleText( const SmNode* pNode, int /*nLevel*/)
         }
 #endif
     }
+    m_pSerializer->writeEscaped(buf.makeStringAndClear());
     m_pSerializer->endElementNS( XML_m, XML_t );
     m_pSerializer->endElementNS( XML_m, XML_r );
 }
commit fefd1221be844a033e409a18e05e8c6e98f6d1a7
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu Jan 21 18:11:12 2016 +0100

    i18npool: handle non-BMP Unicode in cclass_Unicode::parseText()
    
    The UTF-16 code unit limitation was mangling starmath import.
    
    Change-Id: I087e5c5b7954799fdb73e7ee1a8d3d02669f8831

diff --git a/i18npool/inc/cclass_unicode.hxx b/i18npool/inc/cclass_unicode.hxx
index eb449e4..e88530a 100644
--- a/i18npool/inc/cclass_unicode.hxx
+++ b/i18npool/inc/cclass_unicode.hxx
@@ -135,13 +135,13 @@ private:
     sal_Unicode                 cDecimalSep;
 
     /// Get corresponding KParseTokens flag for a character
-    static sal_Int32 getParseTokensType( const sal_Unicode* aStr, sal_Int32 nPos );
+    static sal_Int32 getParseTokensType(sal_uInt32 c, bool isFirst);
 
     /// Access parser table flags.
-    UPT_FLAG_TYPE getFlags( const sal_Unicode* aStr, sal_Int32 nPos );
+    UPT_FLAG_TYPE getFlags(sal_uInt32 c);
 
     /// Access parser flags via International and special definitions.
-    UPT_FLAG_TYPE getFlagsExtended( const sal_Unicode* aStr, sal_Int32 nPos );
+    UPT_FLAG_TYPE getFlagsExtended(sal_uInt32 c);
 
     /// Access parser table flags for user defined start characters.
     UPT_FLAG_TYPE getStartCharsFlags( sal_Unicode c );
diff --git a/i18npool/source/characterclassification/cclass_unicode_parser.cxx b/i18npool/source/characterclassification/cclass_unicode_parser.cxx
index 7321a7e..c003959 100644
--- a/i18npool/source/characterclassification/cclass_unicode_parser.cxx
+++ b/i18npool/source/characterclassification/cclass_unicode_parser.cxx
@@ -351,16 +351,15 @@ const sal_Unicode* cclass_Unicode::StrChr( const sal_Unicode* pStr, sal_Unicode
 }
 
 
-sal_Int32 cclass_Unicode::getParseTokensType( const sal_Unicode* aStr, sal_Int32 nPos )
+sal_Int32 cclass_Unicode::getParseTokensType(sal_uInt32 const c, bool const isFirst)
 {
-    sal_Unicode c = aStr[nPos];
     if ( c < nDefCnt )
         return pParseTokensType[ sal_uInt8(c) ];
     else
     {
 
         //! all KParseTokens::UNI_... must be matched
-        switch ( u_charType( (sal_uInt32) c ) )
+        switch (u_charType(c))
         {
             case U_UPPERCASE_LETTER :
                 return KParseTokens::UNI_UPALPHA;
@@ -372,7 +371,7 @@ sal_Int32 cclass_Unicode::getParseTokensType( const sal_Unicode* aStr, sal_Int32
                 return KParseTokens::UNI_MODIFIER_LETTER;
             case U_OTHER_LETTER :
                 // Non_Spacing_Mark could not be as leading character
-                if (nPos == 0) break;
+                if (isFirst) break;
                 // fall through, treat it as Other_Letter.
             case U_NON_SPACING_MARK :
                 return KParseTokens::UNI_OTHER_LETTER;
@@ -571,14 +570,13 @@ void cclass_Unicode::destroyParserTable()
 }
 
 
-UPT_FLAG_TYPE cclass_Unicode::getFlags( const sal_Unicode* aStr, sal_Int32 nPos )
+UPT_FLAG_TYPE cclass_Unicode::getFlags(sal_uInt32 const c)
 {
     UPT_FLAG_TYPE nMask;
-    sal_Unicode c = aStr[nPos];
     if ( c < nDefCnt )
         nMask = pTable[ sal_uInt8(c) ];
     else
-        nMask = getFlagsExtended( aStr, nPos );
+        nMask = getFlagsExtended(c);
     switch ( eState )
     {
         case ssGetChar :
@@ -608,9 +606,8 @@ UPT_FLAG_TYPE cclass_Unicode::getFlags( const sal_Unicode* aStr, sal_Int32 nPos
 }
 
 
-UPT_FLAG_TYPE cclass_Unicode::getFlagsExtended( const sal_Unicode* aStr, sal_Int32 nPos )
+UPT_FLAG_TYPE cclass_Unicode::getFlagsExtended(sal_uInt32 const c)
 {
-    sal_Unicode c = aStr[nPos];
     if ( c == cGroupSep )
         return TOKEN_VALUE;
     else if ( c == cDecimalSep )
@@ -621,7 +618,7 @@ UPT_FLAG_TYPE cclass_Unicode::getFlagsExtended( const sal_Unicode* aStr, sal_Int
     sal_Int32 nTypes = (bStart ? nStartTypes : nContTypes);
 
     //! all KParseTokens::UNI_... must be matched
-    switch ( u_charType( (sal_uInt32) c ) )
+    switch (u_charType(c))
     {
         case U_UPPERCASE_LETTER :
             return (nTypes & KParseTokens::UNI_UPALPHA) ?
@@ -712,25 +709,29 @@ UPT_FLAG_TYPE cclass_Unicode::getContCharsFlags( sal_Unicode c )
 
 void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32 nPos, sal_Int32 nTokenType )
 {
+    assert(r.LeadingWhiteSpace == 0);
     using namespace i18n;
-    const sal_Unicode* const pTextStart = rText.getStr() + nPos;
     eState = ssGetChar;
 
     //! All the variables below (plus ParseResult) have to be resetted on ssRewindFromValue!
-    const sal_Unicode* pSym = pTextStart;
-    const sal_Unicode* pSrc = pSym;
     OUString aSymbol;
-    sal_Unicode c = *pSrc;
-    sal_Unicode cLast = 0;
+    bool isFirst(true);
+    sal_Int32 index(nPos); // index of next code point after current
+    sal_Int32 postSymbolIndex(index); // index of code point following last quote
+    sal_uInt32 current((index < rText.getLength()) ? rText.iterateCodePoints(&index) : 0);
+    sal_uInt32 cLast = 0;
+    sal_Int32 nCodePoints(0);
     int nDecSeps = 0;
     bool bQuote = false;
     bool bMightBeWord = true;
     bool bMightBeWordLast = true;
     //! All the variables above (plus ParseResult) have to be resetted on ssRewindFromValue!
+    sal_Int32 nextCharIndex(0); // == index of nextChar
 
-    while ( (c != 0) && (eState != ssStop) )
+    while ((current != 0) && (eState != ssStop))
     {
-        UPT_FLAG_TYPE nMask = getFlags( pTextStart, pSrc - pTextStart );
+        ++nCodePoints;
+        UPT_FLAG_TYPE nMask = getFlags(current);
         if ( nMask & TOKEN_EXCLUDED )
             eState = ssBounce;
         if ( bMightBeWord )
@@ -741,8 +742,11 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
             else
                 bMightBeWord = ((nMask & TOKEN_WORD) != 0);
         }
-        sal_Int32 nParseTokensType = getParseTokensType( pTextStart, pSrc - pTextStart );
-        pSrc++;
+        sal_Int32 nParseTokensType = getParseTokensType(current, isFirst);
+        isFirst = false;
+        sal_Int32 const nextIndex(nextCharIndex); // == index of char following current
+        nextCharIndex = index; // == index of nextChar
+        sal_uInt32 nextChar((index < rText.getLength()) ? rText.iterateCodePoints(&index) : 0);
         switch (eState)
         {
             case ssGetChar :
@@ -755,14 +759,14 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
                     eState = ssGetValue;
                     if ( nMask & TOKEN_VALUE_DIGIT )
                     {
-                        if ( 128 <= c )
+                        if (128 <= current)
                             r.TokenType = KParseType::UNI_NUMBER;
                         else
                             r.TokenType = KParseType::ASC_NUMBER;
                     }
-                    else if ( c == cDecimalSep )
+                    else if (current == cDecimalSep)
                     {
-                        if ( *pSrc )
+                        if (nextChar)
                             ++nDecSeps;
                         else
                             eState = ssRewindFromValue;
@@ -778,14 +782,14 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
                 {
                     eState = ssGetWordFirstChar;
                     bQuote = true;
-                    pSym++;
+                    postSymbolIndex = nextCharIndex;
                     nParseTokensType = 0;   // will be taken of first real character
                     r.TokenType = KParseType::SINGLE_QUOTE_NAME;
                 }
                 else if ( nMask & TOKEN_CHAR_STRING )
                 {
                     eState = ssGetString;
-                    pSym++;
+                    postSymbolIndex = nextCharIndex;
                     nParseTokensType = 0;   // will be taken of first real character
                     r.TokenType = KParseType::DOUBLE_QUOTE_STRING;
                 }
@@ -795,8 +799,9 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
                     {
                         if (eState == ssRewindFromValue)
                             eState = ssIgnoreLeadingInRewind;
-                        r.LeadingWhiteSpace++;
-                        pSym++;
+                        r.LeadingWhiteSpace = nextCharIndex - nPos;
+                        nCodePoints--; // exclude leading whitespace
+                        postSymbolIndex = nextCharIndex;
                         nParseTokensType = 0;   // wait until real character
                         bMightBeWord = true;
                     }
@@ -821,16 +826,16 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
             {
                 if ( nMask & TOKEN_VALUE_DIGIT )
                 {
-                    if ( 128 <= c )
+                    if (128 <= current)
                         r.TokenType = KParseType::UNI_NUMBER;
                     else if ( r.TokenType != KParseType::UNI_NUMBER )
                         r.TokenType = KParseType::ASC_NUMBER;
                 }
                 if ( nMask & TOKEN_VALUE )
                 {
-                    if ( c == cDecimalSep && ++nDecSeps > 1 )
+                    if (current == cDecimalSep && ++nDecSeps > 1)
                     {
-                        if ( pSrc - pTextStart == 2 )
+                        if (nCodePoints == 2)
                             eState = ssRewindFromValue;
                             // consecutive separators
                         else
@@ -838,12 +843,12 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
                     }
                     // else keep it going
                 }
-                else if ( c == 'E' || c == 'e' )
+                else if (current == 'E' || current == 'e')
                 {
-                    UPT_FLAG_TYPE nNext = getFlags( pTextStart, pSrc - pTextStart );
+                    UPT_FLAG_TYPE nNext = getFlags(nextChar);
                     if ( nNext & TOKEN_VALUE_EXP )
                         ;   // keep it going
-                    else if ( bMightBeWord && ((nNext & TOKEN_WORD) || !*pSrc) )
+                    else if (bMightBeWord && ((nNext & TOKEN_WORD) || !nextChar))
                     {   // might be a numerical name (1.2efg)
                         eState = ssGetWord;
                         r.TokenType = KParseType::IDENTNAME;
@@ -855,10 +860,10 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
                 {
                     if ( (cLast == 'E') || (cLast == 'e') )
                     {
-                        UPT_FLAG_TYPE nNext = getFlags( pTextStart, pSrc - pTextStart );
+                        UPT_FLAG_TYPE nNext = getFlags(nextChar);
                         if ( nNext & TOKEN_VALUE_EXP_VALUE )
                             ;   // keep it going
-                        else if ( bMightBeWord && ((nNext & TOKEN_WORD) || !*pSrc) )
+                        else if (bMightBeWord && ((nNext & TOKEN_WORD) || !nextChar))
                         {   // might be a numerical name (1.2e+fg)
                             eState = ssGetWord;
                             r.TokenType = KParseType::IDENTNAME;
@@ -896,15 +901,15 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
                     {
                         if ( cLast == '\\' )
                         {   // escaped
-                            aSymbol += OUString( pSym, pSrc - pSym - 2 );
-                            aSymbol += OUString( &c, 1);
+                            aSymbol += rText.copy(postSymbolIndex, nextCharIndex - postSymbolIndex - 2);
+                            aSymbol += OUString(&current, 1);
                         }
                         else
                         {
                             eState = ssStop;
-                            aSymbol += OUString( pSym, pSrc - pSym - 1 );
+                            aSymbol += rText.copy(postSymbolIndex, nextCharIndex - postSymbolIndex - 1);
                         }
-                        pSym = pSrc;
+                        postSymbolIndex = nextCharIndex;
                     }
                     else
                         eState = ssStopBack;
@@ -921,21 +926,23 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
                 {
                     if ( cLast == '\\' )
                     {   // escaped
-                        aSymbol += OUString( pSym, pSrc - pSym - 2 );
-                        aSymbol += OUString( &c, 1);
+                        aSymbol += rText.copy(postSymbolIndex, nextCharIndex - postSymbolIndex - 2);
+                        aSymbol += OUString(&current, 1);
                     }
-                    else if ( c == *pSrc &&
+                    else if (current == nextChar &&
                             !(nContTypes & KParseTokens::TWO_DOUBLE_QUOTES_BREAK_STRING) )
                     {   // "" => literal " escaped
-                        aSymbol += OUString( pSym, pSrc - pSym );
-                        pSrc++;
+                        aSymbol += rText.copy(postSymbolIndex, nextCharIndex - postSymbolIndex);
+                        nextCharIndex = index;
+                        if (index < rText.getLength()) { ++nCodePoints; }
+                        nextChar = (index < rText.getLength()) ? rText.iterateCodePoints(&index) : 0;
                     }
                     else
                     {
                         eState = ssStop;
-                        aSymbol += OUString( pSym, pSrc - pSym - 1 );
+                        aSymbol += rText.copy(postSymbolIndex, nextCharIndex - postSymbolIndex - 1);
                     }
-                    pSym = pSrc;
+                    postSymbolIndex = nextCharIndex;
                 }
             }
             break;
@@ -956,10 +963,13 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
         if ( eState == ssRewindFromValue )
         {
             r = ParseResult();
-            pSym = pTextStart;
-            pSrc = pSym;
+            index = nPos;
+            postSymbolIndex = nPos;
+            nextCharIndex = 0;
             aSymbol.clear();
-            c = *pSrc;
+            current = (index < rText.getLength()) ? rText.iterateCodePoints(&index) : 0;
+            nCodePoints = (nPos < rText.getLength()) ? 1 : 0;
+            isFirst = true;
             cLast = 0;
             nDecSeps = 0;
             bQuote = false;
@@ -973,7 +983,7 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
                 if ( (r.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER))
                         && (nTokenType & KParseType::IDENTNAME) && bMightBeWord )
                     ;   // keep a number that might be a word
-                else if ( r.LeadingWhiteSpace == (pSrc - pTextStart) )
+                else if (r.LeadingWhiteSpace == (nextCharIndex - nPos))
                     ;   // keep ignored white space
                 else if ( !r.TokenType && eState == ssGetValue && (nMask & TOKEN_VALUE_SEP) )
                     ;   // keep uncertain value
@@ -987,7 +997,9 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
             }
             if ( eState == ssStopBack )
             {   // put back
-                pSrc--;
+                nextChar = rText.iterateCodePoints(&index, -1);
+                nextCharIndex = nextIndex;
+                --nCodePoints;
                 bMightBeWord = bMightBeWordLast;
                 eState = ssStop;
             }
@@ -999,19 +1011,18 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
                     r.ContFlags |= nParseTokensType;
             }
             bMightBeWordLast = bMightBeWord;
-            cLast = c;
-            c = *pSrc;
+            cLast = current;
+            current = nextChar;
         }
     }
-    // r.CharLen is the length in characters (not code points) of the parsed
-    // token not including any leading white space, change this calculation if
-    // multi-code-point Unicode characters are to be supported.
-    r.CharLen = pSrc - pTextStart - r.LeadingWhiteSpace;
-    r.EndPos = nPos + (pSrc - pTextStart);
+    // r.CharLen is the length in characters (not code units) of the parsed
+    // token not including any leading white space.
+    r.CharLen = nCodePoints;
+    r.EndPos = nextCharIndex;
     if ( r.TokenType & KParseType::ASC_NUMBER )
     {
-        r.Value = rtl_math_uStringToDouble( pTextStart + r.LeadingWhiteSpace,
-                pTextStart + r.EndPos, cDecimalSep, cGroupSep, nullptr, nullptr );
+        r.Value = rtl_math_uStringToDouble(rText.getStr() + nPos + r.LeadingWhiteSpace,
+            rText.getStr() + r.EndPos, cDecimalSep, cGroupSep, nullptr, nullptr);
         if ( bMightBeWord )
             r.TokenType |= KParseType::IDENTNAME;
     }
@@ -1024,8 +1035,8 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
                 xNatNumSup = NativeNumberSupplier::create( m_xContext );
             }
         }
-        OUString aTmp( pTextStart + r.LeadingWhiteSpace, r.EndPos - nPos +
-                r.LeadingWhiteSpace );
+        OUString aTmp(rText.getStr() + nPos + r.LeadingWhiteSpace,
+                r.EndPos - nPos - r.LeadingWhiteSpace);
         // transliterate to ASCII
         aTmp = xNatNumSup->getNativeNumberString( aTmp, aParserLocale,
                 NativeNumberMode::NATNUM0 );
@@ -1035,9 +1046,9 @@ void cclass_Unicode::parseText( ParseResult& r, const OUString& rText, sal_Int32
     }
     else if ( r.TokenType & (KParseType::SINGLE_QUOTE_NAME | KParseType::DOUBLE_QUOTE_STRING) )
     {
-        if ( pSym < pSrc )
+        if (postSymbolIndex < nextCharIndex)
         {   //! open quote
-            aSymbol += OUString( pSym, pSrc - pSym );
+            aSymbol += rText.copy(postSymbolIndex, nextCharIndex - postSymbolIndex - 1);
             r.TokenType |= KParseType::MISSING_QUOTE;
         }
         r.DequotedNameOrString = aSymbol;
diff --git a/starmath/qa/cppunit/test_nodetotextvisitors.cxx b/starmath/qa/cppunit/test_nodetotextvisitors.cxx
index a539761..91d7203 100644
--- a/starmath/qa/cppunit/test_nodetotextvisitors.cxx
+++ b/starmath/qa/cppunit/test_nodetotextvisitors.cxx
@@ -26,7 +26,6 @@ typedef tools::SvRef<SmDocShell> SmDocShellRef;
 
 using namespace ::com::sun::star;
 
-namespace {
 
 class Test : public test::BootstrapFixture {
 
@@ -53,6 +52,7 @@ public:
     void testBinHorInSubSup();
     void testUnaryInMixedNumberAsNumerator();
     void testMiscEquivalent();
+    void testParser();
 
     CPPUNIT_TEST_SUITE(Test);
     CPPUNIT_TEST(SimpleUnaryOp);
@@ -72,6 +72,7 @@ public:
     CPPUNIT_TEST(testBinHorInSubSup);
     CPPUNIT_TEST(testUnaryInMixedNumberAsNumerator);
     CPPUNIT_TEST(testMiscEquivalent);
+    CPPUNIT_TEST(testParser);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -486,13 +487,13 @@ void Test::ParseAndCompare(const char *formula1, const char *formula2, const cha
     SmNode *pNode1, *pNode2;
 
     // parse formula1
-    OUString sInput1 = OUString::createFromAscii(formula1);
+    OUString sInput1 = OUString(formula1, strlen(formula1), RTL_TEXTENCODING_UTF8);
     pNode1 = SmParser().ParseExpression(sInput1);
     pNode1->Prepare(xDocShRef->GetFormat(), *xDocShRef);
     SmNodeToTextVisitor(pNode1, sOutput1);
 
     // parse formula2
-    OUString sInput2 = OUString::createFromAscii(formula2);
+    OUString sInput2 = OUString(formula2, strlen(formula2), RTL_TEXTENCODING_UTF8);
     pNode2 = SmParser().ParseExpression(sInput2);
     pNode2->Prepare(xDocShRef->GetFormat(), *xDocShRef);
     SmNodeToTextVisitor(pNode2, sOutput2);
@@ -652,10 +653,27 @@ void Test::testMiscEquivalent()
     // fdo#66081
     ParseAndCompare("{x}", "x", "Variable in brace");
     ParseAndCompare("{{x+{{y}}}}", "x+y", "Nested braces");
+
+    // check non-BMP Unicode char
+    ParseAndCompare("{\xf0\x9d\x91\x8e}", "\xf0\x9d\x91\x8e", "non-BMP variable in brace");
+    ParseAndCompare("{ \xf0\x9d\x91\x8e }", "\xf0\x9d\x91\x8e", "non-BMP variable in brace");
 }
 
-CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+void Test::testParser()
+{
+    char const* formula = "{ \xf0\x9d\x91\x8e }"; // non-BMP Unicode
+    char const* expected = "\xf0\x9d\x91\x8e";
 
+    OUString sOutput;
+    OUString sInput = OUString(formula, strlen(formula), RTL_TEXTENCODING_UTF8);
+    OUString sExpected = OUString(expected, strlen(expected), RTL_TEXTENCODING_UTF8);
+    std::unique_ptr<SmNode> pNode(SmParser().ParseExpression(sInput));
+    pNode->Prepare(xDocShRef->GetFormat(), *xDocShRef);
+    SmNodeToTextVisitor(pNode.get(), sOutput);
+    CPPUNIT_ASSERT_EQUAL(sExpected, sOutput);
 }
 
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 332a796366b7cb91dff41de4b9ffb17843112a3e
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu Jan 21 17:39:26 2016 +0100

    oox: import Math objects from PPTX files
    
    This is quite hacky and limited: in OOXML these are not OLE objects but
    occur inside text boxes, and PPT 2010 allows inserting multiple Math
    objects into one text box but Impress does not have as-character
    anchored objects, so we can't import that properly; for now only import
    Math if there is nothing else in the text box.
    
    Also for now only import them as children of TextParagraphContext (a:p);
    it's not clear what the possible parent elements could be since the
    OOXML standard only lists WordProcessingML parent elements :(
    
    Change-Id: I847f810084c9ddae4b60f93896fb73a742683cc2

diff --git a/include/oox/mathml/import.hxx b/include/oox/mathml/import.hxx
index 2617ff5..b2ed99b 100644
--- a/include/oox/mathml/import.hxx
+++ b/include/oox/mathml/import.hxx
@@ -9,10 +9,11 @@
 #ifndef INCLUDED_OOX_MATHML_IMPORT_HXX
 #define INCLUDED_OOX_MATHML_IMPORT_HXX
 
-#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <oox/dllapi.h>
+
 #include <tools/gen.hxx>
 
-#include <oox/dllapi.h>
+#include <rtl/ref.hxx>
 
 namespace oox
 {
@@ -39,6 +40,12 @@ protected:
     ~FormulaImportBase() {}
 };
 
+namespace core { class ContextHandler; }
+namespace drawingml { class TextParagraph; }
+
+::rtl::Reference<core::ContextHandler> CreateLazyMathBufferingContext(
+        core::ContextHandler const& rParent, drawingml::TextParagraph & rPara);
+
 } // namespace
 
 #endif
diff --git a/oox/inc/drawingml/textparagraph.hxx b/oox/inc/drawingml/textparagraph.hxx
index f96989c..43bf51a 100644
--- a/oox/inc/drawingml/textparagraph.hxx
+++ b/oox/inc/drawingml/textparagraph.hxx
@@ -28,6 +28,11 @@
 #include <drawingml/textliststyle.hxx>
 #include <drawingml/textparagraphproperties.hxx>
 
+
+namespace oox { namespace formulaimport {
+    class XmlStreamBuilder;
+} }
+
 namespace oox { namespace drawingml {
 
 typedef RefVector< TextRun > TextRunVector;
@@ -57,10 +62,18 @@ public:
                                     bool bFirst = false,
                                     float nDefaultCharHeight = 0) const;
 
+    bool HasMathXml() const
+    {
+        return m_pMathXml != nullptr;
+    }
+    formulaimport::XmlStreamBuilder & GetMathXml();
+
 private:
     TextParagraphProperties     maProperties;
     TextCharacterProperties     maEndProperties;
     TextRunVector               maRuns;
+    // temporarily store this here
+    std::unique_ptr<formulaimport::XmlStreamBuilder> m_pMathXml;
 };
 
 } }
diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index ea1721d..062a600 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -129,11 +129,15 @@ struct NamespaceIds: public rtl::StaticWithInit<
              NMSP_mce},
             {"http://schemas.openxmlformats.org/spreadsheetml/2006/main/v2",
              NMSP_mceTest},
+            {"http://schemas.openxmlformats.org/officeDocument/2006/math",
+             NMSP_officeMath},
             {"http://schemas.microsoft.com/office/drawing/2008/diagram",
              NMSP_dsp},
             {"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main",
              NMSP_xls14Lst},
             {"http://schemas.libreoffice.org/", NMSP_loext},
+            {"http://schemas.microsoft.com/office/drawing/2010/main",
+             NMSP_a14},
             {"http://schemas.microsoft.com/office/powerpoint/2010/main",
              NMSP_p14},
             {"http://schemas.microsoft.com/office/powerpoint/2012/main",
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index b744bb1..9d12b50 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -27,6 +27,7 @@
 #include "effectproperties.hxx"
 #include "oox/drawingml/shapepropertymap.hxx"
 #include "drawingml/textbody.hxx"
+#include <drawingml/textparagraph.hxx>
 #include <drawingml/ThemeOverrideFragmentHandler.hxx>
 #include "drawingml/table/tableproperties.hxx"
 #include "oox/drawingml/chart/chartconverter.hxx"
@@ -40,8 +41,12 @@
 #include "oox/helper/graphichelper.hxx"
 #include "oox/helper/propertyset.hxx"
 #include "oox/helper/modelobjecthelper.hxx"
+#include <oox/mathml/importutils.hxx>
+#include <oox/mathml/import.hxx>
 
+#include <comphelper/classids.hxx>
 #include <tools/gen.hxx>
+#include <tools/globname.hxx>
 #include <tools/mapunit.hxx>
 #include <editeng/unoprnms.hxx>
 #include <com/sun/star/awt/Size.hpp>
@@ -55,6 +60,7 @@
 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
 #include <com/sun/star/text/XText.hpp>
 #include <com/sun/star/table/BorderLine2.hpp>
 #include <com/sun/star/table/ShadowFormat.hpp>
@@ -407,6 +413,25 @@ Reference< XShape > Shape::createAndInsert(
     bool bIsEmbMedia = false;
     SAL_INFO("oox.drawingml", OSL_THIS_FUNC << " id: " << msId);
 
+    formulaimport::XmlStreamBuilder * pMathXml(nullptr);
+    if (mpTextBody.get())
+    {
+        for (auto const& it : mpTextBody->getParagraphs())
+        {
+            if (it->HasMathXml())
+            {
+                if (!mpTextBody->isEmpty() || pMathXml != nullptr)
+                {
+                    SAL_WARN("oox.drawingml", "losing a Math object...");
+                }
+                else
+                {
+                    pMathXml = &it->GetMathXml();
+                }
+            }
+        }
+    }
+
     // tdf#90403 PowerPoint ignores a:ext cx and cy values of p:xfrm, and uses real table width and height
     if ( mpTablePropertiesPtr.get() && rServiceName == "com.sun.star.drawing.TableShape" )
     {
@@ -427,7 +452,15 @@ Reference< XShape > Shape::createAndInsert(
     awt::Rectangle aShapeRectHmm( maPosition.X / EMU_PER_HMM, maPosition.Y / EMU_PER_HMM, maSize.Width / EMU_PER_HMM, maSize.Height / EMU_PER_HMM );
 
     OUString aServiceName;
-    if( rServiceName == "com.sun.star.drawing.GraphicObjectShape" &&
+    if (pMathXml)
+    {
+        // convert this shape to OLE
+        aServiceName = "com.sun.star.drawing.OLE2Shape";
+        msServiceName = aServiceName;
+        meFrameType = FRAMETYPE_GENERIC; // not OLEOBJECT, no stream in package
+        mnSubType = 0;
+    }
+    else if (rServiceName == "com.sun.star.drawing.GraphicObjectShape" &&
         mpGraphicPropertiesPtr && !mpGraphicPropertiesPtr->m_sMediaPackageURL.isEmpty())
     {
         aServiceName = finalizeServiceName( rFilterBase, "com.sun.star.presentation.MediaShape", aShapeRectHmm );
@@ -605,6 +638,22 @@ Reference< XShape > Shape::createAndInsert(
             }
         }
 
+        if (pMathXml)
+        {
+            // the "EmbeddedObject" property is read-only, so we have to create
+            // the shape first, and it can be read only after the shape is
+            // inserted into the document, so delay the actual import until here
+            SvGlobalName name(SO3_SM_CLASSID);
+            xSet->setPropertyValue("CLSID", uno::makeAny(name.GetHexName()));
+            uno::Reference<embed::XEmbeddedObject> const xObj(
+                xSet->getPropertyValue("EmbeddedObject"), uno::UNO_QUERY);
+            uno::Reference<uno::XInterface> const xMathModel(xObj->getComponent());
+            oox::FormulaImportBase *const pMagic(
+                    dynamic_cast<oox::FormulaImportBase*>(xMathModel.get()));
+            assert(pMagic);
+            pMagic->readFormulaOoxml(*pMathXml);
+        }
+
         const GraphicHelper& rGraphicHelper = rFilterBase.getGraphicHelper();
 
         LineProperties aLineProperties;
diff --git a/oox/source/drawingml/textbodycontext.cxx b/oox/source/drawingml/textbodycontext.cxx
index 20d3b26..84fc769 100644
--- a/oox/source/drawingml/textbodycontext.cxx
+++ b/oox/source/drawingml/textbodycontext.cxx
@@ -26,6 +26,8 @@
 #include "drawingml/textfield.hxx"
 #include "drawingml/textfieldcontext.hxx"
 
+#include <oox/mathml/import.hxx>
+
 using namespace ::oox::core;
 using namespace ::com::sun::star::uno;
 using namespace ::com::sun::star::text;
@@ -90,6 +92,9 @@ ContextHandlerRef TextParagraphContext::onCreateContext( sal_Int32 aElementToken
         case W_TOKEN( ins ):
             return this;
         break;
+        case OOX_TOKEN(a14, m):
+            return CreateLazyMathBufferingContext(*this, mrParagraph);
+        break;
         default:
             SAL_WARN("oox", "TextParagraphContext::onCreateContext: unhandled element: " << getBaseToken(aElementToken));
     }
diff --git a/oox/source/drawingml/textparagraph.cxx b/oox/source/drawingml/textparagraph.cxx
index 76d299a..5d49659 100644
--- a/oox/source/drawingml/textparagraph.cxx
+++ b/oox/source/drawingml/textparagraph.cxx
@@ -22,6 +22,7 @@
 #include "drawingml/textcharacterproperties.hxx"
 
 #include <rtl/ustring.hxx>
+#include <oox/mathml/importutils.hxx>
 #include "oox/helper/propertyset.hxx"
 #include <com/sun/star/text/XText.hpp>
 #include <com/sun/star/text/XTextCursor.hpp>
@@ -138,6 +139,15 @@ void TextParagraph::insertAt(
     }
 }
 
+formulaimport::XmlStreamBuilder & TextParagraph::GetMathXml()
+{
+    if (!m_pMathXml)
+    {
+        m_pMathXml.reset(new formulaimport::XmlStreamBuilder);
+    }
+    return *m_pMathXml;
+}
+
 } }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/mathml/import.cxx b/oox/source/mathml/import.cxx
index bf49de2..5b80dc4 100644
--- a/oox/source/mathml/import.cxx
+++ b/oox/source/mathml/import.cxx
@@ -9,6 +9,14 @@
 
 #include "oox/mathml/import.hxx"
 
+#include <oox/mathml/importutils.hxx>
+#include <oox/core/contexthandler.hxx>
+
+#include <drawingml/textparagraph.hxx>
+
+
+using namespace ::com::sun::star;
+
 namespace oox
 {
 
@@ -16,6 +24,88 @@ FormulaImportBase::FormulaImportBase()
 {
 }
 
-} // namespace
+namespace formulaimport {
+
+class LazyMathBufferingContext : public core::ContextHandler
+{
+private:
+    XmlStreamBuilder & m_rBuilder;
+    long m_Counter;
+
+public:
+    LazyMathBufferingContext(core::ContextHandler const& rParent,
+            drawingml::TextParagraph & rPara);
+
+    // com.sun.star.xml.sax.XFastContextHandler interface ---------------------
+
+    virtual void SAL_CALL startFastElement(::sal_Int32 Element, const uno::Reference<xml::sax::XFastAttributeList>& xAttribs) throw (xml::sax::SAXException, uno::RuntimeException, std::exception) override;
+    virtual void SAL_CALL endFastElement(::sal_Int32 Element) throw (xml::sax::SAXException, uno::RuntimeException, std::exception) override;
+    virtual uno::Reference< xml::sax::XFastContextHandler> SAL_CALL createFastChildContext(::sal_Int32 Element, const uno::Reference<xml::sax::XFastAttributeList >& xAttribs) throw (xml::sax::SAXException, uno::RuntimeException, std::exception) override;
+    virtual void SAL_CALL characters(const OUString& rChars) throw (xml::sax::SAXException, uno::RuntimeException, std::exception) override;
+
+};
+
+LazyMathBufferingContext::LazyMathBufferingContext(
+        core::ContextHandler const& rParent, drawingml::TextParagraph & rPara)
+    : core::ContextHandler(rParent)
+    , m_rBuilder(rPara.GetMathXml())
+    , m_Counter(0)
+{
+}
+
+void SAL_CALL LazyMathBufferingContext::startFastElement(
+        sal_Int32 const nElement,
+        uno::Reference<xml::sax::XFastAttributeList> const& xAttrs)
+    throw (xml::sax::SAXException, uno::RuntimeException, std::exception)
+{
+    if (0 < m_Counter) // ignore a14:m
+    {   // ignore outer oMathPara
+        if (1 != m_Counter || OOX_TOKEN(officeMath, oMathPara) != nElement)
+        {
+            m_rBuilder.appendOpeningTag(nElement, xAttrs);
+        }
+    }
+    ++m_Counter;
+}
+
+void SAL_CALL LazyMathBufferingContext::endFastElement(sal_Int32 const nElement)
+    throw (xml::sax::SAXException, uno::RuntimeException, std::exception)
+{
+    --m_Counter;
+    if (0 < m_Counter) // ignore a14:m
+    {   // ignore outer oMathPara
+        if (1 != m_Counter || OOX_TOKEN(officeMath, oMathPara) != nElement)
+        {
+            m_rBuilder.appendClosingTag(nElement);
+        }
+    }
+}
+
+uno::Reference<xml::sax::XFastContextHandler> SAL_CALL
+LazyMathBufferingContext::createFastChildContext(sal_Int32 const,
+        uno::Reference<xml::sax::XFastAttributeList> const&)
+    throw (xml::sax::SAXException, uno::RuntimeException, std::exception)
+{
+    return this;
+}
+
+void SAL_CALL LazyMathBufferingContext::characters(OUString const& rChars)
+    throw (xml::sax::SAXException, uno::RuntimeException, std::exception)
+{
+    if (0 < m_Counter) // ignore a14:m
+    {
+        m_rBuilder.appendCharacters(rChars);
+    }
+}
+
+} // namespace formulaimport
+
+core::ContextHandlerRef CreateLazyMathBufferingContext(
+        core::ContextHandler const& rParent, drawingml::TextParagraph & rPara)
+{
+    return new formulaimport::LazyMathBufferingContext(rParent, rPara);
+}
+
+} // namespace oox
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/qa/unit/export-tests.cxx b/sd/qa/unit/export-tests.cxx
index 818ea21..2f9550a 100644
--- a/sd/qa/unit/export-tests.cxx
+++ b/sd/qa/unit/export-tests.cxx
@@ -1173,7 +1173,30 @@ void SdExportTest::testMathObject()
             "/p:sld/p:cSld/p:spTree/mc:AlternateContent/mc:Choice/p:sp/p:txBody/a:p/a14:m/m:oMath/m:r[1]/m:t",
             "a");
 
-        // TODO can't import yet
+        const SdrPage *pPage = GetPage(1, xDocShRef);
+        const SdrObject* pObj = dynamic_cast<SdrObject*>(pPage->GetObj(0));
+        CPPUNIT_ASSERT_MESSAGE("no object", pObj != nullptr);
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(OBJ_OLE2), pObj->GetObjIdentifier());
+    }
+
+    utl::TempFile tempFile2;
+    xDocShRef = saveAndReload( xDocShRef, PPTX, &tempFile2 );
+
+    // Export an MS specific ole object (imported from a PPTX document)
+    {
+        xmlDocPtr pXmlDocContent = parseExport(tempFile1, "ppt/slides/slide1.xml");
+        assertXPath(pXmlDocContent,
+            "/p:sld/p:cSld/p:spTree/mc:AlternateContent/mc:Choice",
+            "Requires",
+            "a14");
+        assertXPathContent(pXmlDocContent,
+            "/p:sld/p:cSld/p:spTree/mc:AlternateContent/mc:Choice/p:sp/p:txBody/a:p/a14:m/m:oMath/m:r[1]/m:t",
+            "a");
+
+        const SdrPage *pPage = GetPage(1, xDocShRef);
+        const SdrObject* pObj = dynamic_cast<SdrObject*>(pPage->GetObj(0));
+        CPPUNIT_ASSERT_MESSAGE("no object", pObj != nullptr);
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(OBJ_OLE2), pObj->GetObjIdentifier());
     }
 
     xDocShRef->DoClose();
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 4cdd7c0..eeb11a0 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -32,6 +32,7 @@
 #include <com/sun/star/document/PrinterIndependentLayout.hpp>
 #include <com/sun/star/document/IndexedPropertyValues.hpp>
 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
 #include <com/sun/star/style/LineNumberPosition.hpp>


More information about the Libreoffice-commits mailing list