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