diff options
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/Library_vcl.mk | 2 | ||||
-rw-r--r-- | vcl/source/gdi/outdev/outdev.cxx | 597 |
2 files changed, 2 insertions, 597 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 14a097425e5e..5348d3836e07 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -238,6 +238,8 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/gdi/outdev/polygon \ vcl/source/gdi/outdev/outdev2 \ vcl/source/gdi/outdev/outdev3 \ + vcl/source/gdi/outdev/line \ + vcl/source/gdi/outdev/polyline \ vcl/source/gdi/outdev/hatch \ vcl/source/gdi/outdev/gradient \ vcl/source/gdi/outdev/outdev5 \ diff --git a/vcl/source/gdi/outdev/outdev.cxx b/vcl/source/gdi/outdev/outdev.cxx index a05dfa7dfdd3..004910827ca9 100644 --- a/vcl/source/gdi/outdev/outdev.cxx +++ b/vcl/source/gdi/outdev/outdev.cxx @@ -1010,252 +1010,6 @@ void OutputDevice::SetRefPoint( const Point& rRefPoint ) mpAlphaVDev->SetRefPoint( rRefPoint ); } -void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt ) -{ - - if ( mpMetaFile ) - mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt ) ); - - if ( !IsDeviceOutputNecessary() || !mbLineColor || ImplIsRecordLayout() ) - return; - - if ( !mpGraphics ) - { - if ( !ImplGetGraphics() ) - return; - } - - if ( mbInitClipRegion ) - ImplInitClipRegion(); - if ( mbOutputClipped ) - return; - - if ( mbInitLineColor ) - ImplInitLineColor(); - - // #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, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, css::drawing::LineCap_BUTT, this)) - { - return; - } - } - - const Point aStartPt(ImplLogicToDevicePixel(rStartPt)); - const Point aEndPt(ImplLogicToDevicePixel(rEndPt)); - - mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this ); - - if( mpAlphaVDev ) - mpAlphaVDev->DrawLine( rStartPt, rEndPt ); -} - -void OutputDevice::ImplPaintLineGeometryWithEvtlExpand( - const LineInfo& rInfo, - basegfx::B2DPolyPolygon aLinePolyPolygon) -{ - const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) - && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) - && ROP_OVERPAINT == GetRasterOp() - && IsLineColor()); - basegfx::B2DPolyPolygon aFillPolyPolygon; - const bool bDashUsed(LINE_DASH == rInfo.GetStyle()); - const bool bLineWidthUsed(rInfo.GetWidth() > 1); - - if(bDashUsed && aLinePolyPolygon.count()) - { - ::std::vector< double > fDotDashArray; - const double fDashLen(rInfo.GetDashLen()); - const double fDotLen(rInfo.GetDotLen()); - const double fDistance(rInfo.GetDistance()); - - for(sal_uInt16 a(0); a < rInfo.GetDashCount(); a++) - { - fDotDashArray.push_back(fDashLen); - fDotDashArray.push_back(fDistance); - } - - for(sal_uInt16 b(0); b < rInfo.GetDotCount(); b++) - { - fDotDashArray.push_back(fDotLen); - fDotDashArray.push_back(fDistance); - } - - const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0)); - - if(fAccumulated > 0.0) - { - basegfx::B2DPolyPolygon aResult; - - for(sal_uInt32 c(0); c < aLinePolyPolygon.count(); c++) - { - basegfx::B2DPolyPolygon aLineTraget; - basegfx::tools::applyLineDashing( - aLinePolyPolygon.getB2DPolygon(c), - fDotDashArray, - &aLineTraget); - aResult.append(aLineTraget); - } - - aLinePolyPolygon = aResult; - } - } - - if(bLineWidthUsed && aLinePolyPolygon.count()) - { - const double fHalfLineWidth((rInfo.GetWidth() * 0.5) + 0.5); - - if(aLinePolyPolygon.areControlPointsUsed()) - { - // #i110768# When area geometry has to be created, do not - // use the fallback bezier decomposition inside createAreaGeometry, - // but one that is at least as good as ImplSubdivideBezier was. - // There, Polygon::AdaptiveSubdivide was used with default parameter - // 1.0 as quality index. - aLinePolyPolygon = basegfx::tools::adaptiveSubdivideByDistance(aLinePolyPolygon, 1.0); - } - - for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++) - { - aFillPolyPolygon.append(basegfx::tools::createAreaGeometry( - aLinePolyPolygon.getB2DPolygon(a), - fHalfLineWidth, - rInfo.GetLineJoin(), - rInfo.GetLineCap())); - } - - aLinePolyPolygon.clear(); - } - - GDIMetaFile* pOldMetaFile = mpMetaFile; - mpMetaFile = NULL; - - if(aLinePolyPolygon.count()) - { - for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++) - { - const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a)); - bool bDone(false); - - if(bTryAA) - { - bDone = mpGraphics->DrawPolyLine( aCandidate, 0.0, basegfx::B2DVector(1.0,1.0), basegfx::B2DLINEJOIN_NONE, css::drawing::LineCap_BUTT, this); - } - - if(!bDone) - { - const Polygon aPolygon(aCandidate); - mpGraphics->DrawPolyLine(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this); - } - } - } - - if(aFillPolyPolygon.count()) - { - const Color aOldLineColor( maLineColor ); - const Color aOldFillColor( maFillColor ); - - SetLineColor(); - ImplInitLineColor(); - SetFillColor( aOldLineColor ); - ImplInitFillColor(); - - bool bDone(false); - - if(bTryAA) - { - bDone = mpGraphics->DrawPolyPolygon(aFillPolyPolygon, 0.0, this); - } - - if(!bDone) - { - for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++) - { - Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a)); - - // need to subdivide, mpGraphics->DrawPolygon ignores curves - aPolygon.AdaptiveSubdivide(aPolygon); - mpGraphics->DrawPolygon(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this); - } - } - - SetFillColor( aOldFillColor ); - SetLineColor( aOldLineColor ); - } - - mpMetaFile = pOldMetaFile; -} - -void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt, - const LineInfo& rLineInfo ) -{ - - if ( rLineInfo.IsDefault() ) - { - DrawLine( rStartPt, rEndPt ); - return; - } - - if ( mpMetaFile ) - mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt, rLineInfo ) ); - - if ( !IsDeviceOutputNecessary() || !mbLineColor || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() ) - return; - - if( !mpGraphics && !ImplGetGraphics() ) - return; - - if ( mbInitClipRegion ) - ImplInitClipRegion(); - - if ( mbOutputClipped ) - return; - - const Point aStartPt( ImplLogicToDevicePixel( rStartPt ) ); - const Point aEndPt( ImplLogicToDevicePixel( rEndPt ) ); - const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) ); - const bool bDashUsed(LINE_DASH == aInfo.GetStyle()); - const bool bLineWidthUsed(aInfo.GetWidth() > 1); - - if ( mbInitLineColor ) - ImplInitLineColor(); - - if(bDashUsed || bLineWidthUsed) - { - basegfx::B2DPolygon aLinePolygon; - aLinePolygon.append(basegfx::B2DPoint(aStartPt.X(), aStartPt.Y())); - aLinePolygon.append(basegfx::B2DPoint(aEndPt.X(), aEndPt.Y())); - - ImplPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aLinePolygon)); - } - else - { - mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this ); - } - - if( mpAlphaVDev ) - mpAlphaVDev->DrawLine( rStartPt, rEndPt, rLineInfo ); -} - void OutputDevice::DrawRect( const Rectangle& rRect ) { @@ -1293,357 +1047,6 @@ void OutputDevice::DrawRect( const Rectangle& rRect ) mpAlphaVDev->DrawRect( rRect ); } -void OutputDevice::DrawPolyLine( const Polygon& rPoly ) -{ - - if( mpMetaFile ) - mpMetaFile->AddAction( new MetaPolyLineAction( rPoly ) ); - - sal_uInt16 nPoints = rPoly.GetSize(); - - if ( !IsDeviceOutputNecessary() || !mbLineColor || (nPoints < 2) || ImplIsRecordLayout() ) - return; - - // we need a graphics - if ( !mpGraphics ) - if ( !ImplGetGraphics() ) - return; - - if ( mbInitClipRegion ) - ImplInitClipRegion(); - if ( mbOutputClipped ) - return; - - if ( mbInitLineColor ) - ImplInitLineColor(); - - const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) - && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) - && ROP_OVERPAINT == GetRasterOp() - && IsLineColor()); - - // use b2dpolygon drawing if possible - if(bTryAA && ImplTryDrawPolyLineDirect(rPoly.getB2DPolygon())) - { - basegfx::B2DPolygon aB2DPolyLine(rPoly.getB2DPolygon()); - const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); - const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); - - // transform the polygon - aB2DPolyLine.transform( aTransform ); - - if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) - { - aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine); - } - - if(mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, css::drawing::LineCap_BUTT, this)) - { - return; - } - } - - Polygon aPoly = ImplLogicToDevicePixel( rPoly ); - const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry(); - - // #100127# Forward beziers to sal, if any - if( aPoly.HasFlags() ) - { - const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry(); - if( !mpGraphics->DrawPolyLineBezier( nPoints, pPtAry, pFlgAry, this ) ) - { - aPoly = ImplSubdivideBezier(aPoly); - pPtAry = (const SalPoint*)aPoly.GetConstPointAry(); - mpGraphics->DrawPolyLine( aPoly.GetSize(), pPtAry, this ); - } - } - else - { - mpGraphics->DrawPolyLine( nPoints, pPtAry, this ); - } - - if( mpAlphaVDev ) - mpAlphaVDev->DrawPolyLine( rPoly ); -} - -void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo ) -{ - - if ( rLineInfo.IsDefault() ) - { - DrawPolyLine( rPoly ); - return; - } - - // #i101491# - // Try direct Fallback to B2D-Version of DrawPolyLine - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) - && LINE_SOLID == rLineInfo.GetStyle()) - { - DrawPolyLine( rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), rLineInfo.GetLineJoin(), rLineInfo.GetLineCap()); - return; - } - - if ( mpMetaFile ) - mpMetaFile->AddAction( new MetaPolyLineAction( rPoly, rLineInfo ) ); - - ImplDrawPolyLineWithLineInfo(rPoly, rLineInfo); -} - -void OutputDevice::ImplDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo) -{ - sal_uInt16 nPoints(rPoly.GetSize()); - - if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() ) - return; - - Polygon aPoly = ImplLogicToDevicePixel( rPoly ); - - // #100127# LineInfo is not curve-safe, subdivide always - - // What shall this mean? It's wrong to subdivide here when the - // polygon is a fat line. In that case, the painted geometry - // WILL be much different. - // I also have no idea how this could be related to the given ID - // which reads 'consolidate boost versions' in the task description. - // Removing. - - //if( aPoly.HasFlags() ) - //{ - // aPoly = ImplSubdivideBezier( aPoly ); - // nPoints = aPoly.GetSize(); - //} - - // we need a graphics - if ( !mpGraphics && !ImplGetGraphics() ) - return; - - if ( mbInitClipRegion ) - ImplInitClipRegion(); - - if ( mbOutputClipped ) - return; - - if ( mbInitLineColor ) - ImplInitLineColor(); - - const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) ); - const bool bDashUsed(LINE_DASH == aInfo.GetStyle()); - const bool bLineWidthUsed(aInfo.GetWidth() > 1); - - if(bDashUsed || bLineWidthUsed) - { - ImplPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aPoly.getB2DPolygon())); - } - else - { - // #100127# the subdivision HAS to be done here since only a pointer - // to an array of points is given to the DrawPolyLine method, there is - // NO way to find out there that it's a curve. - if( aPoly.HasFlags() ) - { - aPoly = ImplSubdivideBezier( aPoly ); - nPoints = aPoly.GetSize(); - } - - mpGraphics->DrawPolyLine(nPoints, (const SalPoint*)aPoly.GetConstPointAry(), this); - } - - if( mpAlphaVDev ) - mpAlphaVDev->DrawPolyLine( rPoly, rLineInfo ); -} - -bool OutputDevice::ImplTryDrawPolyLineDirect( - const basegfx::B2DPolygon& rB2DPolygon, - double fLineWidth, - double fTransparency, - basegfx::B2DLineJoin eLineJoin, - css::drawing::LineCap eLineCap) -{ - 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 ); - } - - // transform the polygon - basegfx::B2DPolygon aB2DPolygon(rB2DPolygon); - aB2DPolygon.transform(aTransform); - - if((mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) - && aB2DPolygon.count() < 1000) - { - // #i98289#, #i101491# - // better to remove doubles on device coordinates. Also assume from a given amount - // of points that the single edges are not long enough to smooth - aB2DPolygon.removeDoublePoints(); - aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon); - } - - // draw the polyline - return mpGraphics->DrawPolyLine( - aB2DPolygon, - fTransparency, - aB2DLineWidth, - eLineJoin, - eLineCap, - this); -} - -bool OutputDevice::TryDrawPolyLineDirect( - const basegfx::B2DPolygon& rB2DPolygon, - double fLineWidth, - double fTransparency, - basegfx::B2DLineJoin eLineJoin, - css::drawing::LineCap eLineCap) -{ - // AW: Do NOT paint empty PolyPolygons - if(!rB2DPolygon.count()) - return true; - - // we need a graphics - if( !mpGraphics ) - if( !ImplGetGraphics() ) - return false; - - if( mbInitClipRegion ) - ImplInitClipRegion(); - - if( mbOutputClipped ) - return true; - - if( mbInitLineColor ) - ImplInitLineColor(); - - const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) - && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) - && ROP_OVERPAINT == GetRasterOp() - && IsLineColor()); - - if(bTryAA) - { - if(ImplTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, fTransparency, eLineJoin, eLineCap)) - { - // worked, add metafile action (if recorded) and return true - if( mpMetaFile ) - { - LineInfo aLineInfo; - if( fLineWidth != 0.0 ) - aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) ); - const Polygon aToolsPolygon( rB2DPolygon ); - mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) ); - } - - return true; - } - } - - return false; -} - -void OutputDevice::DrawPolyLine( - const basegfx::B2DPolygon& rB2DPolygon, - double fLineWidth, - basegfx::B2DLineJoin eLineJoin, - css::drawing::LineCap eLineCap) -{ - - if( mpMetaFile ) - { - LineInfo aLineInfo; - if( fLineWidth != 0.0 ) - aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) ); - const Polygon aToolsPolygon( rB2DPolygon ); - mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) ); - } - - // Do not paint empty PolyPolygons - if(!rB2DPolygon.count() || !IsDeviceOutputNecessary()) - return; - - // we need a graphics - if( !mpGraphics ) - if( !ImplGetGraphics() ) - return; - - if( mbInitClipRegion ) - ImplInitClipRegion(); - if( mbOutputClipped ) - return; - - if( mbInitLineColor ) - ImplInitLineColor(); - - const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) - && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) - && ROP_OVERPAINT == GetRasterOp() - && IsLineColor()); - - // use b2dpolygon drawing if possible - if(bTryAA && ImplTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, 0.0, eLineJoin, eLineCap)) - { - return; - } - - // #i101491# - // no output yet; fallback to geometry decomposition and use filled polygon paint - // when line is fat and not too complex. ImplDrawPolyPolygonWithB2DPolyPolygon - // will do internal needed AA checks etc. - if(fLineWidth >= 2.5 - && rB2DPolygon.count() - && rB2DPolygon.count() <= 1000) - { - const double fHalfLineWidth((fLineWidth * 0.5) + 0.5); - const basegfx::B2DPolyPolygon aAreaPolyPolygon( - basegfx::tools::createAreaGeometry( - rB2DPolygon, - fHalfLineWidth, - eLineJoin, - eLineCap)); - const Color aOldLineColor(maLineColor); - const Color aOldFillColor(maFillColor); - - SetLineColor(); - ImplInitLineColor(); - SetFillColor(aOldLineColor); - ImplInitFillColor(); - - // draw usig a loop; else the topology will paint a PolyPolygon - for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++) - { - ImplDrawPolyPolygonWithB2DPolyPolygon( - basegfx::B2DPolyPolygon(aAreaPolyPolygon.getB2DPolygon(a))); - } - - SetLineColor(aOldLineColor); - ImplInitLineColor(); - SetFillColor(aOldFillColor); - ImplInitFillColor(); - - if(bTryAA) - { - // when AA it is necessary to also paint the filled polygon's outline - // to avoid optical gaps - for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++) - { - ImplTryDrawPolyLineDirect(aAreaPolyPolygon.getB2DPolygon(a)); - } - } - } - else - { - // fallback to old polygon drawing if needed - const Polygon aToolsPolygon( rB2DPolygon ); - LineInfo aLineInfo; - if( fLineWidth != 0.0 ) - aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) ); - ImplDrawPolyLineWithLineInfo( aToolsPolygon, aLineInfo ); - } -} - sal_uInt32 OutputDevice::GetGCStackDepth() const { const ImplObjStack* pData = mpObjStack; |