1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <drawingml/textcharacterpropertiescontext.hxx>
21 
22 #include <oox/helper/attributelist.hxx>
23 #include <oox/drawingml/drawingmltypes.hxx>
24 #include <drawingml/colorchoicecontext.hxx>
25 #include <drawingml/texteffectscontext.hxx>
26 #include <drawingml/lineproperties.hxx>
27 #include <drawingml/textparagraphproperties.hxx>
28 #include <oox/core/relations.hxx>
29 #include "hyperlinkcontext.hxx"
30 #include <oox/token/namespaces.hxx>
31 #include <oox/token/tokens.hxx>
32 
33 #include <sal/log.hxx>
34 
35 using namespace ::oox::core;
36 using namespace ::com::sun::star::uno;
37 using namespace ::com::sun::star::xml::sax;
38 using namespace ::com::sun::star::awt;
39 
40 namespace oox { namespace drawingml {
41 
42 // CT_TextCharacterProperties
TextCharacterPropertiesContext(ContextHandler2Helper const & rParent,const AttributeList & rAttribs,TextCharacterProperties & rTextCharacterProperties)43 TextCharacterPropertiesContext::TextCharacterPropertiesContext(
44         ContextHandler2Helper const & rParent,
45         const AttributeList& rAttribs,
46         TextCharacterProperties& rTextCharacterProperties )
47 : ContextHandler2( rParent )
48 , mrTextCharacterProperties( rTextCharacterProperties )
49 {
50     if ( rAttribs.hasAttribute( XML_lang ) )
51         mrTextCharacterProperties.moLang = rAttribs.getString( XML_lang );
52     if ( rAttribs.hasAttribute( XML_sz ) )
53         mrTextCharacterProperties.moHeight = rAttribs.getInteger( XML_sz );
54     if ( rAttribs.hasAttribute( XML_spc ) )
55         mrTextCharacterProperties.moSpacing = rAttribs.getInteger( XML_spc );
56     if ( rAttribs.hasAttribute( XML_u ) )
57         mrTextCharacterProperties.moUnderline = rAttribs.getToken( XML_u );
58     if ( rAttribs.hasAttribute( XML_strike ) )
59         mrTextCharacterProperties.moStrikeout = rAttribs.getToken( XML_strike );
60     if ( rAttribs.hasAttribute( XML_baseline ) && rAttribs.getInteger( XML_baseline ).get() != 0 )
61         mrTextCharacterProperties.moBaseline = rAttribs.getInteger( XML_baseline );
62 
63     if ( rAttribs.hasAttribute( XML_b ) )
64         mrTextCharacterProperties.moBold = rAttribs.getBool( XML_b );
65     if ( rAttribs.hasAttribute( XML_i ) )
66         mrTextCharacterProperties.moItalic = rAttribs.getBool( XML_i );
67     if( rAttribs.hasAttribute( XML_cap ) )
68         mrTextCharacterProperties.moCaseMap = rAttribs.getToken( XML_cap );
69 
70     /* TODO / unhandled so far:
71        A_TOKEN( kern )
72        XML_altLang
73        A_TOKEN( kumimoji )
74        A_TOKEN( spc )
75        A_TOKEN( normalizeH )
76        A_TOKEN( noProof )
77        A_TOKEN( dirty )
78        A_TOKEN( err )
79        A_TOKEN( smtClean )
80        A_TOKEN( smtId )
81     */
82 }
83 
~TextCharacterPropertiesContext()84 TextCharacterPropertiesContext::~TextCharacterPropertiesContext()
85 {
86 }
87 
onCreateContext(sal_Int32 aElementToken,const AttributeList & rAttribs)88 ContextHandlerRef TextCharacterPropertiesContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
89 {
90     switch( aElementToken )
91     {
92 // TODO unsupported yet
93 //        case A_TOKEN( ln ):         // CT_LineProperties
94 //            return new LinePropertiesContext( getHandler(), rAttribs, maTextOutlineProperties );
95         // EG_FillProperties
96         case A_TOKEN( noFill ):
97         case A_TOKEN( solidFill ):
98         case A_TOKEN( gradFill ):
99         case A_TOKEN( pattFill ):
100             return FillPropertiesContext::createFillContext( *this, aElementToken, rAttribs, mrTextCharacterProperties.maFillProperties );
101         // EG_EffectProperties
102         case A_TOKEN( effectDag ):  // CT_EffectContainer 5.1.10.25
103         case A_TOKEN( effectLst ):  // CT_EffectList 5.1.10.26
104         break;
105 
106         case A_TOKEN( highlight ):  // CT_Color
107             return new ColorContext( *this, mrTextCharacterProperties.maHighlightColor );
108 
109         // EG_TextUnderlineLine
110         case A_TOKEN( uLnTx ):      // CT_TextUnderlineLineFollowText
111             mrTextCharacterProperties.moUnderlineLineFollowText = true;
112         break;
113 // TODO unsupported yet
114 //        case A_TOKEN( uLn ):        // CT_LineProperties
115 //            return new LinePropertiesContext( getHandler(), rAttribs, maUnderlineProperties );
116 
117         // EG_TextUnderlineFill
118         case A_TOKEN( uFillTx ):    // CT_TextUnderlineFillFollowText
119             mrTextCharacterProperties.moUnderlineFillFollowText = true;
120         break;
121         case A_TOKEN( uFill ):      // CT_TextUnderlineFillGroupWrapper->EG_FillProperties (not supported)
122             return new SimpleFillPropertiesContext( *this, mrTextCharacterProperties.maUnderlineColor );
123 
124         // CT_FontCollection
125         case A_TOKEN( latin ):      // CT_TextFont
126             mrTextCharacterProperties.maLatinFont.setAttributes( rAttribs );
127         break;
128         case A_TOKEN( ea ):         // CT_TextFont
129             mrTextCharacterProperties.maAsianFont.setAttributes( rAttribs );
130         break;
131         case A_TOKEN( cs ):         // CT_TextFont
132             mrTextCharacterProperties.maComplexFont.setAttributes( rAttribs );
133         break;
134         case A_TOKEN( sym ):        // CT_TextFont
135             mrTextCharacterProperties.maSymbolFont.setAttributes( rAttribs );
136         break;
137 
138         case A_TOKEN( hlinkClick ):     // CT_Hyperlink
139         case A_TOKEN( hlinkMouseOver ): // CT_Hyperlink
140             return new HyperLinkContext( *this, rAttribs,  mrTextCharacterProperties.maHyperlinkPropertyMap );
141         case W_TOKEN( rFonts ):
142             if( rAttribs.hasAttribute(W_TOKEN(ascii)) )
143             {
144                 mrTextCharacterProperties.maLatinFont.setAttributes(rAttribs.getString(W_TOKEN(ascii), OUString()));
145             }
146             if (rAttribs.hasAttribute(W_TOKEN(asciiTheme)))
147             {
148                 mrTextCharacterProperties.maLatinThemeFont.setAttributes(rAttribs.getString(W_TOKEN(asciiTheme), OUString()));
149             }
150             if( rAttribs.hasAttribute(W_TOKEN(cs)) )
151             {
152                 mrTextCharacterProperties.maComplexFont.setAttributes(rAttribs.getString(W_TOKEN(cs), OUString()));
153             }
154             if (rAttribs.hasAttribute(W_TOKEN(cstheme)))
155             {
156                 mrTextCharacterProperties.maComplexThemeFont.setAttributes(rAttribs.getString(W_TOKEN(cstheme), OUString()));
157             }
158             if( rAttribs.hasAttribute(W_TOKEN(eastAsia)) )
159             {
160                 mrTextCharacterProperties.maAsianFont.setAttributes(rAttribs.getString(W_TOKEN(eastAsia), OUString()));
161             }
162             if (rAttribs.hasAttribute(W_TOKEN(eastAsiaTheme)))
163             {
164                 mrTextCharacterProperties.maAsianThemeFont.setAttributes(rAttribs.getString(W_TOKEN(eastAsiaTheme), OUString()));
165             }
166             break;
167         case W_TOKEN( b ):
168             mrTextCharacterProperties.moBold = rAttribs.getBool(W_TOKEN( val ), true);
169             break;
170         case W_TOKEN( i ):
171             mrTextCharacterProperties.moItalic = rAttribs.getBool(W_TOKEN( val ), true);
172             break;
173         case W_TOKEN( bCs ):
174             break;
175         case W_TOKEN( color ):
176             if (rAttribs.getInteger(W_TOKEN(val)).has())
177             {
178                 mrTextCharacterProperties.maFillProperties.maFillColor.setSrgbClr(rAttribs.getIntegerHex(W_TOKEN(val)).get());
179                 mrTextCharacterProperties.maFillProperties.moFillType.set(XML_solidFill);
180             }
181             break;
182         case W_TOKEN(  sz ):
183             if (rAttribs.getInteger(W_TOKEN(val)).has())
184             {
185                 sal_Int32 nVal = rAttribs.getInteger(W_TOKEN(val)).get();
186                 // wml has half points, dml has hundred points
187                 mrTextCharacterProperties.moHeight = nVal * 50;
188             }
189             break;
190         case W_TOKEN( szCs ):
191             break;
192         case W_TOKEN( caps ):
193             {
194                 if( rAttribs.getBool(W_TOKEN( val ), true) )
195                     mrTextCharacterProperties.moCaseMap = XML_all;
196                 else
197                     mrTextCharacterProperties.moCaseMap = XML_none;
198             }
199             break;
200         case W_TOKEN( smallCaps ):
201             {
202                 if( rAttribs.getBool(W_TOKEN( val ), true) )
203                     mrTextCharacterProperties.moCaseMap = XML_small;
204                 else
205                     mrTextCharacterProperties.moCaseMap = XML_none;
206             }
207             break;
208         case W_TOKEN(vertAlign):
209         {
210             // Map wordprocessingML <w:vertAlign w:val="..."/> to drawingML
211             // <a:rPr baseline="...">.
212             sal_Int32 nVal = rAttribs.getToken(W_TOKEN(val), 0);
213             if (nVal == XML_superscript)
214                 mrTextCharacterProperties.moBaseline = 30000;
215             else if (nVal == XML_subscript)
216                 mrTextCharacterProperties.moBaseline = -25000;
217             break;
218         }
219         case OOX_TOKEN(w14, glow):
220         case OOX_TOKEN(w14, shadow):
221         case OOX_TOKEN(w14, reflection):
222         case OOX_TOKEN(w14, textOutline):
223         case OOX_TOKEN(w14, textFill):
224         case OOX_TOKEN(w14, scene3d):
225         case OOX_TOKEN(w14, props3d):
226         case OOX_TOKEN(w14, ligatures):
227         case OOX_TOKEN(w14, numForm):
228         case OOX_TOKEN(w14, numSpacing):
229         case OOX_TOKEN(w14, stylisticSets):
230         case OOX_TOKEN(w14, cntxtAlts):
231             {
232                 return new TextEffectsContext( *this, aElementToken, mrTextCharacterProperties.maTextEffectsProperties );
233             }
234             break;
235         default:
236             SAL_WARN("oox", "TextCharacterPropertiesContext::onCreateContext: unhandled element: " << getBaseToken(aElementToken));
237             break;
238     }
239 
240     return this;
241 }
242 
243 } }
244 
245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
246