[Libreoffice-commits] .: 7 commits - oox/inc oox/source starmath/inc starmath/source writerfilter/source

Lubos Lunak llunak at kemper.freedesktop.org
Wed Dec 7 05:47:19 PST 2011


 oox/inc/oox/mathml/importutils.hxx                    |   62 +++++++++++++++---
 oox/source/mathml/importutils.cxx                     |   50 +++++++-------
 starmath/inc/node.hxx                                 |    5 +
 starmath/source/mathtype.cxx                          |   37 ----------
 starmath/source/node.cxx                              |   33 +++++++++
 starmath/source/ooxmlexport.cxx                       |   43 +-----------
 starmath/source/ooxmlimport.cxx                       |   10 +-
 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx |   62 ++++++++++--------
 writerfilter/source/ooxml/OOXMLFastContextHandler.hxx |   45 +++++++++++--
 9 files changed, 208 insertions(+), 139 deletions(-)

New commits:
commit 7be8bac42aa578dc7f250a490634e13d1dac550b
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Fri Dec 2 17:38:51 2011 +0100

    make the linear xml processing API more generic
    
    I'm pretty sure I'll love to use it in writerfilter instead of the normal
    API whenever I get the chance.

diff --git a/oox/inc/oox/mathml/importutils.hxx b/oox/inc/oox/mathml/importutils.hxx
index 9f75930..6906851 100644
--- a/oox/inc/oox/mathml/importutils.hxx
+++ b/oox/inc/oox/mathml/importutils.hxx
@@ -41,15 +41,15 @@ namespace oox
 namespace formulaimport
 {
 
+// used to differentiate between tags that opening or closing
 const int TAG_OPENING = 1 << 29;
 const int TAG_CLOSING = 1 << 30;
 
-// used to differentiate between tags that open or close
-// TODO
-//inline int OPENING( int token ) { return TAG_OPENING | token; }
-//inline int CLOSING( int token ) { return TAG_CLOSING | token; }
-#define OPENING( token ) ( TAG_OPENING | token )
-#define CLOSING( token ) ( TAG_CLOSING | token )
+// you probably want to #define these to something shorter in the .cxx file,
+// but they must be done as macros, otherwise they wouldn't be usable for case values,
+// and macros cannot be namespaced
+#define XML_STREAM_OPENING( token ) ( TAG_OPENING | token )
+#define XML_STREAM_CLOSING( token ) ( TAG_CLOSING | token )
 
 /**
  Class for storing a stream of xml tokens.
@@ -59,7 +59,55 @@ const int TAG_CLOSING = 1 << 30;
  files, unlike the usual LO way of using callbacks, context handlers and similar needlesly
  complicated stuff (YMMV).
 
- @since 3.5.0
+ The advantages of this approach is easy to read and debug code (as it is just functions
+ reading tokens one by one and calling other functions, compared to having to use callbacks
+ and temporary storage). The disadvantage is that the XML structure needs to be handled
+ manually by the code.
+
+ Note that tag identifiers are simply int values and the API does not care besides matching
+ their values to XML stream contents and requiring that the values are not as high as TAG_OPENING.
+ Be prepared for the fact that some of the functions may throw exceptions if the input
+ stream does not match the required token (TBD).
+
+ The API tries to make the common idioms as simple as possible, see the following examples.
+
+ Parse <tagone attr="value"><tagtwo>text</tagtwo></tagone> , where tagtwo is optional:
+ @code
+XmlStream::Tag tagoneTag = stream.ensureOpeningTag( tagone );
+if( attributeTag.hasAttribute( attr ))
+    ... = attributeTag.attribute( attr, defaultValueOfTheRightType );
+if( XmlStream::Tag tagtwoTag = stream.checkOpeningTag( tagtwo ))
+{
+    ... = tagtwoTag.text;
+    stream.ensureClosingTag( tagtwo );
+}
+stream.ensureClosingTag( tagone );
+ @endcode
+
+ Parse an element that may contain several sub-elements of different types in random order:
+ @code
+stream.ensureOpeningTag( element );
+while( !stream.atEnd() && stream.currentToken() != CLOSING( element ))
+    {
+    switch( stream.currentToken())
+    {
+        case OPENING( subelement1 ):
+            handleSubElement1();
+            break;
+        case OPENING( subelement2 ):
+            ... process subelement2;
+            break;
+        default:
+            stream.handleUnexpectedTag();
+            break;
+    }
+stream.ensureClosingTag( element );
+ @endcode
+
+ If there may be just a one type of sub-element, handle it directly without the switch statement.
+ If there may not be a zero number of sub-elements, use a helper bool variable or use a do-while loop.
+
+ @since 3.5
 */
 class OOX_DLLPUBLIC XmlStream
 {
diff --git a/oox/source/mathml/importutils.cxx b/oox/source/mathml/importutils.cxx
index 61f04a9..2a7d19c 100644
--- a/oox/source/mathml/importutils.cxx
+++ b/oox/source/mathml/importutils.cxx
@@ -41,6 +41,8 @@
 #define STR( str ) OUString( RTL_CONSTASCII_USTRINGPARAM( str ))
 #define CSTR( str ) ( rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr())
 
+#define OPENING( token ) XML_STREAM_OPENING( token )
+#define CLOSING( token ) XML_STREAM_CLOSING( token )
 
 // HACK - TODO convert to the real debug stuff
 #undef SAL_LOG_LEVEL
diff --git a/starmath/source/ooxmlimport.cxx b/starmath/source/ooxmlimport.cxx
index c776163..73f0ea5 100644
--- a/starmath/source/ooxmlimport.cxx
+++ b/starmath/source/ooxmlimport.cxx
@@ -44,8 +44,8 @@ The primary internal data structure for the formula is the text representation
 */
 
 #define M_TOKEN( token ) OOX_TOKEN( officeMath, token )
-#define OPENING_TAG( token ) OPENING( token )
-#define CLOSING_TAG( token ) CLOSING( token )
+#define OPENING( token ) XML_STREAM_OPENING( token )
+#define CLOSING( token ) XML_STREAM_CLOSING( token )
 
 // *sigh*
 #define STR( str ) OUString( RTL_CONSTASCII_USTRINGPARAM( str ))
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index 732391c..4b183b9 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -2366,35 +2366,16 @@ Token_t OOXMLFastContextHandlerWrapper::getToken() const
 
 
 /*
-  class OOXMLFastContextHandlerMath
+  class OOXMLFastContextHandlerLinear
  */
 
-OOXMLFastContextHandlerMath::OOXMLFastContextHandlerMath(OOXMLFastContextHandler* pContext)
+OOXMLFastContextHandlerLinear::OOXMLFastContextHandlerLinear(OOXMLFastContextHandler* pContext)
     : OOXMLFastContextHandlerProperties(pContext)
     , depthCount( 0 )
 {
 }
 
-void OOXMLFastContextHandlerMath::process()
-{
-    SvGlobalName name( SO3_SM_CLASSID );
-    comphelper::EmbeddedObjectContainer container;
-    rtl::OUString aName;
-    uno::Reference< embed::XEmbeddedObject > ref = container.CreateEmbeddedObject( name.GetByteSequence(), aName );
-    uno::Reference< uno::XInterface > component( ref->getComponent(), uno::UNO_QUERY );
-    if( oox::FormulaImportBase* import = dynamic_cast< oox::FormulaImportBase* >( component.get()))
-        import->readFormulaOoxml( buffer );
-    if (isForwardEvents())
-    {
-        OOXMLPropertySet * pProps = new OOXMLPropertySetImpl();
-        OOXMLValue::Pointer_t pVal( new OOXMLStarMathValue( ref ));
-        OOXMLProperty::Pointer_t pProp( new OOXMLPropertyImpl( NS_ooxml::LN_starmath, pVal, OOXMLPropertyImpl::ATTRIBUTE ));
-        pProps->add( pProp );
-        mpStream->props( writerfilter::Reference< Properties >::Pointer_t( pProps ));
-    }
-}
-
-void OOXMLFastContextHandlerMath::lcl_startFastElement(Token_t Element,
+void OOXMLFastContextHandlerLinear::lcl_startFastElement(Token_t Element,
     const uno::Reference< xml::sax::XFastAttributeList >& Attribs)
     throw (uno::RuntimeException, xml::sax::SAXException)
 {
@@ -2402,7 +2383,7 @@ void OOXMLFastContextHandlerMath::lcl_startFastElement(Token_t Element,
     ++depthCount;
 }
 
-void OOXMLFastContextHandlerMath::lcl_endFastElement(Token_t Element)
+void OOXMLFastContextHandlerLinear::lcl_endFastElement(Token_t Element)
     throw (uno::RuntimeException, xml::sax::SAXException)
 {
     buffer.appendClosingTag( Element );
@@ -2411,7 +2392,7 @@ void OOXMLFastContextHandlerMath::lcl_endFastElement(Token_t Element)
 }
 
 uno::Reference< xml::sax::XFastContextHandler >
-OOXMLFastContextHandlerMath::lcl_createFastChildContext(Token_t,
+OOXMLFastContextHandlerLinear::lcl_createFastChildContext(Token_t,
     const uno::Reference< xml::sax::XFastAttributeList >&)
     throw (uno::RuntimeException, xml::sax::SAXException)
 {
@@ -2420,12 +2401,39 @@ OOXMLFastContextHandlerMath::lcl_createFastChildContext(Token_t,
     return xContextHandler;
 }
 
-void OOXMLFastContextHandlerMath::lcl_characters(const ::rtl::OUString& aChars)
+void OOXMLFastContextHandlerLinear::lcl_characters(const ::rtl::OUString& aChars)
     throw (uno::RuntimeException, xml::sax::SAXException)
 {
     buffer.appendCharacters( aChars );
 }
 
+/*
+  class OOXMLFastContextHandlerLinear
+ */
+
+OOXMLFastContextHandlerMath::OOXMLFastContextHandlerMath(OOXMLFastContextHandler* pContext)
+    : OOXMLFastContextHandlerLinear(pContext)
+{
+}
+
+void OOXMLFastContextHandlerMath::process()
+{
+    SvGlobalName name( SO3_SM_CLASSID );
+    comphelper::EmbeddedObjectContainer container;
+    rtl::OUString aName;
+    uno::Reference< embed::XEmbeddedObject > ref = container.CreateEmbeddedObject( name.GetByteSequence(), aName );
+    uno::Reference< uno::XInterface > component( ref->getComponent(), uno::UNO_QUERY );
+    if( oox::FormulaImportBase* import = dynamic_cast< oox::FormulaImportBase* >( component.get()))
+        import->readFormulaOoxml( buffer );
+    if (isForwardEvents())
+    {
+        OOXMLPropertySet * pProps = new OOXMLPropertySetImpl();
+        OOXMLValue::Pointer_t pVal( new OOXMLStarMathValue( ref ));
+        OOXMLProperty::Pointer_t pProp( new OOXMLPropertyImpl( NS_ooxml::LN_starmath, pVal, OOXMLPropertyImpl::ATTRIBUTE ));
+        pProps->add( pProp );
+        mpStream->props( writerfilter::Reference< Properties >::Pointer_t( pProps ));
+    }
+}
 
 }}
 
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
index 0d75b7d..bb0e889 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
@@ -641,15 +641,37 @@ private:
     OOXMLFastContextHandler * getFastContextHandler() const;
 };
 
+/**
+ A class that converts from XFastParser/XFastContextHandler usage to a liner XML stream of data.
+
+ The purpose of this class is to convert the rather complex XFastContextHandler-based XML
+ processing that requires context subclasses, callbacks, etc. into a linear stream of XML tokens
+ that can be handled simply by reading the tokens one by one and directly processing them.
+ See the oox::formulaimport::XmlStream class documentation for more information.
+
+ Usage: Create a subclass of OOXMLFastContextHandlerLinear, reimplemented getType() to provide
+ type of the subclass and process() to actually process the XML stream. Also make sure to
+ add a line like the following to model.xml (for class OOXMLFastContextHandlerMath):
 
-class OOXMLFastContextHandlerMath: public OOXMLFastContextHandlerProperties
+ <resource name="CT_OMath" resource="Math"/>
+
+ @since 3.5
+*/
+class OOXMLFastContextHandlerLinear: public OOXMLFastContextHandlerProperties
 {
 public:
-    explicit OOXMLFastContextHandlerMath(OOXMLFastContextHandler * pContext);
-    virtual string getType() const { return "Math"; }
+    explicit OOXMLFastContextHandlerLinear(OOXMLFastContextHandler * pContext);
+    /**
+     Return the type of the class, as written in model.xml .
+     */
+    virtual string getType() const = 0;
 
 protected:
-    virtual void process();
+    /**
+     Called when the tokens for the element, its content and sub-elements have been linearized
+     and should be processed. The data member @ref buffer contains the converted data.
+    */
+    virtual void process() = 0;
 
     virtual void lcl_startFastElement(Token_t Element, const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
         throw (uno::RuntimeException, xml::sax::SAXException);
@@ -662,11 +684,21 @@ protected:
 
     virtual void lcl_characters(const ::rtl::OUString & aChars) throw (uno::RuntimeException, xml::sax::SAXException);
 
-private:
+    // should be private, but not much point in making deep copies of it
     oox::formulaimport::XmlStreamBuilder buffer;
+
+private:
     int depthCount;
 };
 
+class OOXMLFastContextHandlerMath: public OOXMLFastContextHandlerLinear
+{
+public:
+    explicit OOXMLFastContextHandlerMath(OOXMLFastContextHandler * pContext);
+    virtual string getType() const { return "Math"; }
+protected:
+    virtual void process();
+};
 
 }}
 #endif // INCLUDED_OOXML_FAST_CONTEXT_HANDLER_HXX
commit 1e4fb45c03e1787a6f73a93a1d9a68911d17a4e6
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Fri Dec 2 16:17:12 2011 +0100

    disable error logs for now, until the new log macros get sorted out

diff --git a/oox/source/mathml/importutils.cxx b/oox/source/mathml/importutils.cxx
index d09eebd..61f04a9 100644
--- a/oox/source/mathml/importutils.cxx
+++ b/oox/source/mathml/importutils.cxx
@@ -82,6 +82,7 @@ AttributeListBuilder::AttributeListBuilder( const uno::Reference< xml::sax::XFas
     }
 }
 
+#if 0
 static OUString tokenToString( int token )
 {
     OUString tokenname = StaticTokenMap::get().getUnicodeTokenName( token & TOKEN_MASK );
@@ -114,6 +115,7 @@ static OUString tokenToString( int token )
     // just the name itself, not specified whether opening or closing
     return namespacename + STR( ":" ) + tokenname;
 }
+#endif
 
 } // namespace
 
