tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / xmloff / source / style / XMLBackgroundImageContext.cxx
blob686edd7ed1ed073e80d06a9e7f7c17c8c0258245
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 .
21 #include <com/sun/star/drawing/BitmapMode.hpp>
22 #include <com/sun/star/graphic/XGraphic.hpp>
24 #include <tools/debug.hxx>
25 #include <sal/log.hxx>
26 #include <sax/tools/converter.hxx>
28 #include <xmloff/xmluconv.hxx>
29 #include <xmloff/xmlnamespace.hxx>
30 #include <xmloff/xmltoken.hxx>
31 #include <xmloff/xmlimp.hxx>
32 #include <xmloff/xmlement.hxx>
33 #include <xmloff/XMLBase64ImportContext.hxx>
34 #include <XMLBackgroundImageContext.hxx>
37 using namespace ::com::sun::star;
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::style;
40 using namespace ::xmloff::token;
42 const SvXMLEnumMapEntry<GraphicLocation> psXML_BrushHoriPos[] =
44 { XML_LEFT, GraphicLocation_LEFT_MIDDLE },
45 { XML_RIGHT, GraphicLocation_RIGHT_MIDDLE },
46 { XML_TOKEN_INVALID, GraphicLocation(0) }
49 const SvXMLEnumMapEntry<GraphicLocation> psXML_BrushVertPos[] =
51 { XML_TOP, GraphicLocation_MIDDLE_TOP },
52 { XML_BOTTOM, GraphicLocation_MIDDLE_BOTTOM },
53 { XML_TOKEN_INVALID, GraphicLocation(0) }
56 static void lcl_xmlbic_MergeHoriPos( GraphicLocation& ePos,
57 GraphicLocation eHori )
59 DBG_ASSERT( GraphicLocation_LEFT_MIDDLE==eHori ||
60 GraphicLocation_MIDDLE_MIDDLE==eHori ||
61 GraphicLocation_RIGHT_MIDDLE==eHori,
62 "lcl_xmlbic_MergeHoriPos: vertical pos must be middle" );
64 switch( ePos )
66 case GraphicLocation_LEFT_TOP:
67 case GraphicLocation_MIDDLE_TOP:
68 case GraphicLocation_RIGHT_TOP:
69 ePos = GraphicLocation_LEFT_MIDDLE==eHori
70 ? GraphicLocation_LEFT_TOP
71 : (GraphicLocation_MIDDLE_MIDDLE==eHori
72 ? GraphicLocation_MIDDLE_TOP
73 : GraphicLocation_RIGHT_TOP);
74 break;
76 case GraphicLocation_LEFT_MIDDLE:
77 case GraphicLocation_MIDDLE_MIDDLE:
78 case GraphicLocation_RIGHT_MIDDLE:
79 ePos = eHori;
80 break;
82 case GraphicLocation_LEFT_BOTTOM:
83 case GraphicLocation_MIDDLE_BOTTOM:
84 case GraphicLocation_RIGHT_BOTTOM:
85 ePos = GraphicLocation_LEFT_MIDDLE==eHori
86 ? GraphicLocation_LEFT_BOTTOM
87 : (GraphicLocation_MIDDLE_MIDDLE==eHori
88 ? GraphicLocation_MIDDLE_BOTTOM
89 : GraphicLocation_RIGHT_BOTTOM);
90 break;
91 default:
92 break;
96 static void lcl_xmlbic_MergeVertPos( GraphicLocation& ePos,
97 GraphicLocation eVert )
99 DBG_ASSERT( GraphicLocation_MIDDLE_TOP==eVert ||
100 GraphicLocation_MIDDLE_MIDDLE==eVert ||
101 GraphicLocation_MIDDLE_BOTTOM==eVert,
102 "lcl_xmlbic_MergeVertPos: horizontal pos must be middle" );
104 switch( ePos )
106 case GraphicLocation_LEFT_TOP:
107 case GraphicLocation_LEFT_MIDDLE:
108 case GraphicLocation_LEFT_BOTTOM:
109 ePos = GraphicLocation_MIDDLE_TOP==eVert
110 ? GraphicLocation_LEFT_TOP
111 : (GraphicLocation_MIDDLE_MIDDLE==eVert
112 ? GraphicLocation_LEFT_MIDDLE
113 : GraphicLocation_LEFT_BOTTOM);
114 break;
116 case GraphicLocation_MIDDLE_TOP:
117 case GraphicLocation_MIDDLE_MIDDLE:
118 case GraphicLocation_MIDDLE_BOTTOM:
119 ePos = eVert;
120 break;
122 case GraphicLocation_RIGHT_TOP:
123 case GraphicLocation_RIGHT_MIDDLE:
124 case GraphicLocation_RIGHT_BOTTOM:
125 ePos = GraphicLocation_MIDDLE_TOP==eVert
126 ? GraphicLocation_RIGHT_TOP
127 : (GraphicLocation_MIDDLE_MIDDLE==eVert
128 ? GraphicLocation_RIGHT_MIDDLE
129 : GraphicLocation_RIGHT_BOTTOM);
130 break;
131 default:
132 break;
137 void XMLBackgroundImageContext::ProcessAttrs(
138 const Reference< xml::sax::XFastAttributeList >& xAttrList )
140 ePos = GraphicLocation_NONE;
142 for (auto &aIter : sax_fastparser::castToFastAttributeList(xAttrList))
144 switch( aIter.getToken() )
146 case XML_ELEMENT(XLINK, XML_HREF):
147 m_sURL = aIter.toString();
148 if( GraphicLocation_NONE == ePos )
149 ePos = GraphicLocation_TILED;
150 break;
151 case XML_ELEMENT(XLINK, XML_TYPE):
152 case XML_ELEMENT(XLINK, XML_ACTUATE):
153 case XML_ELEMENT(XLINK, XML_SHOW):
154 break;
155 case XML_ELEMENT(STYLE, XML_POSITION):
157 GraphicLocation eNewPos = GraphicLocation_NONE, eTmp;
158 OUString sValue = aIter.toString();
159 SvXMLTokenEnumerator aTokenEnum( sValue );
160 std::u16string_view aToken;
161 bool bHori = false, bVert = false;
162 bool bOK = true;
163 while( bOK && aTokenEnum.getNextToken( aToken ) )
165 GraphicLocation nTmpGraphicLocation;
166 if( bHori && bVert )
168 bOK = false;
170 else if( std::u16string_view::npos != aToken.find( '%' ) )
172 sal_Int32 nPrc = 50;
173 if (::sax::Converter::convertPercent( nPrc, aToken ))
175 if( !bHori )
177 eNewPos = nPrc < 25
178 ? GraphicLocation_LEFT_TOP
179 : (nPrc < 75 ? GraphicLocation_MIDDLE_MIDDLE
180 : GraphicLocation_RIGHT_BOTTOM);
181 bHori = true;
183 else
185 eTmp = nPrc < 25
186 ? GraphicLocation_LEFT_TOP
187 : (nPrc < 75 ? GraphicLocation_LEFT_MIDDLE
188 : GraphicLocation_LEFT_BOTTOM);
189 lcl_xmlbic_MergeVertPos( eNewPos, eTmp );
190 bVert = true;
193 else
195 // wrong percentage
196 bOK = false;
199 else if( IsXMLToken( aToken, XML_CENTER ) )
201 if( bHori )
202 lcl_xmlbic_MergeVertPos( eNewPos,
203 GraphicLocation_MIDDLE_MIDDLE );
204 else if ( bVert )
205 lcl_xmlbic_MergeHoriPos( eNewPos,
206 GraphicLocation_MIDDLE_MIDDLE );
207 else
208 eNewPos = GraphicLocation_MIDDLE_MIDDLE;
210 else if( SvXMLUnitConverter::convertEnum( nTmpGraphicLocation, aToken,
211 psXML_BrushHoriPos ) )
213 if( bVert )
214 lcl_xmlbic_MergeHoriPos( eNewPos, nTmpGraphicLocation );
215 else if( !bHori )
216 eNewPos = nTmpGraphicLocation;
217 else
218 bOK = false;
219 bHori = true;
221 else if( SvXMLUnitConverter::convertEnum( nTmpGraphicLocation, aToken,
222 psXML_BrushVertPos ) )
224 if( bHori )
225 lcl_xmlbic_MergeVertPos( eNewPos, nTmpGraphicLocation );
226 else if( !bVert )
227 eNewPos = nTmpGraphicLocation;
228 else
229 bOK = false;
230 bVert = true;
232 else
234 bOK = false;
238 bOK &= GraphicLocation_NONE != eNewPos;
239 if( bOK )
240 ePos = eNewPos;
242 break;
243 case XML_ELEMENT(STYLE, XML_REPEAT):
245 GraphicLocation nPos = GraphicLocation_NONE;
246 static const SvXMLEnumMapEntry<GraphicLocation> psXML_BrushRepeat[] =
248 { XML_REPEAT, GraphicLocation_TILED },
249 { XML_BACKGROUND_NO_REPEAT, GraphicLocation_MIDDLE_MIDDLE },
250 { XML_STRETCH, GraphicLocation_AREA },
251 { XML_TOKEN_INVALID, GraphicLocation(0) }
253 if( SvXMLUnitConverter::convertEnum( nPos, aIter.toView(),
254 psXML_BrushRepeat ) )
256 if( GraphicLocation_MIDDLE_MIDDLE != nPos ||
257 GraphicLocation_NONE == ePos ||
258 GraphicLocation_AREA == ePos ||
259 GraphicLocation_TILED == ePos )
260 ePos = nPos;
263 break;
264 case XML_ELEMENT(STYLE, XML_FILTER_NAME):
265 sFilter = aIter.toString();
266 break;
267 case XML_ELEMENT(DRAW, XML_OPACITY):
269 sal_Int32 nTmp;
270 // convert from percent and clip
271 if (::sax::Converter::convertPercent( nTmp, aIter.toView() ))
273 if( (nTmp >= 0) && (nTmp <= 100) )
274 nTransparency = static_cast<sal_Int8>( 100-nTmp );
277 break;
278 default:
279 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
285 XMLBackgroundImageContext::XMLBackgroundImageContext(
286 SvXMLImport& rImport, sal_Int32 nElement,
287 const Reference< xml::sax::XFastAttributeList > & xAttrList,
288 const XMLPropertyState& rProp,
289 sal_Int32 nPosIdx,
290 sal_Int32 nFilterIdx,
291 sal_Int32 nTransparencyIdx,
292 sal_Int32 nBitmapModeIdx,
293 ::std::vector< XMLPropertyState > &rProps ) :
294 XMLElementPropertyContext( rImport, nElement, rProp, rProps ),
295 aPosProp( nPosIdx ),
296 m_nBitmapModeIdx(nBitmapModeIdx),
297 aFilterProp( nFilterIdx ),
298 aTransparencyProp( nTransparencyIdx ),
299 nTransparency( 0 )
301 ProcessAttrs( xAttrList );
304 XMLBackgroundImageContext::~XMLBackgroundImageContext()
308 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLBackgroundImageContext::createFastChildContext(
309 sal_Int32 nElement,
310 const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/ )
312 if( nElement == XML_ELEMENT(OFFICE, xmloff::token::XML_BINARY_DATA) )
314 if( m_sURL.isEmpty() && !m_xBase64Stream.is() )
316 m_xBase64Stream = GetImport().GetStreamForGraphicObjectURLFromBase64();
317 if( m_xBase64Stream.is() )
318 return new XMLBase64ImportContext( GetImport(), m_xBase64Stream );
321 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
322 return nullptr;
325 void XMLBackgroundImageContext::endFastElement(sal_Int32 nElement)
327 uno::Reference<graphic::XGraphic> xGraphic;
328 if (!m_sURL.isEmpty())
330 xGraphic = GetImport().loadGraphicByURL(m_sURL);
332 else if (m_xBase64Stream.is())
334 xGraphic = GetImport().loadGraphicFromBase64(m_xBase64Stream);
335 m_xBase64Stream = nullptr;
338 if (!xGraphic.is())
339 ePos = GraphicLocation_NONE;
340 else if (GraphicLocation_NONE == ePos)
341 ePos = GraphicLocation_TILED;
343 if (xGraphic.is())
344 aProp.maValue <<= xGraphic;
345 aPosProp.maValue <<= ePos;
346 aFilterProp.maValue <<= sFilter;
347 aTransparencyProp.maValue <<= nTransparency;
349 SetInsert( true );
350 XMLElementPropertyContext::endFastElement(nElement);
352 if( -1 != aPosProp.mnIndex )
354 // See if a FillBitmapMode property is already set, in that case
355 // BackGraphicLocation will be ignored.
356 bool bFound = false;
357 if (m_nBitmapModeIdx != -1)
359 for (XMLPropertyState& rProperty : rProperties)
361 if (rProperty.mnIndex == m_nBitmapModeIdx)
363 bFound = true;
365 // Found, so map the old property to the new one.
366 switch (ePos)
368 case GraphicLocation_TILED:
369 rProperty.maValue <<= drawing::BitmapMode_REPEAT;
370 break;
371 case GraphicLocation_AREA:
372 rProperty.maValue <<= drawing::BitmapMode_STRETCH;
373 break;
374 case GraphicLocation_MIDDLE_MIDDLE:
375 rProperty.maValue <<= drawing::BitmapMode_NO_REPEAT;
376 break;
377 default:
378 break;
380 break;
384 if (!bFound)
385 rProperties.push_back( aPosProp );
387 if( -1 != aFilterProp.mnIndex )
388 rProperties.push_back( aFilterProp );
389 if( -1 != aTransparencyProp.mnIndex )
390 rProperties.push_back( aTransparencyProp );
393 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */