diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2009-07-27 16:24:52 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2009-07-27 16:24:52 +0000 |
commit | cbf10a85ee07cf370a5547e725cce5f193c9362c (patch) | |
tree | d5bea1160494f98ecaea60f2f7bed38e758c5672 | |
parent | 242fa8cd290df213faea0acd0e511afc45cbd84a (diff) |
CWS-TOOLING: integrate CWS aw073
2009-07-16 11:21:19 +0200 aw r274036 : corrections after resync
2009-07-15 13:34:18 +0200 aw r274009 : CWS-TOOLING: rebase CWS aw073 to trunk@273858 (milestone: DEV300:m52)
2009-07-01 20:04:27 +0200 aw r273613 : CWS-TOOLING: rebase CWS aw073 to trunk@273468 (milestone: DEV300:m51)
2009-06-24 11:51:03 +0200 aw r273324 : #i102062# added using statement for solaris compiler
2009-06-23 12:53:50 +0200 aw r273278 : #i100158# force filled polygons to closed state
2009-06-23 12:28:33 +0200 aw r273276 : #i100158#, #i102371# corrected all (mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) shortcuts to support line/fill and to be not used when FillMode is not overpaint
2009-06-23 12:15:14 +0200 aw r273274 : #i100158# added PolyPolygon support for snapPointsOfHorizontalOrVerticalEdges helper
2009-06-22 17:28:33 +0200 aw r273244 : #i101508# added taking care of cell's distance-to-border values for cell text primitive creation
2009-06-22 12:59:10 +0200 aw r273218 : #i102253# applied patch from OD (see task)
2009-06-18 17:00:52 +0200 aw r273125 : #i102251# added EE_CNTRL_ONLINESPELLING switch off at DrawOutliner during GraphicExporter::GetGraphic
2009-06-18 14:35:57 +0200 aw r273120 : #i102241# added mergeToSinglePolyPolygon usage to SdrObject::ImpConvertToContourObj
2009-06-18 14:35:20 +0200 aw r273119 : #i102241# improved PolygonStrokePrimitive2D::createLocalDecomposition
2009-06-18 14:34:49 +0200 aw r273118 : #i102241# Made B2DCubicBezier::testAndSolveTrivialBezier() numerically more stable
2009-06-17 16:11:21 +0200 aw r273078 : #i102062# added compare support for OutlireParaObject's WrongList in an extra method; using in primitive comparators
2009-06-16 19:10:18 +0200 aw r273037 : #i101957# corrected: offset needs to be added before rotation and shear
2009-06-16 18:58:43 +0200 aw r273035 : #i101957# added needed offset by object width to SdrTextObj::impDecomposeStretchTextPrimitive for vertical texts
2009-06-16 18:35:55 +0200 aw r273034 : #i101941# corrected object initialisation for 3D Scenes on Clone operator
2009-06-16 16:07:30 +0200 aw r273024 : #i101811# extended renderChartPrimitive2D to create a correct embedding in a new MapMode
2009-06-12 19:38:07 +0200 aw r272940 : #i101734# added test code to experiment on demand with more complex transformations for virtual objects than only translations
2009-06-12 19:37:07 +0200 aw r272939 : #i101734# corrected SvtGraphicStroke preparation in MetaFile renderer (AFAP)
2009-06-12 16:31:55 +0200 aw r272931 : #i101648# re-enabled object creation with objecttype OBJ_NONE for SW Frame creation
2009-06-12 13:59:05 +0200 aw r272917 : #i101598# supported AAed single line paint in VCL
2009-06-12 11:34:25 +0200 aw r272907 : #i101598# adapted Graphic::GetBitmap() usage
2009-06-10 16:34:19 +0200 aw r272830 : #i101598# added VCL_DLLPUBLIC to parameter class
2009-06-10 16:30:27 +0200 aw r272829 : #i101598# extended calls to Graphic::GetBitmap/Ex where conversions to Bitmap objects is needed to user defined parameters like AntiAlisasing
2009-06-10 16:28:44 +0200 aw r272828 : #i101598# extended Graphic::GetBitmap/Ex interfaces to transport raster conversion parameters since these calls potentially need to rasterconvert a contained MetaFile
2009-06-09 16:26:40 +0200 aw r272781 : #i100945# checked in proposed patch for now
2009-06-08 18:01:42 +0200 aw r272742 : #i101239# teached BinTextObject to register at EditEngineItemPool sub-pool, not on given pool directly
-rw-r--r-- | basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx | 9 | ||||
-rw-r--r-- | basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx | 14 | ||||
-rw-r--r-- | basegfx/source/curve/b2dcubicbezier.cxx | 36 | ||||
-rw-r--r-- | basegfx/source/polygon/b2dpolypolygoncutter.cxx | 79 | ||||
-rw-r--r-- | basegfx/source/polygon/b2dpolypolygontools.cxx | 12 | ||||
-rw-r--r-- | vcl/inc/vcl/graph.hxx | 44 | ||||
-rw-r--r-- | vcl/inc/vcl/impgraph.hxx | 5 | ||||
-rw-r--r-- | vcl/source/gdi/graph.cxx | 38 | ||||
-rw-r--r-- | vcl/source/gdi/impgraph.cxx | 38 | ||||
-rw-r--r-- | vcl/source/gdi/outdev.cxx | 195 | ||||
-rw-r--r-- | vcl/source/gdi/outdev6.cxx | 14 |
11 files changed, 380 insertions, 104 deletions
diff --git a/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx b/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx index 9474e51e3904..12532ff078f3 100644 --- a/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx +++ b/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx @@ -104,6 +104,15 @@ namespace basegfx // DIFF: Return all areas where CandidateA is not covered by CandidateB (cut B out of A) B2DPolyPolygon solvePolygonOperationDiff(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB); + /** merge all single PolyPolygons to a single, OR-ed PolyPolygon + + @param rInput + The source PolyPolygons + + @return A single PolyPolygon containing the Or-merged result + */ + B2DPolyPolygon mergeToSinglePolyPolygon(const std::vector< basegfx::B2DPolyPolygon >& rInput); + } // end of namespace tools } // end of namespace basegfx diff --git a/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx b/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx index 5c75edd7f262..c4687b3cfc5f 100644 --- a/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx +++ b/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx @@ -262,6 +262,20 @@ namespace basegfx bool equal(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB, const double& rfSmallValue); bool equal(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB); + /** snap some polygon coordinates to discrete coordinates + + This method allows to snap some polygon points to discrete (integer) values + which equals e.g. a snap to discrete coordinates. It will snap points of + horizontal and vertical edges + + @param rCandidate + The source polygon + + @return + The modified version of the source polygon + */ + B2DPolyPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon& rCandidate); + } // end of namespace tools } // end of namespace basegfx diff --git a/basegfx/source/curve/b2dcubicbezier.cxx b/basegfx/source/curve/b2dcubicbezier.cxx index 76d1b74ddbca..e7247a95333b 100644 --- a/basegfx/source/curve/b2dcubicbezier.cxx +++ b/basegfx/source/curve/b2dcubicbezier.cxx @@ -443,21 +443,32 @@ namespace basegfx bool bAIsTrivial(aVecA.equalZero()); bool bBIsTrivial(aVecB.equalZero()); + // #i102241# prepare inverse edge length to normalize cross values; + // else the small compare value used in fTools::equalZero + // will be length dependent and this detection will work as less + // precise as longer the edge is. In principle, the length of the control + // vector would need to be used too, but to be trivial it is assumed to + // be of roughly equal length to the edge, so edge length can be used + // for both. Only needed when one of both is not trivial per se. + const double fInverseEdgeLength(bAIsTrivial && bBIsTrivial + ? 1.0 + : 1.0 / aEdge.getLength()); + // if A is not zero, check if it could be if(!bAIsTrivial) { - // parallel to edge? Check aVecA, aEdge - // B2DVector::areParallel is too correct, uses differences in the e15 region, - // thus do own test here - const double fValA(aVecA.getX() * aEdge.getY()); - const double fValB(aVecA.getY() * aEdge.getX()); + // #i102241# parallel to edge? Check aVecA, aEdge. Use cross() which does what + // we need here with the precision we need + const double fCross(aVecA.cross(aEdge) * fInverseEdgeLength); - if(fTools::equalZero(fabs(fValA) - fabs(fValB))) + if(fTools::equalZero(fCross)) { // get scale to edge. Use bigger distance for numeric quality - const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) ? aVecA.getX() / aEdge.getX() : aVecA.getY() / aEdge.getY()); + const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) + ? aVecA.getX() / aEdge.getX() + : aVecA.getY() / aEdge.getY()); - // end point of vector in edge range? + // relative end point of vector in edge range? if(fTools::moreOrEqual(fScale, 0.0) && fTools::lessOrEqual(fScale, 1.0)) { bAIsTrivial = true; @@ -470,13 +481,14 @@ namespace basegfx if(bAIsTrivial && !bBIsTrivial) { // parallel to edge? Check aVecB, aEdge - const double fValA(aVecB.getX() * aEdge.getY()); - const double fValB(aVecB.getY() * aEdge.getX()); + const double fCross(aVecB.cross(aEdge) * fInverseEdgeLength); - if(fTools::equalZero(fabs(fValA) - fabs(fValB))) + if(fTools::equalZero(fCross)) { // get scale to edge. Use bigger distance for numeric quality - const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) ? aVecB.getX() / aEdge.getX() : aVecB.getY() / aEdge.getY()); + const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) + ? aVecB.getX() / aEdge.getX() + : aVecB.getY() / aEdge.getY()); // end point of vector in edge range? Caution: controlB is directed AGAINST edge if(fTools::lessOrEqual(fScale, 0.0) && fTools::moreOrEqual(fScale, -1.0)) diff --git a/basegfx/source/polygon/b2dpolypolygoncutter.cxx b/basegfx/source/polygon/b2dpolypolygoncutter.cxx index b06e6fbafff7..0674bfe3953e 100644 --- a/basegfx/source/polygon/b2dpolypolygoncutter.cxx +++ b/basegfx/source/polygon/b2dpolypolygoncutter.cxx @@ -929,6 +929,85 @@ namespace basegfx } } + B2DPolyPolygon mergeToSinglePolyPolygon(const std::vector< basegfx::B2DPolyPolygon >& rInput) + { + std::vector< basegfx::B2DPolyPolygon > aInput(rInput); + + // first step: prepareForPolygonOperation and simple merge of non-overlapping + // PolyPolygons for speedup; this is possible for the wanted OR-operation + if(aInput.size()) + { + std::vector< basegfx::B2DPolyPolygon > aResult; + aResult.reserve(aInput.size()); + + for(sal_uInt32 a(0); a < aInput.size(); a++) + { + const basegfx::B2DPolyPolygon aCandidate(prepareForPolygonOperation(aInput[a])); + + if(aResult.size()) + { + const B2DRange aCandidateRange(aCandidate.getB2DRange()); + bool bCouldMergeSimple(false); + + for(sal_uInt32 b(0); !bCouldMergeSimple && b < aResult.size(); b++) + { + basegfx::B2DPolyPolygon aTarget(aResult[b]); + const B2DRange aTargetRange(aTarget.getB2DRange()); + + if(!aCandidateRange.overlaps(aTargetRange)) + { + aTarget.append(aCandidate); + aResult[b] = aTarget; + bCouldMergeSimple = true; + } + } + + if(!bCouldMergeSimple) + { + aResult.push_back(aCandidate); + } + } + else + { + aResult.push_back(aCandidate); + } + } + + aInput = aResult; + } + + // second step: melt pairwise to a single PolyPolygon + while(aInput.size() > 1) + { + std::vector< basegfx::B2DPolyPolygon > aResult; + aResult.reserve((aInput.size() / 2) + 1); + + for(sal_uInt32 a(0); a < aInput.size(); a += 2) + { + if(a + 1 < aInput.size()) + { + // a pair for processing + aResult.push_back(solvePolygonOperationOr(aInput[a], aInput[a + 1])); + } + else + { + // last single PolyPolygon; copy to target to not lose it + aResult.push_back(aInput[a]); + } + } + + aInput = aResult; + } + + // third step: get result + if(1 == aInput.size()) + { + return aInput[0]; + } + + return B2DPolyPolygon(); + } + ////////////////////////////////////////////////////////////////////////////// } // end of namespace tools diff --git a/basegfx/source/polygon/b2dpolypolygontools.cxx b/basegfx/source/polygon/b2dpolypolygontools.cxx index c92f2f29147b..e6b3a448530d 100644 --- a/basegfx/source/polygon/b2dpolypolygontools.cxx +++ b/basegfx/source/polygon/b2dpolypolygontools.cxx @@ -569,6 +569,18 @@ namespace basegfx return equal(rCandidateA, rCandidateB, fSmallValue); } + B2DPolyPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon& rCandidate) + { + B2DPolyPolygon aRetval; + + for(sal_uInt32 a(0L); a < rCandidate.count(); a++) + { + aRetval.append(snapPointsOfHorizontalOrVerticalEdges(rCandidate.getB2DPolygon(a))); + } + + return aRetval; + } + } // end of namespace tools } // end of namespace basegfx diff --git a/vcl/inc/vcl/graph.hxx b/vcl/inc/vcl/graph.hxx index f56c55b7db42..9d70c67d3e55 100644 --- a/vcl/inc/vcl/graph.hxx +++ b/vcl/inc/vcl/graph.hxx @@ -53,6 +53,36 @@ class OutputDevice; class Font; class GfxLink; +class VCL_DLLPUBLIC GraphicConversionParameters +{ +private: + Size maSizePixel; // default is (0,0) + + // bitfield + unsigned mbUnlimitedSize : 1; // default is false + unsigned mbAntiAliase : 1; // default is false + unsigned mbSnapHorVerLines : 1; // default is false + +public: + GraphicConversionParameters( + const Size& rSizePixel = Size(), + bool bUnlimitedSize = false, + bool bAntiAliase = false, + bool bSnapHorVerLines = false) + : maSizePixel(rSizePixel), + mbUnlimitedSize(bUnlimitedSize), + mbAntiAliase(bAntiAliase), + mbSnapHorVerLines(bSnapHorVerLines) + { + } + + // data read access + const Size getSizePixel() const { return maSizePixel; } + bool getUnlimitedSize() const { return mbUnlimitedSize; } + bool getAntiAliase() const { return mbAntiAliase; } + bool getSnapHorVerLines() const { return mbSnapHorVerLines; } +}; + class VCL_DLLPUBLIC Graphic : public SvDataCopyStream { private: @@ -96,12 +126,14 @@ public: BOOL IsAlpha() const; BOOL IsAnimated() const; - Bitmap GetBitmap() const; - Bitmap GetBitmap( const Size* pSizePixel ) const; - BitmapEx GetBitmapEx() const; - BitmapEx GetBitmapEx( const Size* pSizePixel ) const; - Bitmap GetUnlimitedBitmap( const Size* pSizePixel ) const; - BitmapEx GetUnlimitedBitmapEx( const Size* pSizePixel ) const; + // #i102089# Access of Bitmap potentially will have to rasterconvert the Graphic + // if it is a MetaFile. To be able to control this conversion it is necessary to + // allow giving parameters which control AntiAliasing and LineSnapping of the + // MetaFile when played. Defaults will use a no-AAed, not snapped conversion as + // before. + Bitmap GetBitmap(const GraphicConversionParameters& rParameters = GraphicConversionParameters()) const; + BitmapEx GetBitmapEx(const GraphicConversionParameters& rParameters = GraphicConversionParameters()) const; + Animation GetAnimation() const; const GDIMetaFile& GetGDIMetaFile() const; diff --git a/vcl/inc/vcl/impgraph.hxx b/vcl/inc/vcl/impgraph.hxx index 34b61a5fe21c..3b36173891ae 100644 --- a/vcl/inc/vcl/impgraph.hxx +++ b/vcl/inc/vcl/impgraph.hxx @@ -55,6 +55,7 @@ struct ImpSwapInfo class OutputDevice; class GfxLink; struct ImpSwapFile; +class GraphicConversionParameters; class ImpGraphic { @@ -102,8 +103,8 @@ private: BOOL ImplIsAlpha() const; BOOL ImplIsAnimated() const; - Bitmap ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) const; - BitmapEx ImplGetBitmapEx( const Size* pSizePixel, BOOL bUnlimited ) const; + Bitmap ImplGetBitmap(const GraphicConversionParameters& rParameters) const; + BitmapEx ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const; Animation ImplGetAnimation() const; const GDIMetaFile& ImplGetGDIMetaFile() const; diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx index dfa155e29eae..77f065912e5d 100644 --- a/vcl/source/gdi/graph.cxx +++ b/vcl/source/gdi/graph.cxx @@ -430,44 +430,16 @@ BOOL Graphic::IsAnimated() const // ------------------------------------------------------------------------ -Bitmap Graphic::GetBitmap() const +Bitmap Graphic::GetBitmap(const GraphicConversionParameters& rParameters) const { - return GetBitmap( NULL ); + return mpImpGraphic->ImplGetBitmap(rParameters); } // ------------------------------------------------------------------------ -BitmapEx Graphic::GetBitmapEx() const +BitmapEx Graphic::GetBitmapEx(const GraphicConversionParameters& rParameters) const { - return GetBitmapEx( NULL ); -} - -// ------------------------------------------------------------------------ - -Bitmap Graphic::GetBitmap( const Size* pSizePixel ) const -{ - return mpImpGraphic->ImplGetBitmap( pSizePixel, FALSE ); -} - -// ------------------------------------------------------------------------ - -BitmapEx Graphic::GetBitmapEx( const Size* pSizePixel ) const -{ - return mpImpGraphic->ImplGetBitmapEx( pSizePixel, FALSE ); -} - -// ------------------------------------------------------------------------ - -Bitmap Graphic::GetUnlimitedBitmap( const Size* pSizePixel ) const -{ - return mpImpGraphic->ImplGetBitmap( pSizePixel, TRUE ) ; -} - -// ------------------------------------------------------------------------ - -BitmapEx Graphic::GetUnlimitedBitmapEx( const Size* pSizePixel ) const -{ - return mpImpGraphic->ImplGetBitmapEx( pSizePixel, TRUE ) ; + return mpImpGraphic->ImplGetBitmapEx(rParameters); } // ------------------------------------------------------------------------ @@ -553,7 +525,7 @@ Size Graphic::GetSizePixel( const OutputDevice* pRefDevice ) const Size aRet; if( GRAPHIC_BITMAP == mpImpGraphic->ImplGetType() ) - aRet = mpImpGraphic->ImplGetBitmapEx( NULL, FALSE ).GetSizePixel(); + aRet = mpImpGraphic->ImplGetBitmapEx(GraphicConversionParameters()).GetSizePixel(); else aRet = ( pRefDevice ? pRefDevice : Application::GetDefaultDevice() )->LogicToPixel( GetPrefSize(), GetPrefMapMode() ); diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index a67d6fa7feac..d73f35bef962 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -483,7 +483,7 @@ BOOL ImpGraphic::ImplIsAnimated() const // ------------------------------------------------------------------------ -Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) const +Bitmap ImpGraphic::ImplGetBitmap(const GraphicConversionParameters& rParameters) const { Bitmap aRetBmp; @@ -494,8 +494,8 @@ Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) cons aRetBmp = rRetBmpEx.GetBitmap( &aReplaceColor ); - if( pSizePixel ) - aRetBmp.Scale( *pSizePixel ); + if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height()) + aRetBmp.Scale(rParameters.getSizePixel()); } else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() ) { @@ -508,16 +508,18 @@ Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) cons Size aDrawSize( aVDev.LogicToPixel( maMetaFile.GetPrefSize(), maMetaFile.GetPrefMapMode() ) ); Size aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 ); - if( pSizePixel && aSizePix.Width() && aSizePix.Height() ) + if(rParameters.getSizePixel().Width() && rParameters.getSizePixel().Height()) { - aDrawSize.Width() = FRound( (double) pSizePixel->Width() * (double) aDrawSize.Width() / (double) aSizePix.Width() ); - aDrawSize.Height() = FRound( (double) pSizePixel->Height() * (double) aDrawSize.Height() / (double) aSizePix.Height() ); + aDrawSize.Width() = FRound((double)rParameters.getSizePixel().Width() * + (double)aDrawSize.Width() / (double)aSizePix.Width()); + aDrawSize.Height() = FRound((double)rParameters.getSizePixel().Height() * + (double)aDrawSize.Height() / (double)aSizePix.Height()); - aSizePix = *pSizePixel; + aSizePix = rParameters.getSizePixel(); } - if( aSizePix.Width() && aSizePix.Height() && !bUnlimited && - ( aSizePix.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aSizePix.Height() > GRAPHIC_MTFTOBMP_MAXEXT ) ) + if( aSizePix.Width() && aSizePix.Height() && !rParameters.getUnlimitedSize() + && (aSizePix.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aSizePix.Height() > GRAPHIC_MTFTOBMP_MAXEXT)) { const Size aOldSizePix( aSizePix ); double fWH = (double) aSizePix.Width() / aSizePix.Height(); @@ -533,6 +535,16 @@ Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) cons if( aVDev.SetOutputSizePixel( aSizePix ) ) { + if(rParameters.getAntiAliase()) + { + aVDev.SetAntialiasing(aVDev.GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW); + } + + if(rParameters.getSnapHorVerLines()) + { + aVDev.SetAntialiasing(aVDev.GetAntialiasing() | ANTIALIASING_PIXELSNAPHAIRLINE); + } + ImplDraw( &aVDev, aNullPt, aDrawSize ); aRetBmp = aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ); } @@ -549,7 +561,7 @@ Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) cons // ------------------------------------------------------------------------ -BitmapEx ImpGraphic::ImplGetBitmapEx( const Size* pSizePixel, BOOL bUnlimited ) const +BitmapEx ImpGraphic::ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const { BitmapEx aRetBmpEx; @@ -557,13 +569,13 @@ BitmapEx ImpGraphic::ImplGetBitmapEx( const Size* pSizePixel, BOOL bUnlimited ) { aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx ); - if( pSizePixel ) - aRetBmpEx.Scale( *pSizePixel ); + if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height()) + aRetBmpEx.Scale(rParameters.getSizePixel()); } else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() ) { const ImpGraphic aMonoMask( maMetaFile.GetMonochromeMtf( COL_BLACK ) ); - aRetBmpEx = BitmapEx( ImplGetBitmap( pSizePixel, bUnlimited ), aMonoMask.ImplGetBitmap( pSizePixel, bUnlimited ) ); + aRetBmpEx = BitmapEx(ImplGetBitmap(rParameters), aMonoMask.ImplGetBitmap(rParameters)); } return aRetBmpEx; diff --git a/vcl/source/gdi/outdev.cxx b/vcl/source/gdi/outdev.cxx index 0e9da9f81136..ebcf31199364 100644 --- a/vcl/source/gdi/outdev.cxx +++ b/vcl/source/gdi/outdev.cxx @@ -68,6 +68,7 @@ #include <basegfx/polygon/b2dpolypolygon.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> #include <com/sun/star/awt/XGraphics.hpp> #include <com/sun/star/uno/Sequence.hxx> @@ -2285,8 +2286,35 @@ void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt ) if ( mbInitLineColor ) ImplInitLineColor(); - Point aStartPt = ImplLogicToDevicePixel( rStartPt ); - Point aEndPt = ImplLogicToDevicePixel( rEndPt ); + // #i101598# support AA and snap for lines, too + if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && IsLineColor()) + { + // at least transform with double precision to device coordinates; this will + // avoid pixel snap of single, appended lines + const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation()); + const basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); + basegfx::B2DPolygon aB2DPolyLine; + + aB2DPolyLine.append(basegfx::B2DPoint(rStartPt.X(), rStartPt.Y())); + aB2DPolyLine.append(basegfx::B2DPoint(rEndPt.X(), rEndPt.Y())); + aB2DPolyLine.transform( aTransform ); + + if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) + { + aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine); + } + + if(mpGraphics->DrawPolyLine(aB2DPolyLine, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this)) + { + return; + } + } + + const Point aStartPt(ImplLogicToDevicePixel(rStartPt)); + const Point aEndPt(ImplLogicToDevicePixel(rEndPt)); mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this ); @@ -2445,21 +2473,27 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly ) ImplInitLineColor(); // use b2dpolygon drawing if possible - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)) + if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && IsLineColor()) { - ::basegfx::B2DPolygon aB2DPolyLine = rPoly.getB2DPolygon(); + basegfx::B2DPolygon aB2DPolyLine(rPoly.getB2DPolygon()); const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); - aB2DPolyLine.transform( aTransform ); const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && (mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)) + // transform the polygon + aB2DPolyLine.transform( aTransform ); + + if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) { - // #i98289# aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine); } - if( mpGraphics->DrawPolyLine( aB2DPolyLine, aB2DLineWidth, basegfx::B2DLINEJOIN_ROUND, this ) ) + if(mpGraphics->DrawPolyLine(aB2DPolyLine, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this)) + { return; + } } Polygon aPoly = ImplLogicToDevicePixel( rPoly ); @@ -2598,13 +2632,40 @@ void OutputDevice::DrawPolygon( const Polygon& rPoly ) ImplInitFillColor(); // use b2dpolygon drawing if possible - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)) + if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && (IsLineColor() || IsFillColor())) { - ::basegfx::B2DPolyPolygon aB2DPolyPolygon( rPoly.getB2DPolygon() ); const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); - aB2DPolyPolygon.transform( aTransform ); - if( mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, 0.0, this ) ) + basegfx::B2DPolygon aB2DPolygon(rPoly.getB2DPolygon()); + bool bSuccess(true); + + // transform the polygon and ensure closed + aB2DPolygon.transform(aTransform); + aB2DPolygon.setClosed(true); + + if(IsFillColor()) + { + bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(aB2DPolygon), 0.0, this); + } + + if(bSuccess && IsLineColor()) + { + const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); + + if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) + { + aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon); + } + + bSuccess = mpGraphics->DrawPolyLine(aB2DPolygon, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this); + } + + if(bSuccess) + { return; + } } Polygon aPoly = ImplLogicToDevicePixel( rPoly ); @@ -2661,13 +2722,43 @@ void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly ) ImplInitFillColor(); // use b2dpolygon drawing if possible - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)) + if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && (IsLineColor() || IsFillColor())) { - ::basegfx::B2DPolyPolygon aB2DPolyPolygon = rPolyPoly.getB2DPolyPolygon(); const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); - aB2DPolyPolygon.transform( aTransform ); - if( mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, 0.0, this ) ) + basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPoly.getB2DPolyPolygon()); + bool bSuccess(true); + + // transform the polygon and ensure closed + aB2DPolyPolygon.transform(aTransform); + aB2DPolyPolygon.setClosed(true); + + if(IsFillColor()) + { + bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this); + } + + if(bSuccess && IsLineColor()) + { + const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); + + if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) + { + aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon); + } + + for(sal_uInt32 a(0); bSuccess && a < aB2DPolyPolygon.count(); a++) + { + bSuccess = mpGraphics->DrawPolyLine(aB2DPolyPolygon.getB2DPolygon(a), aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this); + } + } + + if(bSuccess) + { return; + } } if ( nPoly == 1 ) @@ -2748,13 +2839,43 @@ void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly if( mbInitFillColor ) ImplInitFillColor(); - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)) + if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && (IsLineColor() || IsFillColor())) { - const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); - ::basegfx::B2DPolyPolygon aB2DPP = rB2DPolyPoly; - aB2DPP.transform( aTransform ); - if( mpGraphics->DrawPolyPolygon( aB2DPP, 0.0, this ) ) + const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation()); + basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly); + bool bSuccess(true); + + // transform the polygon and ensure closed + aB2DPolyPolygon.transform(aTransform); + aB2DPolyPolygon.setClosed(true); + + if(IsFillColor()) + { + bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this); + } + + if(bSuccess && IsLineColor()) + { + const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); + + if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) + { + aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon); + } + + for(sal_uInt32 a(0);bSuccess && a < aB2DPolyPolygon.count(); a++) + { + bSuccess = mpGraphics->DrawPolyLine(aB2DPolyPolygon.getB2DPolygon(a), aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this); + } + } + + if(bSuccess) + { return; + } } // fallback to old polygon drawing if needed @@ -2809,28 +2930,34 @@ void OutputDevice::DrawPolyLine( ImplInitLineColor(); // #i98289# use b2dpolygon drawing if possible - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)) + if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && IsLineColor()) { - const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); - ::basegfx::B2DVector aB2DLineWidth(1.0, 1.0); - - // transform the line width if used - if( fLineWidth != 0.0 ) - aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, fLineWidth ); + const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation()); + basegfx::B2DPolygon aB2DPolygon(rB2DPolygon); + basegfx::B2DVector aB2DLineWidth(1.0, 1.0); // transform the polygon - ::basegfx::B2DPolygon aB2DPL = rB2DPolygon; - aB2DPL.transform( aTransform ); + aB2DPolygon.transform(aTransform); - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && (mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)) + // transform the line width if used + if(fLineWidth != 0.0) { - // #i98289# - aB2DPL = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPL); + aB2DLineWidth = aTransform * ::basegfx::B2DVector(fLineWidth, fLineWidth); + } + + if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) + { + aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon); } // draw the polyline - if( mpGraphics->DrawPolyLine( aB2DPL, aB2DLineWidth, eLineJoin, this ) ) + if(mpGraphics->DrawPolyLine(aB2DPolygon, aB2DLineWidth, eLineJoin, this)) + { return; + } } // fallback to old polygon drawing if needed diff --git a/vcl/source/gdi/outdev6.cxx b/vcl/source/gdi/outdev6.cxx index cee4f475a577..a11e276982f7 100644 --- a/vcl/source/gdi/outdev6.cxx +++ b/vcl/source/gdi/outdev6.cxx @@ -185,14 +185,20 @@ void OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, if( mbInitFillColor ) ImplInitFillColor(); - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)) + if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && IsFillColor()) { // b2dpolygon support not implemented yet on non-UNX platforms const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); - ::basegfx::B2DPolyPolygon aB2DPP = rB2DPolyPoly; - aB2DPP.transform( aTransform ); + basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly); - if( mpGraphics->DrawPolyPolygon( aB2DPP, fTransparency, this ) ) + // transform the polygon and ensure closed + aB2DPolyPolygon.transform(aTransform); + aB2DPolyPolygon.setClosed(true); + + if(mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, fTransparency, this)) { #if 0 // MetaB2DPolyPolygonAction is not implemented yet: |