@@ -141,7 +143,7 @@ bool XmlStream::AttributeList::attribute( int token, bool def ) const
         if( find->second.equalsIgnoreAsciiCaseAscii( "false" ) || find->second.equalsIgnoreAsciiCaseAscii( "off" )
             || find->second.equalsIgnoreAsciiCaseAscii( "f" ) || find->second.equalsIgnoreAsciiCaseAscii( "0" ))
             return false;
-        fprintf( stderr, "Cannot convert \'%s\' to bool.\n", CSTR( find->second ));
+//        fprintf( stderr, "Cannot convert \'%s\' to bool.\n", CSTR( find->second ));
     }
     return def;
 }
@@ -153,8 +155,8 @@ sal_Unicode XmlStream::AttributeList::attribute( int token, sal_Unicode def ) co
     {
         if( find->second.getLength() >= 1 )
         {
-            if( find->second.getLength() != 1 )
-                fprintf( stderr, "Cannot convert \'%s\' to sal_Unicode, stripping.\n", CSTR( find->second ));
+//            if( find->second.getLength() != 1 )
+//                fprintf( stderr, "Cannot convert \'%s\' to sal_Unicode, stripping.\n", CSTR( find->second ));
             return find->second[ 0 ];
         }
     }
@@ -247,7 +249,7 @@ XmlStream::Tag XmlStream::checkTag( int token, bool optional )
         pos = savedPos;
         return Tag();
     }
-    fprintf( stderr, "Expected tag %s not found.\n", CSTR( tokenToString( token )));
+//    fprintf( stderr, "Expected tag %s not found.\n", CSTR( tokenToString( token )));
     return Tag();
 }
 
@@ -256,7 +258,7 @@ bool XmlStream::recoverAndFindTag( int token )
     return recoverAndFindTagInternal( token, false );
 }
 
-bool XmlStream::recoverAndFindTagInternal( int token, bool silent )
+bool XmlStream::recoverAndFindTagInternal( int token, bool /*silent*/ )
 {
     int depth = 0;
     for(;
@@ -267,20 +269,20 @@ bool XmlStream::recoverAndFindTagInternal( int token, bool silent )
         {
             if( currentToken() == OPENING( currentToken()))
             {
-                if( !silent )
-                    fprintf( stderr, "Skipping tag %s\n", CSTR( tokenToString( currentToken())));
+//                if( !silent )
+//                    fprintf( stderr, "Skipping tag %s\n", CSTR( tokenToString( currentToken())));
                 ++depth;
             }
             else if( currentToken() == CLOSING( currentToken()))
             {
-                if( !silent )
-                    fprintf( stderr, "Skipping tag %s\n", CSTR( tokenToString( currentToken())));
+//                if( !silent )
+//                    fprintf( stderr, "Skipping tag %s\n", CSTR( tokenToString( currentToken())));
                 --depth;
             }
             else
             {
-                if( !silent )
-                    fprintf( stderr, "Malformed token %d (%s)\n", currentToken(), CSTR( tokenToString( currentToken())));
+//                if( !silent )
+//                    fprintf( stderr, "Malformed token %d (%s)\n", currentToken(), CSTR( tokenToString( currentToken())));
                 abort();
             }
             continue;
@@ -291,15 +293,15 @@ bool XmlStream::recoverAndFindTagInternal( int token, bool silent )
             return false; // that would be leaving current element, so not found
         if( currentToken() == OPENING( currentToken()))
         {
-            if( !silent )
-                fprintf( stderr, "Skipping tag %s\n", CSTR( tokenToString( currentToken())));
+//            if( !silent )
+//                fprintf( stderr, "Skipping tag %s\n", CSTR( tokenToString( currentToken())));
             ++depth;
         }
         else
             abort();
     }
-    if( !silent )
-        fprintf( stderr, "Unexpected end of stream reached.\n" );
+//    if( !silent )
+//        fprintf( stderr, "Unexpected end of stream reached.\n" );
     return false;
 }
 
@@ -308,23 +310,23 @@ void XmlStream::skipElement( int token )
     return skipElementInternal( token, true ); // no debug about skipping if called from outside
 }
 
