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