# HG changeset patch
# User Michael Stahl <mst@openoffice.org>
# Date 1285951056 -7200
# Node ID a21348d0f92755f627fda553462757886ba0922c
# Parent  f23793c1ff4127cf6673aa257546dbf383388a02
rtftok01: support for color table and charfmt color controls (as far as supported by dm)

diff --git a/writerfilter/source/rtftok/RTFDestination.hxx b/writerfilter/source/rtftok/RTFDestination.hxx
--- a/writerfilter/source/rtftok/RTFDestination.hxx
+++ b/writerfilter/source/rtftok/RTFDestination.hxx
@@ -316,6 +316,7 @@
     }
 
     void SetEncodingToFont(const sal_Int32 i);
+    sal_uInt32 GetColorTableEntry(const sal_Int32 i);
     void SetAttribute(Id const id, RTFValue::Pointer_t const& pValue);
     void SetSprm(Id const id, RTFValue::Pointer_t const& pValue);
     void ResetCharacterProperties();
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
@@ -221,6 +221,7 @@
 
 
 typedef ::std::map<sal_Int32, rtl_TextEncoding> FontTable_t;
+typedef ::std::vector<sal_uInt32> ColorTable_t;
 
 static char
 lcl_HexDigit(char const c)
@@ -390,7 +391,10 @@
     void SetFontTable(FontTable_t const& rFontTable) {
         m_FontTable = rFontTable;
     }
-    void SetEncodingToFont(const sal_Int32 i) {
+    void SetColorTable(ColorTable_t const& rColorTable) {
+        m_ColorTable = rColorTable;
+    }
+    void SetEncodingToFont(sal_Int32 const i) {
         FontTable_t::const_iterator const iter(m_FontTable.find(i));
         if (m_FontTable.end() != iter) {
             SetEncoding(iter->second);
@@ -398,6 +402,11 @@
             OSL_TRACE("RTFScannerHandlerImpl: invalid font: %d", i);
         }
     }
+    sal_uInt32 GetColorTableEntry(const sal_Int32 i)
+    {
+        return ((0 <= i) && (static_cast<size_t>(i) < m_ColorTable.size()))
+            ? m_ColorTable[i] : 0;
+    }
     void SetAttribute(Id const id, RTFValue::Pointer_t const& pValue) {
         GetCurrentGroup().m_CharacterProperties.m_Attributes[id] = pValue;
     }
@@ -440,16 +449,23 @@
     ::std::stack< ::std::pair<int, RTFDestination::Pointer_t> > m_Destinations;
     ::std::stack< RTFGroup > m_Groups;
     FontTable_t m_FontTable;
+    ColorTable_t m_ColorTable;
     RTFGroup::Attributes_t m_Defaults;
 };
 
 
 void
-RTFDestination::SetEncodingToFont(const sal_Int32 i)
+RTFDestination::SetEncodingToFont(sal_Int32 const i)
 {
     GetHandler().SetEncodingToFont(i);
 }
 
