fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / oox / source / vml / vmltextboxcontext.cxx
blob3cd88a38ddec4bb17bf213db4a22c8004fc36f2e
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>
25 namespace oox {
26 namespace vml {
28 // ============================================================================
30 using ::oox::core::ContextHandler2;
31 using ::oox::core::ContextHandler2Helper;
32 using ::oox::core::ContextHandlerRef;
34 // ============================================================================
36 TextPortionContext::TextPortionContext( ContextHandler2Helper& rParent,
37 TextBox& rTextBox, TextParagraphModel& rParagraph, const TextFontModel& rParentFont,
38 sal_Int32 nElement, const AttributeList& rAttribs ) :
39 ContextHandler2( rParent ),
40 mrTextBox( rTextBox ),
41 maParagraph( rParagraph ),
42 maFont( rParentFont ),
43 mnInitialPortions( rTextBox.getPortionCount() )
45 switch( nElement )
47 case XML_font:
48 maFont.moName = rAttribs.getXString( XML_face );
49 maFont.moColor = rAttribs.getXString( XML_color );
50 maFont.monSize = rAttribs.getInteger( XML_size );
51 break;
52 case XML_u:
53 OSL_ENSURE( !maFont.monUnderline, "TextPortionContext::TextPortionContext - nested <u> elements" );
54 maFont.monUnderline = (rAttribs.getToken( XML_class, XML_TOKEN_INVALID ) == XML_font4) ? XML_double : XML_single;
55 break;
56 case XML_sub:
57 case XML_sup:
58 OSL_ENSURE( !maFont.monEscapement, "TextPortionContext::TextPortionContext - nested <sub> or <sup> elements" );
59 maFont.monEscapement = nElement;
60 break;
61 case XML_b:
62 OSL_ENSURE( !maFont.mobBold, "TextPortionContext::TextPortionContext - nested <b> elements" );
63 maFont.mobBold = true;
64 break;
65 case XML_i:
66 OSL_ENSURE( !maFont.mobItalic, "TextPortionContext::TextPortionContext - nested <i> elements" );
67 maFont.mobItalic = true;
68 break;
69 case XML_s:
70 OSL_ENSURE( !maFont.mobStrikeout, "TextPortionContext::TextPortionContext - nested <s> elements" );
71 maFont.mobStrikeout = true;
72 break;
73 case OOX_TOKEN(dml, blip):
75 OptValue<OUString> oRelId = rAttribs.getString(R_TOKEN(embed));
76 if (oRelId.has())
77 mrTextBox.mrTypeModel.moGraphicPath = getFragmentPathFromRelId(oRelId.get());
79 break;
80 case VML_TOKEN(imagedata):
82 OptValue<OUString> oRelId = rAttribs.getString(R_TOKEN(id));
83 if (oRelId.has())
84 mrTextBox.mrTypeModel.moGraphicPath = getFragmentPathFromRelId(oRelId.get());
86 break;
87 case XML_span:
88 case OOX_TOKEN(doc, r):
89 break;
90 default:
91 OSL_ENSURE( false, "TextPortionContext::TextPortionContext - unknown element" );
95 ContextHandlerRef TextPortionContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
97 OSL_ENSURE( nElement != XML_font, "TextPortionContext::onCreateContext - nested <font> elements" );
98 if (getNamespace(getCurrentElement()) == NMSP_doc)
99 return this;
100 return new TextPortionContext( *this, mrTextBox, maParagraph, maFont, nElement, rAttribs );
103 void TextPortionContext::onCharacters( const OUString& rChars )
105 if (getNamespace(getCurrentElement()) == NMSP_doc && getCurrentElement() != OOX_TOKEN(doc, t))
106 return;
108 switch( getCurrentElement() )
110 case XML_span:
111 // replace all NBSP characters with SP
112 mrTextBox.appendPortion( maParagraph, maFont, rChars.replace( 0xA0, ' ' ) );
113 break;
114 default:
115 mrTextBox.appendPortion( maParagraph, maFont, rChars );
119 void TextPortionContext::onStartElement(const AttributeList& rAttribs)
121 switch (getCurrentElement())
123 case OOX_TOKEN(doc, b):
124 maFont.mobBold = true;
125 break;
126 case OOX_TOKEN(doc, sz):
127 maFont.monSize = rAttribs.getInteger( OOX_TOKEN(doc, val) );
128 break;
129 case OOX_TOKEN(doc, br):
130 mrTextBox.appendPortion( maParagraph, maFont, "\n" );
131 break;
132 case OOX_TOKEN(doc, color):
133 maFont.moColor = rAttribs.getString( OOX_TOKEN(doc, val) );
134 break;
135 case OOX_TOKEN(doc, spacing):
136 maFont.monSpacing = rAttribs.getInteger(OOX_TOKEN(doc, val));
137 break;
138 case OOX_TOKEN(doc, r):
139 case OOX_TOKEN(doc, rPr):
140 case OOX_TOKEN(doc, t):
141 break;
142 default:
143 SAL_INFO("oox", "unhandled: 0x" << std::hex<< getCurrentElement());
144 break;
148 void TextPortionContext::onEndElement()
150 if (getNamespace(getCurrentElement()) == NMSP_doc && getCurrentElement() != OOX_TOKEN(doc, t))
151 return;
153 /* A child element without own child elements may contain a single space
154 character, for example:
156 <div>
157 <font><i>abc</i></font>
158 <font> </font>
159 <font><b>def</b></font>
160 </div>
162 represents the italic text 'abc', an unformatted space character, and
163 the bold text 'def'. Unfortunately, the XML parser skips the space
164 character without issuing a 'characters' event. The class member
165 'mnInitialPortions' contains the number of text portions existing when
166 this context has been constructed. If no text has been added in the
167 meantime, the space character has to be added manually.
169 if( mrTextBox.getPortionCount() == mnInitialPortions )
170 mrTextBox.appendPortion( maParagraph, maFont, OUString( sal_Unicode( ' ' ) ) );
173 // ============================================================================
175 TextBoxContext::TextBoxContext( ContextHandler2Helper& rParent, TextBox& rTextBox, const AttributeList& rAttribs,
176 const GraphicHelper& graphicHelper ) :
177 ContextHandler2( rParent ),
178 mrTextBox( rTextBox )
180 if( rAttribs.getString( XML_insetmode ).get() != "auto" )
182 OUString inset = rAttribs.getString( XML_inset ).get();
183 OUString value;
184 ConversionHelper::separatePair( value, inset, inset, ',' );
185 rTextBox.borderDistanceLeft = ConversionHelper::decodeMeasureToHmm( graphicHelper,
186 value.isEmpty() ? "0.1in" : value, 0, false, false );
187 ConversionHelper::separatePair( value, inset, inset, ',' );
188 rTextBox.borderDistanceTop = ConversionHelper::decodeMeasureToHmm( graphicHelper,
189 value.isEmpty() ? "0.05in" : value, 0, false, false );
190 ConversionHelper::separatePair( value, inset, inset, ',' );
191 rTextBox.borderDistanceRight = ConversionHelper::decodeMeasureToHmm( graphicHelper,
192 value.isEmpty() ? "0.1in" : value, 0, false, false );
193 ConversionHelper::separatePair( value, inset, inset, ',' );
194 rTextBox.borderDistanceBottom = ConversionHelper::decodeMeasureToHmm( graphicHelper,
195 value.isEmpty() ? "0.05in" : value, 0, false, false );
196 rTextBox.borderDistanceSet = true;
199 OUString sStyle = rAttribs.getString( XML_style, OUString() );
200 sal_Int32 nIndex = 0;
201 while( nIndex >= 0 )
203 OUString aName, aValue;
204 if( ConversionHelper::separatePair( aName, aValue, sStyle.getToken( 0, ';', nIndex ), ':' ) )
206 if( aName == "layout-flow" ) rTextBox.maLayoutFlow = aValue;
207 else if (aName == "mso-fit-shape-to-text")
208 rTextBox.mrTypeModel.mbAutoHeight = true;
209 else
210 SAL_WARN("oox", "unhandled style property: " << aName);
215 ContextHandlerRef TextBoxContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
217 switch( getCurrentElement() )
219 case VML_TOKEN( textbox ):
220 if( nElement == XML_div ) return this;
221 else if (nElement == OOX_TOKEN(doc, txbxContent)) return this;
222 break;
223 case XML_div:
224 if( nElement == XML_font ) return new TextPortionContext( *this, mrTextBox, maParagraph, TextFontModel(), nElement, rAttribs );
225 break;
226 case OOX_TOKEN(doc, txbxContent):
227 if (nElement == OOX_TOKEN(doc, p)) return this;
228 break;
229 case OOX_TOKEN(doc, p):
230 case OOX_TOKEN(doc, sdtContent):
231 if (nElement == OOX_TOKEN(doc, r))
232 return new TextPortionContext( *this, mrTextBox, maParagraph, TextFontModel(), nElement, rAttribs );
233 else
234 return this;
235 break;
236 case OOX_TOKEN(doc, pPr):
237 case OOX_TOKEN(doc, sdt):
238 return this;
239 break;
240 default:
241 SAL_INFO("oox", "unhandled 0x" << std::hex << getCurrentElement());
242 break;
244 return 0;
247 void TextBoxContext::onStartElement(const AttributeList& rAttribs)
249 switch (getCurrentElement())
251 case OOX_TOKEN(doc, jc):
252 maParagraph.moParaAdjust = rAttribs.getString( OOX_TOKEN(doc, val) );
253 break;
257 void TextBoxContext::onEndElement()
259 if (getCurrentElement() == OOX_TOKEN(doc, p))
261 mrTextBox.appendPortion( maParagraph, TextFontModel(), "\n" );
262 maParagraph = TextParagraphModel();
266 // ============================================================================
268 } // namespace vml
269 } // namespace oox
271 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */