| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_xmloff.hxx" |
| #include <tools/debug.hxx> |
| #include <com/sun/star/io/XOutputStream.hpp> |
| #include <xmloff/xmltkmap.hxx> |
| #include <xmloff/xmluconv.hxx> |
| #include "xmloff/xmlnmspe.hxx" |
| #include <xmloff/xmltoken.hxx> |
| #include <xmloff/xmlimp.hxx> |
| #include <xmloff/nmspmap.hxx> |
| #include <xmloff/XMLBase64ImportContext.hxx> |
| #include "XMLBackgroundImageContext.hxx" |
| |
| using ::rtl::OUString; |
| using ::rtl::OUStringBuffer; |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::style; |
| using namespace ::com::sun::star::io; |
| using namespace ::xmloff::token; |
| |
| enum SvXMLTokenMapAttrs |
| { |
| XML_TOK_BGIMG_HREF, |
| XML_TOK_BGIMG_TYPE, |
| XML_TOK_BGIMG_ACTUATE, |
| XML_TOK_BGIMG_SHOW, |
| XML_TOK_BGIMG_POSITION, |
| XML_TOK_BGIMG_REPEAT, |
| XML_TOK_BGIMG_FILTER, |
| XML_TOK_BGIMG_OPACITY, |
| XML_TOK_NGIMG_END=XML_TOK_UNKNOWN |
| }; |
| const SvXMLTokenMapEntry* lcl_getBGImgAttributesAttrTokenMap() |
| { |
| static __FAR_DATA SvXMLTokenMapEntry aBGImgAttributesAttrTokenMap[] = |
| { |
| { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_BGIMG_HREF }, |
| { XML_NAMESPACE_XLINK, XML_TYPE, XML_TOK_BGIMG_TYPE }, |
| { XML_NAMESPACE_XLINK, XML_ACTUATE, XML_TOK_BGIMG_ACTUATE }, |
| { XML_NAMESPACE_XLINK, XML_SHOW, XML_TOK_BGIMG_SHOW }, |
| { XML_NAMESPACE_STYLE, XML_POSITION, XML_TOK_BGIMG_POSITION }, |
| { XML_NAMESPACE_STYLE, XML_REPEAT, XML_TOK_BGIMG_REPEAT }, |
| { XML_NAMESPACE_STYLE, XML_FILTER_NAME, XML_TOK_BGIMG_FILTER }, |
| { XML_NAMESPACE_DRAW, XML_OPACITY, XML_TOK_BGIMG_OPACITY }, |
| XML_TOKEN_MAP_END |
| }; |
| return aBGImgAttributesAttrTokenMap; |
| } |
| |
| |
| |
| SvXMLEnumMapEntry psXML_BrushHoriPos[] = |
| { |
| { XML_LEFT, GraphicLocation_LEFT_MIDDLE }, |
| { XML_RIGHT, GraphicLocation_RIGHT_MIDDLE }, |
| { XML_TOKEN_INVALID, 0 } |
| }; |
| |
| SvXMLEnumMapEntry psXML_BrushVertPos[] = |
| { |
| { XML_TOP, GraphicLocation_MIDDLE_TOP }, |
| { XML_BOTTOM, GraphicLocation_MIDDLE_BOTTOM }, |
| { XML_TOKEN_INVALID, 0 } |
| }; |
| |
| void lcl_xmlbic_MergeHoriPos( GraphicLocation& ePos, |
| GraphicLocation eHori ) |
| { |
| DBG_ASSERT( GraphicLocation_LEFT_MIDDLE==eHori || |
| GraphicLocation_MIDDLE_MIDDLE==eHori || |
| GraphicLocation_RIGHT_MIDDLE==eHori, |
| "lcl_xmlbic_MergeHoriPos: vertical pos must be middle" ); |
| |
| switch( ePos ) |
| { |
| case GraphicLocation_LEFT_TOP: |
| case GraphicLocation_MIDDLE_TOP: |
| case GraphicLocation_RIGHT_TOP: |
| ePos = GraphicLocation_LEFT_MIDDLE==eHori |
| ? GraphicLocation_LEFT_TOP |
| : (GraphicLocation_MIDDLE_MIDDLE==eHori |
| ? GraphicLocation_MIDDLE_TOP |
| : GraphicLocation_RIGHT_TOP); |
| break; |
| |
| case GraphicLocation_LEFT_MIDDLE: |
| case GraphicLocation_MIDDLE_MIDDLE: |
| case GraphicLocation_RIGHT_MIDDLE: |
| ePos = eHori; |
| break; |
| |
| case GraphicLocation_LEFT_BOTTOM: |
| case GraphicLocation_MIDDLE_BOTTOM: |
| case GraphicLocation_RIGHT_BOTTOM: |
| ePos = GraphicLocation_LEFT_MIDDLE==eHori |
| ? GraphicLocation_LEFT_BOTTOM |
| : (GraphicLocation_MIDDLE_MIDDLE==eHori |
| ? GraphicLocation_MIDDLE_BOTTOM |
| : GraphicLocation_RIGHT_BOTTOM); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| void lcl_xmlbic_MergeVertPos( GraphicLocation& ePos, |
| GraphicLocation eVert ) |
| { |
| DBG_ASSERT( GraphicLocation_MIDDLE_TOP==eVert || |
| GraphicLocation_MIDDLE_MIDDLE==eVert || |
| GraphicLocation_MIDDLE_BOTTOM==eVert, |
| "lcl_xmlbic_MergeVertPos: horizontal pos must be middle" ); |
| |
| switch( ePos ) |
| { |
| case GraphicLocation_LEFT_TOP: |
| case GraphicLocation_LEFT_MIDDLE: |
| case GraphicLocation_LEFT_BOTTOM: |
| ePos = GraphicLocation_MIDDLE_TOP==eVert |
| ? GraphicLocation_LEFT_TOP |
| : (GraphicLocation_MIDDLE_MIDDLE==eVert |
| ? GraphicLocation_LEFT_MIDDLE |
| : GraphicLocation_LEFT_BOTTOM); |
| ePos = eVert; |
| break; |
| |
| case GraphicLocation_MIDDLE_TOP: |
| case GraphicLocation_MIDDLE_MIDDLE: |
| case GraphicLocation_MIDDLE_BOTTOM: |
| ePos = eVert; |
| break; |
| |
| case GraphicLocation_RIGHT_TOP: |
| case GraphicLocation_RIGHT_MIDDLE: |
| case GraphicLocation_RIGHT_BOTTOM: |
| ePos = GraphicLocation_MIDDLE_TOP==eVert |
| ? GraphicLocation_RIGHT_TOP |
| : (GraphicLocation_MIDDLE_MIDDLE==eVert |
| ? GraphicLocation_RIGHT_MIDDLE |
| : GraphicLocation_RIGHT_BOTTOM); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| TYPEINIT1( XMLBackgroundImageContext, XMLElementPropertyContext ); |
| |
| void XMLBackgroundImageContext::ProcessAttrs( |
| const Reference< xml::sax::XAttributeList >& xAttrList ) |
| { |
| SvXMLTokenMap aTokenMap( lcl_getBGImgAttributesAttrTokenMap() ); |
| |
| ePos = GraphicLocation_NONE; |
| |
| sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; |
| for( sal_Int16 i=0; i < nAttrCount; i++ ) |
| { |
| const OUString& rAttrName = xAttrList->getNameByIndex( i ); |
| OUString aLocalName; |
| sal_uInt16 nPrefix = |
| GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, |
| &aLocalName ); |
| const OUString& rValue = xAttrList->getValueByIndex( i ); |
| |
| switch( aTokenMap.Get( nPrefix, aLocalName ) ) |
| { |
| case XML_TOK_BGIMG_HREF: |
| sURL = rValue; |
| if( GraphicLocation_NONE == ePos ) |
| ePos = GraphicLocation_TILED; |
| break; |
| case XML_TOK_BGIMG_TYPE: |
| case XML_TOK_BGIMG_ACTUATE: |
| case XML_TOK_BGIMG_SHOW: |
| break; |
| case XML_TOK_BGIMG_POSITION: |
| { |
| GraphicLocation eNewPos = GraphicLocation_NONE, eTmp; |
| sal_uInt16 nTmp; |
| SvXMLTokenEnumerator aTokenEnum( rValue ); |
| OUString aToken; |
| sal_Bool bHori = sal_False, bVert = sal_False; |
| sal_Bool bOK = sal_True; |
| while( bOK && aTokenEnum.getNextToken( aToken ) ) |
| { |
| if( bHori && bVert ) |
| { |
| bOK = sal_False; |
| } |
| else if( -1 != aToken.indexOf( sal_Unicode('%') ) ) |
| { |
| sal_Int32 nPrc = 50; |
| if( SvXMLUnitConverter::convertPercent( nPrc, aToken ) ) |
| { |
| if( !bHori ) |
| { |
| eNewPos = nPrc < 25 |
| ? GraphicLocation_LEFT_TOP |
| : (nPrc < 75 ? GraphicLocation_MIDDLE_MIDDLE |
| : GraphicLocation_RIGHT_BOTTOM); |
| bHori = sal_True; |
| } |
| else |
| { |
| eTmp = nPrc < 25 |
| ? GraphicLocation_LEFT_TOP |
| : (nPrc < 75 ? GraphicLocation_LEFT_MIDDLE |
| : GraphicLocation_LEFT_BOTTOM); |
| lcl_xmlbic_MergeVertPos( eNewPos, eTmp ); |
| bVert = sal_True; |
| } |
| } |
| else |
| { |
| // wrong percentage |
| bOK = sal_False; |
| } |
| } |
| else if( IsXMLToken( aToken, XML_CENTER ) ) |
| { |
| if( bHori ) |
| lcl_xmlbic_MergeVertPos( eNewPos, |
| GraphicLocation_MIDDLE_MIDDLE ); |
| else if ( bVert ) |
| lcl_xmlbic_MergeHoriPos( eNewPos, |
| GraphicLocation_MIDDLE_MIDDLE ); |
| else |
| eNewPos = GraphicLocation_MIDDLE_MIDDLE; |
| } |
| else if( SvXMLUnitConverter::convertEnum( nTmp, aToken, |
| psXML_BrushHoriPos ) ) |
| { |
| if( bVert ) |
| lcl_xmlbic_MergeHoriPos( eNewPos, |
| (GraphicLocation)nTmp ); |
| else if( !bHori ) |
| eNewPos = (GraphicLocation)nTmp; |
| else |
| bOK = sal_False; |
| bHori = sal_True; |
| } |
| else if( SvXMLUnitConverter::convertEnum( nTmp, aToken, |
| psXML_BrushVertPos ) ) |
| { |
| if( bHori ) |
| lcl_xmlbic_MergeVertPos( eNewPos, |
| (GraphicLocation)nTmp ); |
| else if( !bVert ) |
| eNewPos = (GraphicLocation)nTmp; |
| else |
| bOK = sal_False; |
| bVert = sal_True; |
| } |
| else |
| { |
| bOK = sal_False; |
| } |
| } |
| |
| bOK &= GraphicLocation_NONE != eNewPos; |
| if( bOK ) |
| ePos = eNewPos; |
| } |
| break; |
| case XML_TOK_BGIMG_REPEAT: |
| { |
| sal_uInt16 nPos = GraphicLocation_NONE; |
| static SvXMLEnumMapEntry psXML_BrushRepeat[] = |
| { |
| { XML_BACKGROUND_REPEAT, GraphicLocation_TILED }, |
| { XML_BACKGROUND_NO_REPEAT, GraphicLocation_MIDDLE_MIDDLE }, |
| { XML_BACKGROUND_STRETCH, GraphicLocation_AREA }, |
| { XML_TOKEN_INVALID, 0 } |
| }; |
| if( SvXMLUnitConverter::convertEnum( nPos, rValue, |
| psXML_BrushRepeat ) ) |
| { |
| if( GraphicLocation_MIDDLE_MIDDLE != nPos || |
| GraphicLocation_NONE == ePos || |
| GraphicLocation_AREA == ePos || |
| GraphicLocation_TILED == ePos ) |
| ePos = (GraphicLocation)nPos; |
| } |
| } |
| break; |
| case XML_TOK_BGIMG_FILTER: |
| sFilter = rValue; |
| break; |
| case XML_TOK_BGIMG_OPACITY: |
| { |
| sal_Int32 nTmp; |
| // convert from percent and clip |
| if( SvXMLUnitConverter::convertPercent( nTmp, rValue ) ) |
| { |
| if( (nTmp >= 0) && (nTmp <= 100) ) |
| nTransparency = static_cast<sal_Int8>( 100-nTmp ); |
| } |
| } |
| break; |
| } |
| } |
| |
| } |
| |
| XMLBackgroundImageContext::XMLBackgroundImageContext( |
| SvXMLImport& rImport, sal_uInt16 nPrfx, |
| const OUString& rLName, |
| const Reference< xml::sax::XAttributeList > & xAttrList, |
| const XMLPropertyState& rProp, |
| sal_Int32 nPosIdx, |
| sal_Int32 nFilterIdx, |
| sal_Int32 nTransparencyIdx, |
| ::std::vector< XMLPropertyState > &rProps ) : |
| XMLElementPropertyContext( rImport, nPrfx, rLName, rProp, rProps ), |
| aPosProp( nPosIdx ), |
| aFilterProp( nFilterIdx ), |
| aTransparencyProp( nTransparencyIdx ), |
| nTransparency( 0 ) |
| { |
| ProcessAttrs( xAttrList ); |
| } |
| |
| XMLBackgroundImageContext::~XMLBackgroundImageContext() |
| { |
| } |
| |
| SvXMLImportContext *XMLBackgroundImageContext::CreateChildContext( |
| sal_uInt16 nPrefix, const OUString& rLocalName, |
| const Reference< xml::sax::XAttributeList > & xAttrList ) |
| { |
| SvXMLImportContext *pContext = NULL; |
| if( (XML_NAMESPACE_OFFICE == nPrefix) && |
| xmloff::token::IsXMLToken( rLocalName, |
| xmloff::token::XML_BINARY_DATA ) ) |
| { |
| if( !sURL.getLength() && !xBase64Stream.is() ) |
| { |
| xBase64Stream = GetImport().GetStreamForGraphicObjectURLFromBase64(); |
| if( xBase64Stream.is() ) |
| pContext = new XMLBase64ImportContext( GetImport(), nPrefix, |
| rLocalName, xAttrList, |
| xBase64Stream ); |
| } |
| } |
| if( !pContext ) |
| { |
| pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); |
| } |
| |
| return pContext; |
| } |
| |
| void XMLBackgroundImageContext::EndElement() |
| { |
| if( sURL.getLength() ) |
| { |
| sURL = GetImport().ResolveGraphicObjectURL( sURL, sal_False ); |
| } |
| else if( xBase64Stream.is() ) |
| { |
| sURL = GetImport().ResolveGraphicObjectURLFromBase64( xBase64Stream ); |
| xBase64Stream = 0; |
| } |
| |
| if( !sURL.getLength() ) |
| ePos = GraphicLocation_NONE; |
| else if( GraphicLocation_NONE == ePos ) |
| ePos = GraphicLocation_TILED; |
| |
| aProp.maValue <<= sURL; |
| aPosProp.maValue <<= ePos; |
| aFilterProp.maValue <<= sFilter; |
| aTransparencyProp.maValue <<= nTransparency; |
| |
| SetInsert( sal_True ); |
| XMLElementPropertyContext::EndElement(); |
| |
| if( -1 != aPosProp.mnIndex ) |
| rProperties.push_back( aPosProp ); |
| if( -1 != aFilterProp.mnIndex ) |
| rProperties.push_back( aFilterProp ); |
| if( -1 != aTransparencyProp.mnIndex ) |
| rProperties.push_back( aTransparencyProp ); |
| } |