+sal_uInt32
+RTFDestination::GetColorTableEntry(const sal_Int32 i)
+{
+    return GetHandler().GetColorTableEntry(i);
+}
+
 void
 RTFDestination::SetAttribute(Id const id, RTFValue::Pointer_t const& pValue)
 {
@@ -681,6 +697,78 @@
 
 
 
+class RTFDestinationColorTable
+    : public RTFDestination
+{
+public:
+    explicit RTFDestinationColorTable(RTFScannerHandlerImpl & rHandler)
+        : RTFDestination(rHandler)
+    { }
+    virtual ~RTFDestinationColorTable() { }
+
+    virtual void ctrl(Token_t const token, char const*const value)
+    {
+        switch (token)
+        {
+            case RTF_red:
+            {
+                m_Entry.m_Red = ::rtl::OString(value).toInt32();
+            }
+            break;
+            case RTF_green:
+            {
+                m_Entry.m_Green = ::rtl::OString(value).toInt32();
+            }
+            break;
+            case RTF_blue:
+            {
+                m_Entry.m_Blue = ::rtl::OString(value).toInt32();
+            }
+            break;
+            //theme color stuff does not seem to be supported by domainmapper
+        }
+    }
+#if 0
+    virtual void lbrace()
+    {
+    }
+#endif
+    virtual void rbrace()
+    {
+        GetHandler().SetColorTable(m_ColorTable);
+    }
+    virtual void HandleString (::rtl::OStringBuffer  & rBuf)
+    {
+        // terminator
+        if (0 <= rBuf.makeStringAndClear().indexOf(sal_Unicode(';')))
+        {
+            sal_uInt32 const color(m_Entry.m_Red
+                                | (m_Entry.m_Green <<  8)
+                                | (m_Entry.m_Blue  << 16) );
+            m_ColorTable.push_back(color);
+            m_Entry = Entry(); // reset
+        }
+    }
+    virtual void HandleStringU(::rtl::OUStringBuffer & /*rBuf*/)
+    {
+    }
+
+private:
+    ColorTable_t m_ColorTable;
+    struct Entry {
+        sal_uInt8 m_Red;
+        sal_uInt8 m_Green;
+        sal_uInt8 m_Blue;
+        explicit Entry()
+            : m_Red(0)
+            , m_Green(0)
+            , m_Blue(0)
+        { }
+    } m_Entry;
+};
+
+
+
 class RTFDestinationRTF
     : public RTFDestination
 {
@@ -699,6 +787,11 @@
 fprintf(stderr, "create RTFDestinationFontTable\n");
                 return Pointer_t(new RTFDestinationFontTable(GetHandler()));
             }
+            case RTF_colortbl:
+            {
+fprintf(stderr, "create RTFDestinationColorTable\n");
+                return Pointer_t(new RTFDestinationColorTable(GetHandler()));
+            }
             default:
             {
                 return RTFDestination::dest(token, value);
diff --git a/writerfilter/source/rtftok/rtfactions.xml b/writerfilter/source/rtftok/rtfactions.xml
--- a/writerfilter/source/rtftok/rtfactions.xml
+++ b/writerfilter/source/rtftok/rtfactions.xml
@@ -10,9 +10,9 @@
     <ref name="animtext" tokenid="sprm:CSfxText"/>
     <ref name="b" tokenid="sprm:CFBold"/>
     <ref name="caps" tokenid="sprm:CFCaps"/>
-    <!--    <ref name="cb" tokenid="sprm:CHighlight"/>-->
+    <ref name="cb" tokenid="sprm:CHighlight"/> <!--domainmapper hardcoded tbl-->
     <!-- <ref name="cchs"/>     hopefully this crap is never used anyway -->
-    <!--    <ref name="cf" tokenid="sprm:CIco"/>-->
+    <ref name="cf" tokenid="sprm:CIco"/> <!--domainmapper hardcoded tbl-->
     <ref name="charscalex" tokenid="sprm:CCharScale"/>
     <!--    <ref name="cs" tokenid=""/>-->
     <!--    <ref name="cgrid"/>-->
@@ -46,7 +46,7 @@
     <ref name="sub" tokenid="sprm:CIss" value="2"/>
     <ref name="super" tokenid="sprm:CIss" value="1"/>
     <ref name="ul" tokenid="sprm:CKul" nonzero-value="1"/>
-    <!--    <ref name="ulc" tokenid="0x6877"/>-->
+    <ref name="ulc" tokenid="0x6877" colortablelookup="true"/>
     <ref name="uld" tokenid="sprm:CKul" value="4"/> <!-- why flag??? -->
     <ref name="uldash" tokenid="sprm:CKul" nonzero-value="7"/>
     <ref name="uldashd" tokenid="sprm:CKul" nonzero-value="9"/>
diff --git a/writerfilter/source/rtftok/rtfcontrols.xsl b/writerfilter/source/rtftok/rtfcontrols.xsl
--- a/writerfilter/source/rtftok/rtfcontrols.xsl
+++ b/writerfilter/source/rtftok/rtfcontrols.xsl
@@ -83,6 +83,9 @@
               <xsl:text>NS_sprm::LN_</xsl:text>
               <xsl:value-of select="substring(@tokenid, 6)"/>
             </xsl:when>
+            <xsl:when test="starts-with(@tokenid, '0x')">
+              <xsl:value-of select="@tokenid"/>
+            </xsl:when>
         </xsl:choose>
       </xsl:variable>
       <xsl:text>case RTF_</xsl:text>
@@ -126,7 +129,15 @@
           </xsl:when>
           <xsl:when test="$type='value'">
             <xsl:text>sal_Int32 const n( ('\0' == *value) ? 0 : ::rtl::OString(value).toInt32() );&#xA;</xsl:text>
-            <xsl:text>RTFValue::Pointer_t const pValue(new RTFValueInt(n));&#xA;</xsl:text>
+            <xsl:choose>
+              <xsl:when test="@colortablelookup">
+                <xsl:text>sal_uInt32 const color(rDestination.GetColorTableEntry(n));&#xA;</xsl:text>
+                <xsl:text>RTFValue::Pointer_t const pValue(new RTFValueInt(color));&#xA;</xsl:text>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:text>RTFValue::Pointer_t const pValue(new RTFValueInt(n));&#xA;</xsl:text>
+              </xsl:otherwise>
+            </xsl:choose>
           </xsl:when>
           <xsl:otherwise>
             <xsl:text>#error token: </xsl:text>
@@ -137,7 +148,7 @@
           </xsl:otherwise>
         </xsl:choose>
         <xsl:choose>
-          <xsl:when test="starts-with(@tokenid, 'sprm')">
+          <xsl:when test="starts-with(@tokenid, 'sprm') or starts-with(@tokenid, '0x')">
             <xsl:text>rDestination.SetSprm(</xsl:text>
             <xsl:value-of select="$token"/>
             <xsl:text>, pValue);&#xA;</xsl:text>
