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