1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/io/XOutputStream.hpp>
22 #include <com/sun/star/drawing/BitmapMode.hpp>
24 #include <tools/debug.hxx>
26 #include <sax/tools/converter.hxx>
28 #include <xmloff/xmltkmap.hxx>
29 #include <xmloff/xmluconv.hxx>
30 #include <xmloff/xmlnmspe.hxx>
31 #include <xmloff/xmltoken.hxx>
32 #include <xmloff/xmlimp.hxx>
33 #include <xmloff/nmspmap.hxx>
34 #include <xmloff/XMLBase64ImportContext.hxx>
35 #include "XMLBackgroundImageContext.hxx"
38 using namespace ::com::sun::star
;
39 using namespace ::com::sun::star::uno
;
40 using namespace ::com::sun::star::style
;
41 using namespace ::com::sun::star::io
;
42 using namespace ::xmloff::token
;
44 enum SvXMLTokenMapAttrs
48 XML_TOK_BGIMG_ACTUATE
,
50 XML_TOK_BGIMG_POSITION
,
53 XML_TOK_BGIMG_OPACITY
,
54 XML_TOK_NGIMG_END
=XML_TOK_UNKNOWN
56 static const SvXMLTokenMapEntry
* lcl_getBGImgAttributesAttrTokenMap()
58 static const SvXMLTokenMapEntry aBGImgAttributesAttrTokenMap
[] =
60 { XML_NAMESPACE_XLINK
, XML_HREF
, XML_TOK_BGIMG_HREF
},
61 { XML_NAMESPACE_XLINK
, XML_TYPE
, XML_TOK_BGIMG_TYPE
},
62 { XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_TOK_BGIMG_ACTUATE
},
63 { XML_NAMESPACE_XLINK
, XML_SHOW
, XML_TOK_BGIMG_SHOW
},
64 { XML_NAMESPACE_STYLE
, XML_POSITION
, XML_TOK_BGIMG_POSITION
},
65 { XML_NAMESPACE_STYLE
, XML_REPEAT
, XML_TOK_BGIMG_REPEAT
},
66 { XML_NAMESPACE_STYLE
, XML_FILTER_NAME
, XML_TOK_BGIMG_FILTER
},
67 { XML_NAMESPACE_DRAW
, XML_OPACITY
, XML_TOK_BGIMG_OPACITY
},
70 return aBGImgAttributesAttrTokenMap
;
75 static const SvXMLEnumMapEntry psXML_BrushHoriPos
[] =
77 { XML_LEFT
, GraphicLocation_LEFT_MIDDLE
},
78 { XML_RIGHT
, GraphicLocation_RIGHT_MIDDLE
},
79 { XML_TOKEN_INVALID
, 0 }
82 static const SvXMLEnumMapEntry psXML_BrushVertPos
[] =
84 { XML_TOP
, GraphicLocation_MIDDLE_TOP
},
85 { XML_BOTTOM
, GraphicLocation_MIDDLE_BOTTOM
},
86 { XML_TOKEN_INVALID
, 0 }
89 static void lcl_xmlbic_MergeHoriPos( GraphicLocation
& ePos
,
90 GraphicLocation eHori
)
92 DBG_ASSERT( GraphicLocation_LEFT_MIDDLE
==eHori
||
93 GraphicLocation_MIDDLE_MIDDLE
==eHori
||
94 GraphicLocation_RIGHT_MIDDLE
==eHori
,
95 "lcl_xmlbic_MergeHoriPos: vertical pos must be middle" );
99 case GraphicLocation_LEFT_TOP
:
100 case GraphicLocation_MIDDLE_TOP
:
101 case GraphicLocation_RIGHT_TOP
:
102 ePos
= GraphicLocation_LEFT_MIDDLE
==eHori
103 ? GraphicLocation_LEFT_TOP
104 : (GraphicLocation_MIDDLE_MIDDLE
==eHori
105 ? GraphicLocation_MIDDLE_TOP
106 : GraphicLocation_RIGHT_TOP
);
109 case GraphicLocation_LEFT_MIDDLE
:
110 case GraphicLocation_MIDDLE_MIDDLE
:
111 case GraphicLocation_RIGHT_MIDDLE
:
115 case GraphicLocation_LEFT_BOTTOM
:
116 case GraphicLocation_MIDDLE_BOTTOM
:
117 case GraphicLocation_RIGHT_BOTTOM
:
118 ePos
= GraphicLocation_LEFT_MIDDLE
==eHori
119 ? GraphicLocation_LEFT_BOTTOM
120 : (GraphicLocation_MIDDLE_MIDDLE
==eHori
121 ? GraphicLocation_MIDDLE_BOTTOM
122 : GraphicLocation_RIGHT_BOTTOM
);
129 static void lcl_xmlbic_MergeVertPos( GraphicLocation
& ePos
,
130 GraphicLocation eVert
)
132 DBG_ASSERT( GraphicLocation_MIDDLE_TOP
==eVert
||
133 GraphicLocation_MIDDLE_MIDDLE
==eVert
||
134 GraphicLocation_MIDDLE_BOTTOM
==eVert
,
135 "lcl_xmlbic_MergeVertPos: horizontal pos must be middle" );
139 case GraphicLocation_LEFT_TOP
:
140 case GraphicLocation_LEFT_MIDDLE
:
141 case GraphicLocation_LEFT_BOTTOM
:
142 ePos
= GraphicLocation_MIDDLE_TOP
==eVert
143 ? GraphicLocation_LEFT_TOP
144 : (GraphicLocation_MIDDLE_MIDDLE
==eVert
145 ? GraphicLocation_LEFT_MIDDLE
146 : GraphicLocation_LEFT_BOTTOM
);
149 case GraphicLocation_MIDDLE_TOP
:
150 case GraphicLocation_MIDDLE_MIDDLE
:
151 case GraphicLocation_MIDDLE_BOTTOM
:
155 case GraphicLocation_RIGHT_TOP
:
156 case GraphicLocation_RIGHT_MIDDLE
:
157 case GraphicLocation_RIGHT_BOTTOM
:
158 ePos
= GraphicLocation_MIDDLE_TOP
==eVert
159 ? GraphicLocation_RIGHT_TOP
160 : (GraphicLocation_MIDDLE_MIDDLE
==eVert
161 ? GraphicLocation_RIGHT_MIDDLE
162 : GraphicLocation_RIGHT_BOTTOM
);
169 TYPEINIT1( XMLBackgroundImageContext
, XMLElementPropertyContext
);
171 void XMLBackgroundImageContext::ProcessAttrs(
172 const Reference
< xml::sax::XAttributeList
>& xAttrList
)
174 SvXMLTokenMap
aTokenMap( lcl_getBGImgAttributesAttrTokenMap() );
176 ePos
= GraphicLocation_NONE
;
178 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
179 for( sal_Int16 i
=0; i
< nAttrCount
; i
++ )
181 const OUString
& rAttrName
= xAttrList
->getNameByIndex( i
);
184 GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName
,
186 const OUString
& rValue
= xAttrList
->getValueByIndex( i
);
188 switch( aTokenMap
.Get( nPrefix
, aLocalName
) )
190 case XML_TOK_BGIMG_HREF
:
192 if( GraphicLocation_NONE
== ePos
)
193 ePos
= GraphicLocation_TILED
;
195 case XML_TOK_BGIMG_TYPE
:
196 case XML_TOK_BGIMG_ACTUATE
:
197 case XML_TOK_BGIMG_SHOW
:
199 case XML_TOK_BGIMG_POSITION
:
201 GraphicLocation eNewPos
= GraphicLocation_NONE
, eTmp
;
203 SvXMLTokenEnumerator
aTokenEnum( rValue
);
205 bool bHori
= false, bVert
= false;
207 while( bOK
&& aTokenEnum
.getNextToken( aToken
) )
213 else if( -1 != aToken
.indexOf( '%' ) )
216 if (::sax::Converter::convertPercent( nPrc
, aToken
))
221 ? GraphicLocation_LEFT_TOP
222 : (nPrc
< 75 ? GraphicLocation_MIDDLE_MIDDLE
223 : GraphicLocation_RIGHT_BOTTOM
);
229 ? GraphicLocation_LEFT_TOP
230 : (nPrc
< 75 ? GraphicLocation_LEFT_MIDDLE
231 : GraphicLocation_LEFT_BOTTOM
);
232 lcl_xmlbic_MergeVertPos( eNewPos
, eTmp
);
242 else if( IsXMLToken( aToken
, XML_CENTER
) )
245 lcl_xmlbic_MergeVertPos( eNewPos
,
246 GraphicLocation_MIDDLE_MIDDLE
);
248 lcl_xmlbic_MergeHoriPos( eNewPos
,
249 GraphicLocation_MIDDLE_MIDDLE
);
251 eNewPos
= GraphicLocation_MIDDLE_MIDDLE
;
253 else if( SvXMLUnitConverter::convertEnum( nTmp
, aToken
,
254 psXML_BrushHoriPos
) )
257 lcl_xmlbic_MergeHoriPos( eNewPos
,
258 (GraphicLocation
)nTmp
);
260 eNewPos
= (GraphicLocation
)nTmp
;
265 else if( SvXMLUnitConverter::convertEnum( nTmp
, aToken
,
266 psXML_BrushVertPos
) )
269 lcl_xmlbic_MergeVertPos( eNewPos
,
270 (GraphicLocation
)nTmp
);
272 eNewPos
= (GraphicLocation
)nTmp
;
283 bOK
&= GraphicLocation_NONE
!= eNewPos
;
288 case XML_TOK_BGIMG_REPEAT
:
290 sal_uInt16 nPos
= GraphicLocation_NONE
;
291 static const SvXMLEnumMapEntry psXML_BrushRepeat
[] =
293 { XML_BACKGROUND_REPEAT
, GraphicLocation_TILED
},
294 { XML_BACKGROUND_NO_REPEAT
, GraphicLocation_MIDDLE_MIDDLE
},
295 { XML_BACKGROUND_STRETCH
, GraphicLocation_AREA
},
296 { XML_TOKEN_INVALID
, 0 }
298 if( SvXMLUnitConverter::convertEnum( nPos
, rValue
,
299 psXML_BrushRepeat
) )
301 if( GraphicLocation_MIDDLE_MIDDLE
!= nPos
||
302 GraphicLocation_NONE
== ePos
||
303 GraphicLocation_AREA
== ePos
||
304 GraphicLocation_TILED
== ePos
)
305 ePos
= (GraphicLocation
)nPos
;
309 case XML_TOK_BGIMG_FILTER
:
312 case XML_TOK_BGIMG_OPACITY
:
315 // convert from percent and clip
316 if (::sax::Converter::convertPercent( nTmp
, rValue
))
318 if( (nTmp
>= 0) && (nTmp
<= 100) )
319 nTransparency
= static_cast<sal_Int8
>( 100-nTmp
);
328 XMLBackgroundImageContext::XMLBackgroundImageContext(
329 SvXMLImport
& rImport
, sal_uInt16 nPrfx
,
330 const OUString
& rLName
,
331 const Reference
< xml::sax::XAttributeList
> & xAttrList
,
332 const XMLPropertyState
& rProp
,
334 sal_Int32 nFilterIdx
,
335 sal_Int32 nTransparencyIdx
,
336 sal_Int32 nBitmapModeIdx
,
337 ::std::vector
< XMLPropertyState
> &rProps
) :
338 XMLElementPropertyContext( rImport
, nPrfx
, rLName
, rProp
, rProps
),
340 m_nBitmapModeIdx(nBitmapModeIdx
),
341 aFilterProp( nFilterIdx
),
342 aTransparencyProp( nTransparencyIdx
),
345 ProcessAttrs( xAttrList
);
348 XMLBackgroundImageContext::~XMLBackgroundImageContext()
352 SvXMLImportContext
*XMLBackgroundImageContext::CreateChildContext(
353 sal_uInt16 nPrefix
, const OUString
& rLocalName
,
354 const Reference
< xml::sax::XAttributeList
> & xAttrList
)
356 SvXMLImportContext
*pContext
= NULL
;
357 if( (XML_NAMESPACE_OFFICE
== nPrefix
) &&
358 xmloff::token::IsXMLToken( rLocalName
,
359 xmloff::token::XML_BINARY_DATA
) )
361 if( sURL
.isEmpty() && !xBase64Stream
.is() )
363 xBase64Stream
= GetImport().GetStreamForGraphicObjectURLFromBase64();
364 if( xBase64Stream
.is() )
365 pContext
= new XMLBase64ImportContext( GetImport(), nPrefix
,
366 rLocalName
, xAttrList
,
372 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLocalName
);
378 void XMLBackgroundImageContext::EndElement()
380 if( !sURL
.isEmpty() )
382 sURL
= GetImport().ResolveGraphicObjectURL( sURL
, false );
384 else if( xBase64Stream
.is() )
386 sURL
= GetImport().ResolveGraphicObjectURLFromBase64( xBase64Stream
);
391 ePos
= GraphicLocation_NONE
;
392 else if( GraphicLocation_NONE
== ePos
)
393 ePos
= GraphicLocation_TILED
;
396 aProp
.maValue
<<= sURL
;
397 aPosProp
.maValue
<<= ePos
;
398 aFilterProp
.maValue
<<= sFilter
;
399 aTransparencyProp
.maValue
<<= nTransparency
;
402 XMLElementPropertyContext::EndElement();
404 if( -1 != aPosProp
.mnIndex
)
406 // See if a FillBitmapMode property is already set, in that case
407 // BackGraphicLocation will be ignored.
409 if (m_nBitmapModeIdx
!= -1)
411 for (XMLPropertyState
& rProperty
: rProperties
)
413 if (rProperty
.mnIndex
== m_nBitmapModeIdx
)
417 // Found, so map the old property to the new one.
420 case GraphicLocation_TILED
:
421 rProperty
.maValue
<<= drawing::BitmapMode_REPEAT
;
423 case GraphicLocation_AREA
:
424 rProperty
.maValue
<<= drawing::BitmapMode_STRETCH
;
426 case GraphicLocation_MIDDLE_MIDDLE
:
427 rProperty
.maValue
<<= drawing::BitmapMode_NO_REPEAT
;
437 rProperties
.push_back( aPosProp
);
439 if( -1 != aFilterProp
.mnIndex
)
440 rProperties
.push_back( aFilterProp
);
441 if( -1 != aTransparencyProp
.mnIndex
)
442 rProperties
.push_back( aTransparencyProp
);
445 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */