1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove 25*b1cdbd2cSJim Jagielski #include "precompiled_drawinglayer.hxx" 26*b1cdbd2cSJim Jagielski 27*b1cdbd2cSJim Jagielski #include <drawinglayer/processor2d/vclprocessor2d.hxx> 28*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/textprimitive2d.hxx> 29*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx> 30*b1cdbd2cSJim Jagielski #include <tools/debug.hxx> 31*b1cdbd2cSJim Jagielski #include <vcl/outdev.hxx> 32*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 33*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> 34*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolygontools.hxx> 35*b1cdbd2cSJim Jagielski #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx> 36*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx> 37*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 38*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/metafileprimitive2d.hxx> 39*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/maskprimitive2d.hxx> 40*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolypolygontools.hxx> 41*b1cdbd2cSJim Jagielski #include <vclhelperbufferdevice.hxx> 42*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> 43*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> 44*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/transparenceprimitive2d.hxx> 45*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 46*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx> 47*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx> 48*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx> 49*b1cdbd2cSJim Jagielski #include <svl/ctloptions.hxx> 50*b1cdbd2cSJim Jagielski #include <vcl/svapp.hxx> 51*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> 52*b1cdbd2cSJim Jagielski #include <tools/diagnose_ex.h> 53*b1cdbd2cSJim Jagielski #include <vcl/metric.hxx> 54*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/textenumsprimitive2d.hxx> 55*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/epsprimitive2d.hxx> 56*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/svggradientprimitive2d.hxx> 57*b1cdbd2cSJim Jagielski #include <basegfx/color/bcolor.hxx> 58*b1cdbd2cSJim Jagielski #include <basegfx/matrix/b2dhommatrixtools.hxx> 59*b1cdbd2cSJim Jagielski #include <vcl/graph.hxx> 60*b1cdbd2cSJim Jagielski 61*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 62*b1cdbd2cSJim Jagielski // control support 63*b1cdbd2cSJim Jagielski 64*b1cdbd2cSJim Jagielski #include <com/sun/star/awt/XWindow2.hpp> 65*b1cdbd2cSJim Jagielski #include <com/sun/star/awt/PosSize.hpp> 66*b1cdbd2cSJim Jagielski #include <com/sun/star/awt/XView.hpp> 67*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/controlprimitive2d.hxx> 68*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/textlayoutdevice.hxx> 69*b1cdbd2cSJim Jagielski 70*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 71*b1cdbd2cSJim Jagielski // for test, can be removed again 72*b1cdbd2cSJim Jagielski 73*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolygonclipper.hxx> 74*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dtrapezoid.hxx> 75*b1cdbd2cSJim Jagielski 76*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 77*b1cdbd2cSJim Jagielski 78*b1cdbd2cSJim Jagielski using namespace com::sun::star; 79*b1cdbd2cSJim Jagielski 80*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 81*b1cdbd2cSJim Jagielski 82*b1cdbd2cSJim Jagielski namespace 83*b1cdbd2cSJim Jagielski { calculateStepsForSvgGradient(const basegfx::BColor & rColorA,const basegfx::BColor & rColorB,double fDelta,double fDiscreteUnit)84*b1cdbd2cSJim Jagielski sal_uInt32 calculateStepsForSvgGradient(const basegfx::BColor& rColorA, const basegfx::BColor& rColorB, double fDelta, double fDiscreteUnit) 85*b1cdbd2cSJim Jagielski { 86*b1cdbd2cSJim Jagielski // use color distance, assume to do every color step 87*b1cdbd2cSJim Jagielski sal_uInt32 nSteps(basegfx::fround(rColorA.getDistance(rColorB) * 255.0)); 88*b1cdbd2cSJim Jagielski 89*b1cdbd2cSJim Jagielski if(nSteps) 90*b1cdbd2cSJim Jagielski { 91*b1cdbd2cSJim Jagielski // calc discrete length to change color each disctete unit (pixel) 92*b1cdbd2cSJim Jagielski const sal_uInt32 nDistSteps(basegfx::fround(fDelta / fDiscreteUnit)); 93*b1cdbd2cSJim Jagielski 94*b1cdbd2cSJim Jagielski nSteps = std::min(nSteps, nDistSteps); 95*b1cdbd2cSJim Jagielski } 96*b1cdbd2cSJim Jagielski 97*b1cdbd2cSJim Jagielski // reduce quality to 3 discrete units or every 3rd color step for rendering 98*b1cdbd2cSJim Jagielski nSteps /= 2; 99*b1cdbd2cSJim Jagielski 100*b1cdbd2cSJim Jagielski // roughly cut when too big or too small (not full quality, reduce complexity) 101*b1cdbd2cSJim Jagielski nSteps = std::min(nSteps, sal_uInt32(255)); 102*b1cdbd2cSJim Jagielski nSteps = std::max(nSteps, sal_uInt32(1)); 103*b1cdbd2cSJim Jagielski 104*b1cdbd2cSJim Jagielski return nSteps; 105*b1cdbd2cSJim Jagielski } 106*b1cdbd2cSJim Jagielski } // end of anonymous namespace 107*b1cdbd2cSJim Jagielski 108*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 109*b1cdbd2cSJim Jagielski 110*b1cdbd2cSJim Jagielski namespace drawinglayer 111*b1cdbd2cSJim Jagielski { 112*b1cdbd2cSJim Jagielski namespace processor2d 113*b1cdbd2cSJim Jagielski { 114*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 115*b1cdbd2cSJim Jagielski // UNO class usages 116*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::Reference; 117*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::UNO_QUERY; 118*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::UNO_QUERY_THROW; 119*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::Exception; 120*b1cdbd2cSJim Jagielski using ::com::sun::star::awt::XView; 121*b1cdbd2cSJim Jagielski using ::com::sun::star::awt::XGraphics; 122*b1cdbd2cSJim Jagielski using ::com::sun::star::awt::XWindow; 123*b1cdbd2cSJim Jagielski using ::com::sun::star::awt::PosSize::POSSIZE; 124*b1cdbd2cSJim Jagielski 125*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 126*b1cdbd2cSJim Jagielski // rendering support 127*b1cdbd2cSJim Jagielski 128*b1cdbd2cSJim Jagielski // directdraw of text simple portion or decorated portion primitive. When decorated, all the extra 129*b1cdbd2cSJim Jagielski // information is translated to VCL parameters and set at the font. 130*b1cdbd2cSJim Jagielski // Acceptance is restricted to no shearing and positive scaling in X and Y (no font mirroring 131*b1cdbd2cSJim Jagielski // for VCL) RenderTextSimpleOrDecoratedPortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D & rTextCandidate)132*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate) 133*b1cdbd2cSJim Jagielski { 134*b1cdbd2cSJim Jagielski // decompose matrix to have position and size of text 135*b1cdbd2cSJim Jagielski basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rTextCandidate.getTextTransform()); 136*b1cdbd2cSJim Jagielski basegfx::B2DVector aFontScaling, aTranslate; 137*b1cdbd2cSJim Jagielski double fRotate, fShearX; 138*b1cdbd2cSJim Jagielski aLocalTransform.decompose(aFontScaling, aTranslate, fRotate, fShearX); 139*b1cdbd2cSJim Jagielski bool bPrimitiveAccepted(false); 140*b1cdbd2cSJim Jagielski 141*b1cdbd2cSJim Jagielski if(basegfx::fTools::equalZero(fShearX)) 142*b1cdbd2cSJim Jagielski { 143*b1cdbd2cSJim Jagielski if(basegfx::fTools::less(aFontScaling.getX(), 0.0) && basegfx::fTools::less(aFontScaling.getY(), 0.0)) 144*b1cdbd2cSJim Jagielski { 145*b1cdbd2cSJim Jagielski // handle special case: If scale is negative in (x,y) (3rd quadrant), it can 146*b1cdbd2cSJim Jagielski // be expressed as rotation by PI. Use this since the Font rendering will not 147*b1cdbd2cSJim Jagielski // apply the negative scales in any form 148*b1cdbd2cSJim Jagielski aFontScaling = basegfx::absolute(aFontScaling); 149*b1cdbd2cSJim Jagielski fRotate += F_PI; 150*b1cdbd2cSJim Jagielski } 151*b1cdbd2cSJim Jagielski 152*b1cdbd2cSJim Jagielski if(basegfx::fTools::more(aFontScaling.getX(), 0.0) && basegfx::fTools::more(aFontScaling.getY(), 0.0)) 153*b1cdbd2cSJim Jagielski { 154*b1cdbd2cSJim Jagielski // Get the VCL font (use FontHeight as FontWidth) 155*b1cdbd2cSJim Jagielski Font aFont(primitive2d::getVclFontFromFontAttribute( 156*b1cdbd2cSJim Jagielski rTextCandidate.getFontAttribute(), 157*b1cdbd2cSJim Jagielski aFontScaling.getX(), 158*b1cdbd2cSJim Jagielski aFontScaling.getY(), 159*b1cdbd2cSJim Jagielski fRotate, 160*b1cdbd2cSJim Jagielski rTextCandidate.getLocale())); 161*b1cdbd2cSJim Jagielski 162*b1cdbd2cSJim Jagielski // handle additional font attributes 163*b1cdbd2cSJim Jagielski const primitive2d::TextDecoratedPortionPrimitive2D* pTCPP = 164*b1cdbd2cSJim Jagielski dynamic_cast<const primitive2d::TextDecoratedPortionPrimitive2D*>( &rTextCandidate ); 165*b1cdbd2cSJim Jagielski 166*b1cdbd2cSJim Jagielski if( pTCPP != NULL ) 167*b1cdbd2cSJim Jagielski { 168*b1cdbd2cSJim Jagielski 169*b1cdbd2cSJim Jagielski // set the color of text decorations 170*b1cdbd2cSJim Jagielski const basegfx::BColor aTextlineColor = maBColorModifierStack.getModifiedColor(pTCPP->getTextlineColor()); 171*b1cdbd2cSJim Jagielski mpOutputDevice->SetTextLineColor( Color(aTextlineColor) ); 172*b1cdbd2cSJim Jagielski 173*b1cdbd2cSJim Jagielski // set Overline attribute 174*b1cdbd2cSJim Jagielski const FontUnderline eFontOverline(primitive2d::mapTextLineToFontUnderline( pTCPP->getFontOverline() )); 175*b1cdbd2cSJim Jagielski if( eFontOverline != UNDERLINE_NONE ) 176*b1cdbd2cSJim Jagielski { 177*b1cdbd2cSJim Jagielski aFont.SetOverline( eFontOverline ); 178*b1cdbd2cSJim Jagielski const basegfx::BColor aOverlineColor = maBColorModifierStack.getModifiedColor(pTCPP->getOverlineColor()); 179*b1cdbd2cSJim Jagielski mpOutputDevice->SetOverlineColor( Color(aOverlineColor) ); 180*b1cdbd2cSJim Jagielski if( pTCPP->getWordLineMode() ) 181*b1cdbd2cSJim Jagielski aFont.SetWordLineMode( true ); 182*b1cdbd2cSJim Jagielski } 183*b1cdbd2cSJim Jagielski 184*b1cdbd2cSJim Jagielski // set Underline attribute 185*b1cdbd2cSJim Jagielski const FontUnderline eFontUnderline(primitive2d::mapTextLineToFontUnderline( pTCPP->getFontUnderline() )); 186*b1cdbd2cSJim Jagielski if( eFontUnderline != UNDERLINE_NONE ) 187*b1cdbd2cSJim Jagielski { 188*b1cdbd2cSJim Jagielski aFont.SetUnderline( eFontUnderline ); 189*b1cdbd2cSJim Jagielski if( pTCPP->getWordLineMode() ) 190*b1cdbd2cSJim Jagielski aFont.SetWordLineMode( true ); 191*b1cdbd2cSJim Jagielski //TODO: ??? if( pTCPP->getUnderlineAbove() ) 192*b1cdbd2cSJim Jagielski // aFont.SetUnderlineAbove( true ); 193*b1cdbd2cSJim Jagielski } 194*b1cdbd2cSJim Jagielski 195*b1cdbd2cSJim Jagielski // set Strikeout attribute 196*b1cdbd2cSJim Jagielski const FontStrikeout eFontStrikeout(primitive2d::mapTextStrikeoutToFontStrikeout(pTCPP->getTextStrikeout())); 197*b1cdbd2cSJim Jagielski 198*b1cdbd2cSJim Jagielski if( eFontStrikeout != STRIKEOUT_NONE ) 199*b1cdbd2cSJim Jagielski aFont.SetStrikeout( eFontStrikeout ); 200*b1cdbd2cSJim Jagielski 201*b1cdbd2cSJim Jagielski // set EmphasisMark attribute 202*b1cdbd2cSJim Jagielski FontEmphasisMark eFontEmphasisMark = EMPHASISMARK_NONE; 203*b1cdbd2cSJim Jagielski switch( pTCPP->getTextEmphasisMark() ) 204*b1cdbd2cSJim Jagielski { 205*b1cdbd2cSJim Jagielski default: 206*b1cdbd2cSJim Jagielski DBG_WARNING1( "DrawingLayer: Unknown EmphasisMark style (%d)!", pTCPP->getTextEmphasisMark() ); 207*b1cdbd2cSJim Jagielski // fall through 208*b1cdbd2cSJim Jagielski case primitive2d::TEXT_EMPHASISMARK_NONE: eFontEmphasisMark = EMPHASISMARK_NONE; break; 209*b1cdbd2cSJim Jagielski case primitive2d::TEXT_EMPHASISMARK_DOT: eFontEmphasisMark = EMPHASISMARK_DOT; break; 210*b1cdbd2cSJim Jagielski case primitive2d::TEXT_EMPHASISMARK_CIRCLE: eFontEmphasisMark = EMPHASISMARK_CIRCLE; break; 211*b1cdbd2cSJim Jagielski case primitive2d::TEXT_EMPHASISMARK_DISC: eFontEmphasisMark = EMPHASISMARK_DISC; break; 212*b1cdbd2cSJim Jagielski case primitive2d::TEXT_EMPHASISMARK_ACCENT: eFontEmphasisMark = EMPHASISMARK_ACCENT; break; 213*b1cdbd2cSJim Jagielski } 214*b1cdbd2cSJim Jagielski 215*b1cdbd2cSJim Jagielski if( eFontEmphasisMark != EMPHASISMARK_NONE ) 216*b1cdbd2cSJim Jagielski { 217*b1cdbd2cSJim Jagielski DBG_ASSERT( (pTCPP->getEmphasisMarkAbove() != pTCPP->getEmphasisMarkBelow()), 218*b1cdbd2cSJim Jagielski "DrawingLayer: Bad EmphasisMark position!" ); 219*b1cdbd2cSJim Jagielski if( pTCPP->getEmphasisMarkAbove() ) 220*b1cdbd2cSJim Jagielski eFontEmphasisMark |= EMPHASISMARK_POS_ABOVE; 221*b1cdbd2cSJim Jagielski else 222*b1cdbd2cSJim Jagielski eFontEmphasisMark |= EMPHASISMARK_POS_BELOW; 223*b1cdbd2cSJim Jagielski aFont.SetEmphasisMark( eFontEmphasisMark ); 224*b1cdbd2cSJim Jagielski } 225*b1cdbd2cSJim Jagielski 226*b1cdbd2cSJim Jagielski // set Relief attribute 227*b1cdbd2cSJim Jagielski FontRelief eFontRelief = RELIEF_NONE; 228*b1cdbd2cSJim Jagielski switch( pTCPP->getTextRelief() ) 229*b1cdbd2cSJim Jagielski { 230*b1cdbd2cSJim Jagielski default: 231*b1cdbd2cSJim Jagielski DBG_WARNING1( "DrawingLayer: Unknown Relief style (%d)!", pTCPP->getTextRelief() ); 232*b1cdbd2cSJim Jagielski // fall through 233*b1cdbd2cSJim Jagielski case primitive2d::TEXT_RELIEF_NONE: eFontRelief = RELIEF_NONE; break; 234*b1cdbd2cSJim Jagielski case primitive2d::TEXT_RELIEF_EMBOSSED: eFontRelief = RELIEF_EMBOSSED; break; 235*b1cdbd2cSJim Jagielski case primitive2d::TEXT_RELIEF_ENGRAVED: eFontRelief = RELIEF_ENGRAVED; break; 236*b1cdbd2cSJim Jagielski } 237*b1cdbd2cSJim Jagielski 238*b1cdbd2cSJim Jagielski if( eFontRelief != RELIEF_NONE ) 239*b1cdbd2cSJim Jagielski aFont.SetRelief( eFontRelief ); 240*b1cdbd2cSJim Jagielski 241*b1cdbd2cSJim Jagielski // set Shadow attribute 242*b1cdbd2cSJim Jagielski if( pTCPP->getShadow() ) 243*b1cdbd2cSJim Jagielski aFont.SetShadow( true ); 244*b1cdbd2cSJim Jagielski } 245*b1cdbd2cSJim Jagielski 246*b1cdbd2cSJim Jagielski // create transformed integer DXArray in view coordinate system 247*b1cdbd2cSJim Jagielski ::std::vector< sal_Int32 > aTransformedDXArray; 248*b1cdbd2cSJim Jagielski 249*b1cdbd2cSJim Jagielski if(rTextCandidate.getDXArray().size()) 250*b1cdbd2cSJim Jagielski { 251*b1cdbd2cSJim Jagielski aTransformedDXArray.reserve(rTextCandidate.getDXArray().size()); 252*b1cdbd2cSJim Jagielski const basegfx::B2DVector aPixelVector(maCurrentTransformation * basegfx::B2DVector(1.0, 0.0)); 253*b1cdbd2cSJim Jagielski const double fPixelVectorFactor(aPixelVector.getLength()); 254*b1cdbd2cSJim Jagielski 255*b1cdbd2cSJim Jagielski for(::std::vector< double >::const_iterator aStart(rTextCandidate.getDXArray().begin()); 256*b1cdbd2cSJim Jagielski aStart != rTextCandidate.getDXArray().end(); aStart++) 257*b1cdbd2cSJim Jagielski { 258*b1cdbd2cSJim Jagielski aTransformedDXArray.push_back(basegfx::fround((*aStart) * fPixelVectorFactor)); 259*b1cdbd2cSJim Jagielski } 260*b1cdbd2cSJim Jagielski } 261*b1cdbd2cSJim Jagielski 262*b1cdbd2cSJim Jagielski // set parameters and paint text snippet 263*b1cdbd2cSJim Jagielski const basegfx::BColor aRGBFontColor(maBColorModifierStack.getModifiedColor(rTextCandidate.getFontColor())); 264*b1cdbd2cSJim Jagielski const basegfx::B2DPoint aPoint(aLocalTransform * basegfx::B2DPoint(0.0, 0.0)); 265*b1cdbd2cSJim Jagielski const Point aStartPoint(basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY())); 266*b1cdbd2cSJim Jagielski const sal_uInt32 nOldLayoutMode(mpOutputDevice->GetLayoutMode()); 267*b1cdbd2cSJim Jagielski 268*b1cdbd2cSJim Jagielski if(rTextCandidate.getFontAttribute().getRTL()) 269*b1cdbd2cSJim Jagielski { 270*b1cdbd2cSJim Jagielski sal_uInt32 nRTLLayoutMode(nOldLayoutMode & ~(TEXT_LAYOUT_COMPLEX_DISABLED|TEXT_LAYOUT_BIDI_STRONG)); 271*b1cdbd2cSJim Jagielski nRTLLayoutMode |= TEXT_LAYOUT_BIDI_RTL|TEXT_LAYOUT_TEXTORIGIN_LEFT; 272*b1cdbd2cSJim Jagielski mpOutputDevice->SetLayoutMode(nRTLLayoutMode); 273*b1cdbd2cSJim Jagielski } 274*b1cdbd2cSJim Jagielski 275*b1cdbd2cSJim Jagielski mpOutputDevice->SetFont(aFont); 276*b1cdbd2cSJim Jagielski mpOutputDevice->SetTextColor(Color(aRGBFontColor)); 277*b1cdbd2cSJim Jagielski 278*b1cdbd2cSJim Jagielski if(aTransformedDXArray.size()) 279*b1cdbd2cSJim Jagielski { 280*b1cdbd2cSJim Jagielski mpOutputDevice->DrawTextArray( 281*b1cdbd2cSJim Jagielski aStartPoint, 282*b1cdbd2cSJim Jagielski rTextCandidate.getText(), 283*b1cdbd2cSJim Jagielski &(aTransformedDXArray[0]), 284*b1cdbd2cSJim Jagielski rTextCandidate.getTextPosition(), 285*b1cdbd2cSJim Jagielski rTextCandidate.getTextLength()); 286*b1cdbd2cSJim Jagielski } 287*b1cdbd2cSJim Jagielski else 288*b1cdbd2cSJim Jagielski { 289*b1cdbd2cSJim Jagielski mpOutputDevice->DrawText( 290*b1cdbd2cSJim Jagielski aStartPoint, 291*b1cdbd2cSJim Jagielski rTextCandidate.getText(), 292*b1cdbd2cSJim Jagielski rTextCandidate.getTextPosition(), 293*b1cdbd2cSJim Jagielski rTextCandidate.getTextLength()); 294*b1cdbd2cSJim Jagielski } 295*b1cdbd2cSJim Jagielski 296*b1cdbd2cSJim Jagielski if(rTextCandidate.getFontAttribute().getRTL()) 297*b1cdbd2cSJim Jagielski { 298*b1cdbd2cSJim Jagielski mpOutputDevice->SetLayoutMode(nOldLayoutMode); 299*b1cdbd2cSJim Jagielski } 300*b1cdbd2cSJim Jagielski 301*b1cdbd2cSJim Jagielski bPrimitiveAccepted = true; 302*b1cdbd2cSJim Jagielski } 303*b1cdbd2cSJim Jagielski } 304*b1cdbd2cSJim Jagielski 305*b1cdbd2cSJim Jagielski if(!bPrimitiveAccepted) 306*b1cdbd2cSJim Jagielski { 307*b1cdbd2cSJim Jagielski // let break down 308*b1cdbd2cSJim Jagielski process(rTextCandidate.get2DDecomposition(getViewInformation2D())); 309*b1cdbd2cSJim Jagielski } 310*b1cdbd2cSJim Jagielski } 311*b1cdbd2cSJim Jagielski 312*b1cdbd2cSJim Jagielski // direct draw of hairline RenderPolygonHairlinePrimitive2D(const primitive2d::PolygonHairlinePrimitive2D & rPolygonCandidate,bool bPixelBased)313*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderPolygonHairlinePrimitive2D(const primitive2d::PolygonHairlinePrimitive2D& rPolygonCandidate, bool bPixelBased) 314*b1cdbd2cSJim Jagielski { 315*b1cdbd2cSJim Jagielski const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rPolygonCandidate.getBColor())); 316*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(Color(aHairlineColor)); 317*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(); 318*b1cdbd2cSJim Jagielski 319*b1cdbd2cSJim Jagielski basegfx::B2DPolygon aLocalPolygon(rPolygonCandidate.getB2DPolygon()); 320*b1cdbd2cSJim Jagielski aLocalPolygon.transform(maCurrentTransformation); 321*b1cdbd2cSJim Jagielski 322*b1cdbd2cSJim Jagielski static bool bCheckTrapezoidDecomposition(false); 323*b1cdbd2cSJim Jagielski static bool bShowOutlinesThere(false); 324*b1cdbd2cSJim Jagielski if(bCheckTrapezoidDecomposition) 325*b1cdbd2cSJim Jagielski { 326*b1cdbd2cSJim Jagielski // clip against discrete ViewPort 327*b1cdbd2cSJim Jagielski const basegfx::B2DRange& rDiscreteViewport = getViewInformation2D().getDiscreteViewport(); 328*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aLocalPolyPolygon(basegfx::tools::clipPolygonOnRange( 329*b1cdbd2cSJim Jagielski aLocalPolygon, rDiscreteViewport, true, false)); 330*b1cdbd2cSJim Jagielski 331*b1cdbd2cSJim Jagielski if(aLocalPolyPolygon.count()) 332*b1cdbd2cSJim Jagielski { 333*b1cdbd2cSJim Jagielski // subdivide 334*b1cdbd2cSJim Jagielski aLocalPolyPolygon = basegfx::tools::adaptiveSubdivideByDistance( 335*b1cdbd2cSJim Jagielski aLocalPolyPolygon, 0.5); 336*b1cdbd2cSJim Jagielski 337*b1cdbd2cSJim Jagielski // trapezoidize 338*b1cdbd2cSJim Jagielski static double fLineWidth(2.0); 339*b1cdbd2cSJim Jagielski basegfx::B2DTrapezoidVector aB2DTrapezoidVector; 340*b1cdbd2cSJim Jagielski basegfx::tools::createLineTrapezoidFromB2DPolyPolygon(aB2DTrapezoidVector, aLocalPolyPolygon, fLineWidth); 341*b1cdbd2cSJim Jagielski 342*b1cdbd2cSJim Jagielski const sal_uInt32 nCount(aB2DTrapezoidVector.size()); 343*b1cdbd2cSJim Jagielski 344*b1cdbd2cSJim Jagielski if(nCount) 345*b1cdbd2cSJim Jagielski { 346*b1cdbd2cSJim Jagielski basegfx::BColor aInvPolygonColor(aHairlineColor); 347*b1cdbd2cSJim Jagielski aInvPolygonColor.invert(); 348*b1cdbd2cSJim Jagielski 349*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0); a < nCount; a++) 350*b1cdbd2cSJim Jagielski { 351*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon aTempPolygon(aB2DTrapezoidVector[a].getB2DPolygon()); 352*b1cdbd2cSJim Jagielski 353*b1cdbd2cSJim Jagielski if(bShowOutlinesThere) 354*b1cdbd2cSJim Jagielski { 355*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(Color(aHairlineColor)); 356*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(); 357*b1cdbd2cSJim Jagielski } 358*b1cdbd2cSJim Jagielski 359*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolygon(aTempPolygon); 360*b1cdbd2cSJim Jagielski 361*b1cdbd2cSJim Jagielski if(bShowOutlinesThere) 362*b1cdbd2cSJim Jagielski { 363*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(); 364*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(Color(aInvPolygonColor)); 365*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aTempPolygon, 0.0); 366*b1cdbd2cSJim Jagielski } 367*b1cdbd2cSJim Jagielski } 368*b1cdbd2cSJim Jagielski } 369*b1cdbd2cSJim Jagielski } 370*b1cdbd2cSJim Jagielski } 371*b1cdbd2cSJim Jagielski else 372*b1cdbd2cSJim Jagielski { 373*b1cdbd2cSJim Jagielski if(bPixelBased && getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete()) 374*b1cdbd2cSJim Jagielski { 375*b1cdbd2cSJim Jagielski // #i98289# 376*b1cdbd2cSJim Jagielski // when a Hairline is painted and AntiAliasing is on the option SnapHorVerLinesToDiscrete 377*b1cdbd2cSJim Jagielski // allows to suppress AntiAliasing for pure horizontal or vertical lines. This is done since 378*b1cdbd2cSJim Jagielski // not-AntiAliased such lines look more pleasing to the eye (e.g. 2D chart content). This 379*b1cdbd2cSJim Jagielski // NEEDS to be done in discrete coordinates, so only useful for pixel based rendering. 380*b1cdbd2cSJim Jagielski aLocalPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aLocalPolygon); 381*b1cdbd2cSJim Jagielski } 382*b1cdbd2cSJim Jagielski 383*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aLocalPolygon, 0.0); 384*b1cdbd2cSJim Jagielski } 385*b1cdbd2cSJim Jagielski } 386*b1cdbd2cSJim Jagielski 387*b1cdbd2cSJim Jagielski // direct draw of transformed BitmapEx primitive RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D & rBitmapCandidate)388*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate) 389*b1cdbd2cSJim Jagielski { 390*b1cdbd2cSJim Jagielski BitmapEx aBitmapEx(rBitmapCandidate.getBitmapEx()); 391*b1cdbd2cSJim Jagielski const basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rBitmapCandidate.getTransform()); 392*b1cdbd2cSJim Jagielski 393*b1cdbd2cSJim Jagielski if(maBColorModifierStack.count()) 394*b1cdbd2cSJim Jagielski { 395*b1cdbd2cSJim Jagielski aBitmapEx = aBitmapEx.ModifyBitmapEx(maBColorModifierStack); 396*b1cdbd2cSJim Jagielski 397*b1cdbd2cSJim Jagielski if(aBitmapEx.IsEmpty()) 398*b1cdbd2cSJim Jagielski { 399*b1cdbd2cSJim Jagielski // color gets completely replaced, get it 400*b1cdbd2cSJim Jagielski const basegfx::BColor aModifiedColor(maBColorModifierStack.getModifiedColor(basegfx::BColor())); 401*b1cdbd2cSJim Jagielski basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon()); 402*b1cdbd2cSJim Jagielski aPolygon.transform(aLocalTransform); 403*b1cdbd2cSJim Jagielski 404*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(Color(aModifiedColor)); 405*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(); 406*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolygon(aPolygon); 407*b1cdbd2cSJim Jagielski 408*b1cdbd2cSJim Jagielski return; 409*b1cdbd2cSJim Jagielski } 410*b1cdbd2cSJim Jagielski } 411*b1cdbd2cSJim Jagielski 412*b1cdbd2cSJim Jagielski // #122923# do no longer add Alpha channel here; the right place to do this is when really 413*b1cdbd2cSJim Jagielski // the own transformer is used (see OutputDevice::DrawTransformedBitmapEx). 414*b1cdbd2cSJim Jagielski 415*b1cdbd2cSJim Jagielski // draw using OutputDevice'sDrawTransformedBitmapEx 416*b1cdbd2cSJim Jagielski mpOutputDevice->DrawTransformedBitmapEx(aLocalTransform, aBitmapEx); 417*b1cdbd2cSJim Jagielski } 418*b1cdbd2cSJim Jagielski RenderFillGraphicPrimitive2D(const primitive2d::FillGraphicPrimitive2D & rFillBitmapCandidate)419*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderFillGraphicPrimitive2D(const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate) 420*b1cdbd2cSJim Jagielski { 421*b1cdbd2cSJim Jagielski const attribute::FillGraphicAttribute& rFillGraphicAttribute(rFillBitmapCandidate.getFillGraphic()); 422*b1cdbd2cSJim Jagielski bool bPrimitiveAccepted(false); 423*b1cdbd2cSJim Jagielski static bool bTryTilingDirect = true; 424*b1cdbd2cSJim Jagielski 425*b1cdbd2cSJim Jagielski // #121194# when tiling is used and content is bitmap-based, do direct tiling in the 426*b1cdbd2cSJim Jagielski // renderer on pixel base to ensure tight fitting. Do not do this when 427*b1cdbd2cSJim Jagielski // the fill is rotated or sheared. 428*b1cdbd2cSJim Jagielski 429*b1cdbd2cSJim Jagielski // ovveride static bool (for debug) and tiling is active 430*b1cdbd2cSJim Jagielski if(bTryTilingDirect && rFillGraphicAttribute.getTiling()) 431*b1cdbd2cSJim Jagielski { 432*b1cdbd2cSJim Jagielski // content is bitmap(ex) 433*b1cdbd2cSJim Jagielski // 434*b1cdbd2cSJim Jagielski // for SVG support, force decomposition when SVG is present. This will lead to use 435*b1cdbd2cSJim Jagielski // the primitive representation of the svg directly. 436*b1cdbd2cSJim Jagielski // 437*b1cdbd2cSJim Jagielski // when graphic is animated, force decomposition to use the correct graphic, else 438*b1cdbd2cSJim Jagielski // fill style will not be animated 439*b1cdbd2cSJim Jagielski if(GRAPHIC_BITMAP == rFillGraphicAttribute.getGraphic().GetType() 440*b1cdbd2cSJim Jagielski && !rFillGraphicAttribute.getGraphic().getSvgData().get() 441*b1cdbd2cSJim Jagielski && !rFillGraphicAttribute.getGraphic().IsAnimated()) 442*b1cdbd2cSJim Jagielski { 443*b1cdbd2cSJim Jagielski // decompose matrix to check for shear, rotate and mirroring 444*b1cdbd2cSJim Jagielski basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rFillBitmapCandidate.getTransformation()); 445*b1cdbd2cSJim Jagielski basegfx::B2DVector aScale, aTranslate; 446*b1cdbd2cSJim Jagielski double fRotate, fShearX; 447*b1cdbd2cSJim Jagielski aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX); 448*b1cdbd2cSJim Jagielski 449*b1cdbd2cSJim Jagielski // when nopt rotated/sheared 450*b1cdbd2cSJim Jagielski if(basegfx::fTools::equalZero(fRotate) && basegfx::fTools::equalZero(fShearX)) 451*b1cdbd2cSJim Jagielski { 452*b1cdbd2cSJim Jagielski // no shear or rotate, draw direct in pixel coordinates 453*b1cdbd2cSJim Jagielski bPrimitiveAccepted = true; 454*b1cdbd2cSJim Jagielski 455*b1cdbd2cSJim Jagielski // transform object range to device coordinates (pixels). Use 456*b1cdbd2cSJim Jagielski // the device transformation for better accuracy 457*b1cdbd2cSJim Jagielski basegfx::B2DRange aObjectRange(aTranslate, aTranslate + aScale); 458*b1cdbd2cSJim Jagielski aObjectRange.transform(mpOutputDevice->GetViewTransformation()); 459*b1cdbd2cSJim Jagielski 460*b1cdbd2cSJim Jagielski // extract discrete size of object 461*b1cdbd2cSJim Jagielski const sal_Int32 nOWidth(basegfx::fround(aObjectRange.getWidth())); 462*b1cdbd2cSJim Jagielski const sal_Int32 nOHeight(basegfx::fround(aObjectRange.getHeight())); 463*b1cdbd2cSJim Jagielski 464*b1cdbd2cSJim Jagielski // only do something when object has a size in discrete units 465*b1cdbd2cSJim Jagielski if(nOWidth > 0 && nOHeight > 0) 466*b1cdbd2cSJim Jagielski { 467*b1cdbd2cSJim Jagielski // transform graphic range to device coordinates (pixels). Use 468*b1cdbd2cSJim Jagielski // the device transformation for better accuracy 469*b1cdbd2cSJim Jagielski basegfx::B2DRange aGraphicRange(rFillGraphicAttribute.getGraphicRange()); 470*b1cdbd2cSJim Jagielski aGraphicRange.transform(mpOutputDevice->GetViewTransformation() * aLocalTransform); 471*b1cdbd2cSJim Jagielski 472*b1cdbd2cSJim Jagielski // extract discrete size of graphic 473*b1cdbd2cSJim Jagielski // caution: when getting to zero, nothing would be painted; thus, do not allow this 474*b1cdbd2cSJim Jagielski const sal_Int32 nBWidth(std::max(sal_Int32(1), basegfx::fround(aGraphicRange.getWidth()))); 475*b1cdbd2cSJim Jagielski const sal_Int32 nBHeight(std::max(sal_Int32(1), basegfx::fround(aGraphicRange.getHeight()))); 476*b1cdbd2cSJim Jagielski 477*b1cdbd2cSJim Jagielski // only do something when bitmap fill has a size in discrete units 478*b1cdbd2cSJim Jagielski if(nBWidth > 0 && nBHeight > 0) 479*b1cdbd2cSJim Jagielski { 480*b1cdbd2cSJim Jagielski // nBWidth, nBHeight is the pixel size of the neede bitmap. To not need to scale it 481*b1cdbd2cSJim Jagielski // in vcl many times, create a size-optimized version 482*b1cdbd2cSJim Jagielski const Size aNeededBitmapSizePixel(nBWidth, nBHeight); 483*b1cdbd2cSJim Jagielski BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx()); 484*b1cdbd2cSJim Jagielski static bool bEnablePreScaling(true); 485*b1cdbd2cSJim Jagielski const bool bPreScaled(bEnablePreScaling && nBWidth * nBHeight < (250 * 250)); 486*b1cdbd2cSJim Jagielski 487*b1cdbd2cSJim Jagielski // ... but only up to a maximum size, else it gets too expensive 488*b1cdbd2cSJim Jagielski if(bPreScaled) 489*b1cdbd2cSJim Jagielski { 490*b1cdbd2cSJim Jagielski // if color depth is below 24bit, expand before scaling for better quality. 491*b1cdbd2cSJim Jagielski // This is even needed for low colors, else the scale will produce 492*b1cdbd2cSJim Jagielski // a bitmap in gray or Black/White (!) 493*b1cdbd2cSJim Jagielski if(aBitmapEx.GetBitCount() < 24) 494*b1cdbd2cSJim Jagielski { 495*b1cdbd2cSJim Jagielski aBitmapEx.Convert(BMP_CONVERSION_24BIT); 496*b1cdbd2cSJim Jagielski } 497*b1cdbd2cSJim Jagielski 498*b1cdbd2cSJim Jagielski aBitmapEx.Scale(aNeededBitmapSizePixel, BMP_SCALE_INTERPOLATE); 499*b1cdbd2cSJim Jagielski } 500*b1cdbd2cSJim Jagielski 501*b1cdbd2cSJim Jagielski bool bPainted(false); 502*b1cdbd2cSJim Jagielski 503*b1cdbd2cSJim Jagielski if(maBColorModifierStack.count()) 504*b1cdbd2cSJim Jagielski { 505*b1cdbd2cSJim Jagielski // when color modifier, apply to bitmap 506*b1cdbd2cSJim Jagielski aBitmapEx = aBitmapEx.ModifyBitmapEx(maBColorModifierStack); 507*b1cdbd2cSJim Jagielski 508*b1cdbd2cSJim Jagielski // impModifyBitmapEx uses empty bitmap as sign to return that 509*b1cdbd2cSJim Jagielski // the content will be completely replaced to mono color, use shortcut 510*b1cdbd2cSJim Jagielski if(aBitmapEx.IsEmpty()) 511*b1cdbd2cSJim Jagielski { 512*b1cdbd2cSJim Jagielski // color gets completely replaced, get it 513*b1cdbd2cSJim Jagielski const basegfx::BColor aModifiedColor(maBColorModifierStack.getModifiedColor(basegfx::BColor())); 514*b1cdbd2cSJim Jagielski basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon()); 515*b1cdbd2cSJim Jagielski aPolygon.transform(aLocalTransform); 516*b1cdbd2cSJim Jagielski 517*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(Color(aModifiedColor)); 518*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(); 519*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolygon(aPolygon); 520*b1cdbd2cSJim Jagielski 521*b1cdbd2cSJim Jagielski bPainted = true; 522*b1cdbd2cSJim Jagielski } 523*b1cdbd2cSJim Jagielski } 524*b1cdbd2cSJim Jagielski 525*b1cdbd2cSJim Jagielski if(!bPainted) 526*b1cdbd2cSJim Jagielski { 527*b1cdbd2cSJim Jagielski sal_Int32 nBLeft(basegfx::fround(aGraphicRange.getMinX())); 528*b1cdbd2cSJim Jagielski sal_Int32 nBTop(basegfx::fround(aGraphicRange.getMinY())); 529*b1cdbd2cSJim Jagielski const sal_Int32 nOLeft(basegfx::fround(aObjectRange.getMinX())); 530*b1cdbd2cSJim Jagielski const sal_Int32 nOTop(basegfx::fround(aObjectRange.getMinY())); 531*b1cdbd2cSJim Jagielski sal_Int32 nPosX(0); 532*b1cdbd2cSJim Jagielski sal_Int32 nPosY(0); 533*b1cdbd2cSJim Jagielski 534*b1cdbd2cSJim Jagielski if(nBLeft > nOLeft) 535*b1cdbd2cSJim Jagielski { 536*b1cdbd2cSJim Jagielski const sal_Int32 nDiff((nBLeft / nBWidth) + 1); 537*b1cdbd2cSJim Jagielski 538*b1cdbd2cSJim Jagielski nPosX -= nDiff; 539*b1cdbd2cSJim Jagielski nBLeft -= nDiff * nBWidth; 540*b1cdbd2cSJim Jagielski } 541*b1cdbd2cSJim Jagielski 542*b1cdbd2cSJim Jagielski if(nBLeft + nBWidth <= nOLeft) 543*b1cdbd2cSJim Jagielski { 544*b1cdbd2cSJim Jagielski const sal_Int32 nDiff(-nBLeft / nBWidth); 545*b1cdbd2cSJim Jagielski 546*b1cdbd2cSJim Jagielski nPosX += nDiff; 547*b1cdbd2cSJim Jagielski nBLeft += nDiff * nBWidth; 548*b1cdbd2cSJim Jagielski } 549*b1cdbd2cSJim Jagielski 550*b1cdbd2cSJim Jagielski if(nBTop > nOTop) 551*b1cdbd2cSJim Jagielski { 552*b1cdbd2cSJim Jagielski const sal_Int32 nDiff((nBTop / nBHeight) + 1); 553*b1cdbd2cSJim Jagielski 554*b1cdbd2cSJim Jagielski nPosY -= nDiff; 555*b1cdbd2cSJim Jagielski nBTop -= nDiff * nBHeight; 556*b1cdbd2cSJim Jagielski } 557*b1cdbd2cSJim Jagielski 558*b1cdbd2cSJim Jagielski if(nBTop + nBHeight <= nOTop) 559*b1cdbd2cSJim Jagielski { 560*b1cdbd2cSJim Jagielski const sal_Int32 nDiff(-nBTop / nBHeight); 561*b1cdbd2cSJim Jagielski 562*b1cdbd2cSJim Jagielski nPosY += nDiff; 563*b1cdbd2cSJim Jagielski nBTop += nDiff * nBHeight; 564*b1cdbd2cSJim Jagielski } 565*b1cdbd2cSJim Jagielski 566*b1cdbd2cSJim Jagielski // prepare OutDev 567*b1cdbd2cSJim Jagielski const Point aEmptyPoint(0, 0); 568*b1cdbd2cSJim Jagielski const Rectangle aVisiblePixel(aEmptyPoint, mpOutputDevice->GetOutputSizePixel()); 569*b1cdbd2cSJim Jagielski const bool bWasEnabled(mpOutputDevice->IsMapModeEnabled()); 570*b1cdbd2cSJim Jagielski mpOutputDevice->EnableMapMode(false); 571*b1cdbd2cSJim Jagielski 572*b1cdbd2cSJim Jagielski // check if offset is used 573*b1cdbd2cSJim Jagielski const sal_Int32 nOffsetX(basegfx::fround(rFillGraphicAttribute.getOffsetX() * nBWidth)); 574*b1cdbd2cSJim Jagielski 575*b1cdbd2cSJim Jagielski if(nOffsetX) 576*b1cdbd2cSJim Jagielski { 577*b1cdbd2cSJim Jagielski // offset in X, so iterate over Y first and draw lines 578*b1cdbd2cSJim Jagielski for(sal_Int32 nYPos(nBTop); nYPos < nOTop + nOHeight; nYPos += nBHeight, nPosY++) 579*b1cdbd2cSJim Jagielski { 580*b1cdbd2cSJim Jagielski for(sal_Int32 nXPos(nPosY % 2 ? nBLeft - nBWidth + nOffsetX : nBLeft); 581*b1cdbd2cSJim Jagielski nXPos < nOLeft + nOWidth; nXPos += nBWidth) 582*b1cdbd2cSJim Jagielski { 583*b1cdbd2cSJim Jagielski const Rectangle aOutRectPixel(Point(nXPos, nYPos), aNeededBitmapSizePixel); 584*b1cdbd2cSJim Jagielski 585*b1cdbd2cSJim Jagielski if(aOutRectPixel.IsOver(aVisiblePixel)) 586*b1cdbd2cSJim Jagielski { 587*b1cdbd2cSJim Jagielski if(bPreScaled) 588*b1cdbd2cSJim Jagielski { 589*b1cdbd2cSJim Jagielski mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx); 590*b1cdbd2cSJim Jagielski } 591*b1cdbd2cSJim Jagielski else 592*b1cdbd2cSJim Jagielski { 593*b1cdbd2cSJim Jagielski mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aNeededBitmapSizePixel, aBitmapEx); 594*b1cdbd2cSJim Jagielski } 595*b1cdbd2cSJim Jagielski } 596*b1cdbd2cSJim Jagielski } 597*b1cdbd2cSJim Jagielski } 598*b1cdbd2cSJim Jagielski } 599*b1cdbd2cSJim Jagielski else 600*b1cdbd2cSJim Jagielski { 601*b1cdbd2cSJim Jagielski // check if offset is used 602*b1cdbd2cSJim Jagielski const sal_Int32 nOffsetY(basegfx::fround(rFillGraphicAttribute.getOffsetY() * nBHeight)); 603*b1cdbd2cSJim Jagielski 604*b1cdbd2cSJim Jagielski // possible offset in Y, so iterate over X first and draw columns 605*b1cdbd2cSJim Jagielski for(sal_Int32 nXPos(nBLeft); nXPos < nOLeft + nOWidth; nXPos += nBWidth, nPosX++) 606*b1cdbd2cSJim Jagielski { 607*b1cdbd2cSJim Jagielski for(sal_Int32 nYPos(nPosX % 2 ? nBTop - nBHeight + nOffsetY : nBTop); 608*b1cdbd2cSJim Jagielski nYPos < nOTop + nOHeight; nYPos += nBHeight) 609*b1cdbd2cSJim Jagielski { 610*b1cdbd2cSJim Jagielski const Rectangle aOutRectPixel(Point(nXPos, nYPos), aNeededBitmapSizePixel); 611*b1cdbd2cSJim Jagielski 612*b1cdbd2cSJim Jagielski if(aOutRectPixel.IsOver(aVisiblePixel)) 613*b1cdbd2cSJim Jagielski { 614*b1cdbd2cSJim Jagielski if(bPreScaled) 615*b1cdbd2cSJim Jagielski { 616*b1cdbd2cSJim Jagielski mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx); 617*b1cdbd2cSJim Jagielski } 618*b1cdbd2cSJim Jagielski else 619*b1cdbd2cSJim Jagielski { 620*b1cdbd2cSJim Jagielski mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aNeededBitmapSizePixel, aBitmapEx); 621*b1cdbd2cSJim Jagielski } 622*b1cdbd2cSJim Jagielski } 623*b1cdbd2cSJim Jagielski } 624*b1cdbd2cSJim Jagielski } 625*b1cdbd2cSJim Jagielski } 626*b1cdbd2cSJim Jagielski 627*b1cdbd2cSJim Jagielski // restore OutDev 628*b1cdbd2cSJim Jagielski mpOutputDevice->EnableMapMode(bWasEnabled); 629*b1cdbd2cSJim Jagielski } 630*b1cdbd2cSJim Jagielski } 631*b1cdbd2cSJim Jagielski } 632*b1cdbd2cSJim Jagielski } 633*b1cdbd2cSJim Jagielski } 634*b1cdbd2cSJim Jagielski } 635*b1cdbd2cSJim Jagielski 636*b1cdbd2cSJim Jagielski if(!bPrimitiveAccepted) 637*b1cdbd2cSJim Jagielski { 638*b1cdbd2cSJim Jagielski // do not accept, use decomposition 639*b1cdbd2cSJim Jagielski process(rFillBitmapCandidate.get2DDecomposition(getViewInformation2D())); 640*b1cdbd2cSJim Jagielski } 641*b1cdbd2cSJim Jagielski } 642*b1cdbd2cSJim Jagielski 643*b1cdbd2cSJim Jagielski // direct draw of Graphic RenderPolyPolygonGraphicPrimitive2D(const primitive2d::PolyPolygonGraphicPrimitive2D & rPolygonCandidate)644*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderPolyPolygonGraphicPrimitive2D(const primitive2d::PolyPolygonGraphicPrimitive2D& rPolygonCandidate) 645*b1cdbd2cSJim Jagielski { 646*b1cdbd2cSJim Jagielski bool bDone(false); 647*b1cdbd2cSJim Jagielski const basegfx::B2DPolyPolygon& rPolyPolygon = rPolygonCandidate.getB2DPolyPolygon(); 648*b1cdbd2cSJim Jagielski 649*b1cdbd2cSJim Jagielski // #121194# Todo: check if this works 650*b1cdbd2cSJim Jagielski if(!rPolyPolygon.count()) 651*b1cdbd2cSJim Jagielski { 652*b1cdbd2cSJim Jagielski // empty polyPolygon, done 653*b1cdbd2cSJim Jagielski bDone = true; 654*b1cdbd2cSJim Jagielski } 655*b1cdbd2cSJim Jagielski else 656*b1cdbd2cSJim Jagielski { 657*b1cdbd2cSJim Jagielski const attribute::FillGraphicAttribute& rFillGraphicAttribute = rPolygonCandidate.getFillGraphic(); 658*b1cdbd2cSJim Jagielski 659*b1cdbd2cSJim Jagielski // try to catch cases where the graphic will be color-modified to a single 660*b1cdbd2cSJim Jagielski // color (e.g. shadow) 661*b1cdbd2cSJim Jagielski switch(rFillGraphicAttribute.getGraphic().GetType()) 662*b1cdbd2cSJim Jagielski { 663*b1cdbd2cSJim Jagielski case GRAPHIC_GDIMETAFILE: 664*b1cdbd2cSJim Jagielski { 665*b1cdbd2cSJim Jagielski // metafiles are potentially transparent, cannot optimize, not done 666*b1cdbd2cSJim Jagielski break; 667*b1cdbd2cSJim Jagielski } 668*b1cdbd2cSJim Jagielski case GRAPHIC_BITMAP: 669*b1cdbd2cSJim Jagielski { 670*b1cdbd2cSJim Jagielski if(!rFillGraphicAttribute.getGraphic().IsTransparent() && !rFillGraphicAttribute.getGraphic().IsAlpha()) 671*b1cdbd2cSJim Jagielski { 672*b1cdbd2cSJim Jagielski // bitmap is not transparent and has no alpha 673*b1cdbd2cSJim Jagielski const sal_uInt32 nBColorModifierStackCount(maBColorModifierStack.count()); 674*b1cdbd2cSJim Jagielski 675*b1cdbd2cSJim Jagielski if(nBColorModifierStackCount) 676*b1cdbd2cSJim Jagielski { 677*b1cdbd2cSJim Jagielski const basegfx::BColorModifierSharedPtr& rTopmostModifier = maBColorModifierStack.getBColorModifier(nBColorModifierStackCount - 1); 678*b1cdbd2cSJim Jagielski const basegfx::BColorModifier_replace* pReplacer = dynamic_cast< const basegfx::BColorModifier_replace* >(rTopmostModifier.get()); 679*b1cdbd2cSJim Jagielski 680*b1cdbd2cSJim Jagielski if(pReplacer) 681*b1cdbd2cSJim Jagielski { 682*b1cdbd2cSJim Jagielski // the bitmap fill is in unified color, so we can replace it with 683*b1cdbd2cSJim Jagielski // a single polygon fill. The form of the fill depends on tiling 684*b1cdbd2cSJim Jagielski if(rFillGraphicAttribute.getTiling()) 685*b1cdbd2cSJim Jagielski { 686*b1cdbd2cSJim Jagielski // with tiling, fill the whole PolyPolygon with the modifier color 687*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolyPolygon); 688*b1cdbd2cSJim Jagielski 689*b1cdbd2cSJim Jagielski aLocalPolyPolygon.transform(maCurrentTransformation); 690*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(); 691*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(Color(pReplacer->getBColor())); 692*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); 693*b1cdbd2cSJim Jagielski } 694*b1cdbd2cSJim Jagielski else 695*b1cdbd2cSJim Jagielski { 696*b1cdbd2cSJim Jagielski // without tiling, only the area common to the bitmap tile and the 697*b1cdbd2cSJim Jagielski // PolyPolygon is filled. Create the bitmap tile area in object 698*b1cdbd2cSJim Jagielski // coordinates. For this, the object transformation needs to be created 699*b1cdbd2cSJim Jagielski // from the already scaled PolyPolygon. The tile area in object 700*b1cdbd2cSJim Jagielski // coordinates wil always be non-rotated, so it's not necessary to 701*b1cdbd2cSJim Jagielski // work with a polygon here 702*b1cdbd2cSJim Jagielski basegfx::B2DRange aTileRange(rFillGraphicAttribute.getGraphicRange()); 703*b1cdbd2cSJim Jagielski const basegfx::B2DRange aPolyPolygonRange(rPolyPolygon.getB2DRange()); 704*b1cdbd2cSJim Jagielski const basegfx::B2DHomMatrix aNewObjectTransform( 705*b1cdbd2cSJim Jagielski basegfx::tools::createScaleTranslateB2DHomMatrix( 706*b1cdbd2cSJim Jagielski aPolyPolygonRange.getRange(), 707*b1cdbd2cSJim Jagielski aPolyPolygonRange.getMinimum())); 708*b1cdbd2cSJim Jagielski 709*b1cdbd2cSJim Jagielski aTileRange.transform(aNewObjectTransform); 710*b1cdbd2cSJim Jagielski 711*b1cdbd2cSJim Jagielski // now clip the object polyPolygon against the tile range 712*b1cdbd2cSJim Jagielski // to get the common area 713*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aTarget = basegfx::tools::clipPolyPolygonOnRange( 714*b1cdbd2cSJim Jagielski rPolyPolygon, 715*b1cdbd2cSJim Jagielski aTileRange, 716*b1cdbd2cSJim Jagielski true, 717*b1cdbd2cSJim Jagielski false); 718*b1cdbd2cSJim Jagielski 719*b1cdbd2cSJim Jagielski if(aTarget.count()) 720*b1cdbd2cSJim Jagielski { 721*b1cdbd2cSJim Jagielski aTarget.transform(maCurrentTransformation); 722*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(); 723*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(Color(pReplacer->getBColor())); 724*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyPolygon(aTarget); 725*b1cdbd2cSJim Jagielski } 726*b1cdbd2cSJim Jagielski } 727*b1cdbd2cSJim Jagielski 728*b1cdbd2cSJim Jagielski // simplified output executed, we are done 729*b1cdbd2cSJim Jagielski bDone = true; 730*b1cdbd2cSJim Jagielski } 731*b1cdbd2cSJim Jagielski } 732*b1cdbd2cSJim Jagielski } 733*b1cdbd2cSJim Jagielski break; 734*b1cdbd2cSJim Jagielski } 735*b1cdbd2cSJim Jagielski default: //GRAPHIC_NONE, GRAPHIC_DEFAULT 736*b1cdbd2cSJim Jagielski { 737*b1cdbd2cSJim Jagielski // empty graphic, we are done 738*b1cdbd2cSJim Jagielski bDone = true; 739*b1cdbd2cSJim Jagielski break; 740*b1cdbd2cSJim Jagielski } 741*b1cdbd2cSJim Jagielski } 742*b1cdbd2cSJim Jagielski } 743*b1cdbd2cSJim Jagielski 744*b1cdbd2cSJim Jagielski if(!bDone) 745*b1cdbd2cSJim Jagielski { 746*b1cdbd2cSJim Jagielski // use default decomposition 747*b1cdbd2cSJim Jagielski process(rPolygonCandidate.get2DDecomposition(getViewInformation2D())); 748*b1cdbd2cSJim Jagielski } 749*b1cdbd2cSJim Jagielski } 750*b1cdbd2cSJim Jagielski 751*b1cdbd2cSJim Jagielski // mask group. Force output to VDev and create mask from given mask RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D & rMaskCandidate)752*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate) 753*b1cdbd2cSJim Jagielski { 754*b1cdbd2cSJim Jagielski if(rMaskCandidate.getChildren().hasElements()) 755*b1cdbd2cSJim Jagielski { 756*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aMask(rMaskCandidate.getMask()); 757*b1cdbd2cSJim Jagielski 758*b1cdbd2cSJim Jagielski if(aMask.count()) 759*b1cdbd2cSJim Jagielski { 760*b1cdbd2cSJim Jagielski aMask.transform(maCurrentTransformation); 761*b1cdbd2cSJim Jagielski const basegfx::B2DRange aRange(basegfx::tools::getRange(aMask)); 762*b1cdbd2cSJim Jagielski impBufferDevice aBufferDevice(*mpOutputDevice, aRange, true); 763*b1cdbd2cSJim Jagielski 764*b1cdbd2cSJim Jagielski if(aBufferDevice.isVisible()) 765*b1cdbd2cSJim Jagielski { 766*b1cdbd2cSJim Jagielski // remember last OutDev and set to content 767*b1cdbd2cSJim Jagielski OutputDevice* pLastOutputDevice = mpOutputDevice; 768*b1cdbd2cSJim Jagielski mpOutputDevice = &aBufferDevice.getContent(); 769*b1cdbd2cSJim Jagielski 770*b1cdbd2cSJim Jagielski // paint to it 771*b1cdbd2cSJim Jagielski process(rMaskCandidate.getChildren()); 772*b1cdbd2cSJim Jagielski 773*b1cdbd2cSJim Jagielski // back to old OutDev 774*b1cdbd2cSJim Jagielski mpOutputDevice = pLastOutputDevice; 775*b1cdbd2cSJim Jagielski 776*b1cdbd2cSJim Jagielski // draw mask 777*b1cdbd2cSJim Jagielski if(getOptionsDrawinglayer().IsAntiAliasing()) 778*b1cdbd2cSJim Jagielski { 779*b1cdbd2cSJim Jagielski // with AA, use 8bit AlphaMask to get nice borders 780*b1cdbd2cSJim Jagielski VirtualDevice& rTransparence = aBufferDevice.getTransparence(); 781*b1cdbd2cSJim Jagielski rTransparence.SetLineColor(); 782*b1cdbd2cSJim Jagielski rTransparence.SetFillColor(COL_BLACK); 783*b1cdbd2cSJim Jagielski rTransparence.DrawPolyPolygon(aMask); 784*b1cdbd2cSJim Jagielski 785*b1cdbd2cSJim Jagielski // dump buffer to outdev 786*b1cdbd2cSJim Jagielski aBufferDevice.paint(); 787*b1cdbd2cSJim Jagielski } 788*b1cdbd2cSJim Jagielski else 789*b1cdbd2cSJim Jagielski { 790*b1cdbd2cSJim Jagielski // No AA, use 1bit mask 791*b1cdbd2cSJim Jagielski VirtualDevice& rMask = aBufferDevice.getMask(); 792*b1cdbd2cSJim Jagielski rMask.SetLineColor(); 793*b1cdbd2cSJim Jagielski rMask.SetFillColor(COL_BLACK); 794*b1cdbd2cSJim Jagielski rMask.DrawPolyPolygon(aMask); 795*b1cdbd2cSJim Jagielski 796*b1cdbd2cSJim Jagielski // dump buffer to outdev 797*b1cdbd2cSJim Jagielski aBufferDevice.paint(); 798*b1cdbd2cSJim Jagielski } 799*b1cdbd2cSJim Jagielski } 800*b1cdbd2cSJim Jagielski } 801*b1cdbd2cSJim Jagielski } 802*b1cdbd2cSJim Jagielski } 803*b1cdbd2cSJim Jagielski 804*b1cdbd2cSJim Jagielski // modified color group. Force output to unified color. RenderModifiedColorPrimitive2D(const primitive2d::ModifiedColorPrimitive2D & rModifiedCandidate)805*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderModifiedColorPrimitive2D(const primitive2d::ModifiedColorPrimitive2D& rModifiedCandidate) 806*b1cdbd2cSJim Jagielski { 807*b1cdbd2cSJim Jagielski if(rModifiedCandidate.getChildren().hasElements()) 808*b1cdbd2cSJim Jagielski { 809*b1cdbd2cSJim Jagielski maBColorModifierStack.push(rModifiedCandidate.getColorModifier()); 810*b1cdbd2cSJim Jagielski process(rModifiedCandidate.getChildren()); 811*b1cdbd2cSJim Jagielski maBColorModifierStack.pop(); 812*b1cdbd2cSJim Jagielski } 813*b1cdbd2cSJim Jagielski } 814*b1cdbd2cSJim Jagielski 815*b1cdbd2cSJim Jagielski // unified sub-transparence. Draw to VDev first. RenderUnifiedTransparencePrimitive2D(const primitive2d::UnifiedTransparencePrimitive2D & rTransCandidate)816*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderUnifiedTransparencePrimitive2D(const primitive2d::UnifiedTransparencePrimitive2D& rTransCandidate) 817*b1cdbd2cSJim Jagielski { 818*b1cdbd2cSJim Jagielski static bool bForceToDecomposition(false); 819*b1cdbd2cSJim Jagielski 820*b1cdbd2cSJim Jagielski if(rTransCandidate.getChildren().hasElements()) 821*b1cdbd2cSJim Jagielski { 822*b1cdbd2cSJim Jagielski if(bForceToDecomposition) 823*b1cdbd2cSJim Jagielski { 824*b1cdbd2cSJim Jagielski // use decomposition 825*b1cdbd2cSJim Jagielski process(rTransCandidate.get2DDecomposition(getViewInformation2D())); 826*b1cdbd2cSJim Jagielski } 827*b1cdbd2cSJim Jagielski else 828*b1cdbd2cSJim Jagielski { 829*b1cdbd2cSJim Jagielski if(0.0 == rTransCandidate.getTransparence()) 830*b1cdbd2cSJim Jagielski { 831*b1cdbd2cSJim Jagielski // no transparence used, so just use the content 832*b1cdbd2cSJim Jagielski process(rTransCandidate.getChildren()); 833*b1cdbd2cSJim Jagielski } 834*b1cdbd2cSJim Jagielski else if(rTransCandidate.getTransparence() > 0.0 && rTransCandidate.getTransparence() < 1.0) 835*b1cdbd2cSJim Jagielski { 836*b1cdbd2cSJim Jagielski // transparence is in visible range 837*b1cdbd2cSJim Jagielski basegfx::B2DRange aRange(primitive2d::getB2DRangeFromPrimitive2DSequence(rTransCandidate.getChildren(), getViewInformation2D())); 838*b1cdbd2cSJim Jagielski aRange.transform(maCurrentTransformation); 839*b1cdbd2cSJim Jagielski impBufferDevice aBufferDevice(*mpOutputDevice, aRange, true); 840*b1cdbd2cSJim Jagielski 841*b1cdbd2cSJim Jagielski if(aBufferDevice.isVisible()) 842*b1cdbd2cSJim Jagielski { 843*b1cdbd2cSJim Jagielski // remember last OutDev and set to content 844*b1cdbd2cSJim Jagielski OutputDevice* pLastOutputDevice = mpOutputDevice; 845*b1cdbd2cSJim Jagielski mpOutputDevice = &aBufferDevice.getContent(); 846*b1cdbd2cSJim Jagielski 847*b1cdbd2cSJim Jagielski // paint content to it 848*b1cdbd2cSJim Jagielski process(rTransCandidate.getChildren()); 849*b1cdbd2cSJim Jagielski 850*b1cdbd2cSJim Jagielski // back to old OutDev 851*b1cdbd2cSJim Jagielski mpOutputDevice = pLastOutputDevice; 852*b1cdbd2cSJim Jagielski 853*b1cdbd2cSJim Jagielski // dump buffer to outdev using given transparence 854*b1cdbd2cSJim Jagielski aBufferDevice.paint(rTransCandidate.getTransparence()); 855*b1cdbd2cSJim Jagielski } 856*b1cdbd2cSJim Jagielski } 857*b1cdbd2cSJim Jagielski } 858*b1cdbd2cSJim Jagielski } 859*b1cdbd2cSJim Jagielski } 860*b1cdbd2cSJim Jagielski 861*b1cdbd2cSJim Jagielski // sub-transparence group. Draw to VDev first. RenderTransparencePrimitive2D(const primitive2d::TransparencePrimitive2D & rTransCandidate)862*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderTransparencePrimitive2D(const primitive2d::TransparencePrimitive2D& rTransCandidate) 863*b1cdbd2cSJim Jagielski { 864*b1cdbd2cSJim Jagielski if(rTransCandidate.getChildren().hasElements()) 865*b1cdbd2cSJim Jagielski { 866*b1cdbd2cSJim Jagielski basegfx::B2DRange aRange(primitive2d::getB2DRangeFromPrimitive2DSequence(rTransCandidate.getChildren(), getViewInformation2D())); 867*b1cdbd2cSJim Jagielski aRange.transform(maCurrentTransformation); 868*b1cdbd2cSJim Jagielski impBufferDevice aBufferDevice(*mpOutputDevice, aRange, true); 869*b1cdbd2cSJim Jagielski 870*b1cdbd2cSJim Jagielski if(aBufferDevice.isVisible()) 871*b1cdbd2cSJim Jagielski { 872*b1cdbd2cSJim Jagielski // remember last OutDev and set to content 873*b1cdbd2cSJim Jagielski OutputDevice* pLastOutputDevice = mpOutputDevice; 874*b1cdbd2cSJim Jagielski mpOutputDevice = &aBufferDevice.getContent(); 875*b1cdbd2cSJim Jagielski 876*b1cdbd2cSJim Jagielski // paint content to it 877*b1cdbd2cSJim Jagielski process(rTransCandidate.getChildren()); 878*b1cdbd2cSJim Jagielski 879*b1cdbd2cSJim Jagielski // set to mask 880*b1cdbd2cSJim Jagielski mpOutputDevice = &aBufferDevice.getTransparence(); 881*b1cdbd2cSJim Jagielski 882*b1cdbd2cSJim Jagielski // when painting transparence masks, reset the color stack 883*b1cdbd2cSJim Jagielski basegfx::BColorModifierStack aLastBColorModifierStack(maBColorModifierStack); 884*b1cdbd2cSJim Jagielski maBColorModifierStack = basegfx::BColorModifierStack(); 885*b1cdbd2cSJim Jagielski 886*b1cdbd2cSJim Jagielski // paint mask to it (always with transparence intensities, evtl. with AA) 887*b1cdbd2cSJim Jagielski process(rTransCandidate.getTransparence()); 888*b1cdbd2cSJim Jagielski 889*b1cdbd2cSJim Jagielski // back to old color stack 890*b1cdbd2cSJim Jagielski maBColorModifierStack = aLastBColorModifierStack; 891*b1cdbd2cSJim Jagielski 892*b1cdbd2cSJim Jagielski // back to old OutDev 893*b1cdbd2cSJim Jagielski mpOutputDevice = pLastOutputDevice; 894*b1cdbd2cSJim Jagielski 895*b1cdbd2cSJim Jagielski // dump buffer to outdev 896*b1cdbd2cSJim Jagielski aBufferDevice.paint(); 897*b1cdbd2cSJim Jagielski } 898*b1cdbd2cSJim Jagielski } 899*b1cdbd2cSJim Jagielski } 900*b1cdbd2cSJim Jagielski 901*b1cdbd2cSJim Jagielski // transform group. RenderTransformPrimitive2D(const primitive2d::TransformPrimitive2D & rTransformCandidate)902*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderTransformPrimitive2D(const primitive2d::TransformPrimitive2D& rTransformCandidate) 903*b1cdbd2cSJim Jagielski { 904*b1cdbd2cSJim Jagielski // remember current transformation and ViewInformation 905*b1cdbd2cSJim Jagielski const basegfx::B2DHomMatrix aLastCurrentTransformation(maCurrentTransformation); 906*b1cdbd2cSJim Jagielski const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D()); 907*b1cdbd2cSJim Jagielski 908*b1cdbd2cSJim Jagielski // create new transformations for CurrentTransformation 909*b1cdbd2cSJim Jagielski // and for local ViewInformation2D 910*b1cdbd2cSJim Jagielski maCurrentTransformation = maCurrentTransformation * rTransformCandidate.getTransformation(); 911*b1cdbd2cSJim Jagielski const geometry::ViewInformation2D aViewInformation2D( 912*b1cdbd2cSJim Jagielski getViewInformation2D().getObjectTransformation() * rTransformCandidate.getTransformation(), 913*b1cdbd2cSJim Jagielski getViewInformation2D().getViewTransformation(), 914*b1cdbd2cSJim Jagielski getViewInformation2D().getViewport(), 915*b1cdbd2cSJim Jagielski getViewInformation2D().getVisualizedPage(), 916*b1cdbd2cSJim Jagielski getViewInformation2D().getViewTime(), 917*b1cdbd2cSJim Jagielski getViewInformation2D().getExtendedInformationSequence()); 918*b1cdbd2cSJim Jagielski updateViewInformation(aViewInformation2D); 919*b1cdbd2cSJim Jagielski 920*b1cdbd2cSJim Jagielski // proccess content 921*b1cdbd2cSJim Jagielski process(rTransformCandidate.getChildren()); 922*b1cdbd2cSJim Jagielski 923*b1cdbd2cSJim Jagielski // restore transformations 924*b1cdbd2cSJim Jagielski maCurrentTransformation = aLastCurrentTransformation; 925*b1cdbd2cSJim Jagielski updateViewInformation(aLastViewInformation2D); 926*b1cdbd2cSJim Jagielski } 927*b1cdbd2cSJim Jagielski 928*b1cdbd2cSJim Jagielski // new XDrawPage for ViewInformation2D RenderPagePreviewPrimitive2D(const primitive2d::PagePreviewPrimitive2D & rPagePreviewCandidate)929*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderPagePreviewPrimitive2D(const primitive2d::PagePreviewPrimitive2D& rPagePreviewCandidate) 930*b1cdbd2cSJim Jagielski { 931*b1cdbd2cSJim Jagielski // remember current transformation and ViewInformation 932*b1cdbd2cSJim Jagielski const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D()); 933*b1cdbd2cSJim Jagielski 934*b1cdbd2cSJim Jagielski // create new local ViewInformation2D 935*b1cdbd2cSJim Jagielski const geometry::ViewInformation2D aViewInformation2D( 936*b1cdbd2cSJim Jagielski getViewInformation2D().getObjectTransformation(), 937*b1cdbd2cSJim Jagielski getViewInformation2D().getViewTransformation(), 938*b1cdbd2cSJim Jagielski getViewInformation2D().getViewport(), 939*b1cdbd2cSJim Jagielski rPagePreviewCandidate.getXDrawPage(), 940*b1cdbd2cSJim Jagielski getViewInformation2D().getViewTime(), 941*b1cdbd2cSJim Jagielski getViewInformation2D().getExtendedInformationSequence()); 942*b1cdbd2cSJim Jagielski updateViewInformation(aViewInformation2D); 943*b1cdbd2cSJim Jagielski 944*b1cdbd2cSJim Jagielski // proccess decomposed content 945*b1cdbd2cSJim Jagielski process(rPagePreviewCandidate.get2DDecomposition(getViewInformation2D())); 946*b1cdbd2cSJim Jagielski 947*b1cdbd2cSJim Jagielski // restore transformations 948*b1cdbd2cSJim Jagielski updateViewInformation(aLastViewInformation2D); 949*b1cdbd2cSJim Jagielski } 950*b1cdbd2cSJim Jagielski 951*b1cdbd2cSJim Jagielski // marker RenderMarkerArrayPrimitive2D(const primitive2d::MarkerArrayPrimitive2D & rMarkArrayCandidate)952*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderMarkerArrayPrimitive2D(const primitive2d::MarkerArrayPrimitive2D& rMarkArrayCandidate) 953*b1cdbd2cSJim Jagielski { 954*b1cdbd2cSJim Jagielski static bool bCheckCompleteMarkerDecompose(false); 955*b1cdbd2cSJim Jagielski if(bCheckCompleteMarkerDecompose) 956*b1cdbd2cSJim Jagielski { 957*b1cdbd2cSJim Jagielski process(rMarkArrayCandidate.get2DDecomposition(getViewInformation2D())); 958*b1cdbd2cSJim Jagielski return; 959*b1cdbd2cSJim Jagielski } 960*b1cdbd2cSJim Jagielski 961*b1cdbd2cSJim Jagielski // get data 962*b1cdbd2cSJim Jagielski const std::vector< basegfx::B2DPoint >& rPositions = rMarkArrayCandidate.getPositions(); 963*b1cdbd2cSJim Jagielski const sal_uInt32 nCount(rPositions.size()); 964*b1cdbd2cSJim Jagielski 965*b1cdbd2cSJim Jagielski if(nCount && !rMarkArrayCandidate.getMarker().IsEmpty()) 966*b1cdbd2cSJim Jagielski { 967*b1cdbd2cSJim Jagielski // get pixel size 968*b1cdbd2cSJim Jagielski const BitmapEx& rMarker(rMarkArrayCandidate.getMarker()); 969*b1cdbd2cSJim Jagielski const Size aBitmapSize(rMarker.GetSizePixel()); 970*b1cdbd2cSJim Jagielski 971*b1cdbd2cSJim Jagielski if(aBitmapSize.Width() && aBitmapSize.Height()) 972*b1cdbd2cSJim Jagielski { 973*b1cdbd2cSJim Jagielski // get discrete half size 974*b1cdbd2cSJim Jagielski const basegfx::B2DVector aDiscreteHalfSize( 975*b1cdbd2cSJim Jagielski (aBitmapSize.getWidth() - 1.0) * 0.5, 976*b1cdbd2cSJim Jagielski (aBitmapSize.getHeight() - 1.0) * 0.5); 977*b1cdbd2cSJim Jagielski const bool bWasEnabled(mpOutputDevice->IsMapModeEnabled()); 978*b1cdbd2cSJim Jagielski 979*b1cdbd2cSJim Jagielski // do not forget evtl. moved origin in target device MapMode when 980*b1cdbd2cSJim Jagielski // switching it off; it would be missing and lead to wrong positions. 981*b1cdbd2cSJim Jagielski // All his could be done using logic sizes and coordinates, too, but 982*b1cdbd2cSJim Jagielski // we want a 1:1 bitmap rendering here, so it's more safe and faster 983*b1cdbd2cSJim Jagielski // to work with switching off MapMode usage completely. 984*b1cdbd2cSJim Jagielski const Point aOrigin(mpOutputDevice->GetMapMode().GetOrigin()); 985*b1cdbd2cSJim Jagielski 986*b1cdbd2cSJim Jagielski mpOutputDevice->EnableMapMode(false); 987*b1cdbd2cSJim Jagielski 988*b1cdbd2cSJim Jagielski for(std::vector< basegfx::B2DPoint >::const_iterator aIter(rPositions.begin()); aIter != rPositions.end(); aIter++) 989*b1cdbd2cSJim Jagielski { 990*b1cdbd2cSJim Jagielski const basegfx::B2DPoint aDiscreteTopLeft((maCurrentTransformation * (*aIter)) - aDiscreteHalfSize); 991*b1cdbd2cSJim Jagielski const Point aDiscretePoint(basegfx::fround(aDiscreteTopLeft.getX()), basegfx::fround(aDiscreteTopLeft.getY())); 992*b1cdbd2cSJim Jagielski 993*b1cdbd2cSJim Jagielski mpOutputDevice->DrawBitmapEx(aDiscretePoint + aOrigin, rMarker); 994*b1cdbd2cSJim Jagielski } 995*b1cdbd2cSJim Jagielski 996*b1cdbd2cSJim Jagielski mpOutputDevice->EnableMapMode(bWasEnabled); 997*b1cdbd2cSJim Jagielski } 998*b1cdbd2cSJim Jagielski } 999*b1cdbd2cSJim Jagielski } 1000*b1cdbd2cSJim Jagielski 1001*b1cdbd2cSJim Jagielski // point RenderPointArrayPrimitive2D(const primitive2d::PointArrayPrimitive2D & rPointArrayCandidate)1002*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderPointArrayPrimitive2D(const primitive2d::PointArrayPrimitive2D& rPointArrayCandidate) 1003*b1cdbd2cSJim Jagielski { 1004*b1cdbd2cSJim Jagielski const std::vector< basegfx::B2DPoint >& rPositions = rPointArrayCandidate.getPositions(); 1005*b1cdbd2cSJim Jagielski const basegfx::BColor aRGBColor(maBColorModifierStack.getModifiedColor(rPointArrayCandidate.getRGBColor())); 1006*b1cdbd2cSJim Jagielski const Color aVCLColor(aRGBColor); 1007*b1cdbd2cSJim Jagielski 1008*b1cdbd2cSJim Jagielski for(std::vector< basegfx::B2DPoint >::const_iterator aIter(rPositions.begin()); aIter != rPositions.end(); aIter++) 1009*b1cdbd2cSJim Jagielski { 1010*b1cdbd2cSJim Jagielski const basegfx::B2DPoint aViewPosition(maCurrentTransformation * (*aIter)); 1011*b1cdbd2cSJim Jagielski const Point aPos(basegfx::fround(aViewPosition.getX()), basegfx::fround(aViewPosition.getY())); 1012*b1cdbd2cSJim Jagielski 1013*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPixel(aPos, aVCLColor); 1014*b1cdbd2cSJim Jagielski } 1015*b1cdbd2cSJim Jagielski } 1016*b1cdbd2cSJim Jagielski RenderPolygonStrokePrimitive2D(const primitive2d::PolygonStrokePrimitive2D & rPolygonStrokeCandidate)1017*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderPolygonStrokePrimitive2D(const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokeCandidate) 1018*b1cdbd2cSJim Jagielski { 1019*b1cdbd2cSJim Jagielski // #i101491# method restructured to clearly use the DrawPolyLine 1020*b1cdbd2cSJim Jagielski // calls starting from a deined line width 1021*b1cdbd2cSJim Jagielski const attribute::LineAttribute& rLineAttribute = rPolygonStrokeCandidate.getLineAttribute(); 1022*b1cdbd2cSJim Jagielski const double fLineWidth(rLineAttribute.getWidth()); 1023*b1cdbd2cSJim Jagielski bool bDone(false); 1024*b1cdbd2cSJim Jagielski 1025*b1cdbd2cSJim Jagielski if(basegfx::fTools::more(fLineWidth, 0.0)) 1026*b1cdbd2cSJim Jagielski { 1027*b1cdbd2cSJim Jagielski const basegfx::B2DVector aDiscreteUnit(maCurrentTransformation * basegfx::B2DVector(fLineWidth, 0.0)); 1028*b1cdbd2cSJim Jagielski const double fDiscreteLineWidth(aDiscreteUnit.getLength()); 1029*b1cdbd2cSJim Jagielski const attribute::StrokeAttribute& rStrokeAttribute = rPolygonStrokeCandidate.getStrokeAttribute(); 1030*b1cdbd2cSJim Jagielski const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLineAttribute.getColor())); 1031*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aHairlinePolyPolygon; 1032*b1cdbd2cSJim Jagielski 1033*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(Color(aHairlineColor)); 1034*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(); 1035*b1cdbd2cSJim Jagielski 1036*b1cdbd2cSJim Jagielski if(0.0 == rStrokeAttribute.getFullDotDashLen()) 1037*b1cdbd2cSJim Jagielski { 1038*b1cdbd2cSJim Jagielski // no line dashing, just copy 1039*b1cdbd2cSJim Jagielski aHairlinePolyPolygon.append(rPolygonStrokeCandidate.getB2DPolygon()); 1040*b1cdbd2cSJim Jagielski } 1041*b1cdbd2cSJim Jagielski else 1042*b1cdbd2cSJim Jagielski { 1043*b1cdbd2cSJim Jagielski // else apply LineStyle 1044*b1cdbd2cSJim Jagielski basegfx::tools::applyLineDashing(rPolygonStrokeCandidate.getB2DPolygon(), 1045*b1cdbd2cSJim Jagielski rStrokeAttribute.getDotDashArray(), 1046*b1cdbd2cSJim Jagielski &aHairlinePolyPolygon, 0, rStrokeAttribute.getFullDotDashLen()); 1047*b1cdbd2cSJim Jagielski } 1048*b1cdbd2cSJim Jagielski 1049*b1cdbd2cSJim Jagielski const sal_uInt32 nCount(aHairlinePolyPolygon.count()); 1050*b1cdbd2cSJim Jagielski 1051*b1cdbd2cSJim Jagielski if(nCount) 1052*b1cdbd2cSJim Jagielski { 1053*b1cdbd2cSJim Jagielski const bool bAntiAliased(getOptionsDrawinglayer().IsAntiAliasing()); 1054*b1cdbd2cSJim Jagielski aHairlinePolyPolygon.transform(maCurrentTransformation); 1055*b1cdbd2cSJim Jagielski 1056*b1cdbd2cSJim Jagielski if(bAntiAliased) 1057*b1cdbd2cSJim Jagielski { 1058*b1cdbd2cSJim Jagielski if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 1.0)) 1059*b1cdbd2cSJim Jagielski { 1060*b1cdbd2cSJim Jagielski // line in range ]0.0 .. 1.0[ 1061*b1cdbd2cSJim Jagielski // paint as simple hairline 1062*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0); a < nCount; a++) 1063*b1cdbd2cSJim Jagielski { 1064*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aHairlinePolyPolygon.getB2DPolygon(a), 0.0); 1065*b1cdbd2cSJim Jagielski } 1066*b1cdbd2cSJim Jagielski 1067*b1cdbd2cSJim Jagielski bDone = true; 1068*b1cdbd2cSJim Jagielski } 1069*b1cdbd2cSJim Jagielski else if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 2.0)) 1070*b1cdbd2cSJim Jagielski { 1071*b1cdbd2cSJim Jagielski // line in range [1.0 .. 2.0[ 1072*b1cdbd2cSJim Jagielski // paint as 2x2 with dynamic line distance 1073*b1cdbd2cSJim Jagielski basegfx::B2DHomMatrix aMat; 1074*b1cdbd2cSJim Jagielski const double fDistance(fDiscreteLineWidth - 1.0); 1075*b1cdbd2cSJim Jagielski const double fHalfDistance(fDistance * 0.5); 1076*b1cdbd2cSJim Jagielski 1077*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0); a < nCount; a++) 1078*b1cdbd2cSJim Jagielski { 1079*b1cdbd2cSJim Jagielski basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a)); 1080*b1cdbd2cSJim Jagielski 1081*b1cdbd2cSJim Jagielski aMat.set(0, 2, -fHalfDistance); 1082*b1cdbd2cSJim Jagielski aMat.set(1, 2, -fHalfDistance); 1083*b1cdbd2cSJim Jagielski aCandidate.transform(aMat); 1084*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aCandidate, 0.0); 1085*b1cdbd2cSJim Jagielski 1086*b1cdbd2cSJim Jagielski aMat.set(0, 2, fDistance); 1087*b1cdbd2cSJim Jagielski aMat.set(1, 2, 0.0); 1088*b1cdbd2cSJim Jagielski aCandidate.transform(aMat); 1089*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aCandidate, 0.0); 1090*b1cdbd2cSJim Jagielski 1091*b1cdbd2cSJim Jagielski aMat.set(0, 2, 0.0); 1092*b1cdbd2cSJim Jagielski aMat.set(1, 2, fDistance); 1093*b1cdbd2cSJim Jagielski aCandidate.transform(aMat); 1094*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aCandidate, 0.0); 1095*b1cdbd2cSJim Jagielski 1096*b1cdbd2cSJim Jagielski aMat.set(0, 2, -fDistance); 1097*b1cdbd2cSJim Jagielski aMat.set(1, 2, 0.0); 1098*b1cdbd2cSJim Jagielski aCandidate.transform(aMat); 1099*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aCandidate, 0.0); 1100*b1cdbd2cSJim Jagielski } 1101*b1cdbd2cSJim Jagielski 1102*b1cdbd2cSJim Jagielski bDone = true; 1103*b1cdbd2cSJim Jagielski } 1104*b1cdbd2cSJim Jagielski else if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 3.0)) 1105*b1cdbd2cSJim Jagielski { 1106*b1cdbd2cSJim Jagielski // line in range [2.0 .. 3.0] 1107*b1cdbd2cSJim Jagielski // paint as cross in a 3x3 with dynamic line distance 1108*b1cdbd2cSJim Jagielski basegfx::B2DHomMatrix aMat; 1109*b1cdbd2cSJim Jagielski const double fDistance((fDiscreteLineWidth - 1.0) * 0.5); 1110*b1cdbd2cSJim Jagielski 1111*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0); a < nCount; a++) 1112*b1cdbd2cSJim Jagielski { 1113*b1cdbd2cSJim Jagielski basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a)); 1114*b1cdbd2cSJim Jagielski 1115*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aCandidate, 0.0); 1116*b1cdbd2cSJim Jagielski 1117*b1cdbd2cSJim Jagielski aMat.set(0, 2, -fDistance); 1118*b1cdbd2cSJim Jagielski aMat.set(1, 2, 0.0); 1119*b1cdbd2cSJim Jagielski aCandidate.transform(aMat); 1120*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aCandidate, 0.0); 1121*b1cdbd2cSJim Jagielski 1122*b1cdbd2cSJim Jagielski aMat.set(0, 2, fDistance); 1123*b1cdbd2cSJim Jagielski aMat.set(1, 2, -fDistance); 1124*b1cdbd2cSJim Jagielski aCandidate.transform(aMat); 1125*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aCandidate, 0.0); 1126*b1cdbd2cSJim Jagielski 1127*b1cdbd2cSJim Jagielski aMat.set(0, 2, fDistance); 1128*b1cdbd2cSJim Jagielski aMat.set(1, 2, fDistance); 1129*b1cdbd2cSJim Jagielski aCandidate.transform(aMat); 1130*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aCandidate, 0.0); 1131*b1cdbd2cSJim Jagielski 1132*b1cdbd2cSJim Jagielski aMat.set(0, 2, -fDistance); 1133*b1cdbd2cSJim Jagielski aMat.set(1, 2, fDistance); 1134*b1cdbd2cSJim Jagielski aCandidate.transform(aMat); 1135*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aCandidate, 0.0); 1136*b1cdbd2cSJim Jagielski } 1137*b1cdbd2cSJim Jagielski 1138*b1cdbd2cSJim Jagielski bDone = true; 1139*b1cdbd2cSJim Jagielski } 1140*b1cdbd2cSJim Jagielski else 1141*b1cdbd2cSJim Jagielski { 1142*b1cdbd2cSJim Jagielski // #i101491# line width above 3.0 1143*b1cdbd2cSJim Jagielski } 1144*b1cdbd2cSJim Jagielski } 1145*b1cdbd2cSJim Jagielski else 1146*b1cdbd2cSJim Jagielski { 1147*b1cdbd2cSJim Jagielski if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 1.5)) 1148*b1cdbd2cSJim Jagielski { 1149*b1cdbd2cSJim Jagielski // line width below 1.5, draw the basic hairline polygon 1150*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0); a < nCount; a++) 1151*b1cdbd2cSJim Jagielski { 1152*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aHairlinePolyPolygon.getB2DPolygon(a), 0.0); 1153*b1cdbd2cSJim Jagielski } 1154*b1cdbd2cSJim Jagielski 1155*b1cdbd2cSJim Jagielski bDone = true; 1156*b1cdbd2cSJim Jagielski } 1157*b1cdbd2cSJim Jagielski else if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 2.5)) 1158*b1cdbd2cSJim Jagielski { 1159*b1cdbd2cSJim Jagielski // line width is in range ]1.5 .. 2.5], use four hairlines 1160*b1cdbd2cSJim Jagielski // drawn in a square 1161*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0); a < nCount; a++) 1162*b1cdbd2cSJim Jagielski { 1163*b1cdbd2cSJim Jagielski basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a)); 1164*b1cdbd2cSJim Jagielski basegfx::B2DHomMatrix aMat; 1165*b1cdbd2cSJim Jagielski 1166*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aCandidate, 0.0); 1167*b1cdbd2cSJim Jagielski 1168*b1cdbd2cSJim Jagielski aMat.set(0, 2, 1.0); 1169*b1cdbd2cSJim Jagielski aMat.set(1, 2, 0.0); 1170*b1cdbd2cSJim Jagielski aCandidate.transform(aMat); 1171*b1cdbd2cSJim Jagielski 1172*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aCandidate, 0.0); 1173*b1cdbd2cSJim Jagielski 1174*b1cdbd2cSJim Jagielski aMat.set(0, 2, 0.0); 1175*b1cdbd2cSJim Jagielski aMat.set(1, 2, 1.0); 1176*b1cdbd2cSJim Jagielski aCandidate.transform(aMat); 1177*b1cdbd2cSJim Jagielski 1178*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aCandidate, 0.0); 1179*b1cdbd2cSJim Jagielski 1180*b1cdbd2cSJim Jagielski aMat.set(0, 2, -1.0); 1181*b1cdbd2cSJim Jagielski aMat.set(1, 2, 0.0); 1182*b1cdbd2cSJim Jagielski aCandidate.transform(aMat); 1183*b1cdbd2cSJim Jagielski 1184*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine(aCandidate, 0.0); 1185*b1cdbd2cSJim Jagielski } 1186*b1cdbd2cSJim Jagielski 1187*b1cdbd2cSJim Jagielski bDone = true; 1188*b1cdbd2cSJim Jagielski } 1189*b1cdbd2cSJim Jagielski else 1190*b1cdbd2cSJim Jagielski { 1191*b1cdbd2cSJim Jagielski // #i101491# line width is above 2.5 1192*b1cdbd2cSJim Jagielski } 1193*b1cdbd2cSJim Jagielski } 1194*b1cdbd2cSJim Jagielski 1195*b1cdbd2cSJim Jagielski if(!bDone && rPolygonStrokeCandidate.getB2DPolygon().count() > 1000) 1196*b1cdbd2cSJim Jagielski { 1197*b1cdbd2cSJim Jagielski // #i101491# If the polygon complexity uses more than a given amount, do 1198*b1cdbd2cSJim Jagielski // use OuputDevice::DrawPolyLine directly; this will avoid buffering all 1199*b1cdbd2cSJim Jagielski // decompositions in primtives (memory) and fallback to old line painting 1200*b1cdbd2cSJim Jagielski // for very complex polygons, too 1201*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0); a < nCount; a++) 1202*b1cdbd2cSJim Jagielski { 1203*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyLine( 1204*b1cdbd2cSJim Jagielski aHairlinePolyPolygon.getB2DPolygon(a), 1205*b1cdbd2cSJim Jagielski fDiscreteLineWidth, 1206*b1cdbd2cSJim Jagielski rLineAttribute.getLineJoin(), 1207*b1cdbd2cSJim Jagielski rLineAttribute.getLineCap()); 1208*b1cdbd2cSJim Jagielski } 1209*b1cdbd2cSJim Jagielski 1210*b1cdbd2cSJim Jagielski bDone = true; 1211*b1cdbd2cSJim Jagielski } 1212*b1cdbd2cSJim Jagielski } 1213*b1cdbd2cSJim Jagielski } 1214*b1cdbd2cSJim Jagielski 1215*b1cdbd2cSJim Jagielski if(!bDone) 1216*b1cdbd2cSJim Jagielski { 1217*b1cdbd2cSJim Jagielski // remeber that we enter a PolygonStrokePrimitive2D decomposition, 1218*b1cdbd2cSJim Jagielski // used for AA thick line drawing 1219*b1cdbd2cSJim Jagielski mnPolygonStrokePrimitive2D++; 1220*b1cdbd2cSJim Jagielski 1221*b1cdbd2cSJim Jagielski // line width is big enough for standard filled polygon visualisation or zero 1222*b1cdbd2cSJim Jagielski process(rPolygonStrokeCandidate.get2DDecomposition(getViewInformation2D())); 1223*b1cdbd2cSJim Jagielski 1224*b1cdbd2cSJim Jagielski // leave PolygonStrokePrimitive2D 1225*b1cdbd2cSJim Jagielski mnPolygonStrokePrimitive2D--; 1226*b1cdbd2cSJim Jagielski } 1227*b1cdbd2cSJim Jagielski } 1228*b1cdbd2cSJim Jagielski RenderEpsPrimitive2D(const primitive2d::EpsPrimitive2D & rEpsPrimitive2D)1229*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderEpsPrimitive2D(const primitive2d::EpsPrimitive2D& rEpsPrimitive2D) 1230*b1cdbd2cSJim Jagielski { 1231*b1cdbd2cSJim Jagielski // The new decomposition of Metafiles made it necessary to add an Eps 1232*b1cdbd2cSJim Jagielski // primitive to handle embedded Eps data. On some devices, this can be 1233*b1cdbd2cSJim Jagielski // painted directly (mac, printer). 1234*b1cdbd2cSJim Jagielski // To be able to handle the replacement correctly, i need to handle it myself 1235*b1cdbd2cSJim Jagielski // since DrawEPS will not be able e.g. to rotate the replacement. To be able 1236*b1cdbd2cSJim Jagielski // to do that, i added a boolean return to OutputDevice::DrawEPS(..) 1237*b1cdbd2cSJim Jagielski // to know when EPS was handled directly already. 1238*b1cdbd2cSJim Jagielski basegfx::B2DRange aRange(0.0, 0.0, 1.0, 1.0); 1239*b1cdbd2cSJim Jagielski aRange.transform(maCurrentTransformation * rEpsPrimitive2D.getEpsTransform()); 1240*b1cdbd2cSJim Jagielski 1241*b1cdbd2cSJim Jagielski if(!aRange.isEmpty()) 1242*b1cdbd2cSJim Jagielski { 1243*b1cdbd2cSJim Jagielski const Rectangle aRectangle( 1244*b1cdbd2cSJim Jagielski (sal_Int32)floor(aRange.getMinX()), (sal_Int32)floor(aRange.getMinY()), 1245*b1cdbd2cSJim Jagielski (sal_Int32)ceil(aRange.getMaxX()), (sal_Int32)ceil(aRange.getMaxY())); 1246*b1cdbd2cSJim Jagielski 1247*b1cdbd2cSJim Jagielski if(!aRectangle.IsEmpty()) 1248*b1cdbd2cSJim Jagielski { 1249*b1cdbd2cSJim Jagielski // try to paint EPS directly without fallback visualisation 1250*b1cdbd2cSJim Jagielski const bool bEPSPaintedDirectly(mpOutputDevice->DrawEPS( 1251*b1cdbd2cSJim Jagielski aRectangle.TopLeft(), 1252*b1cdbd2cSJim Jagielski aRectangle.GetSize(), 1253*b1cdbd2cSJim Jagielski rEpsPrimitive2D.getGfxLink(), 1254*b1cdbd2cSJim Jagielski 0)); 1255*b1cdbd2cSJim Jagielski 1256*b1cdbd2cSJim Jagielski if(!bEPSPaintedDirectly) 1257*b1cdbd2cSJim Jagielski { 1258*b1cdbd2cSJim Jagielski // use the decomposition which will correctly handle the 1259*b1cdbd2cSJim Jagielski // fallback visualisation using full transformation (e.g. rotation) 1260*b1cdbd2cSJim Jagielski process(rEpsPrimitive2D.get2DDecomposition(getViewInformation2D())); 1261*b1cdbd2cSJim Jagielski } 1262*b1cdbd2cSJim Jagielski } 1263*b1cdbd2cSJim Jagielski } 1264*b1cdbd2cSJim Jagielski } 1265*b1cdbd2cSJim Jagielski RenderSvgLinearAtomPrimitive2D(const primitive2d::SvgLinearAtomPrimitive2D & rCandidate)1266*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderSvgLinearAtomPrimitive2D(const primitive2d::SvgLinearAtomPrimitive2D& rCandidate) 1267*b1cdbd2cSJim Jagielski { 1268*b1cdbd2cSJim Jagielski const double fDelta(rCandidate.getOffsetB() - rCandidate.getOffsetA()); 1269*b1cdbd2cSJim Jagielski 1270*b1cdbd2cSJim Jagielski if(basegfx::fTools::more(fDelta, 0.0)) 1271*b1cdbd2cSJim Jagielski { 1272*b1cdbd2cSJim Jagielski const basegfx::BColor aColorA(maBColorModifierStack.getModifiedColor(rCandidate.getColorA())); 1273*b1cdbd2cSJim Jagielski const basegfx::BColor aColorB(maBColorModifierStack.getModifiedColor(rCandidate.getColorB())); 1274*b1cdbd2cSJim Jagielski 1275*b1cdbd2cSJim Jagielski // calculate discrete unit in WorldCoordinates; use diagonal (1.0, 1.0) and divide by sqrt(2) 1276*b1cdbd2cSJim Jagielski const basegfx::B2DVector aDiscreteVector(getViewInformation2D().getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0)); 1277*b1cdbd2cSJim Jagielski const double fDiscreteUnit(aDiscreteVector.getLength() * (1.0 / 1.414213562373)); 1278*b1cdbd2cSJim Jagielski 1279*b1cdbd2cSJim Jagielski // use color distance and discrete lengths to calculate step count 1280*b1cdbd2cSJim Jagielski const sal_uInt32 nSteps(calculateStepsForSvgGradient(aColorA, aColorB, fDelta, fDiscreteUnit)); 1281*b1cdbd2cSJim Jagielski 1282*b1cdbd2cSJim Jagielski // switch off line painting 1283*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(); 1284*b1cdbd2cSJim Jagielski 1285*b1cdbd2cSJim Jagielski // prepare polygon in needed width at start position (with discrete overlap) 1286*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon aPolygon( 1287*b1cdbd2cSJim Jagielski basegfx::tools::createPolygonFromRect( 1288*b1cdbd2cSJim Jagielski basegfx::B2DRange( 1289*b1cdbd2cSJim Jagielski rCandidate.getOffsetA() - fDiscreteUnit, 1290*b1cdbd2cSJim Jagielski 0.0, 1291*b1cdbd2cSJim Jagielski rCandidate.getOffsetA() + (fDelta / nSteps) + fDiscreteUnit, 1292*b1cdbd2cSJim Jagielski 1.0))); 1293*b1cdbd2cSJim Jagielski 1294*b1cdbd2cSJim Jagielski 1295*b1cdbd2cSJim Jagielski // prepare loop ([0.0 .. 1.0[) 1296*b1cdbd2cSJim Jagielski double fUnitScale(0.0); 1297*b1cdbd2cSJim Jagielski const double fUnitStep(1.0 / nSteps); 1298*b1cdbd2cSJim Jagielski 1299*b1cdbd2cSJim Jagielski // loop and paint 1300*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0); a < nSteps; a++, fUnitScale += fUnitStep) 1301*b1cdbd2cSJim Jagielski { 1302*b1cdbd2cSJim Jagielski basegfx::B2DPolygon aNew(aPolygon); 1303*b1cdbd2cSJim Jagielski 1304*b1cdbd2cSJim Jagielski aNew.transform(maCurrentTransformation * basegfx::tools::createTranslateB2DHomMatrix(fDelta * fUnitScale, 0.0)); 1305*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(Color(basegfx::interpolate(aColorA, aColorB, fUnitScale))); 1306*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyPolygon(basegfx::B2DPolyPolygon(aNew)); 1307*b1cdbd2cSJim Jagielski } 1308*b1cdbd2cSJim Jagielski } 1309*b1cdbd2cSJim Jagielski } 1310*b1cdbd2cSJim Jagielski RenderSvgRadialAtomPrimitive2D(const primitive2d::SvgRadialAtomPrimitive2D & rCandidate)1311*b1cdbd2cSJim Jagielski void VclProcessor2D::RenderSvgRadialAtomPrimitive2D(const primitive2d::SvgRadialAtomPrimitive2D& rCandidate) 1312*b1cdbd2cSJim Jagielski { 1313*b1cdbd2cSJim Jagielski const double fDeltaScale(rCandidate.getScaleB() - rCandidate.getScaleA()); 1314*b1cdbd2cSJim Jagielski 1315*b1cdbd2cSJim Jagielski if(basegfx::fTools::more(fDeltaScale, 0.0)) 1316*b1cdbd2cSJim Jagielski { 1317*b1cdbd2cSJim Jagielski const basegfx::BColor aColorA(maBColorModifierStack.getModifiedColor(rCandidate.getColorA())); 1318*b1cdbd2cSJim Jagielski const basegfx::BColor aColorB(maBColorModifierStack.getModifiedColor(rCandidate.getColorB())); 1319*b1cdbd2cSJim Jagielski 1320*b1cdbd2cSJim Jagielski // calculate discrete unit in WorldCoordinates; use diagonal (1.0, 1.0) and divide by sqrt(2) 1321*b1cdbd2cSJim Jagielski const basegfx::B2DVector aDiscreteVector(getViewInformation2D().getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0)); 1322*b1cdbd2cSJim Jagielski const double fDiscreteUnit(aDiscreteVector.getLength() * (1.0 / 1.414213562373)); 1323*b1cdbd2cSJim Jagielski 1324*b1cdbd2cSJim Jagielski // use color distance and discrete lengths to calculate step count 1325*b1cdbd2cSJim Jagielski const sal_uInt32 nSteps(calculateStepsForSvgGradient(aColorA, aColorB, fDeltaScale, fDiscreteUnit)); 1326*b1cdbd2cSJim Jagielski 1327*b1cdbd2cSJim Jagielski // switch off line painting 1328*b1cdbd2cSJim Jagielski mpOutputDevice->SetLineColor(); 1329*b1cdbd2cSJim Jagielski 1330*b1cdbd2cSJim Jagielski // prepare loop ([0.0 .. 1.0[, full polygons, no polypolygons with holes) 1331*b1cdbd2cSJim Jagielski double fUnitScale(0.0); 1332*b1cdbd2cSJim Jagielski const double fUnitStep(1.0 / nSteps); 1333*b1cdbd2cSJim Jagielski 1334*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0); a < nSteps; a++, fUnitScale += fUnitStep) 1335*b1cdbd2cSJim Jagielski { 1336*b1cdbd2cSJim Jagielski basegfx::B2DHomMatrix aTransform; 1337*b1cdbd2cSJim Jagielski const double fEndScale(rCandidate.getScaleB() - (fDeltaScale * fUnitScale)); 1338*b1cdbd2cSJim Jagielski 1339*b1cdbd2cSJim Jagielski if(rCandidate.isTranslateSet()) 1340*b1cdbd2cSJim Jagielski { 1341*b1cdbd2cSJim Jagielski const basegfx::B2DVector aTranslate( 1342*b1cdbd2cSJim Jagielski basegfx::interpolate( 1343*b1cdbd2cSJim Jagielski rCandidate.getTranslateB(), 1344*b1cdbd2cSJim Jagielski rCandidate.getTranslateA(), 1345*b1cdbd2cSJim Jagielski fUnitScale)); 1346*b1cdbd2cSJim Jagielski 1347*b1cdbd2cSJim Jagielski aTransform = basegfx::tools::createScaleTranslateB2DHomMatrix( 1348*b1cdbd2cSJim Jagielski fEndScale, 1349*b1cdbd2cSJim Jagielski fEndScale, 1350*b1cdbd2cSJim Jagielski aTranslate.getX(), 1351*b1cdbd2cSJim Jagielski aTranslate.getY()); 1352*b1cdbd2cSJim Jagielski } 1353*b1cdbd2cSJim Jagielski else 1354*b1cdbd2cSJim Jagielski { 1355*b1cdbd2cSJim Jagielski aTransform = basegfx::tools::createScaleB2DHomMatrix( 1356*b1cdbd2cSJim Jagielski fEndScale, 1357*b1cdbd2cSJim Jagielski fEndScale); 1358*b1cdbd2cSJim Jagielski } 1359*b1cdbd2cSJim Jagielski 1360*b1cdbd2cSJim Jagielski basegfx::B2DPolygon aNew(basegfx::tools::createPolygonFromUnitCircle()); 1361*b1cdbd2cSJim Jagielski 1362*b1cdbd2cSJim Jagielski aNew.transform(maCurrentTransformation * aTransform); 1363*b1cdbd2cSJim Jagielski mpOutputDevice->SetFillColor(Color(basegfx::interpolate(aColorB, aColorA, fUnitScale))); 1364*b1cdbd2cSJim Jagielski mpOutputDevice->DrawPolyPolygon(basegfx::B2DPolyPolygon(aNew)); 1365*b1cdbd2cSJim Jagielski } 1366*b1cdbd2cSJim Jagielski } 1367*b1cdbd2cSJim Jagielski } 1368*b1cdbd2cSJim Jagielski adaptLineToFillDrawMode() const1369*b1cdbd2cSJim Jagielski void VclProcessor2D::adaptLineToFillDrawMode() const 1370*b1cdbd2cSJim Jagielski { 1371*b1cdbd2cSJim Jagielski const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 1372*b1cdbd2cSJim Jagielski 1373*b1cdbd2cSJim Jagielski if(nOriginalDrawMode & (DRAWMODE_BLACKLINE|DRAWMODE_GRAYLINE|DRAWMODE_GHOSTEDLINE|DRAWMODE_WHITELINE|DRAWMODE_SETTINGSLINE)) 1374*b1cdbd2cSJim Jagielski { 1375*b1cdbd2cSJim Jagielski sal_uInt32 nAdaptedDrawMode(nOriginalDrawMode); 1376*b1cdbd2cSJim Jagielski 1377*b1cdbd2cSJim Jagielski if(nOriginalDrawMode & DRAWMODE_BLACKLINE) 1378*b1cdbd2cSJim Jagielski { 1379*b1cdbd2cSJim Jagielski nAdaptedDrawMode |= DRAWMODE_BLACKFILL; 1380*b1cdbd2cSJim Jagielski } 1381*b1cdbd2cSJim Jagielski else 1382*b1cdbd2cSJim Jagielski { 1383*b1cdbd2cSJim Jagielski nAdaptedDrawMode &= ~DRAWMODE_BLACKFILL; 1384*b1cdbd2cSJim Jagielski } 1385*b1cdbd2cSJim Jagielski 1386*b1cdbd2cSJim Jagielski if(nOriginalDrawMode & DRAWMODE_GRAYLINE) 1387*b1cdbd2cSJim Jagielski { 1388*b1cdbd2cSJim Jagielski nAdaptedDrawMode |= DRAWMODE_GRAYFILL; 1389*b1cdbd2cSJim Jagielski } 1390*b1cdbd2cSJim Jagielski else 1391*b1cdbd2cSJim Jagielski { 1392*b1cdbd2cSJim Jagielski nAdaptedDrawMode &= ~DRAWMODE_GRAYFILL; 1393*b1cdbd2cSJim Jagielski } 1394*b1cdbd2cSJim Jagielski 1395*b1cdbd2cSJim Jagielski if(nOriginalDrawMode & DRAWMODE_GHOSTEDLINE) 1396*b1cdbd2cSJim Jagielski { 1397*b1cdbd2cSJim Jagielski nAdaptedDrawMode |= DRAWMODE_GHOSTEDFILL; 1398*b1cdbd2cSJim Jagielski } 1399*b1cdbd2cSJim Jagielski else 1400*b1cdbd2cSJim Jagielski { 1401*b1cdbd2cSJim Jagielski nAdaptedDrawMode &= ~DRAWMODE_GHOSTEDFILL; 1402*b1cdbd2cSJim Jagielski } 1403*b1cdbd2cSJim Jagielski 1404*b1cdbd2cSJim Jagielski if(nOriginalDrawMode & DRAWMODE_WHITELINE) 1405*b1cdbd2cSJim Jagielski { 1406*b1cdbd2cSJim Jagielski nAdaptedDrawMode |= DRAWMODE_WHITEFILL; 1407*b1cdbd2cSJim Jagielski } 1408*b1cdbd2cSJim Jagielski else 1409*b1cdbd2cSJim Jagielski { 1410*b1cdbd2cSJim Jagielski nAdaptedDrawMode &= ~DRAWMODE_WHITEFILL; 1411*b1cdbd2cSJim Jagielski } 1412*b1cdbd2cSJim Jagielski 1413*b1cdbd2cSJim Jagielski if(nOriginalDrawMode & DRAWMODE_SETTINGSLINE) 1414*b1cdbd2cSJim Jagielski { 1415*b1cdbd2cSJim Jagielski nAdaptedDrawMode |= DRAWMODE_SETTINGSFILL; 1416*b1cdbd2cSJim Jagielski } 1417*b1cdbd2cSJim Jagielski else 1418*b1cdbd2cSJim Jagielski { 1419*b1cdbd2cSJim Jagielski nAdaptedDrawMode &= ~DRAWMODE_SETTINGSFILL; 1420*b1cdbd2cSJim Jagielski } 1421*b1cdbd2cSJim Jagielski 1422*b1cdbd2cSJim Jagielski mpOutputDevice->SetDrawMode(nAdaptedDrawMode); 1423*b1cdbd2cSJim Jagielski } 1424*b1cdbd2cSJim Jagielski } 1425*b1cdbd2cSJim Jagielski adaptTextToFillDrawMode() const1426*b1cdbd2cSJim Jagielski void VclProcessor2D::adaptTextToFillDrawMode() const 1427*b1cdbd2cSJim Jagielski { 1428*b1cdbd2cSJim Jagielski const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 1429*b1cdbd2cSJim Jagielski if(nOriginalDrawMode & (DRAWMODE_BLACKTEXT|DRAWMODE_GRAYTEXT|DRAWMODE_GHOSTEDTEXT|DRAWMODE_WHITETEXT|DRAWMODE_SETTINGSTEXT)) 1430*b1cdbd2cSJim Jagielski { 1431*b1cdbd2cSJim Jagielski sal_uInt32 nAdaptedDrawMode(nOriginalDrawMode); 1432*b1cdbd2cSJim Jagielski 1433*b1cdbd2cSJim Jagielski if(nOriginalDrawMode & DRAWMODE_BLACKTEXT) 1434*b1cdbd2cSJim Jagielski { 1435*b1cdbd2cSJim Jagielski nAdaptedDrawMode |= DRAWMODE_BLACKFILL; 1436*b1cdbd2cSJim Jagielski } 1437*b1cdbd2cSJim Jagielski else 1438*b1cdbd2cSJim Jagielski { 1439*b1cdbd2cSJim Jagielski nAdaptedDrawMode &= ~DRAWMODE_BLACKFILL; 1440*b1cdbd2cSJim Jagielski } 1441*b1cdbd2cSJim Jagielski 1442*b1cdbd2cSJim Jagielski if(nOriginalDrawMode & DRAWMODE_GRAYTEXT) 1443*b1cdbd2cSJim Jagielski { 1444*b1cdbd2cSJim Jagielski nAdaptedDrawMode |= DRAWMODE_GRAYFILL; 1445*b1cdbd2cSJim Jagielski } 1446*b1cdbd2cSJim Jagielski else 1447*b1cdbd2cSJim Jagielski { 1448*b1cdbd2cSJim Jagielski nAdaptedDrawMode &= ~DRAWMODE_GRAYFILL; 1449*b1cdbd2cSJim Jagielski } 1450*b1cdbd2cSJim Jagielski 1451*b1cdbd2cSJim Jagielski if(nOriginalDrawMode & DRAWMODE_GHOSTEDTEXT) 1452*b1cdbd2cSJim Jagielski { 1453*b1cdbd2cSJim Jagielski nAdaptedDrawMode |= DRAWMODE_GHOSTEDFILL; 1454*b1cdbd2cSJim Jagielski } 1455*b1cdbd2cSJim Jagielski else 1456*b1cdbd2cSJim Jagielski { 1457*b1cdbd2cSJim Jagielski nAdaptedDrawMode &= ~DRAWMODE_GHOSTEDFILL; 1458*b1cdbd2cSJim Jagielski } 1459*b1cdbd2cSJim Jagielski 1460*b1cdbd2cSJim Jagielski if(nOriginalDrawMode & DRAWMODE_WHITETEXT) 1461*b1cdbd2cSJim Jagielski { 1462*b1cdbd2cSJim Jagielski nAdaptedDrawMode |= DRAWMODE_WHITEFILL; 1463*b1cdbd2cSJim Jagielski } 1464*b1cdbd2cSJim Jagielski else 1465*b1cdbd2cSJim Jagielski { 1466*b1cdbd2cSJim Jagielski nAdaptedDrawMode &= ~DRAWMODE_WHITEFILL; 1467*b1cdbd2cSJim Jagielski } 1468*b1cdbd2cSJim Jagielski 1469*b1cdbd2cSJim Jagielski if(nOriginalDrawMode & DRAWMODE_SETTINGSTEXT) 1470*b1cdbd2cSJim Jagielski { 1471*b1cdbd2cSJim Jagielski nAdaptedDrawMode |= DRAWMODE_SETTINGSFILL; 1472*b1cdbd2cSJim Jagielski } 1473*b1cdbd2cSJim Jagielski else 1474*b1cdbd2cSJim Jagielski { 1475*b1cdbd2cSJim Jagielski nAdaptedDrawMode &= ~DRAWMODE_SETTINGSFILL; 1476*b1cdbd2cSJim Jagielski } 1477*b1cdbd2cSJim Jagielski 1478*b1cdbd2cSJim Jagielski mpOutputDevice->SetDrawMode(nAdaptedDrawMode); 1479*b1cdbd2cSJim Jagielski } 1480*b1cdbd2cSJim Jagielski } 1481*b1cdbd2cSJim Jagielski 1482*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 1483*b1cdbd2cSJim Jagielski // process support 1484*b1cdbd2cSJim Jagielski VclProcessor2D(const geometry::ViewInformation2D & rViewInformation,OutputDevice & rOutDev)1485*b1cdbd2cSJim Jagielski VclProcessor2D::VclProcessor2D( 1486*b1cdbd2cSJim Jagielski const geometry::ViewInformation2D& rViewInformation, 1487*b1cdbd2cSJim Jagielski OutputDevice& rOutDev) 1488*b1cdbd2cSJim Jagielski : BaseProcessor2D(rViewInformation), 1489*b1cdbd2cSJim Jagielski mpOutputDevice(&rOutDev), 1490*b1cdbd2cSJim Jagielski maBColorModifierStack(), 1491*b1cdbd2cSJim Jagielski maCurrentTransformation(), 1492*b1cdbd2cSJim Jagielski maDrawinglayerOpt(), 1493*b1cdbd2cSJim Jagielski mnPolygonStrokePrimitive2D(0) 1494*b1cdbd2cSJim Jagielski { 1495*b1cdbd2cSJim Jagielski // set digit language, derived from SvtCTLOptions to have the correct 1496*b1cdbd2cSJim Jagielski // number display for arabic/hindi numerals 1497*b1cdbd2cSJim Jagielski const SvtCTLOptions aSvtCTLOptions; 1498*b1cdbd2cSJim Jagielski LanguageType eLang(LANGUAGE_SYSTEM); 1499*b1cdbd2cSJim Jagielski 1500*b1cdbd2cSJim Jagielski if(SvtCTLOptions::NUMERALS_HINDI == aSvtCTLOptions.GetCTLTextNumerals()) 1501*b1cdbd2cSJim Jagielski { 1502*b1cdbd2cSJim Jagielski eLang = LANGUAGE_ARABIC_SAUDI_ARABIA; 1503*b1cdbd2cSJim Jagielski } 1504*b1cdbd2cSJim Jagielski else if(SvtCTLOptions::NUMERALS_ARABIC == aSvtCTLOptions.GetCTLTextNumerals()) 1505*b1cdbd2cSJim Jagielski { 1506*b1cdbd2cSJim Jagielski eLang = LANGUAGE_ENGLISH; 1507*b1cdbd2cSJim Jagielski } 1508*b1cdbd2cSJim Jagielski else 1509*b1cdbd2cSJim Jagielski { 1510*b1cdbd2cSJim Jagielski eLang = (LanguageType)Application::GetSettings().GetLanguage(); 1511*b1cdbd2cSJim Jagielski } 1512*b1cdbd2cSJim Jagielski 1513*b1cdbd2cSJim Jagielski rOutDev.SetDigitLanguage(eLang); 1514*b1cdbd2cSJim Jagielski } 1515*b1cdbd2cSJim Jagielski ~VclProcessor2D()1516*b1cdbd2cSJim Jagielski VclProcessor2D::~VclProcessor2D() 1517*b1cdbd2cSJim Jagielski { 1518*b1cdbd2cSJim Jagielski } 1519*b1cdbd2cSJim Jagielski } // end of namespace processor2d 1520*b1cdbd2cSJim Jagielski } // end of namespace drawinglayer 1521*b1cdbd2cSJim Jagielski 1522*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 1523*b1cdbd2cSJim Jagielski // eof 1524