-void XmlStream::skipElementInternal( int token, bool silent )
+void XmlStream::skipElementInternal( int token, bool /*silent*/ )
 {
     int closing = ( token & ~TAG_OPENING ) | TAG_CLOSING; // make it a closing tag
     assert( currentToken() == OPENING( token ));
-    if( !silent )
-        fprintf( stderr, "Skipping unexpected element %s\n", CSTR( tokenToString( currentToken())));
+//    if( !silent )
+//        fprintf( stderr, "Skipping unexpected element %s\n", CSTR( tokenToString( currentToken())));
     moveToNextTag();
     // and just find the matching closing tag
     if( recoverAndFindTag( closing ))
     {
-        if( !silent )
-            fprintf( stderr, "Skipped unexpected element %s\n", CSTR( tokenToString( token )));
+//        if( !silent )
+//            fprintf( stderr, "Skipped unexpected element %s\n", CSTR( tokenToString( token )));
         moveToNextTag(); // and skip it too
         return;
     }
     // this one is an unexpected problem, do not silent it
-    fprintf( stderr, "Expected end of element %s not found.\n", CSTR( tokenToString( token )));
+//    fprintf( stderr, "Expected end of element %s not found.\n", CSTR( tokenToString( token )));
 }
 
 void XmlStream::handleUnexpectedTag()
@@ -333,7 +335,7 @@ void XmlStream::handleUnexpectedTag()
         return;
     if( currentToken() == CLOSING( currentToken()))
     {
-        fprintf( stderr, "Skipping unexpected tag %s\n", CSTR( tokenToString( currentToken())));
+//        fprintf( stderr, "Skipping unexpected tag %s\n", CSTR( tokenToString( currentToken())));
         moveToNextTag(); // just skip it
         return;
     }
diff --git a/starmath/source/ooxmlimport.cxx b/starmath/source/ooxmlimport.cxx
index 233334d..c776163 100644
--- a/starmath/source/ooxmlimport.cxx
+++ b/starmath/source/ooxmlimport.cxx
@@ -88,7 +88,7 @@ OUString SmOoxmlImport::handleStream()
     // And as a result, empty parts of the formula that are not placeholders are written out
     // as a single space, so fix that up too.
     ret = comphelper::string::searchAndReplaceAllAsciiWithAscii( ret, "{ }", "{}" );
-    fprintf(stderr, "FORMULA: %s\n", rtl::OUStringToOString( ret, RTL_TEXTENCODING_UTF8 ).getStr());
+//    fprintf(stderr, "FORMULA: %s\n", rtl::OUStringToOString( ret, RTL_TEXTENCODING_UTF8 ).getStr());
     return ret;
 }
 
