# HG changeset patch
# User Michael Stahl <mst@openoffice.org>
# Date 1303140562 0
# Node ID 4d286e27d1745f0d9643230acf946dbbe87001f5
# Parent  8e3529d5590ef9912f2273a8d291aebcb371b505
rtftok01: writerfilter: support for unicode characters

diff --git a/writerfilter/source/rtftok/RTFDocumentImpl.cxx b/writerfilter/source/rtftok/RTFDocumentImpl.cxx
--- a/writerfilter/source/rtftok/RTFDocumentImpl.cxx
+++ b/writerfilter/source/rtftok/RTFDocumentImpl.cxx
@@ -314,6 +314,8 @@
     explicit RTFScannerHandlerImpl(Stream & rStream)
         : m_rStream(rStream)
         , m_TextEncoding(osl_getThreadTextEncoding())
+        , m_NegativeCharacters(0)
+        , m_UnicodeCharacters(1)
     {
         m_Destinations.push( ::std::make_pair(0,
             RTFDestination::Pointer_t(createRootDestination(*this))) );
@@ -321,6 +323,7 @@
     virtual ~RTFScannerHandlerImpl() { }
     virtual void dest(char const*const token, char const*const value)
     {
+        m_NegativeCharacters = 0;
         checkStrings();
         RTFDestination::Pointer_t const pDestination(
             m_Destinations.top().second->dest(token, value) );
@@ -331,17 +334,37 @@
     }
     virtual void ctrl(char const*const token, char const*const value)
     {
+        m_NegativeCharacters = 0;
         checkStrings();
-        m_Destinations.top().second->ctrl(token, value);
+        if (('u' == token[0]) && ('\0' == token[1]))
+        {
+            sal_Int32 const v(::rtl::OString(value).toInt32());
+fprintf(stderr, "RTFScannerHandlerImpl::ctrl: \\u%d\n", v);
+            if ((SAL_MIN_INT16 <= v) && (v <= SAL_MAX_INT16)) {
+                RTFScannerHandlerImpl::addCharU(static_cast<sal_Unicode>(v));
+            }
+        }
+        else if (('u' == token[0]) && ('c' == token[1]) && ('\0' == token[2]))
+        {
+            sal_Int32 const v(::rtl::OString(value).toInt32());
+            if ((0 <= v) && (v < SAL_MAX_UINT16)) {
+                SetUnicodeCharacters(v);
+            }
+        }
+        else {
+            m_Destinations.top().second->ctrl(token, value);
+        }
     }
     virtual void lbrace()
     {
+        m_NegativeCharacters = 0;
         checkStrings();
         m_Destinations.top().second->lbrace();
         ++m_Destinations.top().first;
     }
     virtual void rbrace()
     {
+        m_NegativeCharacters = 0;
         checkStrings();
         m_Destinations.top().second->rbrace();
         --m_Destinations.top().first;
@@ -355,7 +378,14 @@
     virtual void addSpaces(unsigned int const count)
     {
         checkUString();
-        for (unsigned int i = 0; i < count; ++i) {
+        unsigned int realCount(0);
+        if (count >= m_NegativeCharacters) {
+            realCount = count - m_NegativeCharacters;
+            m_NegativeCharacters = 0;
+        } else {
+            m_NegativeCharacters -= count;
+        }
+        for (unsigned int i = 0; i < realCount; ++i) {
             m_String.append(" ");
         }
     }
@@ -366,18 +396,24 @@
     virtual void addChar(char const ch)
     {
         checkUString();
-        m_String.append(ch);
+        if (0 != m_NegativeCharacters) {
+fprintf(stderr, "RTFScannerHandlerImpl::addChar: ignoring character '%c'(%x)\n", ch, ch);
+            --m_NegativeCharacters; /* ignore the character */
+        } else {
+            m_String.append(ch);
+        }
     }
     virtual void addCharU(sal_Unicode const ch)
     {
         checkString();
         m_UString.append(ch);
+        /* don't check if it was 0, right? */
+        m_NegativeCharacters = m_UnicodeCharacters;
     }
     virtual void addHexChar(char const hexch[2])
     {
-        checkUString();
         char const c( (lcl_HexDigit(hexch[0]) << 4) | lcl_HexDigit(hexch[1]) );
-        m_String.append(c);
+        RTFScannerHandlerImpl::addChar(c);
     }
     Stream & GetStream() { return m_rStream; }
 
@@ -386,6 +422,10 @@
 fprintf(stderr, "RTFScannerHandlerImpl::SetEncoding: %d\n", e);
         m_TextEncoding = e;
     }
+    void SetUnicodeCharacters(unsigned int const uc) {
+fprintf(stderr, "RTFScannerHandlerImpl::SetUnicodeCharacters: %d\n", uc);
+        m_UnicodeCharacters = uc;
+    }
 
 private:
     void checkStrings()
@@ -414,6 +454,8 @@
     ::rtl::OUStringBuffer m_UString;
     ::std::stack< ::std::pair<int, RTFDestination::Pointer_t> > m_Destinations;
     rtl_TextEncoding m_TextEncoding;
+    unsigned int m_NegativeCharacters;
+    unsigned int m_UnicodeCharacters;
 };
 
 
