1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_drawinglayer.hxx" 30 31 #include <drawinglayer/processor2d/vclpixelprocessor2d.hxx> 32 #include <vcl/outdev.hxx> 33 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 34 #include <drawinglayer/primitive2d/textprimitive2d.hxx> 35 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 36 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 37 #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> 38 #include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx> 39 #include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx> 40 #include <drawinglayer/primitive2d/metafileprimitive2d.hxx> 41 #include <drawinglayer/primitive2d/maskprimitive2d.hxx> 42 #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> 43 #include <drawinglayer/primitive2d/transparenceprimitive2d.hxx> 44 #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 45 #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx> 46 #include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx> 47 #include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx> 48 #include <drawinglayer/primitive2d/controlprimitive2d.hxx> 49 #include <com/sun/star/awt/XWindow2.hpp> 50 #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> 51 #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> 52 #include <drawinglayer/primitive2d/chartprimitive2d.hxx> 53 #include <helperchartrenderer.hxx> 54 #include <helperwrongspellrenderer.hxx> 55 #include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx> 56 #include <basegfx/polygon/b2dpolygontools.hxx> 57 #include <vcl/hatch.hxx> 58 #include <tools/diagnose_ex.h> 59 #include <com/sun/star/awt/PosSize.hpp> 60 #include <drawinglayer/primitive2d/invertprimitive2d.hxx> 61 #include <cstdio> 62 #include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx> 63 #include <basegfx/matrix/b2dhommatrixtools.hxx> 64 #include <drawinglayer/primitive2d/epsprimitive2d.hxx> 65 66 #include <toolkit/helper/vclunohelper.hxx> 67 #include <vcl/window.hxx> 68 69 ////////////////////////////////////////////////////////////////////////////// 70 71 using namespace com::sun::star; 72 73 ////////////////////////////////////////////////////////////////////////////// 74 75 namespace drawinglayer 76 { 77 namespace processor2d 78 { 79 VclPixelProcessor2D::VclPixelProcessor2D(const geometry::ViewInformation2D& rViewInformation, OutputDevice& rOutDev) 80 : VclProcessor2D(rViewInformation, rOutDev), 81 maOriginalMapMode(rOutDev.GetMapMode()) 82 { 83 // prepare maCurrentTransformation matrix with viewTransformation to target directly to pixels 84 maCurrentTransformation = rViewInformation.getObjectToViewTransformation(); 85 86 // prepare output directly to pixels 87 mpOutputDevice->Push(PUSH_MAPMODE); 88 mpOutputDevice->SetMapMode(); 89 90 // react on AntiAliasing settings 91 if(getOptionsDrawinglayer().IsAntiAliasing()) 92 { 93 mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW); 94 } 95 else 96 { 97 mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); 98 } 99 } 100 101 VclPixelProcessor2D::~VclPixelProcessor2D() 102 { 103 // restore MapMode 104 mpOutputDevice->Pop(); 105 106 // restore AntiAliasing 107 mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); 108 } 109 110 void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) 111 { 112 switch(rCandidate.getPrimitive2DID()) 113 { 114 case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D : 115 { 116 // directdraw of wrong spell primitive; added test possibility to check wrong spell decompose 117 static bool bHandleWrongSpellDirectly(true); 118 119 if(bHandleWrongSpellDirectly) 120 { 121 const primitive2d::WrongSpellPrimitive2D& rWrongSpellPrimitive = static_cast< const primitive2d::WrongSpellPrimitive2D& >(rCandidate); 122 123 if(!renderWrongSpellPrimitive2D( 124 rWrongSpellPrimitive, 125 *mpOutputDevice, 126 maCurrentTransformation, 127 maBColorModifierStack)) 128 { 129 // fallback to decomposition (MetaFile) 130 process(rWrongSpellPrimitive.get2DDecomposition(getViewInformation2D())); 131 } 132 } 133 else 134 { 135 process(rCandidate.get2DDecomposition(getViewInformation2D())); 136 } 137 break; 138 } 139 case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D : 140 { 141 // directdraw of text simple portion; added test possibility to check text decompose 142 static bool bForceSimpleTextDecomposition(false); 143 144 // Adapt evtl. used special DrawMode 145 const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 146 adaptTextToFillDrawMode(); 147 148 if(!bForceSimpleTextDecomposition && getOptionsDrawinglayer().IsRenderSimpleTextDirect()) 149 { 150 RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate)); 151 } 152 else 153 { 154 process(rCandidate.get2DDecomposition(getViewInformation2D())); 155 } 156 157 // restore DrawMode 158 mpOutputDevice->SetDrawMode(nOriginalDrawMode); 159 160 break; 161 } 162 case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D : 163 { 164 // directdraw of text simple portion; added test possibility to check text decompose 165 static bool bForceComplexTextDecomposition(false); 166 167 // Adapt evtl. used special DrawMode 168 const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 169 adaptTextToFillDrawMode(); 170 171 if(!bForceComplexTextDecomposition && getOptionsDrawinglayer().IsRenderDecoratedTextDirect()) 172 { 173 RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate)); 174 } 175 else 176 { 177 process(rCandidate.get2DDecomposition(getViewInformation2D())); 178 } 179 180 // restore DrawMode 181 mpOutputDevice->SetDrawMode(nOriginalDrawMode); 182 183 break; 184 } 185 case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D : 186 { 187 // direct draw of hairline 188 RenderPolygonHairlinePrimitive2D(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate), true); 189 break; 190 } 191 case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D : 192 { 193 // direct draw of transformed BitmapEx primitive 194 RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate)); 195 break; 196 } 197 case PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D : 198 { 199 // direct draw of transformed BitmapEx primitive 200 RenderRenderGraphicPrimitive2D(static_cast< const primitive2d::RenderGraphicPrimitive2D& >(rCandidate)); 201 break; 202 } 203 case PRIMITIVE2D_ID_FILLBITMAPPRIMITIVE2D : 204 { 205 // direct draw of fillBitmapPrimitive 206 RenderFillBitmapPrimitive2D(static_cast< const primitive2d::FillBitmapPrimitive2D& >(rCandidate)); 207 break; 208 } 209 case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D : 210 { 211 // direct draw of gradient 212 RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate)); 213 break; 214 } 215 case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D : 216 { 217 // direct draw of bitmap 218 RenderPolyPolygonBitmapPrimitive2D(static_cast< const primitive2d::PolyPolygonBitmapPrimitive2D& >(rCandidate)); 219 break; 220 } 221 case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D : 222 { 223 // direct draw of PolyPolygon with color 224 RenderPolyPolygonColorPrimitive2D(static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate)); 225 break; 226 } 227 case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D : 228 { 229 // #i98289# 230 const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete()); 231 const sal_uInt16 nOldAntiAliase(mpOutputDevice->GetAntialiasing()); 232 233 if(bForceLineSnap) 234 { 235 mpOutputDevice->SetAntialiasing(nOldAntiAliase | ANTIALIASING_PIXELSNAPHAIRLINE); 236 } 237 238 static bool bTestMetaFilePrimitiveDecomposition(true); 239 if(bTestMetaFilePrimitiveDecomposition) 240 { 241 // use new Metafile decomposition 242 process(rCandidate.get2DDecomposition(getViewInformation2D())); 243 } 244 else 245 { 246 // direct draw of MetaFile 247 RenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate)); 248 } 249 250 if(bForceLineSnap) 251 { 252 mpOutputDevice->SetAntialiasing(nOldAntiAliase); 253 } 254 255 break; 256 } 257 case PRIMITIVE2D_ID_MASKPRIMITIVE2D : 258 { 259 // mask group. 260 RenderMaskPrimitive2DPixel(static_cast< const primitive2d::MaskPrimitive2D& >(rCandidate)); 261 break; 262 } 263 case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D : 264 { 265 // modified color group. Force output to unified color. 266 RenderModifiedColorPrimitive2D(static_cast< const primitive2d::ModifiedColorPrimitive2D& >(rCandidate)); 267 break; 268 } 269 case PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D : 270 { 271 // Detect if a single PolyPolygonColorPrimitive2D is contained; in that case, 272 // use the faster OutputDevice::DrawTransparent method 273 const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate = static_cast< const primitive2d::UnifiedTransparencePrimitive2D& >(rCandidate); 274 const primitive2d::Primitive2DSequence rContent = rUniTransparenceCandidate.getChildren(); 275 276 if(rContent.hasElements()) 277 { 278 if(0.0 == rUniTransparenceCandidate.getTransparence()) 279 { 280 // not transparent at all, use content 281 process(rUniTransparenceCandidate.getChildren()); 282 } 283 else if(rUniTransparenceCandidate.getTransparence() > 0.0 && rUniTransparenceCandidate.getTransparence() < 1.0) 284 { 285 bool bDrawTransparentUsed(false); 286 287 // since DEV300 m33 DrawTransparent is supported in VCL (for some targets 288 // natively), so i am now enabling this shortcut 289 static bool bAllowUsingDrawTransparent(true); 290 291 if(bAllowUsingDrawTransparent && 1 == rContent.getLength()) 292 { 293 const primitive2d::Primitive2DReference xReference(rContent[0]); 294 const primitive2d::BasePrimitive2D* pBasePrimitive = dynamic_cast< const primitive2d::BasePrimitive2D* >(xReference.get()); 295 296 if(pBasePrimitive) 297 { 298 switch(pBasePrimitive->getPrimitive2DID()) 299 { 300 case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D: 301 { 302 // single transparent PolyPolygon identified, use directly 303 const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = static_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(pBasePrimitive); 304 OSL_ENSURE(pPoPoColor, "OOps, PrimitiveID and PrimitiveType do not match (!)"); 305 const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor())); 306 mpOutputDevice->SetFillColor(Color(aPolygonColor)); 307 mpOutputDevice->SetLineColor(); 308 309 basegfx::B2DPolyPolygon aLocalPolyPolygon(pPoPoColor->getB2DPolyPolygon()); 310 aLocalPolyPolygon.transform(maCurrentTransformation); 311 312 mpOutputDevice->DrawTransparent(aLocalPolyPolygon, rUniTransparenceCandidate.getTransparence()); 313 bDrawTransparentUsed = true; 314 break; 315 } 316 // #i# need to wait for #i101378# which is in CWS vcl112 to directly paint transparent hairlines 317 //case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D: 318 //{ 319 // // single transparent PolygonHairlinePrimitive2D identified, use directly 320 // const primitive2d::PolygonHairlinePrimitive2D* pPoHair = static_cast< const primitive2d::PolygonHairlinePrimitive2D* >(pBasePrimitive); 321 // OSL_ENSURE(pPoHair, "OOps, PrimitiveID and PrimitiveType do not match (!)"); 322 // break; 323 //} 324 } 325 } 326 } 327 328 if(!bDrawTransparentUsed) 329 { 330 // unified sub-transparence. Draw to VDev first. 331 RenderUnifiedTransparencePrimitive2D(rUniTransparenceCandidate); 332 } 333 } 334 } 335 336 break; 337 } 338 case PRIMITIVE2D_ID_TRANSPARENCEPRIMITIVE2D : 339 { 340 // sub-transparence group. Draw to VDev first. 341 RenderTransparencePrimitive2D(static_cast< const primitive2d::TransparencePrimitive2D& >(rCandidate)); 342 break; 343 } 344 case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D : 345 { 346 // transform group. 347 RenderTransformPrimitive2D(static_cast< const primitive2d::TransformPrimitive2D& >(rCandidate)); 348 break; 349 } 350 case PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D : 351 { 352 // new XDrawPage for ViewInformation2D 353 RenderPagePreviewPrimitive2D(static_cast< const primitive2d::PagePreviewPrimitive2D& >(rCandidate)); 354 break; 355 } 356 case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D : 357 { 358 // marker array 359 RenderMarkerArrayPrimitive2D(static_cast< const primitive2d::MarkerArrayPrimitive2D& >(rCandidate)); 360 break; 361 } 362 case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D : 363 { 364 // point array 365 RenderPointArrayPrimitive2D(static_cast< const primitive2d::PointArrayPrimitive2D& >(rCandidate)); 366 break; 367 } 368 case PRIMITIVE2D_ID_CONTROLPRIMITIVE2D : 369 { 370 // control primitive 371 const primitive2d::ControlPrimitive2D& rControlPrimitive = static_cast< const primitive2d::ControlPrimitive2D& >(rCandidate); 372 const uno::Reference< awt::XControl >& rXControl(rControlPrimitive.getXControl()); 373 374 try 375 { 376 // remember old graphics and create new 377 uno::Reference< awt::XView > xControlView(rXControl, uno::UNO_QUERY_THROW); 378 const uno::Reference< awt::XGraphics > xOriginalGraphics(xControlView->getGraphics()); 379 const uno::Reference< awt::XGraphics > xNewGraphics(mpOutputDevice->CreateUnoGraphics()); 380 381 if(xNewGraphics.is()) 382 { 383 // link graphics and view 384 xControlView->setGraphics(xNewGraphics); 385 386 // get position 387 const basegfx::B2DHomMatrix aObjectToPixel(maCurrentTransformation * rControlPrimitive.getTransform()); 388 const basegfx::B2DPoint aTopLeftPixel(aObjectToPixel * basegfx::B2DPoint(0.0, 0.0)); 389 390 // find out if the control is already visualized as a VCL-ChildWindow. If yes, 391 // it does not need to be painted at all. 392 uno::Reference< awt::XWindow2 > xControlWindow(rXControl, uno::UNO_QUERY_THROW); 393 const bool bControlIsVisibleAsChildWindow(rXControl->getPeer().is() && xControlWindow->isVisible()); 394 395 if(!bControlIsVisibleAsChildWindow) 396 { 397 // draw it. Do not forget to use the evtl. offsetted origin of the target device, 398 // e.g. when used with mask/transparence buffer device 399 const Point aOrigin(mpOutputDevice->GetMapMode().GetOrigin()); 400 xControlView->draw( 401 aOrigin.X() + basegfx::fround(aTopLeftPixel.getX()), 402 aOrigin.Y() + basegfx::fround(aTopLeftPixel.getY())); 403 } 404 405 // restore original graphics 406 xControlView->setGraphics(xOriginalGraphics); 407 } 408 } 409 catch(const uno::Exception&) 410 { 411 // #i116763# removing since there is a good alternative when the xControlView 412 // is not found and it is allowed to happen 413 // DBG_UNHANDLED_EXCEPTION(); 414 415 // process recursively and use the decomposition as Bitmap 416 process(rCandidate.get2DDecomposition(getViewInformation2D())); 417 } 418 419 break; 420 } 421 case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D: 422 { 423 // the stroke primitive may be decomposed to filled polygons. To keep 424 // evtl. set DrawModes aka DRAWMODE_BLACKLINE, DRAWMODE_GRAYLINE, 425 // DRAWMODE_GHOSTEDLINE, DRAWMODE_WHITELINE or DRAWMODE_SETTINGSLINE 426 // working, these need to be copied to the corresponding fill modes 427 const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); 428 adaptLineToFillDrawMode(); 429 430 // polygon stroke primitive 431 static bool bSuppressFatToHairlineCorrection(false); 432 433 if(bSuppressFatToHairlineCorrection) 434 { 435 // remeber that we enter a PolygonStrokePrimitive2D decomposition, 436 // used for AA thick line drawing 437 mnPolygonStrokePrimitive2D++; 438 439 // with AA there is no need to handle thin lines special 440 process(rCandidate.get2DDecomposition(getViewInformation2D())); 441 442 // leave PolygonStrokePrimitive2D 443 mnPolygonStrokePrimitive2D--; 444 } 445 else 446 { 447 // Lines with 1 and 2 pixel width without AA need special treatment since their vsiualisation 448 // as filled polygons is geometrically corret but looks wrong since polygon filling avoids 449 // the right and bottom pixels. The used method evaluates that and takes the correct action, 450 // including calling recursively with decomposition if line is wide enough 451 const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive = static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate); 452 453 RenderPolygonStrokePrimitive2D(rPolygonStrokePrimitive); 454 } 455 456 // restore DrawMode 457 mpOutputDevice->SetDrawMode(nOriginalDrawMode); 458 459 break; 460 } 461 case PRIMITIVE2D_ID_CHARTPRIMITIVE2D : 462 { 463 // chart primitive in pixel renderer; restore original DrawMode during call 464 // since the evtl. used ChartPrettyPainter will use the MapMode 465 const primitive2d::ChartPrimitive2D& rChartPrimitive = static_cast< const primitive2d::ChartPrimitive2D& >(rCandidate); 466 mpOutputDevice->Push(PUSH_MAPMODE); 467 mpOutputDevice->SetMapMode(maOriginalMapMode); 468 469 if(!renderChartPrimitive2D( 470 rChartPrimitive, 471 *mpOutputDevice, 472 getViewInformation2D())) 473 { 474 // fallback to decomposition (MetaFile) 475 process(rChartPrimitive.get2DDecomposition(getViewInformation2D())); 476 } 477 478 mpOutputDevice->Pop(); 479 break; 480 } 481 case PRIMITIVE2D_ID_FILLHATCHPRIMITIVE2D : 482 { 483 static bool bForceIgnoreHatchSmoothing(false); 484 485 if(bForceIgnoreHatchSmoothing || getOptionsDrawinglayer().IsAntiAliasing()) 486 { 487 // if AA is used (or ignore smoothing is on), there is no need to smooth 488 // hatch painting, use decomposition 489 process(rCandidate.get2DDecomposition(getViewInformation2D())); 490 } 491 else 492 { 493 // without AA, use VCL to draw the hatch. It snaps hatch distances to the next pixel 494 // and forces hatch distance to be >= 3 pixels to make the hatch display look smoother. 495 // This is wrong in principle, but looks nicer. This could also be done here directly 496 // without VCL usage if needed 497 const primitive2d::FillHatchPrimitive2D& rFillHatchPrimitive = static_cast< const primitive2d::FillHatchPrimitive2D& >(rCandidate); 498 const attribute::FillHatchAttribute& rFillHatchAttributes = rFillHatchPrimitive.getFillHatch(); 499 500 // create hatch polygon in range size and discrete coordinates 501 basegfx::B2DRange aHatchRange(rFillHatchPrimitive.getObjectRange()); 502 aHatchRange.transform(maCurrentTransformation); 503 const basegfx::B2DPolygon aHatchPolygon(basegfx::tools::createPolygonFromRect(aHatchRange)); 504 505 if(rFillHatchAttributes.isFillBackground()) 506 { 507 // #i111846# background fill is active; draw fill polygon 508 const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor())); 509 510 mpOutputDevice->SetFillColor(Color(aPolygonColor)); 511 mpOutputDevice->SetLineColor(); 512 mpOutputDevice->DrawPolygon(aHatchPolygon); 513 } 514 515 // set hatch line color 516 const basegfx::BColor aHatchColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor())); 517 mpOutputDevice->SetFillColor(); 518 mpOutputDevice->SetLineColor(Color(aHatchColor)); 519 520 // get hatch style 521 HatchStyle eHatchStyle(HATCH_SINGLE); 522 523 switch(rFillHatchAttributes.getStyle()) 524 { 525 default : // HATCHSTYLE_SINGLE 526 { 527 break; 528 } 529 case attribute::HATCHSTYLE_DOUBLE : 530 { 531 eHatchStyle = HATCH_DOUBLE; 532 break; 533 } 534 case attribute::HATCHSTYLE_TRIPLE : 535 { 536 eHatchStyle = HATCH_TRIPLE; 537 break; 538 } 539 } 540 541 // create hatch 542 const basegfx::B2DVector aDiscreteDistance(maCurrentTransformation * basegfx::B2DVector(rFillHatchAttributes.getDistance(), 0.0)); 543 const sal_uInt32 nDistance(basegfx::fround(aDiscreteDistance.getLength())); 544 const sal_uInt16 nAngle10((sal_uInt16)basegfx::fround(rFillHatchAttributes.getAngle() / F_PI1800)); 545 ::Hatch aVCLHatch(eHatchStyle, Color(rFillHatchAttributes.getColor()), nDistance, nAngle10); 546 547 // draw hatch using VCL 548 mpOutputDevice->DrawHatch(PolyPolygon(Polygon(aHatchPolygon)), aVCLHatch); 549 } 550 break; 551 } 552 case PRIMITIVE2D_ID_BACKGROUNDCOLORPRIMITIVE2D : 553 { 554 // #i98404# Handle directly, especially when AA is active 555 const primitive2d::BackgroundColorPrimitive2D& rPrimitive = static_cast< const primitive2d::BackgroundColorPrimitive2D& >(rCandidate); 556 const sal_uInt16 nOriginalAA(mpOutputDevice->GetAntialiasing()); 557 558 // switch AA off in all cases 559 mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); 560 561 // create color for fill 562 const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPrimitive.getBColor())); 563 mpOutputDevice->SetFillColor(Color(aPolygonColor)); 564 mpOutputDevice->SetLineColor(); 565 566 // create rectangle for fill 567 const basegfx::B2DRange& aViewport(getViewInformation2D().getDiscreteViewport()); 568 const Rectangle aRectangle( 569 (sal_Int32)floor(aViewport.getMinX()), (sal_Int32)floor(aViewport.getMinY()), 570 (sal_Int32)ceil(aViewport.getMaxX()), (sal_Int32)ceil(aViewport.getMaxY())); 571 mpOutputDevice->DrawRect(aRectangle); 572 573 // restore AA setting 574 mpOutputDevice->SetAntialiasing(nOriginalAA); 575 break; 576 } 577 case PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D : 578 { 579 // #i97628# 580 // This primitive means that the content is derived from an active text edit, 581 // not from model data itself. Some renderers need to suppress this content, e.g. 582 // the pixel renderer used for displaying the edit view (like this one). It's 583 // not to be suppressed by the MetaFile renderers, so that the edited text is 584 // part of the MetaFile, e.g. needed for presentation previews. 585 // Action: Ignore here, do nothing. 586 break; 587 } 588 case PRIMITIVE2D_ID_INVERTPRIMITIVE2D : 589 { 590 // invert primitive (currently only used for HighContrast fallback for selection in SW and SC). 591 // Set OutDev to XOR and switch AA off (XOR does not work with AA) 592 mpOutputDevice->Push(); 593 mpOutputDevice->SetRasterOp( ROP_XOR ); 594 const sal_uInt16 nAntiAliasing(mpOutputDevice->GetAntialiasing()); 595 mpOutputDevice->SetAntialiasing(nAntiAliasing & ~ANTIALIASING_ENABLE_B2DDRAW); 596 597 // process content recursively 598 process(rCandidate.get2DDecomposition(getViewInformation2D())); 599 600 // restore OutDev 601 mpOutputDevice->Pop(); 602 mpOutputDevice->SetAntialiasing(nAntiAliasing); 603 break; 604 } 605 case PRIMITIVE2D_ID_EPSPRIMITIVE2D : 606 { 607 RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate)); 608 break; 609 } 610 default : 611 { 612 // process recursively 613 process(rCandidate.get2DDecomposition(getViewInformation2D())); 614 break; 615 } 616 } 617 } 618 } // end of namespace processor2d 619 } // end of namespace drawinglayer 620 621 ////////////////////////////////////////////////////////////////////////////// 622 // eof 623