LibreOffice Module xmloff (master) 1
XMLBackgroundImageContext.cxx
Go to the documentation of this file.
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
21#include <com/sun/star/io/XOutputStream.hpp>
22#include <com/sun/star/drawing/BitmapMode.hpp>
23#include <com/sun/star/graphic/XGraphic.hpp>
24
25#include <tools/debug.hxx>
26#include <sal/log.hxx>
28
29#include <xmloff/xmltkmap.hxx>
30#include <xmloff/xmluconv.hxx>
32#include <xmloff/xmltoken.hxx>
33#include <xmloff/xmlimp.hxx>
35#include <xmloff/xmlement.hxx>
38
39
40using namespace ::com::sun::star;
41using namespace ::com::sun::star::uno;
42using namespace ::com::sun::star::style;
43using namespace ::com::sun::star::io;
44using namespace ::xmloff::token;
45
47{
48 { XML_LEFT, GraphicLocation_LEFT_MIDDLE },
49 { XML_RIGHT, GraphicLocation_RIGHT_MIDDLE },
50 { XML_TOKEN_INVALID, GraphicLocation(0) }
51};
52
54{
55 { XML_TOP, GraphicLocation_MIDDLE_TOP },
56 { XML_BOTTOM, GraphicLocation_MIDDLE_BOTTOM },
57 { XML_TOKEN_INVALID, GraphicLocation(0) }
58};
59
60static void lcl_xmlbic_MergeHoriPos( GraphicLocation& ePos,
61 GraphicLocation eHori )
62{
63 DBG_ASSERT( GraphicLocation_LEFT_MIDDLE==eHori ||
64 GraphicLocation_MIDDLE_MIDDLE==eHori ||
65 GraphicLocation_RIGHT_MIDDLE==eHori,
66 "lcl_xmlbic_MergeHoriPos: vertical pos must be middle" );
67
68 switch( ePos )
69 {
70 case GraphicLocation_LEFT_TOP:
71 case GraphicLocation_MIDDLE_TOP:
72 case GraphicLocation_RIGHT_TOP:
73 ePos = GraphicLocation_LEFT_MIDDLE==eHori
74 ? GraphicLocation_LEFT_TOP
75 : (GraphicLocation_MIDDLE_MIDDLE==eHori
76 ? GraphicLocation_MIDDLE_TOP
77 : GraphicLocation_RIGHT_TOP);
78 break;
79
80 case GraphicLocation_LEFT_MIDDLE:
81 case GraphicLocation_MIDDLE_MIDDLE:
82 case GraphicLocation_RIGHT_MIDDLE:
83 ePos = eHori;
84 break;
85
86 case GraphicLocation_LEFT_BOTTOM:
87 case GraphicLocation_MIDDLE_BOTTOM:
88 case GraphicLocation_RIGHT_BOTTOM:
89 ePos = GraphicLocation_LEFT_MIDDLE==eHori
90 ? GraphicLocation_LEFT_BOTTOM
91 : (GraphicLocation_MIDDLE_MIDDLE==eHori
92 ? GraphicLocation_MIDDLE_BOTTOM
93 : GraphicLocation_RIGHT_BOTTOM);
94 break;
95 default:
96 break;
97 }
98}
99
100static void lcl_xmlbic_MergeVertPos( GraphicLocation& ePos,
101 GraphicLocation eVert )
102{
103 DBG_ASSERT( GraphicLocation_MIDDLE_TOP==eVert ||
104 GraphicLocation_MIDDLE_MIDDLE==eVert ||
105 GraphicLocation_MIDDLE_BOTTOM==eVert,
106 "lcl_xmlbic_MergeVertPos: horizontal pos must be middle" );
107
108 switch( ePos )
109 {
110 case GraphicLocation_LEFT_TOP:
111 case GraphicLocation_LEFT_MIDDLE:
112 case GraphicLocation_LEFT_BOTTOM:
113 ePos = GraphicLocation_MIDDLE_TOP==eVert
114 ? GraphicLocation_LEFT_TOP
115 : (GraphicLocation_MIDDLE_MIDDLE==eVert
116 ? GraphicLocation_LEFT_MIDDLE
117 : GraphicLocation_LEFT_BOTTOM);
118 break;
119
120 case GraphicLocation_MIDDLE_TOP:
121 case GraphicLocation_MIDDLE_MIDDLE:
122 case GraphicLocation_MIDDLE_BOTTOM:
123 ePos = eVert;
124 break;
125
126 case GraphicLocation_RIGHT_TOP:
127 case GraphicLocation_RIGHT_MIDDLE:
128 case GraphicLocation_RIGHT_BOTTOM:
129 ePos = GraphicLocation_MIDDLE_TOP==eVert
130 ? GraphicLocation_RIGHT_TOP
131 : (GraphicLocation_MIDDLE_MIDDLE==eVert
132 ? GraphicLocation_RIGHT_MIDDLE
133 : GraphicLocation_RIGHT_BOTTOM);
134 break;
135 default:
136 break;
137 }
138}
139
140
142 const Reference< xml::sax::XFastAttributeList >& xAttrList )
143{
144 ePos = GraphicLocation_NONE;
145
146 for (auto &aIter : sax_fastparser::castToFastAttributeList(xAttrList))
147 {
148 switch( aIter.getToken() )
149 {
150 case XML_ELEMENT(XLINK, XML_HREF):
151 m_sURL = aIter.toString();
152 if( GraphicLocation_NONE == ePos )
153 ePos = GraphicLocation_TILED;
154 break;
155 case XML_ELEMENT(XLINK, XML_TYPE):
156 case XML_ELEMENT(XLINK, XML_ACTUATE):
157 case XML_ELEMENT(XLINK, XML_SHOW):
158 break;
160 {
161 GraphicLocation eNewPos = GraphicLocation_NONE, eTmp;
162 OUString sValue = aIter.toString();
163 SvXMLTokenEnumerator aTokenEnum( sValue );
164 std::u16string_view aToken;
165 bool bHori = false, bVert = false;
166 bool bOK = true;
167 while( bOK && aTokenEnum.getNextToken( aToken ) )
168 {
169 GraphicLocation nTmpGraphicLocation;
170 if( bHori && bVert )
171 {
172 bOK = false;
173 }
174 else if( std::u16string_view::npos != aToken.find( '%' ) )
175 {
176 sal_Int32 nPrc = 50;
177 if (::sax::Converter::convertPercent( nPrc, aToken ))
178 {
179 if( !bHori )
180 {
181 eNewPos = nPrc < 25
182 ? GraphicLocation_LEFT_TOP
183 : (nPrc < 75 ? GraphicLocation_MIDDLE_MIDDLE
184 : GraphicLocation_RIGHT_BOTTOM);
185 bHori = true;
186 }
187 else
188 {
189 eTmp = nPrc < 25
190 ? GraphicLocation_LEFT_TOP
191 : (nPrc < 75 ? GraphicLocation_LEFT_MIDDLE
192 : GraphicLocation_LEFT_BOTTOM);
193 lcl_xmlbic_MergeVertPos( eNewPos, eTmp );
194 bVert = true;
195 }
196 }
197 else
198 {
199 // wrong percentage
200 bOK = false;
201 }
202 }
203 else if( IsXMLToken( aToken, XML_CENTER ) )
204 {
205 if( bHori )
207 GraphicLocation_MIDDLE_MIDDLE );
208 else if ( bVert )
210 GraphicLocation_MIDDLE_MIDDLE );
211 else
212 eNewPos = GraphicLocation_MIDDLE_MIDDLE;
213 }
214 else if( SvXMLUnitConverter::convertEnum( nTmpGraphicLocation, aToken,
216 {
217 if( bVert )
218 lcl_xmlbic_MergeHoriPos( eNewPos, nTmpGraphicLocation );
219 else if( !bHori )
220 eNewPos = nTmpGraphicLocation;
221 else
222 bOK = false;
223 bHori = true;
224 }
225 else if( SvXMLUnitConverter::convertEnum( nTmpGraphicLocation, aToken,
227 {
228 if( bHori )
229 lcl_xmlbic_MergeVertPos( eNewPos, nTmpGraphicLocation );
230 else if( !bVert )
231 eNewPos = nTmpGraphicLocation;
232 else
233 bOK = false;
234 bVert = true;
235 }
236 else
237 {
238 bOK = false;
239 }
240 }
241
242 bOK &= GraphicLocation_NONE != eNewPos;
243 if( bOK )
244 ePos = eNewPos;
245 }
246 break;
248 {
249 GraphicLocation nPos = GraphicLocation_NONE;
251 {
252 { XML_REPEAT, GraphicLocation_TILED },
253 { XML_BACKGROUND_NO_REPEAT, GraphicLocation_MIDDLE_MIDDLE },
254 { XML_STRETCH, GraphicLocation_AREA },
255 { XML_TOKEN_INVALID, GraphicLocation(0) }
256 };
257 if( SvXMLUnitConverter::convertEnum( nPos, aIter.toView(),
259 {
260 if( GraphicLocation_MIDDLE_MIDDLE != nPos ||
261 GraphicLocation_NONE == ePos ||
262 GraphicLocation_AREA == ePos ||
263 GraphicLocation_TILED == ePos )
264 ePos = nPos;
265 }
266 }
267 break;
269 sFilter = aIter.toString();
270 break;
272 {
273 sal_Int32 nTmp;
274 // convert from percent and clip
275 if (::sax::Converter::convertPercent( nTmp, aIter.toView() ))
276 {
277 if( (nTmp >= 0) && (nTmp <= 100) )
278 nTransparency = static_cast<sal_Int8>( 100-nTmp );
279 }
280 }
281 break;
282 default:
283 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
284 }
285 }
286
287}
288
290 SvXMLImport& rImport, sal_Int32 nElement,
291 const Reference< xml::sax::XFastAttributeList > & xAttrList,
292 const XMLPropertyState& rProp,
293 sal_Int32 nPosIdx,
294 sal_Int32 nFilterIdx,
295 sal_Int32 nTransparencyIdx,
296 sal_Int32 nBitmapModeIdx,
297 ::std::vector< XMLPropertyState > &rProps ) :
298 XMLElementPropertyContext( rImport, nElement, rProp, rProps ),
299 aPosProp( nPosIdx ),
300 m_nBitmapModeIdx(nBitmapModeIdx),
301 aFilterProp( nFilterIdx ),
302 aTransparencyProp( nTransparencyIdx ),
303 nTransparency( 0 )
304{
305 ProcessAttrs( xAttrList );
306}
307
309{
310}
311
312css::uno::Reference< css::xml::sax::XFastContextHandler > XMLBackgroundImageContext::createFastChildContext(
313 sal_Int32 nElement,
314 const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/ )
315{
317 {
318 if( m_sURL.isEmpty() && !m_xBase64Stream.is() )
319 {
321 if( m_xBase64Stream.is() )
323 }
324 }
325 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
326 return nullptr;
327}
328
330{
331 uno::Reference<graphic::XGraphic> xGraphic;
332 if (!m_sURL.isEmpty())
333 {
334 xGraphic = GetImport().loadGraphicByURL(m_sURL);
335 }
336 else if (m_xBase64Stream.is())
337 {
339 m_xBase64Stream = nullptr;
340 }
341
342 if (!xGraphic.is())
343 ePos = GraphicLocation_NONE;
344 else if (GraphicLocation_NONE == ePos)
345 ePos = GraphicLocation_TILED;
346
347 if (xGraphic.is())
348 aProp.maValue <<= xGraphic;
352
353 SetInsert( true );
355
356 if( -1 != aPosProp.mnIndex )
357 {
358 // See if a FillBitmapMode property is already set, in that case
359 // BackGraphicLocation will be ignored.
360 bool bFound = false;
361 if (m_nBitmapModeIdx != -1)
362 {
363 for (XMLPropertyState& rProperty : rProperties)
364 {
365 if (rProperty.mnIndex == m_nBitmapModeIdx)
366 {
367 bFound = true;
368
369 // Found, so map the old property to the new one.
370 switch (ePos)
371 {
372 case GraphicLocation_TILED:
373 rProperty.maValue <<= drawing::BitmapMode_REPEAT;
374 break;
375 case GraphicLocation_AREA:
376 rProperty.maValue <<= drawing::BitmapMode_STRETCH;
377 break;
378 case GraphicLocation_MIDDLE_MIDDLE:
379 rProperty.maValue <<= drawing::BitmapMode_NO_REPEAT;
380 break;
381 default:
382 break;
383 }
384 break;
385 }
386 }
387 }
388 if (!bFound)
389 rProperties.push_back( aPosProp );
390 }
391 if( -1 != aFilterProp.mnIndex )
392 rProperties.push_back( aFilterProp );
393 if( -1 != aTransparencyProp.mnIndex )
394 rProperties.push_back( aTransparencyProp );
395}
396
397/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::chart::ChartAxisLabelPosition ePos
static void lcl_xmlbic_MergeHoriPos(GraphicLocation &ePos, GraphicLocation eHori)
static void lcl_xmlbic_MergeVertPos(GraphicLocation &ePos, GraphicLocation eVert)
const SvXMLEnumMapEntry< GraphicLocation > psXML_BrushVertPos[]
const SvXMLEnumMapEntry< GraphicLocation > psXML_BrushHoriPos[]
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:60
css::uno::Reference< css::io::XOutputStream > GetStreamForGraphicObjectURLFromBase64() const
Definition: xmlimp.cxx:1321
css::uno::Reference< css::graphic::XGraphic > loadGraphicFromBase64(css::uno::Reference< css::io::XOutputStream > const &rxOutputStream)
Definition: xmlimp.cxx:1309
css::uno::Reference< css::graphic::XGraphic > loadGraphicByURL(OUString const &rURL)
Definition: xmlimp.cxx:1287
bool getNextToken(std::u16string_view &rToken)
Definition: xmluconv.cxx:528
static bool convertEnum(EnumT &rEnum, std::u16string_view rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
convert string to enum using given enum map, if the enum is not found in the map, this method will re...
Definition: xmluconv.hxx:145
css::uno::Reference< css::io::XOutputStream > m_xBase64Stream
css::style::GraphicLocation ePos
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &AttrList) override
XMLBackgroundImageContext(SvXMLImport &rImport, sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, const XMLPropertyState &rProp, sal_Int32 nPosIdx, sal_Int32 nFilterIdx, sal_Int32 nTransparencyIdx, sal_Int32 nBitmapModeIdx, ::std::vector< XMLPropertyState > &rProps)
void ProcessAttrs(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
::std::vector< XMLPropertyState > & rProperties
static bool convertPercent(sal_Int32 &rValue, std::u16string_view rString)
#define DBG_ASSERT(sCon, aError)
DRAW
sal_uInt16 nPos
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
Handling of tokens in XML:
@ XML_BACKGROUND_NO_REPEAT
Definition: xmltoken.hxx:314
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
compare eToken to the string
Definition: xmltoken.cxx:3581
Smart struct to transport an Any with an index to the appropriate property-name.
Definition: maptype.hxx:141
css::uno::Any maValue
Definition: maptype.hxx:143
sal_Int32 mnIndex
Definition: maptype.hxx:142
signed char sal_Int8
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
Definition: xmlictxt.hxx:120
#define XMLOFF_WARN_UNKNOWN(area, rIter)
Definition: xmlictxt.hxx:114
#define XML_ELEMENT(prefix, name)
Definition: xmlimp.hxx:98
const struct SvXMLEnumMapEntry< SvxGraphicPosition > psXML_BrushRepeat[]