1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: XMLBackgroundImageContext.cxx,v $
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
57 XML_TOK_BGIMG_ACTUATE
,
59 XML_TOK_BGIMG_POSITION
,
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
},
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" );
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
);
118 case GraphicLocation_LEFT_MIDDLE
:
119 case GraphicLocation_MIDDLE_MIDDLE
:
120 case GraphicLocation_RIGHT_MIDDLE
:
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
);
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" );
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
);
159 case GraphicLocation_MIDDLE_TOP
:
160 case GraphicLocation_MIDDLE_MIDDLE
:
161 case GraphicLocation_MIDDLE_BOTTOM
:
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
);
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
);
194 GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName
,
196 const OUString
& rValue
= xAttrList
->getValueByIndex( i
);
198 switch( aTokenMap
.Get( nPrefix
, aLocalName
) )
200 case XML_TOK_BGIMG_HREF
:
202 if( GraphicLocation_NONE
== ePos
)
203 ePos
= GraphicLocation_TILED
;
205 case XML_TOK_BGIMG_TYPE
:
206 case XML_TOK_BGIMG_ACTUATE
:
207 case XML_TOK_BGIMG_SHOW
:
209 case XML_TOK_BGIMG_POSITION
:
211 GraphicLocation eNewPos
= GraphicLocation_NONE
, eTmp
;
213 SvXMLTokenEnumerator
aTokenEnum( rValue
);
215 sal_Bool bHori
= sal_False
, bVert
= sal_False
;
216 sal_Bool bOK
= sal_True
;
217 while( bOK
&& aTokenEnum
.getNextToken( aToken
) )
223 else if( -1 != aToken
.indexOf( sal_Unicode('%') ) )
226 if( SvXMLUnitConverter::convertPercent( nPrc
, aToken
) )
231 ? GraphicLocation_LEFT_TOP
232 : (nPrc
< 75 ? GraphicLocation_MIDDLE_MIDDLE
233 : GraphicLocation_RIGHT_BOTTOM
);
239 ? GraphicLocation_LEFT_TOP
240 : (nPrc
< 75 ? GraphicLocation_LEFT_MIDDLE
241 : GraphicLocation_LEFT_BOTTOM
);
242 lcl_xmlbic_MergeVertPos( eNewPos
, eTmp
);
252 else if( IsXMLToken( aToken
, XML_CENTER
) )
255 lcl_xmlbic_MergeVertPos( eNewPos
,
256 GraphicLocation_MIDDLE_MIDDLE
);
258 lcl_xmlbic_MergeHoriPos( eNewPos
,
259 GraphicLocation_MIDDLE_MIDDLE
);
261 eNewPos
= GraphicLocation_MIDDLE_MIDDLE
;
263 else if( SvXMLUnitConverter::convertEnum( nTmp
, aToken
,
264 psXML_BrushHoriPos
) )
267 lcl_xmlbic_MergeHoriPos( eNewPos
,
268 (GraphicLocation
)nTmp
);
270 eNewPos
= (GraphicLocation
)nTmp
;
275 else if( SvXMLUnitConverter::convertEnum( nTmp
, aToken
,
276 psXML_BrushVertPos
) )
279 lcl_xmlbic_MergeVertPos( eNewPos
,
280 (GraphicLocation
)nTmp
);
282 eNewPos
= (GraphicLocation
)nTmp
;
293 bOK
&= GraphicLocation_NONE
!= eNewPos
;
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
;
319 case XML_TOK_BGIMG_FILTER
:
322 case XML_TOK_BGIMG_OPACITY
:
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
);
338 XMLBackgroundImageContext::XMLBackgroundImageContext(
339 SvXMLImport
& rImport
, sal_uInt16 nPrfx
,
340 const OUString
& rLName
,
341 const Reference
< xml::sax::XAttributeList
> & xAttrList
,
342 const XMLPropertyState
& rProp
,
344 sal_Int32 nFilterIdx
,
345 sal_Int32 nTransparencyIdx
,
346 ::std::vector
< XMLPropertyState
> &rProps
) :
347 XMLElementPropertyContext( rImport
, nPrfx
, rLName
, rProp
, rProps
),
349 aFilterProp( nFilterIdx
),
350 aTransparencyProp( nTransparencyIdx
),
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
,
380 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLocalName
);
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
);
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
);