diff options
author | Armin Le Grand <Armin.Le.Grand@Sun.COM> | 2009-11-17 13:39:34 +0100 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@Sun.COM> | 2009-11-17 13:39:34 +0100 |
commit | 1d11db194dd5d81983f934ac93a214bf38af58ae (patch) | |
tree | d4e1d225142206a6af5da1d081dec7c5e20b2c1c /drawinglayer | |
parent | 15dcfdd7c813c4158a18c52c7ba22c14c7dac996 (diff) |
#i106541# Metafile decompose done
Diffstat (limited to 'drawinglayer')
18 files changed, 1175 insertions, 298 deletions
diff --git a/drawinglayer/inc/drawinglayer/attribute/fontattribute.hxx b/drawinglayer/inc/drawinglayer/attribute/fontattribute.hxx index f34ee913418f..d8eed659f5e7 100644 --- a/drawinglayer/inc/drawinglayer/attribute/fontattribute.hxx +++ b/drawinglayer/inc/drawinglayer/attribute/fontattribute.hxx @@ -92,6 +92,19 @@ namespace drawinglayer { } + FontAttribute() + : maFamilyName(), + maStyleName(), + mnWeight(0), + mbSymbol(false), + mbVertical(false), + mbItalic(false), + mbOutline(false), + mbRTL(false), + mbBiDiStrong(false) + { + } + /// compare operator bool operator==(const FontAttribute& rCompare) const; diff --git a/drawinglayer/inc/drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx index 82a568fc9ea1..85cf5e236d4f 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx @@ -46,7 +46,7 @@ namespace drawinglayer { namespace primitive2d { - /** AnimatedInterpolatePrimitive2D class + /** BackgroundColorPrimitive2D class This primitive is defined to fill the whole visible Viewport with the given color (and thus decomposes to a filled polygon). This diff --git a/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx index 477c3a19042a..d287482389b5 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx @@ -108,6 +108,7 @@ #define PRIMITIVE2D_ID_TEXTLINEPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 57) #define PRIMITIVE2D_ID_TEXTCHARACTERSTRIKEOUTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 58) #define PRIMITIVE2D_ID_TEXTGEOMETRYSTRIKEOUTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 59) +#define PRIMITIVE2D_ID_EPSPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 60) ////////////////////////////////////////////////////////////////////////////// diff --git a/drawinglayer/inc/drawinglayer/primitive2d/epsprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/epsprimitive2d.hxx new file mode 100644 index 000000000000..0ebb29e153ec --- /dev/null +++ b/drawinglayer/inc/drawinglayer/primitive2d/epsprimitive2d.hxx @@ -0,0 +1,96 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: backgroundcolorprimitive2d.hxx,v $ + * + * $Revision: 1.3 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:16 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_EPSPRIMITIVE2D_HXX +#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_EPSPRIMITIVE2D_HXX + +#include <drawinglayer/primitive2d/baseprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <vcl/gfxlink.hxx> +#include <vcl/gdimtf.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + /** EpsPrimitive2D class */ + class EpsPrimitive2D : public BufferedDecompositionPrimitive2D + { + private: + /// the geometry definition + basegfx::B2DHomMatrix maEpsTransform; + + /// the Eps content definition + GfxLink maGfxLink; + + /// the replacement content definition + GDIMetaFile maMetaFile; + + protected: + /// create local decomposition + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + public: + /// constructor + EpsPrimitive2D( + const basegfx::B2DHomMatrix& rEpsTransform, + const GfxLink& rGfxLink, + const GDIMetaFile& rMetaFile); + + /// data read access + const basegfx::B2DHomMatrix& getEpsTransform() const { return maEpsTransform; } + const GfxLink& getGfxLink() const { return maGfxLink; } + const GDIMetaFile& getMetaFile() const { return maMetaFile; } + + /// compare operator + virtual bool operator==(const BasePrimitive2D& rPrimitive) const; + + /// get B2Drange + virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; + + /// provide unique ID + DeclPrimitrive2DIDBlock() + }; + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_EPSPRIMITIVE2D_HXX + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx index 6c7ea8bd24c5..fe41c2e1824a 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx @@ -71,9 +71,9 @@ namespace drawinglayer basegfx::BColor maTextlineColor; TextLine meFontOverline; TextLine meFontUnderline; - FontStrikeout meFontStrikeout; - FontEmphasisMark meFontEmphasisMark; - FontRelief meFontRelief; + TextStrikeout meTextStrikeout; + TextEmphasisMark meTextEmphasisMark; + TextRelief meTextRelief; /// bitfield unsigned mbUnderlineAbove : 1; @@ -123,20 +123,20 @@ namespace drawinglayer TextLine eFontOverline = TEXT_LINE_NONE, TextLine eFontUnderline = TEXT_LINE_NONE, bool bUnderlineAbove = false, - FontStrikeout eFontStrikeout = FONT_STRIKEOUT_NONE, + TextStrikeout eTextStrikeout = TEXT_STRIKEOUT_NONE, bool bWordLineMode = false, - FontEmphasisMark eFontEmphasisMark = FONT_EMPHASISMARK_NONE, + TextEmphasisMark eTextEmphasisMark = TEXT_EMPHASISMARK_NONE, bool bEmphasisMarkAbove = true, bool bEmphasisMarkBelow = false, - FontRelief eFontRelief = FONT_RELIEF_NONE, + TextRelief eTextRelief = TEXT_RELIEF_NONE, bool bShadow = false); /// data read access TextLine getFontOverline() const { return meFontOverline; } TextLine getFontUnderline() const { return meFontUnderline; } - FontStrikeout getFontStrikeout() const { return meFontStrikeout; } - FontEmphasisMark getFontEmphasisMark() const { return meFontEmphasisMark; } - FontRelief getFontRelief() const { return meFontRelief; } + TextStrikeout getTextStrikeout() const { return meTextStrikeout; } + TextEmphasisMark getTextEmphasisMark() const { return meTextEmphasisMark; } + TextRelief getTextRelief() const { return meTextRelief; } basegfx::BColor getOverlineColor() const { return maOverlineColor; } basegfx::BColor getTextlineColor() const { return maTextlineColor; } bool getUnderlineAbove() const { return mbUnderlineAbove; } diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textenumsprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textenumsprimitive2d.hxx index ec2f7e656b40..b0e7dc8c241e 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/textenumsprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/textenumsprimitive2d.hxx @@ -37,6 +37,7 @@ #define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTENUMSPRIMITIVE2D_HXX #include <drawinglayer/primitive2d/baseprimitive2d.hxx> +#include <vcl/vclenum.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -70,33 +71,41 @@ namespace drawinglayer TEXT_LINE_BOLDWAVE }; + /** helper to convert LineStyle */ + TextLine mapFontUnderlineToTextLine(FontUnderline eLineStyle); + FontUnderline mapTextLineToFontUnderline(TextLine eLineStyle); + /** FontStrikeout definition */ - enum FontStrikeout + enum TextStrikeout { - FONT_STRIKEOUT_NONE, - FONT_STRIKEOUT_SINGLE, - FONT_STRIKEOUT_DOUBLE, - FONT_STRIKEOUT_BOLD, - FONT_STRIKEOUT_SLASH, - FONT_STRIKEOUT_X + TEXT_STRIKEOUT_NONE, + TEXT_STRIKEOUT_SINGLE, + TEXT_STRIKEOUT_DOUBLE, + TEXT_STRIKEOUT_BOLD, + TEXT_STRIKEOUT_SLASH, + TEXT_STRIKEOUT_X }; - /** FontEmphasisMark definition */ - enum FontEmphasisMark + /** helper to convert FontStrikeout */ + TextStrikeout mapFontStrikeoutToTextStrikeout(::FontStrikeout eFontStrikeout); + ::FontStrikeout mapTextStrikeoutToFontStrikeout(TextStrikeout eFontStrikeout); + + /** TextEmphasisMark definition */ + enum TextEmphasisMark { - FONT_EMPHASISMARK_NONE, - FONT_EMPHASISMARK_DOT, - FONT_EMPHASISMARK_CIRCLE, - FONT_EMPHASISMARK_DISC, - FONT_EMPHASISMARK_ACCENT + TEXT_EMPHASISMARK_NONE, + TEXT_EMPHASISMARK_DOT, + TEXT_EMPHASISMARK_CIRCLE, + TEXT_EMPHASISMARK_DISC, + TEXT_EMPHASISMARK_ACCENT }; - /** FontRelief definition */ - enum FontRelief + /** TextRelief definition */ + enum TextRelief { - FONT_RELIEF_NONE, - FONT_RELIEF_EMBOSSED, - FONT_RELIEF_ENGRAVED + TEXT_RELIEF_NONE, + TEXT_RELIEF_EMBOSSED, + TEXT_RELIEF_ENGRAVED }; } // end of namespace primitive2d diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx index 562eb681ddae..34d7d31fb93a 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx @@ -129,7 +129,7 @@ namespace drawinglayer private: double mfHeight; double mfOffset; - FontStrikeout meFontStrikeout; + TextStrikeout meTextStrikeout; protected: /// local decomposition. @@ -143,12 +143,12 @@ namespace drawinglayer const basegfx::BColor& rFontColor, double fHeight, double fOffset, - FontStrikeout eFontStrikeout); + TextStrikeout eTextStrikeout); /// data read access double getHeight() const { return mfHeight; } double getOffset() const { return mfOffset; } - FontStrikeout getFontStrikeout() const { return meFontStrikeout; } + TextStrikeout getTextStrikeout() const { return meTextStrikeout; } /// compare operator virtual bool operator==( const BasePrimitive2D& rPrimitive ) const; diff --git a/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx index 66ca140c2e56..ff77cc3fd5d0 100644 --- a/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx +++ b/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx @@ -64,6 +64,7 @@ namespace drawinglayer { namespace primitive2d { class PolygonStrokePrimitive2D; class ControlPrimitive2D; class PagePreviewPrimitive2D; + class EpsPrimitive2D; }} ////////////////////////////////////////////////////////////////////////////// @@ -113,6 +114,7 @@ namespace drawinglayer void RenderMarkerArrayPrimitive2D(const primitive2d::MarkerArrayPrimitive2D& rMarkerArrayCandidate); void RenderPointArrayPrimitive2D(const primitive2d::PointArrayPrimitive2D& rPointArrayCandidate); void RenderPolygonStrokePrimitive2D(const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokeCandidate); + void RenderEpsPrimitive2D(const primitive2d::EpsPrimitive2D& rEpsPrimitive2D); ///////////////////////////////////////////////////////////////////////////// // DrawMode adaption support diff --git a/drawinglayer/source/primitive2d/epsprimitive2d.cxx b/drawinglayer/source/primitive2d/epsprimitive2d.cxx new file mode 100644 index 000000000000..dc8128ab1386 --- /dev/null +++ b/drawinglayer/source/primitive2d/epsprimitive2d.cxx @@ -0,0 +1,111 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: backgroundcolorprimitive2d.cxx,v $ + * + * $Revision: 1.5 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:20 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_drawinglayer.hxx" + +#include <drawinglayer/primitive2d/epsprimitive2d.hxx> +#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> +#include <drawinglayer/primitive2d/metafileprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence EpsPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + Primitive2DSequence xRetval; + const GDIMetaFile& rSubstituteContent = getMetaFile(); + + if(rSubstituteContent.GetActionCount()) + { + // the default decomposition will use the Metafile replacement visualisation. + // To really use the Eps data, a renderer has to know and interpret this primitive + // directly. + xRetval.realloc(1); + + xRetval[0] = Primitive2DReference( + new MetafilePrimitive2D( + getEpsTransform(), + rSubstituteContent)); + } + + return xRetval; + } + + EpsPrimitive2D::EpsPrimitive2D( + const basegfx::B2DHomMatrix& rEpsTransform, + const GfxLink& rGfxLink, + const GDIMetaFile& rMetaFile) + : BufferedDecompositionPrimitive2D(), + maEpsTransform(rEpsTransform), + maGfxLink(rGfxLink), + maMetaFile(rMetaFile) + { + } + + bool EpsPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const EpsPrimitive2D& rCompare = (EpsPrimitive2D&)rPrimitive; + + return (getEpsTransform() == rCompare.getEpsTransform() + && getGfxLink().IsEqual(rCompare.getGfxLink()) + && getMetaFile() == rCompare.getMetaFile()); + } + + return false; + } + + basegfx::B2DRange EpsPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const + { + // use own implementation to quickly answer the getB2DRange question. + basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0); + aRetval.transform(getEpsTransform()); + + return aRetval; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(EpsPrimitive2D, PRIMITIVE2D_ID_EPSPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx index eca68858cbb5..d7d3929a7a56 100644 --- a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx @@ -689,6 +689,34 @@ namespace drawinglayer //delete pDXArray; } + if(false) + { + const double fHor(aRectangle.getWidth()); + const double fVer(aRectangle.getHeight()); + const Point aPointA( + aRectangle.Left() + basegfx::fround(fHor * 0.2), + aRectangle.Top() + basegfx::fround(fVer * 0.3)); + const Point aPointB( + aRectangle.Left() + basegfx::fround(fHor * 0.2), + aRectangle.Top() + basegfx::fround(fVer * 0.5)); + const Point aPointC( + aRectangle.Left() + basegfx::fround(fHor * 0.2), + aRectangle.Top() + basegfx::fround(fVer * 0.7)); + const String aText(ByteString("Hello, World!"), RTL_TEXTENCODING_UTF8); + + const String aFontName(ByteString("Comic Sans MS"), RTL_TEXTENCODING_UTF8); + Font aFont(aFontName, Size(0, 1000)); + aFont.SetAlign(ALIGN_BASELINE); + aFont.SetColor(COL_RED); + + aOut.SetFont(aFont); + const sal_Int32 nWidth(aOut.GetTextWidth(aText, 0, aText.Len())); + aOut.DrawText(aPointA, aText, 0, aText.Len()); + aOut.DrawTextLine(aPointA, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE); + aOut.DrawTextLine(aPointB, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE); + aOut.DrawTextLine(aPointC, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE); + } + aMtf.Stop(); aMtf.WindStart(); aMtf.SetPrefMapMode(MapMode(MAP_100TH_MM)); diff --git a/drawinglayer/source/primitive2d/makefile.mk b/drawinglayer/source/primitive2d/makefile.mk index 5da4d9c35587..c9a3cc191a35 100644 --- a/drawinglayer/source/primitive2d/makefile.mk +++ b/drawinglayer/source/primitive2d/makefile.mk @@ -55,6 +55,7 @@ SLOFILES= \ $(SLO)$/controlprimitive2d.obj \ $(SLO)$/discretebitmapprimitive2d.obj \ $(SLO)$/embedded3dprimitive2d.obj \ + $(SLO)$/epsprimitive2d.obj \ $(SLO)$/fillbitmapprimitive2d.obj \ $(SLO)$/fillgradientprimitive2d.obj \ $(SLO)$/fillhatchprimitive2d.obj \ @@ -78,6 +79,7 @@ SLOFILES= \ $(SLO)$/shadowprimitive2d.obj \ $(SLO)$/structuretagprimitive2d.obj \ $(SLO)$/texteffectprimitive2d.obj \ + $(SLO)$/textenumsprimitive2d.obj \ $(SLO)$/textlayoutdevice.obj \ $(SLO)$/textlineprimitive2d.obj \ $(SLO)$/textprimitive2d.obj \ diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx index a12172939e99..8434146c6f3a 100644 --- a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx @@ -68,6 +68,9 @@ #include <drawinglayer/primitive2d/textlayoutdevice.hxx> #include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx> #include <i18npool/mslangid.hxx> +#include <drawinglayer/primitive2d/textlineprimitive2d.hxx> +#include <drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx> +#include <drawinglayer/primitive2d/epsprimitive2d.hxx> #include <numeric> ////////////////////////////////////////////////////////////////////////////// @@ -78,12 +81,20 @@ using namespace com::sun::star; namespace { + /** helper class for graphic context + + This class allows to hold a complete status of classic + VCL OutputDevice stati. This data is needed for correct + interpretation of the MetaFile action flow. + */ class PropertyHolder { private: + /// current transformation (aka MapMode) basegfx::B2DHomMatrix maTransformation; MapUnit maMapUnit; + /// current colors basegfx::BColor maLineColor; basegfx::BColor maFillColor; basegfx::BColor maTextColor; @@ -91,13 +102,16 @@ namespace basegfx::BColor maTextLineColor; basegfx::BColor maOverlineColor; + /// clipping, font, etc. Region maRegion; Font maFont; RasterOp maRasterOp; sal_uInt32 mnLayoutMode; LanguageType maLanguageType; + sal_uInt16 mnPushFlags; /// bitfield + /// contains all active markers bool mbLineColor : 1; bool mbFillColor : 1; bool mbTextColor : 1; @@ -121,6 +135,7 @@ namespace maRasterOp(ROP_OVERPAINT), mnLayoutMode(0), maLanguageType(0), + mnPushFlags(0), mbLineColor(false), mbFillColor(false), mbTextColor(true), @@ -135,6 +150,7 @@ namespace { } + /// read/write accesses const basegfx::B2DHomMatrix& getTransformation() const { return maTransformation; } void setTransformation(const basegfx::B2DHomMatrix& rNew) { if(rNew != maTransformation) maTransformation = rNew; } @@ -191,6 +207,9 @@ namespace LanguageType getLanguageType() const { return maLanguageType; } void setLanguageType(LanguageType aNew) { if(aNew != maLanguageType) maLanguageType = aNew; } + sal_uInt16 getPushFlags() const { return mnPushFlags; } + void setPushFlags(sal_uInt16 nNew) { if(nNew != mnPushFlags) mnPushFlags = nNew; } + bool getLineOrFillActive() const { return (mbLineColor || mbFillColor); } }; } // end of anonymous namespace @@ -199,6 +218,15 @@ namespace namespace { + /** stack for properites + + This class builds a stack based on the PropertyHolder + class. It encapsulates the pointer/new/delete usage to + make it safe and implements the push/pop as needed by a + VCL Metafile interpreter. The critical part here are the + flag values VCL OutputDevice uses here; not all stuff is + pushed and thus needs to be copied at pop. + */ class PropertyHolders { private: @@ -215,33 +243,127 @@ namespace return maPropertyHolders.size(); } - void Push() + void Push(sal_uInt16 nPushFlags) { - OSL_ENSURE(maPropertyHolders.size(), "PropertyHolders: PUSH with no property holders (!)"); - maPropertyHolders.push_back(new PropertyHolder(*maPropertyHolders[maPropertyHolders.size() - 1])); + if(nPushFlags) + { + OSL_ENSURE(maPropertyHolders.size(), "PropertyHolders: PUSH with no property holders (!)"); + PropertyHolder* pNew = new PropertyHolder(*maPropertyHolders.back()); + pNew->setPushFlags(nPushFlags); + maPropertyHolders.push_back(pNew); + } } void Pop() { OSL_ENSURE(maPropertyHolders.size(), "PropertyHolders: POP with no property holders (!)"); - if(maPropertyHolders.size()) + const sal_uInt32 nSize(maPropertyHolders.size()); + + if(nSize) { - delete maPropertyHolders[maPropertyHolders.size() - 1]; - maPropertyHolders.pop_back(); + const PropertyHolder* pTip = maPropertyHolders.back(); + const sal_uInt16 nPushFlags(pTip->getPushFlags()); + + if(nPushFlags) + { + if(nSize > 1) + { + // copy back content for all non-set flags + PropertyHolder* pLast = maPropertyHolders[nSize - 2]; + + if(PUSH_ALL != nPushFlags) + { + if(!(nPushFlags & PUSH_LINECOLOR )) + { + pLast->setLineColor(pTip->getLineColor()); + pLast->setLineColorActive(pTip->getLineColorActive()); + } + if(!(nPushFlags & PUSH_FILLCOLOR )) + { + pLast->setFillColor(pTip->getFillColor()); + pLast->setFillColorActive(pTip->getFillColorActive()); + } + if(!(nPushFlags & PUSH_FONT )) + { + pLast->setFont(pTip->getFont()); + } + if(!(nPushFlags & PUSH_TEXTCOLOR )) + { + pLast->setTextColor(pTip->getTextColor()); + pLast->setTextColorActive(pTip->getTextColorActive()); + } + if(!(nPushFlags & PUSH_MAPMODE )) + { + pLast->setTransformation(pTip->getTransformation()); + pLast->setMapUnit(pTip->getMapUnit()); + } + if(!(nPushFlags & PUSH_CLIPREGION )) + { + pLast->setRegion(pTip->getRegion()); + pLast->setRegionActive(pTip->getRegionActive()); + } + if(!(nPushFlags & PUSH_RASTEROP )) + { + pLast->setRasterOp(pTip->getRasterOp()); + } + if(!(nPushFlags & PUSH_TEXTFILLCOLOR )) + { + pLast->setTextFillColor(pTip->getTextFillColor()); + pLast->setTextFillColorActive(pTip->getTextFillColorActive()); + } + if(!(nPushFlags & PUSH_TEXTALIGN )) + { + if(pLast->getFont().GetAlign() != pTip->getFont().GetAlign()) + { + Font aFont(pLast->getFont()); + aFont.SetAlign(pTip->getFont().GetAlign()); + pLast->setFont(aFont); + } + } + if(!(nPushFlags & PUSH_REFPOINT )) + { + // not supported + } + if(!(nPushFlags & PUSH_TEXTLINECOLOR )) + { + pLast->setTextLineColor(pTip->getTextLineColor()); + pLast->setTextLineColorActive(pTip->getTextLineColorActive()); + } + if(!(nPushFlags & PUSH_TEXTLAYOUTMODE )) + { + pLast->setLayoutMode(pTip->getLayoutMode()); + } + if(!(nPushFlags & PUSH_TEXTLANGUAGE )) + { + pLast->setLanguageType(pTip->getLanguageType()); + } + if(!(nPushFlags & PUSH_OVERLINECOLOR )) + { + pLast->setOverlineColor(pTip->getOverlineColor()); + pLast->setOverlineColorActive(pTip->getOverlineColorActive()); + } + } + } + + // execute the pop + delete maPropertyHolders.back(); + maPropertyHolders.pop_back(); + } } } PropertyHolder& Current() { OSL_ENSURE(maPropertyHolders.size(), "PropertyHolders: CURRENT with no property holders (!)"); - return *maPropertyHolders[maPropertyHolders.size() - 1]; + return *maPropertyHolders.back(); } ~PropertyHolders() { while(maPropertyHolders.size()) { - Pop(); + delete maPropertyHolders.back(); + maPropertyHolders.pop_back(); } } }; @@ -251,6 +373,13 @@ namespace namespace { + /** helper to convert a Region to a B2DPolyPolygon + when it does not yet contain one. In the future + this may be expanded to merge the polygons created + from rectangles or use a special algo to directly turn + the spans of regions to a single, already merged + PolyPolygon. + */ basegfx::B2DPolyPolygon getB2DPolyPolygonFromRegion(const Region& rRegion) { basegfx::B2DPolyPolygon aRetval; @@ -288,6 +417,12 @@ namespace namespace { + /** Helper class to buffer and hold a Primive target vector. It + encapsulates the new/delete functionality and aloows to work + on pointers of the implementation classes. All data will + be converted to uno sequences of uno references when accessing the + data. + */ class TargetHolder { private: @@ -369,6 +504,7 @@ namespace namespace { + /** Helper class which builds a stack on the TargetHolder class */ class TargetHolders { private: @@ -395,7 +531,7 @@ namespace OSL_ENSURE(maTargetHolders.size(), "TargetHolders: POP with no property holders (!)"); if(maTargetHolders.size()) { - delete maTargetHolders[maTargetHolders.size() - 1]; + delete maTargetHolders.back(); maTargetHolders.pop_back(); } } @@ -403,14 +539,15 @@ namespace TargetHolder& Current() { OSL_ENSURE(maTargetHolders.size(), "TargetHolders: CURRENT with no property holders (!)"); - return *maTargetHolders[maTargetHolders.size() - 1]; + return *maTargetHolders.back(); } ~TargetHolders() { while(maTargetHolders.size()) { - Pop(); + delete maTargetHolders.back(); + maTargetHolders.pop_back(); } } }; @@ -461,6 +598,7 @@ namespace drawinglayer namespace { + /** helper to convert a MapMode to a transformation */ basegfx::B2DHomMatrix getTransformFromMapMode(const MapMode& rMapMode) { basegfx::B2DHomMatrix aMapping; @@ -482,6 +620,7 @@ namespace return aMapping; } + /** helper to create a PointArrayPrimitive2D based on current context */ void createPointArrayPrimitive( const std::vector< basegfx::B2DPoint >& rPositions, TargetHolder& rTarget, @@ -514,6 +653,7 @@ namespace } } + /** helper to create a PolygonHairlinePrimitive2D based on current context */ void createHairlinePrimitive( const basegfx::B2DPolygon& rLinePolygon, TargetHolder& rTarget, @@ -530,6 +670,7 @@ namespace } } + /** helper to create a PolyPolygonColorPrimitive2D based on current context */ void createFillPrimitive( const basegfx::B2DPolyPolygon& rFillPolyPolygon, TargetHolder& rTarget, @@ -546,6 +687,7 @@ namespace } } + /** helper to create a PolygonStrokePrimitive2D based on current context */ void createLinePrimitive( const basegfx::B2DPolygon& rLinePolygon, const LineInfo& rLineInfo, @@ -611,6 +753,7 @@ namespace } } + /** helper to create needed line and fill primitives based on current context */ void createHairlineAndFillPrimitive( const basegfx::B2DPolygon& rPolygon, TargetHolder& rTarget, @@ -627,6 +770,7 @@ namespace } } + /** helper to create needed line and fill primitives based on current context */ void createHairlineAndFillPrimitive( const basegfx::B2DPolyPolygon& rPolyPolygon, TargetHolder& rTarget, @@ -646,6 +790,12 @@ namespace } } + /** helper to create DiscreteBitmapPrimitive2D based on current context. + The DiscreteBitmapPrimitive2D is especially created for this usage + since no other usage defines a bitmap visualisation based on top-left + position and size in pixels. At the end it will create a view-dependent + transformed embedding of a BitmapPrimitive2D. + */ void createBitmapExPrimitive( const BitmapEx& rBitmapEx, const Point& rPoint, @@ -664,6 +814,7 @@ namespace } } + /** helper to create BitmapPrimitive2D based on current context */ void createBitmapExPrimitive( const BitmapEx& rBitmapEx, const Point& rPoint, @@ -689,6 +840,10 @@ namespace } } + /** helper to create a regular BotmapEx from a MaskAction (definitions + which use a bitmap without alpha but define one of the colors as + transparent) + */ BitmapEx createMaskBmpEx(const Bitmap& rBitmap, const Color& rMaskColor) { const Color aWhite(COL_WHITE); @@ -705,6 +860,9 @@ namespace return BitmapEx(aSolid, aMask); } + /** helper to convert from a VCL Gradient definition to the corresponding + data for primitive representation + */ drawinglayer::attribute::FillGradientAttribute createFillGradientAttribute(const Gradient& rGradient) { const Color aStartColor(rGradient.GetStartColor()); @@ -774,6 +932,9 @@ namespace rGradient.GetSteps()); } + /** helper to convert from a VCL Hatch definition to the corresponding + data for primitive representation + */ drawinglayer::attribute::FillHatchAttribute createFillHatchAttribute(const Hatch& rHatch) { drawinglayer::attribute::HatchStyle aHatchStyle(drawinglayer::attribute::HATCHSTYLE_SINGLE); @@ -802,6 +963,12 @@ namespace false); } + /** helper to take needed action on ClipRegion change. This method needs to be called + on any Region change, e.g. at the obvious actions doing this, but also at pop-calls + whcih change the Region of the current context. It takes care of creating the + current embeddec context, set the new Region at the context and eventually prepare + a new target for embracing new geometry to the current region + */ void HandleNewClipRegion( const Region* pRegion, TargetHolders& rTargetHolders, @@ -828,7 +995,7 @@ namespace } // apply new settings - const bool bNewActive(pRegion); + const bool bNewActive(pRegion && !pRegion->IsEmpty()); rPropertyHolders.Current().setRegionActive(bNewActive); if(bNewActive) @@ -840,6 +1007,12 @@ namespace } } + /** helper to handle the change of RasterOp. It takes care of encapsulating all current + geometry to the current RasterOp (if changed) and needs to be called on any RasterOp + change. It will also start a new geometry target to embrace to the new RasterOp if + a changuing RasterOp is used. Currently, ROP_XOR and ROP_INVERT are supported using + InvertPrimitive2D, and ROP_0 by using a ModifiedColorPrimitive2D to force to black paint + */ void HandleNewRasterOp( RasterOp aRasterOp, TargetHolders& rTargetHolders, @@ -888,6 +1061,9 @@ namespace } } + /** helper to create needed data to emulate the VCL Wallpaper Metafile action. + It is a quite mighty action. This helper is for simple color filled background. + */ drawinglayer::primitive2d::BasePrimitive2D* CreateColorWallpaper( const basegfx::B2DRange& rRange, const basegfx::BColor& rColor, @@ -901,6 +1077,9 @@ namespace rColor); } + /** helper to create needed data to emulate the VCL Wallpaper Metafile action. + It is a quite mighty action. This helper is for gradient filled background. + */ drawinglayer::primitive2d::BasePrimitive2D* CreateGradientWallpaper( const basegfx::B2DRange& rRange, const Gradient& rGradient, @@ -935,6 +1114,12 @@ namespace } } + /** helper to create needed data to emulate the VCL Wallpaper Metafile action. + It is a quite mighty action. This helper decides if color and/or gradient + background is needed for the wnated bitmap fill and then creates the needed + WallpaperBitmapPrimitive2D. This primitive was created for this purpose and + takes over all needed logic of orientations and tiling. + */ void CreateAndAppendBitmapWallpaper( basegfx::B2DRange aWallpaperRange, const Wallpaper& rWallpaper, @@ -998,32 +1183,7 @@ namespace } } - drawinglayer::primitive2d::TextLine mapTextLineStyle(FontUnderline eLineStyle) - { - switch(eLineStyle) - { - case UNDERLINE_SINGLE: return drawinglayer::primitive2d::TEXT_LINE_SINGLE; - case UNDERLINE_DOUBLE: return drawinglayer::primitive2d::TEXT_LINE_DOUBLE; - case UNDERLINE_DOTTED: return drawinglayer::primitive2d::TEXT_LINE_DOTTED; - case UNDERLINE_DASH: return drawinglayer::primitive2d::TEXT_LINE_DASH; - case UNDERLINE_LONGDASH: return drawinglayer::primitive2d::TEXT_LINE_LONGDASH; - case UNDERLINE_DASHDOT: return drawinglayer::primitive2d::TEXT_LINE_DASHDOT; - case UNDERLINE_DASHDOTDOT: return drawinglayer::primitive2d::TEXT_LINE_DASHDOTDOT; - case UNDERLINE_SMALLWAVE: return drawinglayer::primitive2d::TEXT_LINE_SMALLWAVE; - case UNDERLINE_WAVE: return drawinglayer::primitive2d::TEXT_LINE_WAVE; - case UNDERLINE_DOUBLEWAVE: return drawinglayer::primitive2d::TEXT_LINE_DOUBLEWAVE; - case UNDERLINE_BOLD: return drawinglayer::primitive2d::TEXT_LINE_BOLD; - case UNDERLINE_BOLDDOTTED: return drawinglayer::primitive2d::TEXT_LINE_BOLDDOTTED; - case UNDERLINE_BOLDDASH: return drawinglayer::primitive2d::TEXT_LINE_BOLDDASH; - case UNDERLINE_BOLDLONGDASH: return drawinglayer::primitive2d::TEXT_LINE_BOLDLONGDASH; - case UNDERLINE_BOLDDASHDOT: return drawinglayer::primitive2d::TEXT_LINE_BOLDDASHDOT; - case UNDERLINE_BOLDDASHDOTDOT: return drawinglayer::primitive2d::TEXT_LINE_BOLDDASHDOTDOT; - case UNDERLINE_BOLDWAVE: return drawinglayer::primitive2d::TEXT_LINE_BOLDWAVE; - // FontUnderline_FORCE_EQUAL_SIZE, UNDERLINE_DONTKNOW, UNDERLINE_NONE - default: return drawinglayer::primitive2d::TEXT_LINE_NONE; - } - } - + /** helper to decide UnderlineAbove for text primitives */ bool isUnderlineAbove(const Font& rFont) { if(!rFont.IsVertical()) @@ -1040,6 +1200,53 @@ namespace return false; } + void createFontAttributeTransformAndAlignment( + drawinglayer::attribute::FontAttribute& rFontAttribute, + basegfx::B2DHomMatrix& rTextTransform, + basegfx::B2DVector& rAlignmentOffset, + PropertyHolder& rProperty) + { + const Font& rFont = rProperty.getFont(); + basegfx::B2DVector aFontScaling; + + rFontAttribute = drawinglayer::attribute::FontAttribute( + drawinglayer::primitive2d::getFontAttributeFromVclFont( + aFontScaling, + rFont, + 0 != (rProperty.getLayoutMode() & TEXT_LAYOUT_BIDI_RTL), + 0 != (rProperty.getLayoutMode() & TEXT_LAYOUT_BIDI_STRONG))); + + // add FontScaling + rTextTransform.scale(aFontScaling.getX(), aFontScaling.getY()); + + // take text align into account + if(ALIGN_BASELINE != rFont.GetAlign()) + { + drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice; + aTextLayouterDevice.setFont(rFont); + + if(ALIGN_TOP == rFont.GetAlign()) + { + rAlignmentOffset.setY(aTextLayouterDevice.getFontAscent()); + } + else // ALIGN_BOTTOM + { + rAlignmentOffset.setY(-aTextLayouterDevice.getFontDescent()); + } + + rTextTransform.translate(rAlignmentOffset.getX(), rAlignmentOffset.getY()); + } + + // add FontRotation (if used) + if(rFont.GetOrientation()) + { + rTextTransform.rotate(-rFont.GetOrientation() * F_PI1800); + } + } + + /** helper which takes complete care for creating the needed text primitives. It + takes care of decorated stuff and all the geometry adaptions needed + */ void proccessMetaTextAction( const Point& rTextStartPosition, const XubString& rText, @@ -1052,49 +1259,19 @@ namespace drawinglayer::primitive2d::BasePrimitive2D* pResult = 0; const Font& rFont = rProperty.getFont(); std::vector< double > aDXArray; + basegfx::B2DVector aAlignmentOffset(0.0, 0.0); if(nTextLength) { - // get current font and create FontScaling and FontAttribute - basegfx::B2DVector aFontScaling; - const drawinglayer::attribute::FontAttribute aFontAttribute( - drawinglayer::primitive2d::getFontAttributeFromVclFont( - aFontScaling, - rFont, - 0 != (rProperty.getLayoutMode() & TEXT_LAYOUT_BIDI_RTL), - 0 != (rProperty.getLayoutMode() & TEXT_LAYOUT_BIDI_STRONG))); - - // create TextTransform + drawinglayer::attribute::FontAttribute aFontAttribute; basegfx::B2DHomMatrix aTextTransform; - // add FontScaling - aTextTransform.scale(aFontScaling.getX(), aFontScaling.getY()); - - // take text align into account - if(ALIGN_BASELINE != rFont.GetAlign()) - { - drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice; - aTextLayouterDevice.setFont(rFont); - - if(ALIGN_TOP == rFont.GetAlign()) - { - aTextTransform.translate( - 0.0, - aTextLayouterDevice.getFontAscent()); - } - else // ALIGN_BOTTOM - { - aTextTransform.translate( - 0.0, - -aTextLayouterDevice.getFontDescent()); - } - } - - // add FontRotation (if used) - if(rFont.GetOrientation()) - { - aTextTransform.rotate(-rFont.GetOrientation() * F_PI1800); - } + // fill parameters derived from current font + createFontAttributeTransformAndAlignment( + aFontAttribute, + aTextTransform, + aAlignmentOffset, + rProperty); // add TextStartPosition aTextTransform.translate(rTextStartPosition.X(), rTextStartPosition.Y()); @@ -1126,47 +1303,35 @@ namespace if(bDecoratedIsNeeded) { - // prepare overline and underline data - const drawinglayer::primitive2d::TextLine eFontOverline(mapTextLineStyle(rFont.GetOverline())); - const drawinglayer::primitive2d::TextLine eFontUnderline(mapTextLineStyle(rFont.GetUnderline())); + // prepare overline, underline and srikeout data + const drawinglayer::primitive2d::TextLine eFontOverline(drawinglayer::primitive2d::mapFontUnderlineToTextLine(rFont.GetOverline())); + const drawinglayer::primitive2d::TextLine eFontUnderline(drawinglayer::primitive2d::mapFontUnderlineToTextLine(rFont.GetUnderline())); + const drawinglayer::primitive2d::TextStrikeout eTextStrikeout(drawinglayer::primitive2d::mapFontStrikeoutToTextStrikeout(rFont.GetStrikeout())); // check UndelineAbove const bool bUnderlineAbove(drawinglayer::primitive2d::TEXT_LINE_NONE != eFontUnderline && isUnderlineAbove(rFont)); - // prepare strikeout data - drawinglayer::primitive2d::FontStrikeout eFontStrikeout(drawinglayer::primitive2d::FONT_STRIKEOUT_NONE); - - switch(rFont.GetStrikeout()) - { - case STRIKEOUT_SINGLE: eFontStrikeout = drawinglayer::primitive2d::FONT_STRIKEOUT_SINGLE; break; - case STRIKEOUT_DOUBLE: eFontStrikeout = drawinglayer::primitive2d::FONT_STRIKEOUT_DOUBLE; break; - case STRIKEOUT_BOLD: eFontStrikeout = drawinglayer::primitive2d::FONT_STRIKEOUT_BOLD; break; - case STRIKEOUT_SLASH: eFontStrikeout = drawinglayer::primitive2d::FONT_STRIKEOUT_SLASH; break; - case STRIKEOUT_X: eFontStrikeout = drawinglayer::primitive2d::FONT_STRIKEOUT_X; break; - default : break; // FontStrikeout_FORCE_EQUAL_SIZE, STRIKEOUT_NONE, STRIKEOUT_DONTKNOW - } - // prepare emphasis mark data - drawinglayer::primitive2d::FontEmphasisMark eFontEmphasisMark(drawinglayer::primitive2d::FONT_EMPHASISMARK_NONE); + drawinglayer::primitive2d::TextEmphasisMark eTextEmphasisMark(drawinglayer::primitive2d::TEXT_EMPHASISMARK_NONE); switch(rFont.GetEmphasisMark() & EMPHASISMARK_STYLE) { - case EMPHASISMARK_DOT : eFontEmphasisMark = drawinglayer::primitive2d::FONT_EMPHASISMARK_DOT; break; - case EMPHASISMARK_CIRCLE : eFontEmphasisMark = drawinglayer::primitive2d::FONT_EMPHASISMARK_CIRCLE; break; - case EMPHASISMARK_DISC : eFontEmphasisMark = drawinglayer::primitive2d::FONT_EMPHASISMARK_DISC; break; - case EMPHASISMARK_ACCENT : eFontEmphasisMark = drawinglayer::primitive2d::FONT_EMPHASISMARK_ACCENT; break; + case EMPHASISMARK_DOT : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_DOT; break; + case EMPHASISMARK_CIRCLE : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_CIRCLE; break; + case EMPHASISMARK_DISC : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_DISC; break; + case EMPHASISMARK_ACCENT : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_ACCENT; break; } const bool bEmphasisMarkAbove(rFont.GetEmphasisMark() & EMPHASISMARK_POS_ABOVE); const bool bEmphasisMarkBelow(rFont.GetEmphasisMark() & EMPHASISMARK_POS_BELOW); // prepare font relief data - drawinglayer::primitive2d::FontRelief eFontRelief(drawinglayer::primitive2d::FONT_RELIEF_NONE); + drawinglayer::primitive2d::TextRelief eTextRelief(drawinglayer::primitive2d::TEXT_RELIEF_NONE); switch(rFont.GetRelief()) { - case RELIEF_EMBOSSED : eFontRelief = drawinglayer::primitive2d::FONT_RELIEF_EMBOSSED; break; - case RELIEF_ENGRAVED : eFontRelief = drawinglayer::primitive2d::FONT_RELIEF_ENGRAVED; break; + case RELIEF_EMBOSSED : eTextRelief = drawinglayer::primitive2d::TEXT_RELIEF_EMBOSSED; break; + case RELIEF_ENGRAVED : eTextRelief = drawinglayer::primitive2d::TEXT_RELIEF_ENGRAVED; break; default : break; // RELIEF_NONE, FontRelief_FORCE_EQUAL_SIZE } @@ -1192,12 +1357,12 @@ namespace eFontOverline, eFontUnderline, bUnderlineAbove, - eFontStrikeout, + eTextStrikeout, bWordLineMode, - eFontEmphasisMark, + eTextEmphasisMark, bEmphasisMarkAbove, bEmphasisMarkBelow, - eFontRelief, + eTextRelief, bShadow); } else @@ -1217,61 +1382,57 @@ namespace if(pResult && rProperty.getTextFillColorActive()) { + // text background is requested, add and encapsulate both to new primitive drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice; - const bool bRotated(rFont.GetOrientation()); + aTextLayouterDevice.setFont(rFont); + + // get text width + double fTextWidth(0.0); - if(bRotated) + if(aDXArray.empty()) { - // use unrotated font - Font aUnrotatedFont(rFont); - aUnrotatedFont.SetOrientation(0); - aTextLayouterDevice.setFont(aUnrotatedFont); + fTextWidth = aTextLayouterDevice.getTextWidth(rText, nTextStart, nTextLength); } else { - aTextLayouterDevice.setFont(rFont); + fTextWidth = aDXArray.back(); } - // get base range - basegfx::B2DRange aTextRange( - aTextLayouterDevice.getTextBoundRect( - rText, nTextStart, nTextLength)); - - if(aDXArray.size()) + if(basegfx::fTools::more(fTextWidth, 0.0)) { - // use the last entry in DXArray to correct the width - aTextRange = basegfx::B2DRange( - aTextRange.getMinX(), - aTextRange.getMinY(), - aTextRange.getMinX() + aDXArray[aDXArray.size() - 1], - aTextRange.getMaxY()); - } + // build text range + const basegfx::B2DRange aTextRange( + 0.0, -aTextLayouterDevice.getFontAscent(), + fTextWidth, aTextLayouterDevice.getFontDescent()); - // create Transform. Scale and Alignment are already applied. - basegfx::B2DHomMatrix aTextTransform; + // create Transform + basegfx::B2DHomMatrix aTextTransform; - if(bRotated) - { - aTextTransform.rotate(-rFont.GetOrientation() * F_PI1800); - } + aTextTransform.translate(aAlignmentOffset.getX(), aAlignmentOffset.getY()); - aTextTransform.translate(rTextStartPosition.X(), rTextStartPosition.Y()); + if(rFont.GetOrientation()) + { + aTextTransform.rotate(-rFont.GetOrientation() * F_PI1800); + } - // prepare Primitive2DSequence, put text in foreground - drawinglayer::primitive2d::Primitive2DSequence aSequence(2); - aSequence[1] = drawinglayer::primitive2d::Primitive2DReference(pResult); + aTextTransform.translate(rTextStartPosition.X(), rTextStartPosition.Y()); - // prepare filled polygon - basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aTextRange)); - aOutline.transform(aTextTransform); + // prepare Primitive2DSequence, put text in foreground + drawinglayer::primitive2d::Primitive2DSequence aSequence(2); + aSequence[1] = drawinglayer::primitive2d::Primitive2DReference(pResult); - aSequence[0] = drawinglayer::primitive2d::Primitive2DReference( - new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( - basegfx::B2DPolyPolygon(aOutline), - rProperty.getTextFillColor())); + // prepare filled polygon + basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aTextRange)); + aOutline.transform(aTextTransform); + + aSequence[0] = drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(aOutline), + rProperty.getTextFillColor())); - // set as group at pResult - pResult = new drawinglayer::primitive2d::GroupPrimitive2D(aSequence); + // set as group at pResult + pResult = new drawinglayer::primitive2d::GroupPrimitive2D(aSequence); + } } if(pResult) @@ -1294,6 +1455,173 @@ namespace } } + /** helper which takes complete care for creating the needed textLine primitives */ + void proccessMetaTextLineAction( + const MetaTextLineAction& rAction, + TargetHolder& rTarget, + PropertyHolder& rProperty) + { + const double fLineWidth(fabs((double)rAction.GetWidth())); + + if(fLineWidth > 0.0) + { + const drawinglayer::primitive2d::TextLine aOverlineMode(drawinglayer::primitive2d::mapFontUnderlineToTextLine(rAction.GetOverline())); + const drawinglayer::primitive2d::TextLine aUnderlineMode(drawinglayer::primitive2d::mapFontUnderlineToTextLine(rAction.GetUnderline())); + const drawinglayer::primitive2d::TextStrikeout aTextStrikeout(drawinglayer::primitive2d::mapFontStrikeoutToTextStrikeout(rAction.GetStrikeout())); + + const bool bOverlineUsed(drawinglayer::primitive2d::TEXT_LINE_NONE != aOverlineMode); + const bool bUnderlineUsed(drawinglayer::primitive2d::TEXT_LINE_NONE != aUnderlineMode); + const bool bStrikeoutUsed(drawinglayer::primitive2d::TEXT_STRIKEOUT_NONE != aTextStrikeout); + + if(bUnderlineUsed || bStrikeoutUsed || bOverlineUsed) + { + std::vector< drawinglayer::primitive2d::BasePrimitive2D* > aTargetVector; + basegfx::B2DVector aAlignmentOffset(0.0, 0.0); + drawinglayer::attribute::FontAttribute aFontAttribute; + basegfx::B2DHomMatrix aTextTransform; + + // fill parameters derived from current font + createFontAttributeTransformAndAlignment( + aFontAttribute, + aTextTransform, + aAlignmentOffset, + rProperty); + + // add TextStartPosition + aTextTransform.translate(rAction.GetStartPoint().X(), rAction.GetStartPoint().Y()); + + // prepare TextLayouter (used in most cases) + drawinglayer::primitive2d::TextLayouterDevice aTextLayouter; + aTextLayouter.setFont(rProperty.getFont()); + + if(bOverlineUsed) + { + // create primitive geometry for overline + aTargetVector.push_back( + new drawinglayer::primitive2d::TextLinePrimitive2D( + aTextTransform, + fLineWidth, + aTextLayouter.getOverlineOffset(), + aTextLayouter.getOverlineHeight(), + aOverlineMode, + rProperty.getOverlineColor())); + } + + if(bUnderlineUsed) + { + // create primitive geometry for underline + aTargetVector.push_back( + new drawinglayer::primitive2d::TextLinePrimitive2D( + aTextTransform, + fLineWidth, + aTextLayouter.getUnderlineOffset(), + aTextLayouter.getUnderlineHeight(), + aUnderlineMode, + rProperty.getTextLineColor())); + } + + if(bStrikeoutUsed) + { + // create primitive geometry for strikeout + if(drawinglayer::primitive2d::TEXT_STRIKEOUT_SLASH == aTextStrikeout + || drawinglayer::primitive2d::TEXT_STRIKEOUT_X == aTextStrikeout) + { + // strikeout with character + const sal_Unicode aStrikeoutChar( + drawinglayer::primitive2d::TEXT_STRIKEOUT_SLASH == aTextStrikeout ? '/' : 'X'); + const com::sun::star::lang::Locale aLocale(MsLangId::convertLanguageToLocale( + rProperty.getLanguageType())); + + aTargetVector.push_back( + new drawinglayer::primitive2d::TextCharacterStrikeoutPrimitive2D( + aTextTransform, + fLineWidth, + rProperty.getTextColor(), + aStrikeoutChar, + aFontAttribute, + aLocale)); + } + else + { + // strikeout with geometry + aTargetVector.push_back( + new drawinglayer::primitive2d::TextGeometryStrikeoutPrimitive2D( + aTextTransform, + fLineWidth, + rProperty.getTextColor(), + aTextLayouter.getUnderlineHeight(), + aTextLayouter.getStrikeoutOffset(), + aTextStrikeout)); + } + } + + if(aTargetVector.size()) + { + // add created text primitive to target + if(rProperty.getTransformation().isIdentity()) + { + for(sal_uInt32 a(0); a < aTargetVector.size(); a++) + { + rTarget.append(aTargetVector[a]); + } + } + else + { + // when a transformation is set, embed to it + drawinglayer::primitive2d::Primitive2DSequence xTargets(aTargetVector.size()); + + for(sal_uInt32 a(0); a < aTargetVector.size(); a++) + { + xTargets[a] = drawinglayer::primitive2d::Primitive2DReference(aTargetVector[a]); + } + + rTarget.append( + new drawinglayer::primitive2d::TransformPrimitive2D( + rProperty.getTransformation(), + xTargets)); + } + } + } + } + + } + + /** This is the main interpreter method. It is designed to handle the given Metafile + completely inside the given context and target. It may use and modify the context and + target. This design allows to call itself recursively wich adapted contexts and + targets as e.g. needed for the META_FLOATTRANSPARENT_ACTION where the content is expressed + as a metafile as sub-content. + + This interpreter is as free of VCL functionality as possible. It uses VCL data classes + (else reading the data would not be possible), but e.g. does NOT use a local OutputDevice + as most other MetaFile interpreters/exporters do to hold and work with the current context. + This is necessary to be able to get away from the strong internal VCL-binding. + + It tries to combine e.g. pixel and/or point actions and to stitch together single line primitives + where possible (which is not trivial with the possible line geometry definitions). + + It tries to handle clipping no longer as Regions and spans of Rectangles, but as PolyPolygon + ClipRegions with (where possible) high precision by using the best possible data quality + from the Region. The Region is unavoidable as data container, but nowadays allows the transport + of Polygon-based clip regions. Where this is not used, a Polygon is constructed from the + Region ranges. All primitive clipping uses the MaskPrimitive2D with Polygon-based clipping. + + I have marked the single MetaActions with: + + SIMPLE, DONE: + Simple, e.g nothing to do or value setting in the context + + CHECKED, WORKS WELL: + Thoroughly tested with extra written test code which created a replacement + Metafile just to test this action in various combinations + + NEEDS IMPLEMENTATION: + Not implemented and asserted, but also no usage found, neither in own Metafile + creations, nor in EMF/WMF imports (checked with a whole bunch of critical EMF/WMF + bugdocs) + + For more commens, see the single action implementations. + */ void interpretMetafile( const GDIMetaFile& rMetaFile, TargetHolders& rTargetHolders, @@ -1891,7 +2219,9 @@ namespace { if(rWallpaper.IsBitmap()) { - // create bitmap background + // create bitmap background. Caution: This + // also will create gradient/color background(s) + // when the bitmap is transparent or not tiled CreateAndAppendBitmapWallpaper( aWallpaperRange, rWallpaper, @@ -2160,6 +2490,9 @@ namespace case META_MAPMODE_ACTION : { /** CHECKED, WORKS WELL */ + // the most necessary MapMode to be interpreted is MAP_RELATIVE, + // but also the others may occur. Even not yet supported ones + // may need to be added here later const MetaMapModeAction* pA = (const MetaMapModeAction*)pAction; const MapMode& rMapMode = pA->GetMapMode(); basegfx::B2DHomMatrix aMapping; @@ -2216,6 +2549,34 @@ namespace /** SIMPLE, DONE */ const MetaFontAction* pA = (const MetaFontAction*)pAction; rPropertyHolders.Current().setFont(pA->GetFont()); + Size aFontSize(pA->GetFont().GetSize()); + + if(0 == aFontSize.Height()) + { + // this should not happen but i got Metafiles where this was the + // case. A height needs to be guessed (similar to OutputDevice::ImplNewFont()) + Font aCorrectedFont(pA->GetFont()); + + if(aFontSize.Width()) + { + // guess width + aFontSize = Size(0, aFontSize.Width() * 3); + } + else + { + // guess 21 pixel + aFontSize = Size(0, 21); + } + + if(aFontSize.Height() < 75) + { + // assume size is in pixels and convert + aFontSize = Application::GetDefaultDevice()->PixelToLogic(aFontSize, MAP_100TH_MM); + } + + aCorrectedFont.SetSize(aFontSize); + rPropertyHolders.Current().setFont(aCorrectedFont); + } // older Metafiles have no META_TEXTCOLOR_ACTION which defines // the FontColor now, so use the Font's color when not transparent @@ -2249,36 +2610,40 @@ namespace case META_PUSH_ACTION : { /** CHECKED, WORKS WELL */ - rPropertyHolders.Push(); + const MetaPushAction* pA = (const MetaPushAction*)pAction; + rPropertyHolders.Push(pA->GetFlags()); break; } case META_POP_ACTION : { /** CHECKED, WORKS WELL */ - if(rPropertyHolders.Current().getRegionActive()) + const bool bRegionMayChange(rPropertyHolders.Current().getPushFlags() & PUSH_CLIPREGION); + const bool bRasterOpMayChange(rPropertyHolders.Current().getPushFlags() & PUSH_RASTEROP); + + if(bRegionMayChange && rPropertyHolders.Current().getRegionActive()) { - // end clipping + // end evtl. clipping HandleNewClipRegion(0, rTargetHolders, rPropertyHolders); } - if(rPropertyHolders.Current().isRasterOpActive()) + if(bRasterOpMayChange && rPropertyHolders.Current().isRasterOpActive()) { - // end RasterOp + // end evtl. RasterOp HandleNewRasterOp(ROP_OVERPAINT, rTargetHolders, rPropertyHolders); } rPropertyHolders.Pop(); - if(rPropertyHolders.Current().isRasterOpActive()) + if(bRasterOpMayChange && rPropertyHolders.Current().isRasterOpActive()) { - // start RasterOp + // start evtl. RasterOp HandleNewRasterOp(rPropertyHolders.Current().getRasterOp(), rTargetHolders, rPropertyHolders); } - if(rPropertyHolders.Current().getRegionActive()) + if(bRegionMayChange && rPropertyHolders.Current().getRegionActive()) { - // start clipping + // start evtl. clipping HandleNewClipRegion(&rPropertyHolders.Current().getRegion(), rTargetHolders, rPropertyHolders); } @@ -2340,15 +2705,42 @@ namespace } case META_EPS_ACTION : { - /** NEEDS IMPLEMENTATION */ - OSL_ENSURE(false, "META_EPS_ACTION requested (!)"); + /** CHECKED, WORKS WELL */ + // To support this action, i have added a EpsPrimitive2D which will + // by default decompose to the Metafile replacement data. To support + // this EPS on screen, the renderer visualizing this has to support + // that primitive and visualize the Eps file (e.g. printing) const MetaEPSAction* pA = (const MetaEPSAction*)pAction; + const Rectangle aRectangle(pA->GetPoint(), pA->GetSize()); + + if(!aRectangle.IsEmpty()) + { + // create object transform + basegfx::B2DHomMatrix aObjectTransform; + + aObjectTransform.set(0, 0, aRectangle.GetWidth()); + aObjectTransform.set(1, 1, aRectangle.GetHeight()); + aObjectTransform.set(0, 2, aRectangle.Left()); + aObjectTransform.set(1, 2, aRectangle.Top()); + + // add current transformation + aObjectTransform = rPropertyHolders.Current().getTransformation() * aObjectTransform; + + // embed using EpsPrimitive + rTargetHolders.Current().append( + new drawinglayer::primitive2d::EpsPrimitive2D( + aObjectTransform, + pA->GetLink(), + pA->GetSubstitute())); + } + break; } case META_REFPOINT_ACTION : { /** SIMPLE, DONE */ - // only used for hatch and line pattern offsets + // only used for hatch and line pattern offsets, pretty much no longer + // supported today // const MetaRefPointAction* pA = (const MetaRefPointAction*)pAction; break; } @@ -2366,12 +2758,21 @@ namespace } case META_TEXTLINE_ACTION : { - /** NEEDS IMPLEMENTATION */ - OSL_ENSURE(false, "META_TEXTLINE_ACTION requested (!)"); + /** CHECKED, WORKS WELL */ // actually creates overline, underline and strikeouts, so // these should be isolated from TextDecoratedPortionPrimitive2D - // to own primitives... + // to own primitives. Done, available now. + // + // This Metaaction seems not to be used (was not used in any + // checked files). It's used in combination with the current + // Font. const MetaTextLineAction* pA = (const MetaTextLineAction*)pAction; + + proccessMetaTextLineAction( + *pA, + rTargetHolders.Current(), + rPropertyHolders.Current()); + break; } case META_FLOATTRANSPARENT_ACTION : @@ -2386,7 +2787,8 @@ namespace if(rContent.GetActionCount()) { - // create the sub-content + // create the sub-content with no embedding specific to the + // sub-metafile, this seems not to be used. drawinglayer::primitive2d::Primitive2DSequence xSubContent; { rTargetHolders.Push(); @@ -2438,7 +2840,8 @@ namespace case META_GRADIENTEX_ACTION : { /** SIMPLE, DONE */ - // This is only a data holder which is interpreted inside comment actions + // This is only a data holder which is interpreted inside comment actions, + // see META_COMMENT_ACTION for more info // const MetaGradientExAction* pA = (const MetaGradientExAction*)pAction; break; } @@ -2470,9 +2873,78 @@ namespace } case META_COMMENT_ACTION : { - /** NEEDS IMPLEMENTATION */ - OSL_ENSURE(false, "META_COMMENT_ACTION requested (!)"); + /** CHECKED, WORKS WELL */ + // I already implemented + // XPATHFILL_SEQ_BEGIN, XPATHFILL_SEQ_END + // XPATHSTROKE_SEQ_BEGIN, XPATHSTROKE_SEQ_END, + // but opted to remove these again; it works well without them + // and makes the code less dependent from those Metafile Add-Ons const MetaCommentAction* pA = (const MetaCommentAction*)pAction; + + if(COMPARE_EQUAL == pA->GetComment().CompareIgnoreCaseToAscii("XGRAD_SEQ_BEGIN")) + { + // XGRAD_SEQ_BEGIN, XGRAD_SEQ_END should be supported since the + // pure recorded paint of the gradients uses the XOR paint functionality + // ('trick'). This is (and will be) broblematic with AntAliasing, so it's + // better to use this info + const MetaGradientExAction* pMetaGradientExAction = 0; + bool bDone(false); + sal_uInt32 b(a + 1); + + for(; !bDone && b < nCount; b++) + { + pAction = rMetaFile.GetAction(b); + + if(META_GRADIENTEX_ACTION == pAction->GetType()) + { + pMetaGradientExAction = (const MetaGradientExAction*)pAction; + } + else if(META_COMMENT_ACTION == pAction->GetType()) + { + if(COMPARE_EQUAL == ((const MetaCommentAction*)pAction)->GetComment().CompareIgnoreCaseToAscii("XGRAD_SEQ_END")) + { + bDone = true; + } + } + } + + if(bDone && pMetaGradientExAction) + { + // consume actions and skip forward + a = b - 1; + + // get geometry data + basegfx::B2DPolyPolygon aPolyPolygon(pMetaGradientExAction->GetPolyPolygon().getB2DPolyPolygon()); + + if(aPolyPolygon.count()) + { + // transform geometry + aPolyPolygon.transform(rPropertyHolders.Current().getTransformation()); + + // get and check if gradient is a real gradient + const Gradient& rGradient = pMetaGradientExAction->GetGradient(); + const drawinglayer::attribute::FillGradientAttribute aAttribute(createFillGradientAttribute(rGradient)); + + if(aAttribute.getStartColor() == aAttribute.getEndColor()) + { + // not really a gradient + rTargetHolders.Current().append( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + aPolyPolygon, + aAttribute.getStartColor())); + } + else + { + // really a gradient + rTargetHolders.Current().append( + new drawinglayer::primitive2d::PolyPolygonGradientPrimitive2D( + aPolyPolygon, + aAttribute)); + } + } + } + } + break; } default: @@ -2493,25 +2965,33 @@ namespace drawinglayer { Primitive2DSequence MetafilePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { + // prepare target and porperties; each will have one default entry TargetHolders aTargetHolders; PropertyHolders aPropertyHolders; + // interpret the Metafile interpretMetafile(getMetaFile(), aTargetHolders, aPropertyHolders, rViewInformation); - Primitive2DSequence xRetval = aTargetHolders.Current().getPrimitive2DSequence(aPropertyHolders.Current()); - if(xRetval.hasElements()) + // get the content. There should be ony one target, as in the start condition, + // but iterating will be the right thing to do when some push/pop is not closed + Primitive2DSequence xRetval; + + while(aTargetHolders.size() > 1) { - Rectangle aMtfTarget(getMetaFile().GetPrefMapMode().GetOrigin(), getMetaFile().GetPrefSize()); + appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, + aTargetHolders.Current().getPrimitive2DSequence(aPropertyHolders.Current())); + aTargetHolders.Pop(); + } - if(MAP_PIXEL == getMetaFile().GetPrefMapMode().GetMapUnit()) - { - aMtfTarget = Application::GetDefaultDevice()->PixelToLogic(aMtfTarget, MAP_100TH_MM); - } - else - { - aMtfTarget = Application::GetDefaultDevice()->LogicToLogic(aMtfTarget, getMetaFile().GetPrefMapMode(), MAP_100TH_MM); - } + appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, + aTargetHolders.Current().getPrimitive2DSequence(aPropertyHolders.Current())); + if(xRetval.hasElements()) + { + // get target size + const Rectangle aMtfTarget(getMetaFile().GetPrefMapMode().GetOrigin(), getMetaFile().GetPrefSize()); + + // create transformation basegfx::B2DHomMatrix aAdaptedTransform; aAdaptedTransform.translate(-aMtfTarget.Left(), -aMtfTarget.Top()); @@ -2520,6 +3000,7 @@ namespace drawinglayer aMtfTarget.getHeight() ? 1.0 / aMtfTarget.getHeight() : 1.0); aAdaptedTransform = getTransform() * aAdaptedTransform; + // embed to target transformation const Primitive2DReference aEmbeddedTransform( new TransformPrimitive2D( aAdaptedTransform, @@ -2555,8 +3036,13 @@ namespace drawinglayer basegfx::B2DRange MetafilePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const { + // use own implementation to quickly answer the getB2DRange question. The + // MetafilePrimitive2D assumes that all geometry is inside of the shape. If + // this is not the case (i have already seen some wrong Metafiles) it should + // be embedded to a MaskPrimitive2D basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0); aRetval.transform(getTransform()); + return aRetval; } diff --git a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx index 9403df5376aa..f9d245f76a34 100644 --- a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx @@ -81,17 +81,13 @@ namespace drawinglayer // see if something else needs to be done const bool bOverlineUsed(TEXT_LINE_NONE != getFontOverline()); const bool bUnderlineUsed(TEXT_LINE_NONE != getFontUnderline()); - const bool bStrikeoutUsed(FONT_STRIKEOUT_NONE != getFontStrikeout()); + const bool bStrikeoutUsed(TEXT_STRIKEOUT_NONE != getTextStrikeout()); if(bUnderlineUsed || bStrikeoutUsed || bOverlineUsed) { // common preparations TextLayouterDevice aTextLayouter; - // unscaled is needed since scale contains already the font size - const basegfx::B2DHomMatrix aUnscaledTransform(basegfx::tools::createShearXRotateTranslateB2DHomMatrix( - rDecTrans.getShearX(), rDecTrans.getRotate(), rDecTrans.getTranslate())); - // TextLayouterDevice is needed to get metrics for text decorations like // underline/strikeout/emphasis marks from it. For setup, the font size is needed aTextLayouter.setFontAttribute( @@ -149,10 +145,10 @@ namespace drawinglayer if(bStrikeoutUsed) { // create primitive geometry for strikeout - if(FONT_STRIKEOUT_SLASH == getFontStrikeout() || FONT_STRIKEOUT_X == getFontStrikeout()) + if(TEXT_STRIKEOUT_SLASH == getTextStrikeout() || TEXT_STRIKEOUT_X == getTextStrikeout()) { // strikeout with character - const sal_Unicode aStrikeoutChar(FONT_STRIKEOUT_SLASH == getFontStrikeout() ? '/' : 'X'); + const sal_Unicode aStrikeoutChar(TEXT_STRIKEOUT_SLASH == getTextStrikeout() ? '/' : 'X'); rTarget.push_back(Primitive2DReference( new TextCharacterStrikeoutPrimitive2D( @@ -173,7 +169,7 @@ namespace drawinglayer getFontColor(), aTextLayouter.getUnderlineHeight(), aTextLayouter.getStrikeoutOffset(), - getFontStrikeout()))); + getTextStrikeout()))); } } } @@ -420,15 +416,15 @@ namespace drawinglayer } } - // Handle Shadow, Outline and FontRelief + // Handle Shadow, Outline and TextRelief if(aRetval.hasElements()) { - // outline AND shadow depend on NO FontRelief (see dialog) - const bool bHasFontRelief(FONT_RELIEF_NONE != getFontRelief()); - const bool bHasShadow(!bHasFontRelief && getShadow()); - const bool bHasOutline(!bHasFontRelief && getFontAttribute().getOutline()); + // outline AND shadow depend on NO TextRelief (see dialog) + const bool bHasTextRelief(TEXT_RELIEF_NONE != getTextRelief()); + const bool bHasShadow(!bHasTextRelief && getShadow()); + const bool bHasOutline(!bHasTextRelief && getFontAttribute().getOutline()); - if(bHasShadow || bHasFontRelief || bHasOutline) + if(bHasShadow || bHasTextRelief || bHasOutline) { Primitive2DReference aShadow; @@ -453,7 +449,7 @@ namespace drawinglayer aRetval)); } - if(bHasFontRelief) + if(bHasTextRelief) { // create emboss using an own helper primitive since this will // be view-dependent @@ -463,7 +459,7 @@ namespace drawinglayer if(bDefaultTextColor) { - if(FONT_RELIEF_ENGRAVED == getFontRelief()) + if(TEXT_RELIEF_ENGRAVED == getTextRelief()) { aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED_DEFAULT; } @@ -474,7 +470,7 @@ namespace drawinglayer } else { - if(FONT_RELIEF_ENGRAVED == getFontRelief()) + if(TEXT_RELIEF_ENGRAVED == getTextRelief()) { aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED; } @@ -535,21 +531,21 @@ namespace drawinglayer TextLine eFontOverline, TextLine eFontUnderline, bool bUnderlineAbove, - FontStrikeout eFontStrikeout, + TextStrikeout eTextStrikeout, bool bWordLineMode, - FontEmphasisMark eFontEmphasisMark, + TextEmphasisMark eTextEmphasisMark, bool bEmphasisMarkAbove, bool bEmphasisMarkBelow, - FontRelief eFontRelief, + TextRelief eTextRelief, bool bShadow) : TextSimplePortionPrimitive2D(rNewTransform, rText, aTextPosition, aTextLength, rDXArray, rFontAttribute, rLocale, rFontColor), maOverlineColor(rOverlineColor), maTextlineColor(rTextlineColor), meFontOverline(eFontOverline), meFontUnderline(eFontUnderline), - meFontStrikeout(eFontStrikeout), - meFontEmphasisMark(eFontEmphasisMark), - meFontRelief(eFontRelief), + meTextStrikeout(eTextStrikeout), + meTextEmphasisMark(eTextEmphasisMark), + meTextRelief(eTextRelief), mbUnderlineAbove(bUnderlineAbove), mbWordLineMode(bWordLineMode), mbEmphasisMarkAbove(bEmphasisMarkAbove), @@ -568,9 +564,9 @@ namespace drawinglayer && getTextlineColor() == rCompare.getTextlineColor() && getFontOverline() == rCompare.getFontOverline() && getFontUnderline() == rCompare.getFontUnderline() - && getFontStrikeout() == rCompare.getFontStrikeout() - && getFontEmphasisMark() == rCompare.getFontEmphasisMark() - && getFontRelief() == rCompare.getFontRelief() + && getTextStrikeout() == rCompare.getTextStrikeout() + && getTextEmphasisMark() == rCompare.getTextEmphasisMark() + && getTextRelief() == rCompare.getTextRelief() && getUnderlineAbove() == rCompare.getUnderlineAbove() && getWordLineMode() == rCompare.getWordLineMode() && getEmphasisMarkAbove() == rCompare.getEmphasisMarkAbove() @@ -589,9 +585,9 @@ namespace drawinglayer const bool bDecoratedIsNeeded( TEXT_LINE_NONE != getFontOverline() || TEXT_LINE_NONE != getFontUnderline() - || FONT_STRIKEOUT_NONE != getFontStrikeout() - || FONT_EMPHASISMARK_NONE != getFontEmphasisMark() - || FONT_RELIEF_NONE != getFontRelief() + || TEXT_STRIKEOUT_NONE != getTextStrikeout() + || TEXT_EMPHASISMARK_NONE != getTextEmphasisMark() + || TEXT_RELIEF_NONE != getTextRelief() || getShadow()); if(bDecoratedIsNeeded) diff --git a/drawinglayer/source/primitive2d/textenumsprimitive2d.cxx b/drawinglayer/source/primitive2d/textenumsprimitive2d.cxx new file mode 100644 index 000000000000..8b24668cb056 --- /dev/null +++ b/drawinglayer/source/primitive2d/textenumsprimitive2d.cxx @@ -0,0 +1,129 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: textprimitive2d.cxx,v $ + * + * $Revision: 1.22 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:20 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_drawinglayer.hxx" + +#include <drawinglayer/primitive2d/textenumsprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + TextLine mapFontUnderlineToTextLine(FontUnderline eLineStyle) + { + switch(eLineStyle) + { + case UNDERLINE_SINGLE: return TEXT_LINE_SINGLE; + case UNDERLINE_DOUBLE: return TEXT_LINE_DOUBLE; + case UNDERLINE_DOTTED: return TEXT_LINE_DOTTED; + case UNDERLINE_DASH: return TEXT_LINE_DASH; + case UNDERLINE_LONGDASH: return TEXT_LINE_LONGDASH; + case UNDERLINE_DASHDOT: return TEXT_LINE_DASHDOT; + case UNDERLINE_DASHDOTDOT: return TEXT_LINE_DASHDOTDOT; + case UNDERLINE_SMALLWAVE: return TEXT_LINE_SMALLWAVE; + case UNDERLINE_WAVE: return TEXT_LINE_WAVE; + case UNDERLINE_DOUBLEWAVE: return TEXT_LINE_DOUBLEWAVE; + case UNDERLINE_BOLD: return TEXT_LINE_BOLD; + case UNDERLINE_BOLDDOTTED: return TEXT_LINE_BOLDDOTTED; + case UNDERLINE_BOLDDASH: return TEXT_LINE_BOLDDASH; + case UNDERLINE_BOLDLONGDASH: return TEXT_LINE_BOLDLONGDASH; + case UNDERLINE_BOLDDASHDOT: return TEXT_LINE_BOLDDASHDOT; + case UNDERLINE_BOLDDASHDOTDOT: return TEXT_LINE_BOLDDASHDOTDOT; + case UNDERLINE_BOLDWAVE: return TEXT_LINE_BOLDWAVE; + // FontUnderline_FORCE_EQUAL_SIZE, UNDERLINE_DONTKNOW, UNDERLINE_NONE + default: return TEXT_LINE_NONE; + } + } + + FontUnderline mapTextLineToFontUnderline(TextLine eLineStyle) + { + switch(eLineStyle) + { + default: /*TEXT_LINE_NONE*/ return UNDERLINE_NONE; + case TEXT_LINE_SINGLE: return UNDERLINE_SINGLE; + case TEXT_LINE_DOUBLE: return UNDERLINE_DOUBLE; + case TEXT_LINE_DOTTED: return UNDERLINE_DOTTED; + case TEXT_LINE_DASH: return UNDERLINE_DASH; + case TEXT_LINE_LONGDASH: return UNDERLINE_LONGDASH; + case TEXT_LINE_DASHDOT: return UNDERLINE_DASHDOT; + case TEXT_LINE_DASHDOTDOT: return UNDERLINE_DASHDOTDOT; + case TEXT_LINE_SMALLWAVE: return UNDERLINE_SMALLWAVE; + case TEXT_LINE_WAVE: return UNDERLINE_WAVE; + case TEXT_LINE_DOUBLEWAVE: return UNDERLINE_DOUBLEWAVE; + case TEXT_LINE_BOLD: return UNDERLINE_BOLD; + case TEXT_LINE_BOLDDOTTED: return UNDERLINE_BOLDDOTTED; + case TEXT_LINE_BOLDDASH: return UNDERLINE_BOLDDASH; + case TEXT_LINE_BOLDLONGDASH: return UNDERLINE_LONGDASH; + case TEXT_LINE_BOLDDASHDOT: return UNDERLINE_BOLDDASHDOT; + case TEXT_LINE_BOLDDASHDOTDOT:return UNDERLINE_BOLDDASHDOT; + case TEXT_LINE_BOLDWAVE: return UNDERLINE_BOLDWAVE; + } + } + + TextStrikeout mapFontStrikeoutToTextStrikeout(FontStrikeout eFontStrikeout) + { + switch(eFontStrikeout) + { + case STRIKEOUT_SINGLE: return TEXT_STRIKEOUT_SINGLE; + case STRIKEOUT_DOUBLE: return TEXT_STRIKEOUT_DOUBLE; + case STRIKEOUT_BOLD: return TEXT_STRIKEOUT_BOLD; + case STRIKEOUT_SLASH: return TEXT_STRIKEOUT_SLASH; + case STRIKEOUT_X: return TEXT_STRIKEOUT_X; + // FontStrikeout_FORCE_EQUAL_SIZE, STRIKEOUT_NONE, STRIKEOUT_DONTKNOW + default: return TEXT_STRIKEOUT_NONE; + } + } + + FontStrikeout mapTextStrikeoutToFontStrikeout(TextStrikeout eTextStrikeout) + { + switch(eTextStrikeout) + { + default: /*case primitive2d::TEXT_STRIKEOUT_NONE*/ return STRIKEOUT_NONE; + case TEXT_STRIKEOUT_SINGLE: return STRIKEOUT_SINGLE; + case TEXT_STRIKEOUT_DOUBLE: return STRIKEOUT_DOUBLE; + case TEXT_STRIKEOUT_BOLD: return STRIKEOUT_BOLD; + case TEXT_STRIKEOUT_SLASH: return STRIKEOUT_SLASH; + case TEXT_STRIKEOUT_X: return STRIKEOUT_X; + } + } + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx b/drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx index 8b7d664dd62a..936c690d8af5 100644 --- a/drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx @@ -172,8 +172,8 @@ namespace drawinglayer { Primitive2DSequence TextGeometryStrikeoutPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { - OSL_ENSURE(FONT_STRIKEOUT_SLASH != getFontStrikeout() && FONT_STRIKEOUT_X != getFontStrikeout(), - "Wrong FONT_STRIKEOUT type; a TextCharacterStrikeoutPrimitive2D should be used (!)"); + OSL_ENSURE(TEXT_STRIKEOUT_SLASH != getTextStrikeout() && TEXT_STRIKEOUT_X != getTextStrikeout(), + "Wrong TEXT_STRIKEOUT type; a TextCharacterStrikeoutPrimitive2D should be used (!)"); // strikeout with geometry double fStrikeoutHeight(getHeight()); @@ -186,18 +186,18 @@ namespace drawinglayer getObjectTransformation().decompose(aScale, aTranslate, fRotate, fShearX); // set line attribute - switch(getFontStrikeout()) + switch(getTextStrikeout()) { - default : // case primitive2d::FONT_STRIKEOUT_SINGLE: + default : // case primitive2d::TEXT_STRIKEOUT_SINGLE: { break; } - case primitive2d::FONT_STRIKEOUT_DOUBLE: + case primitive2d::TEXT_STRIKEOUT_DOUBLE: { bDoubleLine = true; break; } - case primitive2d::FONT_STRIKEOUT_BOLD: + case primitive2d::TEXT_STRIKEOUT_BOLD: { fStrikeoutHeight *= 2.0; break; @@ -262,11 +262,11 @@ namespace drawinglayer const basegfx::BColor& rFontColor, double fHeight, double fOffset, - FontStrikeout eFontStrikeout) + TextStrikeout eTextStrikeout) : BaseTextStrikeoutPrimitive2D(rObjectTransformation, fWidth, rFontColor), mfHeight(fHeight), mfOffset(fOffset), - meFontStrikeout(eFontStrikeout) + meTextStrikeout(eTextStrikeout) { } @@ -278,7 +278,7 @@ namespace drawinglayer return (getHeight() == rCompare.getHeight() && getOffset() == rCompare.getOffset() - && getFontStrikeout() == rCompare.getFontStrikeout()); + && getTextStrikeout() == rCompare.getTextStrikeout()); } return false; diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx index 062af73f5f0a..a99115a095c4 100644 --- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx @@ -74,6 +74,7 @@ #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> #include <helperchartrenderer.hxx> #include <drawinglayer/primitive2d/hittestprimitive2d.hxx> +#include <drawinglayer/primitive2d/epsprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// // for PDFExtOutDevData Graphic support @@ -1805,6 +1806,11 @@ namespace drawinglayer break; } + case PRIMITIVE2D_ID_EPSPRIMITIVE2D : + { + RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate)); + break; + } default : { // process recursively diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index 51192f2dc72f..5a74b0471b7f 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -68,6 +68,7 @@ #include <cstdio> #include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx> #include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <drawinglayer/primitive2d/epsprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -235,6 +236,7 @@ namespace drawinglayer static bool bTestMetaFilePrimitiveDecomposition(true); if(bTestMetaFilePrimitiveDecomposition) { + // use new Metafile decomposition process(rCandidate.get2DDecomposition(getViewInformation2D())); } else @@ -557,6 +559,11 @@ namespace drawinglayer mpOutputDevice->SetAntialiasing(nAntiAliasing); break; } + case PRIMITIVE2D_ID_EPSPRIMITIVE2D : + { + RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate)); + break; + } default : { // process recursively diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx index 127d4845e672..40f3eebcc78b 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx @@ -64,6 +64,7 @@ #include <tools/diagnose_ex.h> #include <vcl/metric.hxx> #include <drawinglayer/primitive2d/textenumsprimitive2d.hxx> +#include <drawinglayer/primitive2d/epsprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// // control support @@ -100,34 +101,6 @@ namespace drawinglayer using ::com::sun::star::awt::XWindow; using ::com::sun::star::awt::PosSize::POSSIZE; - static FontUnderline mapTextLineStyle(drawinglayer::primitive2d::TextLine eLineStyle) - { - switch(eLineStyle) - { - default: - DBG_WARNING1( "DrawingLayer: Unknown text line style attribute (%d)!", eLineStyle ); - // fall through - case primitive2d::TEXT_LINE_NONE: return UNDERLINE_NONE; - case primitive2d::TEXT_LINE_SINGLE: return UNDERLINE_SINGLE; - case primitive2d::TEXT_LINE_DOUBLE: return UNDERLINE_DOUBLE; - case primitive2d::TEXT_LINE_DOTTED: return UNDERLINE_DOTTED; - case primitive2d::TEXT_LINE_DASH: return UNDERLINE_DASH; - case primitive2d::TEXT_LINE_LONGDASH: return UNDERLINE_LONGDASH; - case primitive2d::TEXT_LINE_DASHDOT: return UNDERLINE_DASHDOT; - case primitive2d::TEXT_LINE_DASHDOTDOT: return UNDERLINE_DASHDOTDOT; - case primitive2d::TEXT_LINE_SMALLWAVE: return UNDERLINE_SMALLWAVE; - case primitive2d::TEXT_LINE_WAVE: return UNDERLINE_WAVE; - case primitive2d::TEXT_LINE_DOUBLEWAVE: return UNDERLINE_DOUBLEWAVE; - case primitive2d::TEXT_LINE_BOLD: return UNDERLINE_BOLD; - case primitive2d::TEXT_LINE_BOLDDOTTED: return UNDERLINE_BOLDDOTTED; - case primitive2d::TEXT_LINE_BOLDDASH: return UNDERLINE_BOLDDASH; - case primitive2d::TEXT_LINE_BOLDLONGDASH: return UNDERLINE_LONGDASH; - case primitive2d::TEXT_LINE_BOLDDASHDOT: return UNDERLINE_BOLDDASHDOT; - case primitive2d::TEXT_LINE_BOLDDASHDOTDOT:return UNDERLINE_BOLDDASHDOT; - case primitive2d::TEXT_LINE_BOLDWAVE: return UNDERLINE_BOLDWAVE; - } - } - ////////////////////////////////////////////////////////////////////////////// // rendering support @@ -177,7 +150,7 @@ namespace drawinglayer mpOutputDevice->SetTextLineColor( Color(aTextlineColor) ); // set Overline attribute - const FontUnderline eFontOverline(mapTextLineStyle( pTCPP->getFontOverline() )); + const FontUnderline eFontOverline(mapTextLineToFontUnderline( pTCPP->getFontOverline() )); if( eFontOverline != UNDERLINE_NONE ) { aFont.SetOverline( eFontOverline ); @@ -188,7 +161,7 @@ namespace drawinglayer } // set Underline attribute - const FontUnderline eFontUnderline(mapTextLineStyle( pTCPP->getFontUnderline() )); + const FontUnderline eFontUnderline(mapTextLineToFontUnderline( pTCPP->getFontUnderline() )); if( eFontUnderline != UNDERLINE_NONE ) { aFont.SetUnderline( eFontUnderline ); @@ -199,35 +172,23 @@ namespace drawinglayer } // set Strikeout attribute - FontStrikeout eFontStrikeout = STRIKEOUT_NONE; - switch( pTCPP->getFontStrikeout() ) - { - default: - DBG_WARNING1( "DrawingLayer: Unknown strikeout attribute (%d)!", pTCPP->getFontStrikeout() ); - // fall through - case primitive2d::FONT_STRIKEOUT_NONE: eFontStrikeout = STRIKEOUT_NONE; break; - case primitive2d::FONT_STRIKEOUT_SINGLE: eFontStrikeout = STRIKEOUT_SINGLE; break; - case primitive2d::FONT_STRIKEOUT_DOUBLE: eFontStrikeout = STRIKEOUT_DOUBLE; break; - case primitive2d::FONT_STRIKEOUT_BOLD: eFontStrikeout = STRIKEOUT_BOLD; break; - case primitive2d::FONT_STRIKEOUT_SLASH: eFontStrikeout = STRIKEOUT_SLASH; break; - case primitive2d::FONT_STRIKEOUT_X: eFontStrikeout = STRIKEOUT_X; break; - } + const FontStrikeout eFontStrikeout(mapTextStrikeoutToFontStrikeout(pTCPP->getTextStrikeout())); if( eFontStrikeout != STRIKEOUT_NONE ) aFont.SetStrikeout( eFontStrikeout ); // set EmphasisMark attribute FontEmphasisMark eFontEmphasisMark = EMPHASISMARK_NONE; - switch( pTCPP->getFontEmphasisMark() ) + switch( pTCPP->getTextEmphasisMark() ) { default: - DBG_WARNING1( "DrawingLayer: Unknown EmphasisMark style (%d)!", pTCPP->getFontEmphasisMark() ); + DBG_WARNING1( "DrawingLayer: Unknown EmphasisMark style (%d)!", pTCPP->getTextEmphasisMark() ); // fall through - case primitive2d::FONT_EMPHASISMARK_NONE: eFontEmphasisMark = EMPHASISMARK_NONE; break; - case primitive2d::FONT_EMPHASISMARK_DOT: eFontEmphasisMark = EMPHASISMARK_DOT; break; - case primitive2d::FONT_EMPHASISMARK_CIRCLE: eFontEmphasisMark = EMPHASISMARK_CIRCLE; break; - case primitive2d::FONT_EMPHASISMARK_DISC: eFontEmphasisMark = EMPHASISMARK_DISC; break; - case primitive2d::FONT_EMPHASISMARK_ACCENT: eFontEmphasisMark = EMPHASISMARK_ACCENT; break; + case primitive2d::TEXT_EMPHASISMARK_NONE: eFontEmphasisMark = EMPHASISMARK_NONE; break; + case primitive2d::TEXT_EMPHASISMARK_DOT: eFontEmphasisMark = EMPHASISMARK_DOT; break; + case primitive2d::TEXT_EMPHASISMARK_CIRCLE: eFontEmphasisMark = EMPHASISMARK_CIRCLE; break; + case primitive2d::TEXT_EMPHASISMARK_DISC: eFontEmphasisMark = EMPHASISMARK_DISC; break; + case primitive2d::TEXT_EMPHASISMARK_ACCENT: eFontEmphasisMark = EMPHASISMARK_ACCENT; break; } if( eFontEmphasisMark != EMPHASISMARK_NONE ) @@ -243,14 +204,14 @@ namespace drawinglayer // set Relief attribute FontRelief eFontRelief = RELIEF_NONE; - switch( pTCPP->getFontRelief() ) + switch( pTCPP->getTextRelief() ) { default: - DBG_WARNING1( "DrawingLayer: Unknown Relief style (%d)!", pTCPP->getFontRelief() ); + DBG_WARNING1( "DrawingLayer: Unknown Relief style (%d)!", pTCPP->getTextRelief() ); // fall through - case primitive2d::FONT_RELIEF_NONE: eFontRelief = RELIEF_NONE; break; - case primitive2d::FONT_RELIEF_EMBOSSED: eFontRelief = RELIEF_EMBOSSED; break; - case primitive2d::FONT_RELIEF_ENGRAVED: eFontRelief = RELIEF_ENGRAVED; break; + case primitive2d::TEXT_RELIEF_NONE: eFontRelief = RELIEF_NONE; break; + case primitive2d::TEXT_RELIEF_EMBOSSED: eFontRelief = RELIEF_EMBOSSED; break; + case primitive2d::TEXT_RELIEF_ENGRAVED: eFontRelief = RELIEF_ENGRAVED; break; } if( eFontRelief != RELIEF_NONE ) @@ -1270,6 +1231,36 @@ namespace drawinglayer } } + void VclProcessor2D::RenderEpsPrimitive2D(const primitive2d::EpsPrimitive2D& rEpsPrimitive2D) + { + // The new decomposition of Metafiles made it necessary to add an Eps + // primitive to handle embedded Eps data. On some devices, this can be + // painted directly (mac, printer). Printer is handled in the + // VclMetafileProcessor2D by not decomposing the Metafiles at all. + // For Mac, the Eps should be painted directly, but unfortunately cannot + // be tested (only in the salgdi layer where true/false is returned). + // To risk nothing currently, always render it using VCL + basegfx::B2DRange aRange(0.0, 0.0, 1.0, 1.0); + aRange.transform(rEpsPrimitive2D.getEpsTransform()); + + if(!aRange.isEmpty()) + { + const Rectangle aRectangle( + (sal_Int32)floor(aRange.getMinX()), (sal_Int32)floor(aRange.getMinY()), + (sal_Int32)ceil(aRange.getMaxX()), (sal_Int32)ceil(aRange.getMaxY())); + + if(!aRectangle.IsEmpty()) + { + const GDIMetaFile& rMetafile = rEpsPrimitive2D.getMetaFile(); + mpOutputDevice->DrawEPS( + aRectangle.TopLeft(), + aRectangle.GetSize(), + rEpsPrimitive2D.getGfxLink(), + rMetafile.GetActionCount() ? const_cast<GDIMetaFile*>(&rMetafile) : 0); + } + } + } + void VclProcessor2D::adaptLineToFillDrawMode() const { const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); |