@@ -226,7 +226,7 @@ OUString SmOoxmlImport::handleAcc()
             break;
         default:
             acc = STR( "acute" );
-            fprintf( stderr, "Unknown m:chr in m:acc '%d'\n", accChr );
+//            fprintf( stderr, "Unknown m:chr in m:acc '%d'\n", accChr );
             break;
     }
     OUString e = readOMathArgInElement( M_TOKEN( e ));
@@ -533,7 +533,7 @@ OUString SmOoxmlImport::handleNary()
             ret = STR( "sum" );
             break;
         default:
-            fprintf( stderr, "Unknown m:nary chr '%d'\n", chr );
+//            fprintf( stderr, "Unknown m:nary chr '%d'\n", chr );
             break;
     }
     if( !subHide )
commit cc39235d47719193d27565ba47c00c9a91ecbce8
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Fri Dec 2 15:36:55 2011 +0100

    process element in endFastElement(), not in dtor
    
    Otherwise with malformed xml the dtor is called in a place where
    the processing of the formula apparently corrupts the internal
    representation somehow and it is impossible to write the document
    back as docx. As a bonus, all UI elements related to saving get
    disabled, so the document then cannot be saved at all. Although
    this is only with malformed xml, which hopefully should never
    happen, it's still better to avoid this. Moreover it seems to be
    the proper way of coding the handlers anyway.

diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index b313b0f..732391c 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -2371,10 +2371,11 @@ Token_t OOXMLFastContextHandlerWrapper::getToken() const
 
 OOXMLFastContextHandlerMath::OOXMLFastContextHandlerMath(OOXMLFastContextHandler* pContext)
     : OOXMLFastContextHandlerProperties(pContext)
+    , depthCount( 0 )
 {
 }
 
-OOXMLFastContextHandlerMath::~OOXMLFastContextHandlerMath()
+void OOXMLFastContextHandlerMath::process()
 {
     SvGlobalName name( SO3_SM_CLASSID );
     comphelper::EmbeddedObjectContainer container;
@@ -2398,12 +2399,15 @@ void OOXMLFastContextHandlerMath::lcl_startFastElement(Token_t Element,
     throw (uno::RuntimeException, xml::sax::SAXException)
 {
     buffer.appendOpeningTag( Element, Attribs );
+    ++depthCount;
 }
 
 void OOXMLFastContextHandlerMath::lcl_endFastElement(Token_t Element)
     throw (uno::RuntimeException, xml::sax::SAXException)
 {
     buffer.appendClosingTag( Element );
+    if( --depthCount == 0 )
+        process();
 }
 
 uno::Reference< xml::sax::XFastContextHandler >
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
index e06f4b1..0d75b7d 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
@@ -646,11 +646,11 @@ class OOXMLFastContextHandlerMath: public OOXMLFastContextHandlerProperties
 {
 public:
     explicit OOXMLFastContextHandlerMath(OOXMLFastContextHandler * pContext);
-    virtual ~OOXMLFastContextHandlerMath();
-
     virtual string getType() const { return "Math"; }
 
 protected:
+    virtual void process();
+
     virtual void lcl_startFastElement(Token_t Element, const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
         throw (uno::RuntimeException, xml::sax::SAXException);
 
@@ -664,6 +664,7 @@ protected:
 
 private:
     oox::formulaimport::XmlStreamBuilder buffer;
+    int depthCount;
 };
 
 
commit a8f46cdc8ea1d6e8041bde5072e5d6aa2e3d61a3
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Fri Dec 2 15:36:41 2011 +0100

    remove needless TODO

diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index 31aa02c..b313b0f 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -2378,7 +2378,7 @@ OOXMLFastContextHandlerMath::~OOXMLFastContextHandlerMath()
 {
     SvGlobalName name( SO3_SM_CLASSID );
     comphelper::EmbeddedObjectContainer container;
-    rtl::OUString aName; // TODO?
+    rtl::OUString aName;
     uno::Reference< embed::XEmbeddedObject > ref = container.CreateEmbeddedObject( name.GetByteSequence(), aName );
     uno::Reference< uno::XInterface > component( ref->getComponent(), uno::UNO_QUERY );
     if( oox::FormulaImportBase* import = dynamic_cast< oox::FormulaImportBase* >( component.get()))
commit efe72126d9942aa6c62608f801670db06a31828f
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Fri Dec 2 14:23:59 2011 +0100

    merge two duplicates of a function

diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx
index 1ecde44..385aa8e 100644
--- a/starmath/inc/node.hxx
+++ b/starmath/inc/node.hxx
@@ -502,6 +502,11 @@ public:
 
     virtual void  GetAccessibleText( String &rText ) const;
     void Accept(SmVisitor* pVisitor);
+    /**
+      Converts the character from StarMath's private area symbols to a matching Unicode
+      character, if necessary. To be used when converting GetText() to a normal text.
+    */
+    static sal_Unicode ConvertSymbolToUnicode(sal_Unicode nIn);
 };
 
 
diff --git a/starmath/source/mathtype.cxx b/starmath/source/mathtype.cxx
index bd5386f..58d37d7 100644
--- a/starmath/source/mathtype.cxx
+++ b/starmath/source/mathtype.cxx
@@ -33,39 +33,6 @@
 
 #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 const 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
@@ -3124,7 +3091,7 @@ void MathType::HandleMath(SmNode *pNode, int /*nLevel*/)
     SmMathSymbolNode *pTemp=(SmMathSymbolNode *)pNode;
     for(xub_StrLen i=0;i<pTemp->GetText().Len();i++)
     {
-        sal_Unicode nArse = Convert(pTemp->GetText().GetChar(i));
+        sal_Unicode nArse = SmTextNode::ConvertSymbolToUnicode(pTemp->GetText().GetChar(i));
         if ((nArse == 0x2224) || (nArse == 0x2288) || (nArse == 0x2285) ||
             (nArse == 0x2289))
         {
@@ -3364,7 +3331,7 @@ void MathType::HandleText(SmNode *pNode, int /*nLevel*/)
             nFace = 0x7;
         *pS << sal_uInt8(nFace+128); //typeface
         sal_uInt16 nChar = pTemp->GetText().GetChar(i);
-        *pS << Convert(nChar);
+        *pS << SmTextNode::ConvertSymbolToUnicode(nChar);
 
         //Mathtype can only have these sort of character
         //attributes on a single character, starmath can put them
diff --git a/starmath/source/node.cxx b/starmath/source/node.cxx
index 1796543..58010e7 100644
--- a/starmath/source/node.cxx
+++ b/starmath/source/node.cxx
@@ -2503,6 +2503,39 @@ void SmTextNode::AdjustFontDesc()
     }
 }
 
+sal_Unicode SmTextNode::ConvertSymbolToUnicode(sal_Unicode nIn)
+{
+    //Find the best match in accepted unicode for our private area symbols
+    static const 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 SmMatrixNode::CreateTextFromNode(String &rText)
diff --git a/starmath/source/ooxmlexport.cxx b/starmath/source/ooxmlexport.cxx
index b84fd38..3604894 100644
--- a/starmath/source/ooxmlexport.cxx
+++ b/starmath/source/ooxmlexport.cxx
@@ -34,41 +34,6 @@
 using namespace oox;
 using namespace oox::core;
 
-// TODO duped from MathType
-
-static sal_Unicode Convert(sal_Unicode nIn)
-{
-    //Find the best match in accepted unicode for our private area symbols
-    static const 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;
-}
-
 SmOoxmlExport::SmOoxmlExport( const String &rIn, const SmNode* pIn, OoxmlVersion v )
 : str( rIn )
 , pTree( pIn )
@@ -268,7 +233,7 @@ void SmOoxmlExport::HandleText( const SmNode* pNode, int /*nLevel*/)
         *pS << sal_uInt8(nFace+128); //typeface
 #endif
         sal_uInt16 nChar = pTemp->GetText().GetChar(i);
-        m_pSerializer->writeEscaped( rtl::OUString( Convert(nChar)));
+        m_pSerializer->writeEscaped( rtl::OUString( SmTextNode::ConvertSymbolToUnicode(nChar)));
 
 #if 0
         //Mathtype can only have these sort of character
@@ -454,8 +419,10 @@ void SmOoxmlExport::HandleRoot( const SmRootNode* pNode, int nLevel )
 
 static rtl::OString mathSymbolToString( const SmNode* node )
 {
-    OSL_ASSERT( node->GetType() == NMATH && static_cast< const SmTextNode* >( node )->GetText().Len() == 1 );
-    sal_Unicode chr = Convert( static_cast< const SmTextNode* >( node )->GetText().GetChar( 0 ));
+    assert( node->GetType() == NMATH );
+    const SmTextNode* txtnode = static_cast< const SmTextNode* >( node );
+    assert( txtnode->GetText().Len() == 1 );
+    sal_Unicode chr = SmTextNode::ConvertSymbolToUnicode( txtnode->GetText().GetChar( 0 ));
     return rtl::OUStringToOString( rtl::OUString( chr ), RTL_TEXTENCODING_UTF8 );
 }
 
commit d7017dbc1754c3b6f27501d3eae997a39f62daf8
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Thu Dec 1 15:22:28 2011 +0100

    append text when reading from xml
    
    The xml parser apparently can call the characters() callback several
    times for one text content (if it needs to un-escape maybe?), so
    append, otherwise some content would be overwritten.

diff --git a/oox/source/mathml/importutils.cxx b/oox/source/mathml/importutils.cxx
index 912f0f6..d09eebd 100644
--- a/oox/source/mathml/importutils.cxx
+++ b/oox/source/mathml/importutils.cxx
@@ -354,7 +354,7 @@ void XmlStreamBuilder::appendClosingTag( int token )
 void XmlStreamBuilder::appendCharacters( const rtl::OUString& chars )
 {
     assert( !tags.empty());
-    tags.back().text = chars;
+    tags.back().text += chars;
 }
 
 } // namespace
commit 5799813f5b95c984b15a348c33daa2103fd09b1b
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Thu Dec 1 14:38:11 2011 +0100

    properly xml-escape written text in docx formula

diff --git a/starmath/source/ooxmlexport.cxx b/starmath/source/ooxmlexport.cxx
index d3d7c05..b84fd38 100644
--- a/starmath/source/ooxmlexport.cxx
+++ b/starmath/source/ooxmlexport.cxx
@@ -268,7 +268,7 @@ void SmOoxmlExport::HandleText( const SmNode* pNode, int /*nLevel*/)
         *pS << sal_uInt8(nFace+128); //typeface
 #endif
         sal_uInt16 nChar = pTemp->GetText().GetChar(i);
-        m_pSerializer->write( rtl::OUString( Convert(nChar)));
+        m_pSerializer->writeEscaped( rtl::OUString( Convert(nChar)));
 
 #if 0
         //Mathtype can only have these sort of character


More information about the Libreoffice-commits mailing list