fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / oox / source / vml / vmltextboxcontext.cxx
blobd1a8b1256d74b490f4c050f39353cbc83fe4e5ae
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "oox/vml/vmlformatting.hxx"
21 #include "oox/vml/vmltextboxcontext.hxx"
22 #include "oox/vml/vmlshape.hxx"
23 #include <com/sun/star/drawing/XShape.hpp>
24 #include <osl/diagnose.h>
26 namespace oox {
27 namespace vml {
29 using ::oox::core::ContextHandler2;
30 using ::oox::core::ContextHandler2Helper;
31 using ::oox::core::ContextHandlerRef;
33 TextPortionContext::TextPortionContext( ContextHandler2Helper& rParent,
34 TextBox& rTextBox, TextParagraphModel& rParagraph, const TextFontModel& rParentFont,
35 sal_Int32 nElement, const AttributeList& rAttribs ) :
36 ContextHandler2( rParent ),
37 mrTextBox( rTextBox ),
38 maParagraph( rParagraph ),
39 maFont( rParentFont ),
40 mnInitialPortions( rTextBox.getPortionCount() )
42 switch( nElement )
44 case XML_font:
45 maFont.moName = rAttribs.getXString( XML_face );
46 maFont.moColor = rAttribs.getXString( XML_color );
47 maFont.monSize = rAttribs.getInteger( XML_size );
48 break;
49 case XML_u:
50 OSL_ENSURE( !maFont.monUnderline, "TextPortionContext::TextPortionContext - nested <u> elements" );
51 maFont.monUnderline = (rAttribs.getToken( XML_class, XML_TOKEN_INVALID ) == XML_font4) ? XML_double : XML_single;
52 break;
53 case XML_sub:
54 case XML_sup:
55 OSL_ENSURE( !maFont.monEscapement, "TextPortionContext::TextPortionContext - nested <sub> or <sup> elements" );
56 maFont.monEscapement = nElement;
57 break;
58 case XML_b:
59 OSL_ENSURE( !maFont.mobBold, "TextPortionContext::TextPortionContext - nested <b> elements" );
60 maFont.mobBold = true;
61 break;
62 case XML_i:
63 OSL_ENSURE( !maFont.mobItalic, "TextPortionContext::TextPortionContext - nested <i> elements" );
64 maFont.mobItalic = true;
65 break;
66 case XML_s:
67 OSL_ENSURE( !maFont.mobStrikeout, "TextPortionContext::TextPortionContext - nested <s> elements" );
68 maFont.mobStrikeout = true;
69 break;
70 case OOX_TOKEN(dml, blip):
72 OptValue<OUString> oRelId = rAttribs.getString(R_TOKEN(embed));
73 if (oRelId.has())
74 mrTextBox.mrTypeModel.moGraphicPath = getFragmentPathFromRelId(oRelId.get());
76 break;
77 case VML_TOKEN(imagedata):
79 OptValue<OUString> oRelId = rAttribs.getString(R_TOKEN(id));
80 if (oRelId.has())
81 mrTextBox.mrTypeModel.moGraphicPath = getFragmentPathFromRelId(oRelId.get());
83 break;
84 case XML_span:
85 case W_TOKEN(r):
86 break;
87 default:
88 OSL_ENSURE( false, "TextPortionContext::TextPortionContext - unknown element" );
92 ContextHandlerRef TextPortionContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
94 OSL_ENSURE( nElement != XML_font, "TextPortionContext::onCreateContext - nested <font> elements" );
95 if (getNamespace(getCurrentElement()) == NMSP_doc)
96 return this;
97 return new TextPortionContext( *this, mrTextBox, maParagraph, maFont, nElement, rAttribs );
100 void TextPortionContext::onCharacters( const OUString& rChars )
102 if (getNamespace(getCurrentElement()) == NMSP_doc && getCurrentElement() != W_TOKEN(t))
103 return;
105 switch( getCurrentElement() )
107 case XML_span:
108 // replace all NBSP characters with SP
109 mrTextBox.appendPortion( maParagraph, maFont, rChars.replace( 0xA0, ' ' ) );
110 break;
111 default:
112 mrTextBox.appendPortion( maParagraph, maFont, rChars );
116 void TextPortionContext::onStartElement(const AttributeList& rAttribs)
118 switch (getCurrentElement())
120 case W_TOKEN(b):
121 maFont.mobBold = true;
122 break;
123 case W_TOKEN(sz):
124 maFont.monSize = rAttribs.getInteger( W_TOKEN(val) );
125 break;
126 case W_TOKEN(br):
127 mrTextBox.appendPortion( maParagraph, maFont, "\n" );
128 break;
129 case W_TOKEN(color):
130 maFont.moColor = rAttribs.getString( W_TOKEN(val) );
131 break;
132 case W_TOKEN(spacing):
133 maFont.monSpacing = rAttribs.getInteger(W_TOKEN(val));
134 break;
135 case W_TOKEN(r):
136 case W_TOKEN(rPr):
137 case W_TOKEN(t):
138 break;
139 default:
140 SAL_INFO("oox", "unhandled: 0x" << std::hex<< getCurrentElement());
141 break;
145 void TextPortionContext::onEndElement()
147 if (getNamespace(getCurrentElement()) == NMSP_doc && getCurrentElement() != W_TOKEN(t))
148 return;
150 /* A child element without own child elements may contain a single space
151 character, for example:
153 <div>
154 <font><i>abc</i></font>
155 <font> </font>
156 <font><b>def</b></font>
157 </div>
159 represents the italic text 'abc', an unformatted space character, and
160 the bold text 'def'. Unfortunately, the XML parser skips the space
161 character without issuing a 'characters' event. The class member
162 'mnInitialPortions' contains the number of text portions existing when
163 this context has been constructed. If no text has been added in the
164 meantime, the space character has to be added manually.
166 if( mrTextBox.getPortionCount() == mnInitialPortions )
167 mrTextBox.appendPortion( maParagraph, maFont, OUString( ' ' ) );
170 TextBoxContext::TextBoxContext( ContextHandler2Helper& rParent, TextBox& rTextBox, const AttributeList& rAttribs,
171 const GraphicHelper& graphicHelper ) :
172 ContextHandler2( rParent ),
173 mrTextBox( rTextBox )
175 if( rAttribs.getString( XML_insetmode ).get() != "auto" )
177 OUString inset = rAttribs.getString( XML_inset ).get();
178 OUString value;
179 OUString remainingStr;
181 ConversionHelper::separatePair( value, remainingStr, inset, ',' );
182 rTextBox.borderDistanceLeft = ConversionHelper::decodeMeasureToHmm( graphicHelper,
183 value.isEmpty() ? "0.1in" : value, 0, false, false );
185 inset = remainingStr;
186 ConversionHelper::separatePair( value, remainingStr, inset, ',' );
187 rTextBox.borderDistanceTop = ConversionHelper::decodeMeasureToHmm( graphicHelper,
188 value.isEmpty() ? "0.05in" : value, 0, false, false );
190 inset = remainingStr;
191 ConversionHelper::separatePair( value, remainingStr, inset, ',' );
192 rTextBox.borderDistanceRight = ConversionHelper::decodeMeasureToHmm( graphicHelper,
193 value.isEmpty() ? "0.1in" : value, 0, false, false );
195 inset = remainingStr;
196 ConversionHelper::separatePair( value, remainingStr, inset, ',' );
197 rTextBox.borderDistanceBottom = ConversionHelper::decodeMeasureToHmm( graphicHelper,
198 value.isEmpty() ? "0.05in" : value, 0, false, false );
200 rTextBox.borderDistanceSet = true;
203 OUString sStyle = rAttribs.getString( XML_style, OUString() );
204 sal_Int32 nIndex = 0;
205 while( nIndex >= 0 )
207 OUString aName, aValue;
208 if( ConversionHelper::separatePair( aName, aValue, sStyle.getToken( 0, ';', nIndex ), ':' ) )
210 if( aName == "layout-flow" ) rTextBox.maLayoutFlow = aValue;
211 else if (aName == "mso-fit-shape-to-text")
212 rTextBox.mrTypeModel.mbAutoHeight = true;
213 else if (aName == "mso-layout-flow-alt")
214 rTextBox.mrTypeModel.maLayoutFlowAlt = aValue;
215 else if (aName == "mso-next-textbox")
216 rTextBox.msNextTextbox = aValue;
217 else
218 SAL_WARN("oox", "unhandled style property: " << aName);
223 ContextHandlerRef TextBoxContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
225 switch( getCurrentElement() )
227 case VML_TOKEN( textbox ):
228 if( nElement == XML_div ) return this;
229 else if (nElement == W_TOKEN(txbxContent)) return this;
230 break;
231 case XML_div:
232 if( nElement == XML_font ) return new TextPortionContext( *this, mrTextBox, maParagraph, TextFontModel(), nElement, rAttribs );
233 break;
234 case W_TOKEN(txbxContent):
235 if (nElement == W_TOKEN(p)) return this;
236 break;
237 case W_TOKEN(p):
238 case W_TOKEN(sdtContent):
239 case W_TOKEN(smartTag):
240 if (nElement == W_TOKEN(r))
241 return new TextPortionContext( *this, mrTextBox, maParagraph, TextFontModel(), nElement, rAttribs );
242 else
243 return this;
244 break;
245 case W_TOKEN(pPr):
246 case W_TOKEN(sdt):
247 return this;
248 break;
249 default:
250 SAL_INFO("oox", "unhandled 0x" << std::hex << getCurrentElement());
251 break;
253 return 0;
256 void TextBoxContext::onStartElement(const AttributeList& rAttribs)
258 switch (getCurrentElement())
260 case W_TOKEN(jc):
261 maParagraph.moParaAdjust = rAttribs.getString( W_TOKEN(val) );
262 break;
266 void TextBoxContext::onEndElement()
268 if (getCurrentElement() == W_TOKEN(p))
270 mrTextBox.appendPortion( maParagraph, TextFontModel(), "\n" );
271 maParagraph = TextParagraphModel();
275 } // namespace vml
276 } // namespace oox
278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */