Update ooo320-m1
[ooovba.git] / xmloff / source / style / XMLBackgroundImageContext.cxx
blob5e7e5534c25a3935ecc26af54cc30d120cf959ef
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: XMLBackgroundImageContext.cxx,v $
10 * $Revision: 1.18 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
33 #include <tools/debug.hxx>
34 #include <com/sun/star/io/XOutputStream.hpp>
35 #include <xmloff/xmltkmap.hxx>
36 #include <xmloff/xmluconv.hxx>
37 #include "xmlnmspe.hxx"
38 #include <xmloff/xmltoken.hxx>
39 #include <xmloff/xmlimp.hxx>
40 #include <xmloff/nmspmap.hxx>
41 #include <xmloff/XMLBase64ImportContext.hxx>
42 #include "XMLBackgroundImageContext.hxx"
44 using ::rtl::OUString;
45 using ::rtl::OUStringBuffer;
47 using namespace ::com::sun::star;
48 using namespace ::com::sun::star::uno;
49 using namespace ::com::sun::star::style;
50 using namespace ::com::sun::star::io;
51 using namespace ::xmloff::token;
53 enum SvXMLTokenMapAttrs
55 XML_TOK_BGIMG_HREF,
56 XML_TOK_BGIMG_TYPE,
57 XML_TOK_BGIMG_ACTUATE,
58 XML_TOK_BGIMG_SHOW,
59 XML_TOK_BGIMG_POSITION,
60 XML_TOK_BGIMG_REPEAT,
61 XML_TOK_BGIMG_FILTER,
62 XML_TOK_BGIMG_OPACITY,
63 XML_TOK_NGIMG_END=XML_TOK_UNKNOWN
65 const SvXMLTokenMapEntry* lcl_getBGImgAttributesAttrTokenMap()
67 static __FAR_DATA SvXMLTokenMapEntry aBGImgAttributesAttrTokenMap[] =
69 { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_BGIMG_HREF },
70 { XML_NAMESPACE_XLINK, XML_TYPE, XML_TOK_BGIMG_TYPE },
71 { XML_NAMESPACE_XLINK, XML_ACTUATE, XML_TOK_BGIMG_ACTUATE },
72 { XML_NAMESPACE_XLINK, XML_SHOW, XML_TOK_BGIMG_SHOW },
73 { XML_NAMESPACE_STYLE, XML_POSITION, XML_TOK_BGIMG_POSITION },
74 { XML_NAMESPACE_STYLE, XML_REPEAT, XML_TOK_BGIMG_REPEAT },
75 { XML_NAMESPACE_STYLE, XML_FILTER_NAME, XML_TOK_BGIMG_FILTER },
76 { XML_NAMESPACE_DRAW, XML_OPACITY, XML_TOK_BGIMG_OPACITY },
77 XML_TOKEN_MAP_END
79 return aBGImgAttributesAttrTokenMap;
84 SvXMLEnumMapEntry psXML_BrushHoriPos[] =
86 { XML_LEFT, GraphicLocation_LEFT_MIDDLE },
87 { XML_RIGHT, GraphicLocation_RIGHT_MIDDLE },
88 { XML_TOKEN_INVALID, 0 }
91 SvXMLEnumMapEntry psXML_BrushVertPos[] =
93 { XML_TOP, GraphicLocation_MIDDLE_TOP },
94 { XML_BOTTOM, GraphicLocation_MIDDLE_BOTTOM },
95 { XML_TOKEN_INVALID, 0 }
98 void lcl_xmlbic_MergeHoriPos( GraphicLocation& ePos,
99 GraphicLocation eHori )
101 DBG_ASSERT( GraphicLocation_LEFT_MIDDLE==eHori ||
102 GraphicLocation_MIDDLE_MIDDLE==eHori ||
103 GraphicLocation_RIGHT_MIDDLE==eHori,
104 "lcl_xmlbic_MergeHoriPos: vertical pos must be middle" );
106 switch( ePos )
108 case GraphicLocation_LEFT_TOP:
109 case GraphicLocation_MIDDLE_TOP:
110 case GraphicLocation_RIGHT_TOP:
111 ePos = GraphicLocation_LEFT_MIDDLE==eHori
112 ? GraphicLocation_LEFT_TOP
113 : (GraphicLocation_MIDDLE_MIDDLE==eHori
114 ? GraphicLocation_MIDDLE_TOP
115 : GraphicLocation_RIGHT_TOP);
116 break;
118 case GraphicLocation_LEFT_MIDDLE:
119 case GraphicLocation_MIDDLE_MIDDLE:
120 case GraphicLocation_RIGHT_MIDDLE:
121 ePos = eHori;
122 break;
124 case GraphicLocation_LEFT_BOTTOM:
125 case GraphicLocation_MIDDLE_BOTTOM:
126 case GraphicLocation_RIGHT_BOTTOM:
127 ePos = GraphicLocation_LEFT_MIDDLE==eHori
128 ? GraphicLocation_LEFT_BOTTOM
129 : (GraphicLocation_MIDDLE_MIDDLE==eHori
130 ? GraphicLocation_MIDDLE_BOTTOM
131 : GraphicLocation_RIGHT_BOTTOM);
132 break;
133 default:
134 break;
138 void lcl_xmlbic_MergeVertPos( GraphicLocation& ePos,
139 GraphicLocation eVert )
141 DBG_ASSERT( GraphicLocation_MIDDLE_TOP==eVert ||
142 GraphicLocation_MIDDLE_MIDDLE==eVert ||
143 GraphicLocation_MIDDLE_BOTTOM==eVert,
144 "lcl_xmlbic_MergeVertPos: horizontal pos must be middle" );
146 switch( ePos )
148 case GraphicLocation_LEFT_TOP:
149 case GraphicLocation_LEFT_MIDDLE:
150 case GraphicLocation_LEFT_BOTTOM:
151 ePos = GraphicLocation_MIDDLE_TOP==eVert
152 ? GraphicLocation_LEFT_TOP
153 : (GraphicLocation_MIDDLE_MIDDLE==eVert
154 ? GraphicLocation_LEFT_MIDDLE
155 : GraphicLocation_LEFT_BOTTOM);
156 ePos = eVert;
157 break;
159 case GraphicLocation_MIDDLE_TOP:
160 case GraphicLocation_MIDDLE_MIDDLE:
161 case GraphicLocation_MIDDLE_BOTTOM:
162 ePos = eVert;
163 break;
165 case GraphicLocation_RIGHT_TOP:
166 case GraphicLocation_RIGHT_MIDDLE:
167 case GraphicLocation_RIGHT_BOTTOM:
168 ePos = GraphicLocation_MIDDLE_TOP==eVert
169 ? GraphicLocation_RIGHT_TOP
170 : (GraphicLocation_MIDDLE_MIDDLE==eVert
171 ? GraphicLocation_RIGHT_MIDDLE
172 : GraphicLocation_RIGHT_BOTTOM);
173 break;
174 default:
175 break;
179 TYPEINIT1( XMLBackgroundImageContext, XMLElementPropertyContext );
181 void XMLBackgroundImageContext::ProcessAttrs(
182 const Reference< xml::sax::XAttributeList >& xAttrList )
184 SvXMLTokenMap aTokenMap( lcl_getBGImgAttributesAttrTokenMap() );
186 ePos = GraphicLocation_NONE;
188 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
189 for( sal_Int16 i=0; i < nAttrCount; i++ )
191 const OUString& rAttrName = xAttrList->getNameByIndex( i );
192 OUString aLocalName;
193 sal_uInt16 nPrefix =
194 GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
195 &aLocalName );
196 const OUString& rValue = xAttrList->getValueByIndex( i );
198 switch( aTokenMap.Get( nPrefix, aLocalName ) )
200 case XML_TOK_BGIMG_HREF:
201 sURL = rValue;
202 if( GraphicLocation_NONE == ePos )
203 ePos = GraphicLocation_TILED;
204 break;
205 case XML_TOK_BGIMG_TYPE:
206 case XML_TOK_BGIMG_ACTUATE:
207 case XML_TOK_BGIMG_SHOW:
208 break;
209 case XML_TOK_BGIMG_POSITION:
211 GraphicLocation eNewPos = GraphicLocation_NONE, eTmp;
212 sal_uInt16 nTmp;
213 SvXMLTokenEnumerator aTokenEnum( rValue );
214 OUString aToken;
215 sal_Bool bHori = sal_False, bVert = sal_False;
216 sal_Bool bOK = sal_True;
217 while( bOK && aTokenEnum.getNextToken( aToken ) )
219 if( bHori && bVert )
221 bOK = sal_False;
223 else if( -1 != aToken.indexOf( sal_Unicode('%') ) )
225 sal_Int32 nPrc = 50;
226 if( SvXMLUnitConverter::convertPercent( nPrc, aToken ) )
228 if( !bHori )
230 eNewPos = nPrc < 25
231 ? GraphicLocation_LEFT_TOP
232 : (nPrc < 75 ? GraphicLocation_MIDDLE_MIDDLE
233 : GraphicLocation_RIGHT_BOTTOM);
234 bHori = sal_True;
236 else
238 eTmp = nPrc < 25
239 ? GraphicLocation_LEFT_TOP
240 : (nPrc < 75 ? GraphicLocation_LEFT_MIDDLE
241 : GraphicLocation_LEFT_BOTTOM);
242 lcl_xmlbic_MergeVertPos( eNewPos, eTmp );
243 bVert = sal_True;
246 else
248 // wrong percentage
249 bOK = sal_False;
252 else if( IsXMLToken( aToken, XML_CENTER ) )
254 if( bHori )
255 lcl_xmlbic_MergeVertPos( eNewPos,
256 GraphicLocation_MIDDLE_MIDDLE );
257 else if ( bVert )
258 lcl_xmlbic_MergeHoriPos( eNewPos,
259 GraphicLocation_MIDDLE_MIDDLE );
260 else
261 eNewPos = GraphicLocation_MIDDLE_MIDDLE;
263 else if( SvXMLUnitConverter::convertEnum( nTmp, aToken,
264 psXML_BrushHoriPos ) )
266 if( bVert )
267 lcl_xmlbic_MergeHoriPos( eNewPos,
268 (GraphicLocation)nTmp );
269 else if( !bHori )
270 eNewPos = (GraphicLocation)nTmp;
271 else
272 bOK = sal_False;
273 bHori = sal_True;
275 else if( SvXMLUnitConverter::convertEnum( nTmp, aToken,
276 psXML_BrushVertPos ) )
278 if( bHori )
279 lcl_xmlbic_MergeVertPos( eNewPos,
280 (GraphicLocation)nTmp );
281 else if( !bVert )
282 eNewPos = (GraphicLocation)nTmp;
283 else
284 bOK = sal_False;
285 bVert = sal_True;
287 else
289 bOK = sal_False;
293 bOK &= GraphicLocation_NONE != eNewPos;
294 if( bOK )
295 ePos = eNewPos;
297 break;
298 case XML_TOK_BGIMG_REPEAT:
300 sal_uInt16 nPos = GraphicLocation_NONE;
301 static SvXMLEnumMapEntry psXML_BrushRepeat[] =
303 { XML_BACKGROUND_REPEAT, GraphicLocation_TILED },
304 { XML_BACKGROUND_NO_REPEAT, GraphicLocation_MIDDLE_MIDDLE },
305 { XML_BACKGROUND_STRETCH, GraphicLocation_AREA },
306 { XML_TOKEN_INVALID, 0 }
308 if( SvXMLUnitConverter::convertEnum( nPos, rValue,
309 psXML_BrushRepeat ) )
311 if( GraphicLocation_MIDDLE_MIDDLE != nPos ||
312 GraphicLocation_NONE == ePos ||
313 GraphicLocation_AREA == ePos ||
314 GraphicLocation_TILED == ePos )
315 ePos = (GraphicLocation)nPos;
318 break;
319 case XML_TOK_BGIMG_FILTER:
320 sFilter = rValue;
321 break;
322 case XML_TOK_BGIMG_OPACITY:
324 sal_Int32 nTmp;
325 // convert from percent and clip
326 if( SvXMLUnitConverter::convertPercent( nTmp, rValue ) )
328 if( (nTmp >= 0) && (nTmp <= 100) )
329 nTransparency = static_cast<sal_Int8>( 100-nTmp );
332 break;
338 XMLBackgroundImageContext::XMLBackgroundImageContext(
339 SvXMLImport& rImport, sal_uInt16 nPrfx,
340 const OUString& rLName,
341 const Reference< xml::sax::XAttributeList > & xAttrList,
342 const XMLPropertyState& rProp,
343 sal_Int32 nPosIdx,
344 sal_Int32 nFilterIdx,
345 sal_Int32 nTransparencyIdx,
346 ::std::vector< XMLPropertyState > &rProps ) :
347 XMLElementPropertyContext( rImport, nPrfx, rLName, rProp, rProps ),
348 aPosProp( nPosIdx ),
349 aFilterProp( nFilterIdx ),
350 aTransparencyProp( nTransparencyIdx ),
351 nTransparency( 0 )
353 ProcessAttrs( xAttrList );
356 XMLBackgroundImageContext::~XMLBackgroundImageContext()
360 SvXMLImportContext *XMLBackgroundImageContext::CreateChildContext(
361 sal_uInt16 nPrefix, const OUString& rLocalName,
362 const Reference< xml::sax::XAttributeList > & xAttrList )
364 SvXMLImportContext *pContext = NULL;
365 if( (XML_NAMESPACE_OFFICE == nPrefix) &&
366 xmloff::token::IsXMLToken( rLocalName,
367 xmloff::token::XML_BINARY_DATA ) )
369 if( !sURL.getLength() && !xBase64Stream.is() )
371 xBase64Stream = GetImport().GetStreamForGraphicObjectURLFromBase64();
372 if( xBase64Stream.is() )
373 pContext = new XMLBase64ImportContext( GetImport(), nPrefix,
374 rLocalName, xAttrList,
375 xBase64Stream );
378 if( !pContext )
380 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
383 return pContext;
386 void XMLBackgroundImageContext::EndElement()
388 if( sURL.getLength() )
390 sURL = GetImport().ResolveGraphicObjectURL( sURL, sal_False );
392 else if( xBase64Stream.is() )
394 sURL = GetImport().ResolveGraphicObjectURLFromBase64( xBase64Stream );
395 xBase64Stream = 0;
398 if( !sURL.getLength() )
399 ePos = GraphicLocation_NONE;
400 else if( GraphicLocation_NONE == ePos )
401 ePos = GraphicLocation_TILED;
403 aProp.maValue <<= sURL;
404 aPosProp.maValue <<= ePos;
405 aFilterProp.maValue <<= sFilter;
406 aTransparencyProp.maValue <<= nTransparency;
408 SetInsert( sal_True );
409 XMLElementPropertyContext::EndElement();
411 if( -1 != aPosProp.mnIndex )
412 rProperties.push_back( aPosProp );
413 if( -1 != aFilterProp.mnIndex )
414 rProperties.push_back( aFilterProp );
415 if( -1 != aTransparencyProp.mnIndex )
416 rProperties.push_back( aTransparencyProp );