| /************************************************************** |
| * |
| * 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 "xmloff/MarkerStyle.hxx" |
| #include "xexptran.hxx" |
| #include <xmloff/attrlist.hxx> |
| #include <xmloff/nmspmap.hxx> |
| #include <xmloff/xmluconv.hxx> |
| #include "xmloff/xmlnmspe.hxx" |
| #include <xmloff/xmltoken.hxx> |
| #include <xmloff/xmlexp.hxx> |
| #include <xmloff/xmlimp.hxx> |
| #include <rtl/ustrbuf.hxx> |
| #include <rtl/ustring.hxx> |
| #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp> |
| |
| using namespace ::com::sun::star; |
| using ::rtl::OUString; |
| using ::rtl::OUStringBuffer; |
| |
| using namespace ::xmloff::token; |
| |
| |
| //------------------------------------------------------------- |
| // Import |
| //------------------------------------------------------------- |
| |
| XMLMarkerStyleImport::XMLMarkerStyleImport( SvXMLImport& rImp ) |
| : rImport( rImp ) |
| { |
| } |
| |
| XMLMarkerStyleImport::~XMLMarkerStyleImport() |
| { |
| } |
| |
| sal_Bool XMLMarkerStyleImport::importXML( |
| const uno::Reference< xml::sax::XAttributeList >& xAttrList, |
| uno::Any& rValue, |
| OUString& rStrName ) |
| { |
| sal_Bool bHasViewBox = sal_False; |
| sal_Bool bHasPathData = sal_False; |
| OUString aDisplayName; |
| |
| SdXMLImExViewBox* pViewBox = NULL; |
| |
| SvXMLNamespaceMap& rNamespaceMap = rImport.GetNamespaceMap(); |
| SvXMLUnitConverter& rUnitConverter = rImport.GetMM100UnitConverter(); |
| |
| OUString strPathData; |
| |
| sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; |
| for( sal_Int16 i = 0; i < nAttrCount; i++ ) |
| { |
| OUString aStrFullAttrName = xAttrList->getNameByIndex( i ); |
| OUString aStrAttrName; |
| rNamespaceMap.GetKeyByAttrName( aStrFullAttrName, &aStrAttrName ); |
| OUString aStrValue = xAttrList->getValueByIndex( i ); |
| |
| if( IsXMLToken( aStrAttrName, XML_NAME ) ) |
| { |
| rStrName = aStrValue; |
| } |
| else if( IsXMLToken( aStrAttrName, XML_DISPLAY_NAME ) ) |
| { |
| aDisplayName = aStrValue; |
| } |
| else if( IsXMLToken( aStrAttrName, XML_VIEWBOX ) ) |
| { |
| pViewBox = new SdXMLImExViewBox( aStrValue, rUnitConverter ); |
| bHasViewBox = sal_True; |
| |
| } |
| else if( IsXMLToken( aStrAttrName, XML_D ) ) |
| { |
| strPathData = aStrValue; |
| bHasPathData = sal_True; |
| } |
| } |
| |
| if( bHasViewBox && bHasPathData ) |
| { |
| SdXMLImExSvgDElement aPoints(strPathData, *pViewBox, awt::Point( 0, 0 ), |
| awt::Size( pViewBox->GetWidth(), pViewBox->GetHeight() ), |
| rUnitConverter ); |
| |
| if(aPoints.IsCurve()) |
| { |
| drawing::PolyPolygonBezierCoords aSourcePolyPolygon( |
| aPoints.GetPointSequenceSequence(), |
| aPoints.GetFlagSequenceSequence()); |
| rValue <<= aSourcePolyPolygon; |
| } |
| else |
| { |
| drawing::PolyPolygonBezierCoords aSourcePolyPolygon; |
| aSourcePolyPolygon.Coordinates = aPoints.GetPointSequenceSequence(); |
| aSourcePolyPolygon.Flags.realloc(aSourcePolyPolygon.Coordinates.getLength()); |
| |
| // Zeiger auf innere sequences holen |
| const drawing::PointSequence* pInnerSequence = aSourcePolyPolygon.Coordinates.getConstArray(); |
| drawing::FlagSequence* pInnerSequenceFlags = aSourcePolyPolygon.Flags.getArray(); |
| |
| for(sal_Int32 a(0); a < aSourcePolyPolygon.Coordinates.getLength(); a++) |
| { |
| pInnerSequenceFlags->realloc(pInnerSequence->getLength()); |
| drawing::PolygonFlags* pPolyFlags = pInnerSequenceFlags->getArray(); |
| |
| for(sal_Int32 b(0); b < pInnerSequence->getLength(); b++) |
| *pPolyFlags++ = drawing::PolygonFlags_NORMAL; |
| |
| // next run |
| pInnerSequence++; |
| pInnerSequenceFlags++; |
| } |
| |
| rValue <<= aSourcePolyPolygon; |
| } |
| |
| if( aDisplayName.getLength() ) |
| { |
| rImport.AddStyleDisplayName( XML_STYLE_FAMILY_SD_MARKER_ID, rStrName, |
| aDisplayName ); |
| rStrName = aDisplayName; |
| } |
| |
| } |
| |
| if( pViewBox ) |
| delete pViewBox; |
| |
| return bHasViewBox && bHasPathData; |
| } |
| |
| |
| //------------------------------------------------------------- |
| // Export |
| //------------------------------------------------------------- |
| |
| #ifndef SVX_LIGHT |
| |
| XMLMarkerStyleExport::XMLMarkerStyleExport( SvXMLExport& rExp ) |
| : rExport( rExp ) |
| { |
| } |
| |
| XMLMarkerStyleExport::~XMLMarkerStyleExport() |
| { |
| } |
| |
| sal_Bool XMLMarkerStyleExport::exportXML( |
| const OUString& rStrName, |
| const uno::Any& rValue ) |
| { |
| sal_Bool bRet(sal_False); |
| |
| if(rStrName.getLength()) |
| { |
| drawing::PolyPolygonBezierCoords aBezier; |
| |
| if(rValue >>= aBezier) |
| { |
| OUString aStrValue; |
| OUStringBuffer aOut; |
| |
| ///////////////// |
| // Name |
| sal_Bool bEncoded = sal_False; |
| OUString aStrName( rStrName ); |
| rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, |
| rExport.EncodeStyleName( aStrName, |
| &bEncoded ) ); |
| if( bEncoded ) |
| rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY_NAME, |
| aStrName ); |
| |
| ///////////////// |
| // Viewbox (viewBox="0 0 1500 1000") |
| sal_Int32 nMinX(0x7fffffff); |
| sal_Int32 nMaxX(0x80000000); |
| sal_Int32 nMinY(0x7fffffff); |
| sal_Int32 nMaxY(0x80000000); |
| sal_Int32 nOuterCnt(aBezier.Coordinates.getLength()); |
| drawing::PointSequence* pOuterSequence = aBezier.Coordinates.getArray(); |
| sal_Int32 a, b; |
| sal_Bool bClosed(sal_False); |
| |
| for (a = 0; a < nOuterCnt; a++) |
| { |
| drawing::PointSequence* pSequence = pOuterSequence++; |
| const awt::Point *pPoints = pSequence->getConstArray(); |
| sal_Int32 nPointCount(pSequence->getLength()); |
| |
| if(nPointCount) |
| { |
| const awt::Point aStart = pPoints[0]; |
| const awt::Point aEnd = pPoints[nPointCount - 1]; |
| |
| if(aStart.X == aEnd.X && aStart.Y == aEnd.Y) |
| { |
| bClosed = sal_True; |
| } |
| } |
| |
| for (b = 0; b < nPointCount; b++) |
| { |
| const awt::Point aPoint = pPoints[b]; |
| |
| if( aPoint.X < nMinX ) |
| nMinX = aPoint.X; |
| |
| if( aPoint.X > nMaxX ) |
| nMaxX = aPoint.X; |
| |
| if( aPoint.Y < nMinY ) |
| nMinY = aPoint.Y; |
| |
| if( aPoint.Y > nMaxY ) |
| nMaxY = aPoint.Y; |
| } |
| } |
| |
| sal_Int32 nDifX(nMaxX - nMinX); |
| sal_Int32 nDifY(nMaxY - nMinY); |
| |
| SdXMLImExViewBox aViewBox( 0, 0, nDifX, nDifY ); |
| rExport.AddAttribute( XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString() ); |
| |
| ///////////////// |
| // Pathdata |
| pOuterSequence = aBezier.Coordinates.getArray(); |
| drawing::FlagSequence* pOuterFlags = aBezier.Flags.getArray(); |
| SdXMLImExSvgDElement aSvgDElement(aViewBox); |
| |
| for (a = 0; a < nOuterCnt; a++) |
| { |
| drawing::PointSequence* pSequence = pOuterSequence++; |
| drawing::FlagSequence* pFlags = pOuterFlags++; |
| |
| aSvgDElement.AddPolygon(pSequence, pFlags, |
| awt::Point( 0, 0 ), |
| awt::Size( aViewBox.GetWidth(), aViewBox.GetHeight() ), |
| bClosed); |
| } |
| |
| // write point array |
| rExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString()); |
| |
| ///////////////// |
| // Do Write |
| SvXMLElementExport rElem( rExport, XML_NAMESPACE_DRAW, XML_MARKER, |
| sal_True, sal_False ); |
| } |
| } |
| |
| return bRet; |
| } |
| |
| #endif // #ifndef SVX_LIGHT |