diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2010-01-04 18:51:18 +0100 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2010-01-04 18:51:18 +0100 |
commit | 7ac363afbb51a37e287762b1fc2a08d98557e991 (patch) | |
tree | f0aacb7e7858b81a0637a19bda46fffb22b21953 /vcl | |
parent | 0c5348ff2c5cede4607555fdab45642db10b07ba (diff) | |
parent | 9afae518759e5d6ecb32dacd76a1aa746ae2cef6 (diff) |
CWS-TOOLING: integrate CWS aw078
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/aqua/source/gdi/salgdi.cxx | 5 | ||||
-rw-r--r-- | vcl/inc/vcl/cvtsvm.hxx | 4 | ||||
-rw-r--r-- | vcl/inc/vcl/lineinfo.hxx | 37 | ||||
-rw-r--r-- | vcl/inc/vcl/outdev.hxx | 10 | ||||
-rw-r--r-- | vcl/os2/source/gdi/salgdi3.cxx | 6 | ||||
-rw-r--r-- | vcl/source/gdi/cvtsvm.cxx | 354 | ||||
-rw-r--r-- | vcl/source/gdi/implncvt.cxx | 577 | ||||
-rw-r--r-- | vcl/source/gdi/implncvt.hxx | 78 | ||||
-rw-r--r-- | vcl/source/gdi/lineinfo.cxx | 109 | ||||
-rwxr-xr-x | vcl/source/gdi/makefile.mk | 1 | ||||
-rw-r--r-- | vcl/source/gdi/metaact.cxx | 77 | ||||
-rw-r--r-- | vcl/source/gdi/outdev.cxx | 284 | ||||
-rw-r--r-- | vcl/source/gdi/outdev6.cxx | 14 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 4 | ||||
-rw-r--r-- | vcl/source/gdi/region.cxx | 9 | ||||
-rw-r--r-- | vcl/source/gdi/salgdilayout.cxx | 1 | ||||
-rwxr-xr-x | vcl/source/gdi/sallayout.cxx | 7 | ||||
-rw-r--r-- | vcl/source/glyphs/gcach_ftyp.cxx | 5 | ||||
-rw-r--r-- | vcl/unx/source/gdi/salgdi.cxx | 12 | ||||
-rw-r--r-- | vcl/win/source/gdi/salgdi3.cxx | 6 | ||||
-rw-r--r-- | vcl/win/source/gdi/salgdi_gdiplus.cxx | 74 |
21 files changed, 786 insertions, 888 deletions
diff --git a/vcl/aqua/source/gdi/salgdi.cxx b/vcl/aqua/source/gdi/salgdi.cxx index 1c9bdda3fbdb..263a5b6e6803 100644 --- a/vcl/aqua/source/gdi/salgdi.cxx +++ b/vcl/aqua/source/gdi/salgdi.cxx @@ -54,6 +54,7 @@ #include "basegfx/polygon/b2dpolygon.hxx" #include "basegfx/polygon/b2dpolygontools.hxx" #include "basegfx/matrix/b2dhommatrix.hxx" +#include <basegfx/matrix/b2dhommatrixtools.hxx> using namespace vcl; @@ -1768,9 +1769,7 @@ BOOL AquaSalGraphics::GetGlyphOutline( long nGlyphId, basegfx::B2DPolyPolygon& r GgoClosePathProc( &aGgoData ); if( mfFontScale != 1.0 ) { - basegfx::B2DHomMatrix aScale; - aScale.scale( +mfFontScale, +mfFontScale ); - rPolyPoly.transform( aScale ); + rPolyPoly.transform(basegfx::tools::createScaleB2DHomMatrix(+mfFontScale, +mfFontScale)); } return true; } diff --git a/vcl/inc/vcl/cvtsvm.hxx b/vcl/inc/vcl/cvtsvm.hxx index 8a17015d99cf..c6f4f2c9a126 100644 --- a/vcl/inc/vcl/cvtsvm.hxx +++ b/vcl/inc/vcl/cvtsvm.hxx @@ -85,6 +85,10 @@ #define GDI_COMMENT_COMMENT 1031 #define GDI_UNICODE_COMMENT 1032 +#define GDI_LINEJOIN_ACTION 1033 +#define GDI_EXTENDEDPOLYGON_ACTION 1034 +#define GDI_LINEDASHDOT_ACTION 1035 + // ---------------- // - SVMConverter - // ---------------- diff --git a/vcl/inc/vcl/lineinfo.hxx b/vcl/inc/vcl/lineinfo.hxx index 60fdc3a3a0b0..33758046c41e 100644 --- a/vcl/inc/vcl/lineinfo.hxx +++ b/vcl/inc/vcl/lineinfo.hxx @@ -32,26 +32,29 @@ #define _SV_LINEINFO_HXX #include <vcl/dllapi.h> - #include <tools/gen.hxx> #include <vcl/vclenum.hxx> +#include <basegfx/vector/b2enums.hxx> // ---------------- // - ImplLineInfo - // ---------------- class SvStream; +namespace basegfx { class B2DPolyPolygon; } struct ImplLineInfo { - ULONG mnRefCount; - LineStyle meStyle; - long mnWidth; - USHORT mnDashCount; - long mnDashLen; - USHORT mnDotCount; - long mnDotLen; - long mnDistance; + ULONG mnRefCount; + LineStyle meStyle; + long mnWidth; + USHORT mnDashCount; + long mnDashLen; + USHORT mnDotCount; + long mnDotLen; + long mnDistance; + + basegfx::B2DLineJoin meLineJoin; ImplLineInfo(); ImplLineInfo( const ImplLineInfo& rImplLineInfo ); @@ -107,10 +110,26 @@ public: void SetDistance( long nDistance ); long GetDistance() const { return mpImplLineInfo->mnDistance; } + void SetLineJoin(basegfx::B2DLineJoin eLineJoin); + basegfx::B2DLineJoin GetLineJoin() const { return mpImplLineInfo->meLineJoin; } + BOOL IsDefault() const { return( !mpImplLineInfo->mnWidth && ( LINE_SOLID == mpImplLineInfo->meStyle ) ); } friend VCL_DLLPUBLIC SvStream& operator>>( SvStream& rIStm, LineInfo& rLineInfo ); friend VCL_DLLPUBLIC SvStream& operator<<( SvStream& rOStm, const LineInfo& rLineInfo ); + + // helper to check if line width or DashDot is used + bool isDashDotOrFatLineUsed() const; + + // helper to get decomposed polygon data with the LineInfo applied. The source + // hairline polygon is given in io_rLinePolyPolygon. Both given polygons may + // contain results; e.g. when no fat line but DasDot is defined, the resut will + // be in io_rLinePolyPolygon while o_rFillPolyPolygon will be empty. When fat line + // is defined, it will be vice-versa. If none is defined, io_rLinePolyPolygon will + // not be changed (but o_rFillPolyPolygon will be freed) + void applyToB2DPolyPolygon( + basegfx::B2DPolyPolygon& io_rLinePolyPolygon, + basegfx::B2DPolyPolygon& o_rFillPolyPolygon) const; }; #endif // _SV_LINEINFO_HXX diff --git a/vcl/inc/vcl/outdev.hxx b/vcl/inc/vcl/outdev.hxx index 1e1f784f0f49..4a5b92444c21 100644 --- a/vcl/inc/vcl/outdev.hxx +++ b/vcl/inc/vcl/outdev.hxx @@ -562,6 +562,9 @@ public: // Helper who tries to use SalGDI's DrawPolyLine direct and returns it's bool. Contains no AA check. SAL_DLLPRIVATE bool ImpTryDrawPolyLineDirect(const basegfx::B2DPolygon& rB2DPolygon, double fLineWidth, basegfx::B2DLineJoin eLineJoin); + // Helper for line geometry paint with support for graphic expansion (pattern and fat_to_area) + void impPaintLineGeometryWithEvtlExpand(const LineInfo& rInfo, basegfx::B2DPolyPolygon aLinePolyPolygon); + protected: OutputDevice(); @@ -1088,7 +1091,12 @@ public: */ BOOL HasAlpha(); - void DrawEPS( const Point& rPt, const Size& rSz, + /** Added return value to see if EPS could be painted directly. + Theoreticaly, handing over a matrix would be needed to handle + painting rotated EPS files (e.g. contained mn Metafiles). This + would then need to be supported for Mac and PS printers, but + that's too much for now, wrote #i107046# for this */ + bool DrawEPS( const Point& rPt, const Size& rSz, const GfxLink& rGfxLink, GDIMetaFile* pSubst = NULL ); /// request XCanvas render interface for this OutputDevice diff --git a/vcl/os2/source/gdi/salgdi3.cxx b/vcl/os2/source/gdi/salgdi3.cxx index 573fa7336fb0..b25feee266e4 100644 --- a/vcl/os2/source/gdi/salgdi3.cxx +++ b/vcl/os2/source/gdi/salgdi3.cxx @@ -1361,10 +1361,8 @@ BOOL Os2SalGraphics::GetGlyphOutline( long nIndex, ::basegfx::B2DPolyPolygon& rB // rescaling needed for the PolyPolygon conversion if( rB2DPolyPoly.count() ) { - ::basegfx::B2DHomMatrix aMatrix; - aMatrix.scale( 1.0/256, 1.0/256 ); - aMatrix.scale( mfFontScale, mfFontScale ); - rB2DPolyPoly.transform( aMatrix ); + const double fFactor((1.0/256) * mfFontScale); + rB2DPolyPoly.transform(basegfx::tools::createScaleB2DHomMatrix(fFactor, fFactor)); } return bRet; diff --git a/vcl/source/gdi/cvtsvm.cxx b/vcl/source/gdi/cvtsvm.cxx index 4ecb89ec5a8e..8c4b6f1a2cb2 100644 --- a/vcl/source/gdi/cvtsvm.cxx +++ b/vcl/source/gdi/cvtsvm.cxx @@ -88,23 +88,6 @@ void ImplReadPoly( SvStream& rIStm, Polygon& rPoly ) // ------------------------------------------------------------------------ -void ImplWritePoly( SvStream& rOStm, const Polygon& rPoly ) -{ - // #i102224# Here the evtl. curved nature of Polygon was - // ignored (for all those Years). Adapted to at least write - // a polygon representing the curve as good as possible - Polygon aSimplePoly; - rPoly.AdaptiveSubdivide(aSimplePoly); - INT32 nSize = aSimplePoly.GetSize(); - - rOStm << nSize; - - for( INT32 i = 0; i < nSize; i++ ) - rOStm << aSimplePoly[ (USHORT) i ]; -} - -// ------------------------------------------------------------------------ - void ImplReadPolyPoly( SvStream& rIStm, PolyPolygon& rPolyPoly ) { Polygon aPoly; @@ -139,10 +122,9 @@ void ImplWritePolyPolyAction( SvStream& rOStm, const PolyPolygon& rPolyPoly ) // #i102224# Here the evtl. curved nature of Polygon was // ignored (for all those Years). Adapted to at least write // a polygon representing the curve as good as possible - const Polygon& rPoly = rPolyPoly[ n ]; - Polygon aSimplePoly; - rPoly.AdaptiveSubdivide(aSimplePoly); - const USHORT nSize = aSimplePoly.GetSize(); + Polygon aSimplePoly; + rPolyPoly[n].AdaptiveSubdivide(aSimplePoly); + const USHORT nSize(aSimplePoly.GetSize()); rOStm << (INT32) nSize; @@ -388,6 +370,128 @@ void ImplSkipActions( SvStream& rIStm, ULONG nSkipCount ) } } +// ------------------------------------------------------------------------ + +bool ImplWriteExtendedPolyPolygonAction(SvStream& rOStm, const PolyPolygon& rPolyPolygon, bool bOnlyWhenCurve) +{ + const sal_uInt16 nPolygonCount(rPolyPolygon.Count()); + + if(nPolygonCount) + { + sal_uInt32 nAllPolygonCount(0); + sal_uInt32 nAllPointCount(0); + sal_uInt32 nAllFlagCount(0); + sal_uInt16 a(0); + + for(a = 0; a < nPolygonCount; a++) + { + const Polygon& rCandidate = rPolyPolygon.GetObject(a); + const sal_uInt16 nPointCount(rCandidate.GetSize()); + + if(nPointCount) + { + nAllPolygonCount++; + nAllPointCount += nPointCount; + + if(rCandidate.HasFlags()) + { + nAllFlagCount += nPointCount; + } + } + } + + if((bOnlyWhenCurve && nAllFlagCount) || (!bOnlyWhenCurve && nAllPointCount)) + { + rOStm << (INT16) GDI_EXTENDEDPOLYGON_ACTION; + + const sal_Int32 nActionSize( + 4 + // Action size + 2 + // PolygonCount + (nAllPolygonCount * 2) + // Points per polygon + (nAllPointCount << 3) + // Points themselves + nAllPolygonCount + // Bool if (when poly has points) it has flags, too + nAllFlagCount); // Flags themselves + + rOStm << nActionSize; + rOStm << (sal_uInt16)nAllPolygonCount; + + for(a = 0; a < nPolygonCount; a++) + { + const Polygon& rCandidate = rPolyPolygon.GetObject(a); + const sal_uInt16 nPointCount(rCandidate.GetSize()); + + if(nPointCount) + { + rOStm << nPointCount; + + for(sal_uInt16 b(0); b < nPointCount; b++) + { + rOStm << rCandidate[b]; + } + + if(rCandidate.HasFlags()) + { + rOStm << (BYTE)true; + + for(sal_uInt16 c(0); c < nPointCount; c++) + { + rOStm << (BYTE)rCandidate.GetFlags(c); + } + } + else + { + rOStm << (BYTE)false; + } + } + } + + return true; + } + } + + return false; +} + +// ------------------------------------------------------------------------ + +void ImplReadExtendedPolyPolygonAction(SvStream& rIStm, PolyPolygon& rPolyPoly) +{ + rPolyPoly.Clear(); + sal_uInt16 nPolygonCount(0); + rIStm >> nPolygonCount; + + for(sal_uInt16 a(0); a < nPolygonCount; a++) + { + sal_uInt16 nPointCount(0); + rIStm >> nPointCount; + Polygon aCandidate(nPointCount); + + if(nPointCount) + { + for(sal_uInt16 b(0); b < nPointCount; b++) + { + rIStm >> aCandidate[b]; + } + + BYTE bHasFlags(false); + rIStm >> bHasFlags; + + if(bHasFlags) + { + BYTE aPolyFlags(0); + + for(sal_uInt16 c(0); c < nPointCount; c++) + { + rIStm >> aPolyFlags; + aCandidate.SetFlags(c, (PolyFlags)aPolyFlags); + } + } + } + + rPolyPoly.Insert(aCandidate); + } +} + // ---------------- // - SVMConverter - // ---------------- @@ -460,6 +564,7 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf ) rMtf.SetPrefSize( aPrefSz ); rMtf.SetPrefMapMode( aMapMode ); + sal_uInt32 nLastPolygonAction(0); for( INT32 i = 0L; i < nActions; i++ ) { @@ -493,6 +598,99 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf ) } break; + case (GDI_LINEJOIN_ACTION) : + { + INT16 nLineJoin(0); + rIStm >> nLineJoin; + aLineInfo.SetLineJoin((basegfx::B2DLineJoin)nLineJoin); + } + break; + + case (GDI_LINEDASHDOT_ACTION) : + { + INT16 a(0); + INT32 b(0); + + rIStm >> a; aLineInfo.SetDashCount(a); + rIStm >> b; aLineInfo.SetDashLen(b); + rIStm >> a; aLineInfo.SetDotCount(a); + rIStm >> b; aLineInfo.SetDotLen(b); + rIStm >> b; aLineInfo.SetDistance(b); + + if(((aLineInfo.GetDashCount() && aLineInfo.GetDashLen()) + || (aLineInfo.GetDotCount() && aLineInfo.GetDotLen())) + && aLineInfo.GetDistance()) + { + aLineInfo.SetStyle(LINE_DASH); + } + } + break; + + case (GDI_EXTENDEDPOLYGON_ACTION) : + { + // read the PolyPolygon in every case + PolyPolygon aInputPolyPolygon; + ImplReadExtendedPolyPolygonAction(rIStm, aInputPolyPolygon); + + // now check if it can be set somewhere + if(nLastPolygonAction < rMtf.GetActionCount()) + { + MetaPolyLineAction* pPolyLineAction = dynamic_cast< MetaPolyLineAction* >(rMtf.GetAction(nLastPolygonAction)); + + if(pPolyLineAction) + { + // replace MetaPolyLineAction when we have a single polygon. Do not rely on the + // same point count; the originally written GDI_POLYLINE_ACTION may have been + // Subdivided for better quality for older usages + if(1 == aInputPolyPolygon.Count()) + { + rMtf.ReplaceAction( + new MetaPolyLineAction( + aInputPolyPolygon.GetObject(0), + pPolyLineAction->GetLineInfo()), + nLastPolygonAction); + pPolyLineAction->Delete(); + } + } + else + { + MetaPolyPolygonAction* pPolyPolygonAction = dynamic_cast< MetaPolyPolygonAction* >(rMtf.GetAction(nLastPolygonAction)); + + if(pPolyPolygonAction) + { + // replace MetaPolyPolygonAction when we have a curved polygon. Do rely on the + // same sub-polygon count + if(pPolyPolygonAction->GetPolyPolygon().Count() == aInputPolyPolygon.Count()) + { + rMtf.ReplaceAction( + new MetaPolyPolygonAction( + aInputPolyPolygon), + nLastPolygonAction); + pPolyPolygonAction->Delete(); + } + } + else + { + MetaPolygonAction* pPolygonAction = dynamic_cast< MetaPolygonAction* >(rMtf.GetAction(nLastPolygonAction)); + + if(pPolygonAction) + { + // replace MetaPolygonAction + if(1 == aInputPolyPolygon.Count()) + { + rMtf.ReplaceAction( + new MetaPolygonAction( + aInputPolyPolygon.GetObject(0)), + nLastPolygonAction); + pPolygonAction->Delete(); + } + } + } + } + } + } + break; + case( GDI_RECT_ACTION ): { ImplReadRect( rIStm, aRect ); @@ -583,6 +781,7 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf ) case( GDI_POLYLINE_ACTION ): { ImplReadPoly( rIStm, aActionPoly ); + nLastPolygonAction = rMtf.GetActionCount(); if( bFatLine ) rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) ); @@ -604,7 +803,10 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf ) rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) ); } else + { + nLastPolygonAction = rMtf.GetActionCount(); rMtf.AddAction( new MetaPolygonAction( aActionPoly ) ); + } } break; @@ -625,7 +827,10 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf ) rMtf.AddAction( new MetaPolyLineAction( aPolyPoly[ nPoly ], aLineInfo ) ); } else + { + nLastPolygonAction = rMtf.GetActionCount(); rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) ); + } } break; @@ -1257,12 +1462,32 @@ ULONG SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf, { MetaLineAction* pAct = (MetaLineAction*) pAction; const LineInfo& rInfo = pAct->GetLineInfo(); - const BOOL bFatLine = ( !rInfo.IsDefault() && ( LINE_NONE != rInfo.GetStyle() ) ); + const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle())); + const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin()); + const bool bLineDashDot(LINE_DASH == rInfo.GetStyle()); if( bFatLine ) { ImplWritePushAction( rOStm ); ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() ); + + if(bLineJoin) + { + rOStm << (INT16) GDI_LINEJOIN_ACTION; + rOStm << (INT32) 6; + rOStm << (INT16) rInfo.GetLineJoin(); + } + + if(bLineDashDot) + { + rOStm << (INT16) GDI_LINEDASHDOT_ACTION; + rOStm << (INT32) 4 + 16; + rOStm << (INT16)rInfo.GetDashCount(); + rOStm << (INT32)rInfo.GetDashLen(); + rOStm << (INT16)rInfo.GetDotCount(); + rOStm << (INT32)rInfo.GetDotLen(); + rOStm << (INT32)rInfo.GetDistance(); + } } rOStm << (INT16) GDI_LINE_ACTION; @@ -1275,6 +1500,16 @@ ULONG SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf, { ImplWritePopAction( rOStm ); nCount += 3; + + if(bLineJoin) + { + nCount += 1; + } + + if(bLineDashDot) + { + nCount += 1; + } } } break; @@ -1355,30 +1590,47 @@ ULONG SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf, for( USHORT n = 0; n < nPoints; n++ ) rOStm << aChordPoly[ n ]; - nCount++; } break; case( META_POLYLINE_ACTION ): { + // #i102224# MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction; - const Polygon& rPoly = pAct->GetPolygon(); - // #i102224# Here the evtl. curved nature of Polygon was // ignored (for all those Years). Adapted to at least write // a polygon representing the curve as good as possible - Polygon aSimplePoly; - rPoly.AdaptiveSubdivide(aSimplePoly); - - const LineInfo& rInfo = pAct->GetLineInfo(); - const USHORT nPoints = aSimplePoly.GetSize(); - const BOOL bFatLine = ( !rInfo.IsDefault() && ( LINE_NONE != rInfo.GetStyle() ) ); + Polygon aSimplePoly; + pAct->GetPolygon().AdaptiveSubdivide(aSimplePoly); + const LineInfo& rInfo = pAct->GetLineInfo(); + const USHORT nPoints(aSimplePoly.GetSize()); + const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle())); + const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin()); + const bool bLineDashDot(LINE_DASH == rInfo.GetStyle()); if( bFatLine ) { ImplWritePushAction( rOStm ); ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() ); + + if(bLineJoin) + { + rOStm << (INT16) GDI_LINEJOIN_ACTION; + rOStm << (INT32) 6; + rOStm << (INT16) rInfo.GetLineJoin(); + } + } + + if(bLineDashDot) + { + rOStm << (INT16) GDI_LINEDASHDOT_ACTION; + rOStm << (INT32) 4 + 16; + rOStm << (INT16)rInfo.GetDashCount(); + rOStm << (INT32)rInfo.GetDashLen(); + rOStm << (INT16)rInfo.GetDotCount(); + rOStm << (INT32)rInfo.GetDotLen(); + rOStm << (INT32)rInfo.GetDistance(); } rOStm << (INT16) GDI_POLYLINE_ACTION; @@ -1386,30 +1638,45 @@ ULONG SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf, rOStm << (INT32) nPoints; for( USHORT n = 0; n < nPoints; n++ ) + { rOStm << aSimplePoly[ n ]; + } nCount++; + const PolyPolygon aPolyPolygon(pAct->GetPolygon()); + if(ImplWriteExtendedPolyPolygonAction(rOStm, aPolyPolygon, true)) + { + nCount++; + } + if( bFatLine ) { ImplWritePopAction( rOStm ); nCount += 3; + + if(bLineJoin) + { + nCount += 1; + } + } + + if(bLineDashDot) + { + nCount += 1; } } break; case( META_POLYGON_ACTION ): { - MetaPolygonAction* pAct = (MetaPolygonAction*) pAction; - const Polygon& rPoly = pAct->GetPolygon(); - + MetaPolygonAction* pAct = (MetaPolygonAction*)pAction; // #i102224# Here the evtl. curved nature of Polygon was // ignored (for all those Years). Adapted to at least write // a polygon representing the curve as good as possible - Polygon aSimplePoly; - rPoly.AdaptiveSubdivide(aSimplePoly); - - const USHORT nPoints = aSimplePoly.GetSize(); + Polygon aSimplePoly; + pAct->GetPolygon().AdaptiveSubdivide(aSimplePoly); + const USHORT nPoints(aSimplePoly.GetSize()); rOStm << (INT16) GDI_POLYGON_ACTION; rOStm << (INT32) ( 8 + ( nPoints << 3 ) ); @@ -1419,6 +1686,12 @@ ULONG SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf, rOStm << aSimplePoly[ n ]; nCount++; + + const PolyPolygon aPolyPolygon(pAct->GetPolygon()); + if(ImplWriteExtendedPolyPolygonAction(rOStm, aPolyPolygon, true)) + { + nCount++; + } } break; @@ -1427,6 +1700,11 @@ ULONG SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf, MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction; ImplWritePolyPolyAction( rOStm, pAct->GetPolyPolygon() ); nCount++; + + if(ImplWriteExtendedPolyPolygonAction(rOStm, pAct->GetPolyPolygon(), true)) + { + nCount++; + } } break; diff --git a/vcl/source/gdi/implncvt.cxx b/vcl/source/gdi/implncvt.cxx deleted file mode 100644 index e59fde15b5be..000000000000 --- a/vcl/source/gdi/implncvt.cxx +++ /dev/null @@ -1,577 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: implncvt.cxx,v $ - * $Revision: 1.10.136.1 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_vcl.hxx" -#include <vcl/salbtype.hxx> -#ifndef _SV_IMPLNCVT_HXX -#include "implncvt.hxx" -#endif - -// ----------- -// - Defines - -// ----------- - -#define CURVE_LEFT 1 -#define CURVE_RIGHT 2 -#define CURVE_STRAIGHTON 3 - -// ----------------- -// - ImplFloatPoint -// ----------------- - -struct ImplFloatPoint -{ - double fX; - double fY; - - inline ImplFloatPoint() {} - inline ImplFloatPoint( const Point& rPoint ) { fX = rPoint.X(); fY = rPoint.Y(); } - inline ImplFloatPoint( double _fX, double _fY ) { fX = _fX; fY = _fY; } - inline ImplFloatPoint( const ImplFloatPoint& rPoint ) { fX = rPoint.fX; fY = rPoint.fY; } - inline ~ImplFloatPoint() {} - - void operator+=( const ImplFloatPoint& rPoint ) { fX += rPoint.fX; fY += rPoint.fY; } - void operator-=( const ImplFloatPoint& rPoint ) { fX -= rPoint.fX; fY -= rPoint.fY; } - void operator*=( const double& rD ) { fX *= rD; fY *= rD; } - BOOL operator==( const ImplFloatPoint& rPoint ) const { return ( ( rPoint.fX == fX ) && ( rPoint.fY == fY ) ); } - void operator=( const Point& rPoint ) { fX = rPoint.X(); fY = rPoint.Y(); } - - ImplFloatPoint GetOVec( const ImplFloatPoint& rPoint ) const; - ImplFloatPoint GetNVec( const ImplFloatPoint& rPoint ) const; -}; - -// ----------------------------------------------------------------------------- - -ImplFloatPoint ImplFloatPoint::GetOVec( const ImplFloatPoint& rPoint ) const -{ - double fxt = rPoint.fX - fX; - double fyt = rPoint.fY - fY; - double fL; - - if( fyt != 0.0 ) - { - fyt = -fxt / fyt; - fL = sqrt( 1 + fyt * fyt ); - - return ImplFloatPoint( 1.0 / fL, fyt / fL ); - } - else - return ImplFloatPoint( fyt, ( fxt > 0.0 ) ? 1.0 : -1.0 ); -}; - -// ----------------------------------------------------------------------------- - -ImplFloatPoint ImplFloatPoint::GetNVec( const ImplFloatPoint& rPoint ) const -{ - const double fxt = rPoint.fX - fX; - const double fyt = rPoint.fY - fY; - const double fL = hypot( fxt, fyt ); - - return ImplFloatPoint( fxt / fL, fyt / fL ); -}; - -// -------------------- -// - ImplLineConverter -// -------------------- - -ImplLineConverter::ImplLineConverter( const Polygon& rPolygon, const LineInfo& rLineInfo, const Point* pRefPoint ) : - mbRefPoint ( FALSE ), - mfWidthHalf ( rLineInfo.GetWidth() >> 1 ), - maLineInfo ( rLineInfo ), - mpFloat0 ( new ImplFloatPoint[ 6 ] ), - mpFloat1 ( new ImplFloatPoint[ 6 ] ), - mnLines ( 0 ), - mpFloatPoint ( NULL ) -{ - UINT16 nIndex, nPolySize = rPolygon.GetSize(); - if ( nPolySize ) - { - if( rPolygon.GetFlags( 0 ) == POLY_NORMAL ) - { - mpFloatPoint = new ImplFloatPoint[ nPolySize ]; - mpFloatPoint[ 0 ] = rPolygon[ 0 ]; - - nIndex = 0; - - while( ++nIndex < nPolySize ) // doppelte Punkte eliminieren und ein FloatPointArray anlegen - { - if( rPolygon.GetFlags( nIndex ) == POLY_NORMAL ) - { - double nxt = mpFloatPoint[ mnLines ].fX; - double nyt = mpFloatPoint[ mnLines ].fY; - - if ( ( nxt == rPolygon[ nIndex ].X() ) && ( nyt == rPolygon[ nIndex ].Y() ) ) - continue; - - mpFloatPoint[ ++mnLines ] = rPolygon[ nIndex ]; - } - else - { - DBG_ERROR( "Bezier points not supported!" ); - } - } - mbClosed = ( mpFloatPoint[ 0 ] == mpFloatPoint[ mnLines ] ) ; - - if ( ( mnLines == 1 ) && ( maLineInfo.GetStyle() == LINE_DASH ) ) - { - BOOL bX = mpFloatPoint[ 0 ].fY == mpFloatPoint[ 1 ].fY; - BOOL bY = mpFloatPoint[ 0 ].fX == mpFloatPoint[ 1 ].fX; - mbRefPoint = pRefPoint && ( bX || bY ); - if ( mbRefPoint ) - { - if ( !maLineInfo.GetDashCount() ) - { - maLineInfo.SetDashCount( maLineInfo.GetDotCount() ); - maLineInfo.SetDashLen( maLineInfo.GetDotLen() ); - maLineInfo.SetDotCount( 0 ); - } - INT32 nDistance = maLineInfo.GetDistance(); - INT32 nDashLen = maLineInfo.GetDashCount() * ( maLineInfo.GetDashLen() + nDistance ); - INT32 nDotLen = maLineInfo.GetDotCount() * ( maLineInfo.GetDotLen() + nDistance ); - if ( bX ) - { - if ( mpFloatPoint[ 1 ].fX > mpFloatPoint[ 0 ].fX ) - { - ImplFloatPoint aFloat = mpFloatPoint[ 0 ]; - mpFloatPoint[ 0 ] = mpFloatPoint[ 1 ]; - mpFloatPoint[ 1 ] = aFloat; - } - mnRefDistance = (INT32)mpFloatPoint[ mnLines ].fX - pRefPoint->X(); - } - else - { - if ( mpFloatPoint[ 1 ].fY > mpFloatPoint[ 0 ].fY ) - { - ImplFloatPoint aFloat = mpFloatPoint[ 0 ]; - mpFloatPoint[ 0 ] = mpFloatPoint[ 1 ]; - mpFloatPoint[ 1 ] = aFloat; - } - mnRefDistance = (INT32)mpFloatPoint[ mnLines ].fY - pRefPoint->Y(); - } - -// mnRefDistance = ( (INT32)mpFloatPoint[ mnLines ].fX - pRefPoint->X() ) + -// ( (INT32)mpFloatPoint[ mnLines ].fY - pRefPoint->Y() ); - - mnRefDistance = mnRefDistance % ( nDashLen + nDotLen ); - if ( mnRefDistance < 0 ) - mnRefDistance = ( nDashLen + nDotLen ) + mnRefDistance; - } - } - } - } -}; - -//------------------------------------------------------------------------ - -ImplLineConverter::~ImplLineConverter() -{ - delete[] mpFloat0; - delete[] mpFloat1; - delete[] mpFloatPoint; -}; - -//------------------------------------------------------------------------ - -const Polygon* ImplLineConverter::ImplGetFirst() -{ - mnFloat1Points = 0; - mnLinesAvailable = mnLines; - - if ( mnLines ) - { - if ( maLineInfo.GetStyle() == LINE_DASH ) - { - mnDashCount = maLineInfo.GetDashCount(); - mnDotCount = maLineInfo.GetDotCount(); - mfDashDotLenght = mnDashCount ? maLineInfo.GetDashLen() : maLineInfo.GetDotLen(); - - if ( mbRefPoint ) - { - INT32 nDistance = maLineInfo.GetDistance(); - INT32 nDashLen = maLineInfo.GetDashLen() + nDistance; - INT32 nDashesLen = maLineInfo.GetDashCount() * nDashLen; - INT32 nDotLen = maLineInfo.GetDotLen() + nDistance; - - if ( mnRefDistance >= nDashesLen ) - { - // get dotcount - if ( nDotLen ) - { - INT32 nLen = ( mnRefDistance - nDashesLen ) % nDotLen; - if ( nLen >= maLineInfo.GetDotLen() ) - { - mnDotCount -= 1 + ( mnRefDistance - nDashesLen ) / nDotLen; - if ( mnDotCount ) - mnDashCount = 0; - else - mnDotCount = maLineInfo.GetDotCount(); - mfDashDotLenght = 0.0; - mfDistanceLenght = ( maLineInfo.GetDotLen() + nDistance ) - nLen; - } - else - { - mnDashCount = 0; - mfDashDotLenght = maLineInfo.GetDotLen() - nLen; - mnDotCount -= ( mnRefDistance - nDashesLen ) / nDotLen; - } - } - } - else - { - if ( nDashLen ) - { - // get dashcount - INT32 nLen = mnRefDistance % nDashLen; - if ( nLen >= maLineInfo.GetDashLen() ) - { - mfDashDotLenght = 0.0; - mfDistanceLenght = ( maLineInfo.GetDashLen() + nDistance ) - nLen; - mnDashCount -= 1 + ( mnRefDistance / nDashLen ); - } - else - { - mfDashDotLenght = maLineInfo.GetDashLen() - nLen; - mnDashCount -= ( mnRefDistance / nDashLen ); - } - } - } - if ( ! ( mnDashCount | mnDotCount ) ) - { - mnDashCount = maLineInfo.GetDashCount(); - mnDotCount = maLineInfo.GetDotCount(); - } - if ( ( mfDashDotLenght == 0.0 ) && ( mfDistanceLenght == 0.0 ) ) - mfDistanceLenght = maLineInfo.GetDistance(); - } - } - } - return ImplGetNext(); -}; - -//------------------------------------------------------------------------ - -const Polygon* ImplLineConverter::ImplGetNext() -{ - while( mnFloat1Points || mnLinesAvailable ) - { - if ( maLineInfo.GetWidth() > 1 ) - { - if ( !mnFloat1Points ) - { - ImplFloatPoint aPointA( mpFloatPoint[ mnLinesAvailable-- ] ); - ImplFloatPoint aPointB( mpFloatPoint[ mnLinesAvailable ] ); - ImplFloatPoint aOVecAB( aPointA.GetOVec( aPointB ) ); - ImplFloatPoint aN1Vec( aPointA.GetNVec( aPointB ) ); - aN1Vec *= mfWidthHalf; - - if ( !mbClosed && ( ( mnLinesAvailable + 1 ) == mnLines ) ) - aPointA -= aN1Vec; - - aOVecAB *= mfWidthHalf; - mpFloat0[ 0 ] = aPointA; - mpFloat0[ 0 ] -= aOVecAB; - mpFloat0[ 3 ] = aPointA; - mpFloat0[ 3 ] += aOVecAB; - mpFloat0[ 1 ] = aPointB; - mpFloat0[ 1 ] -= aOVecAB; - mpFloat0[ 2 ] = aPointB; - mpFloat0[ 2 ] += aOVecAB; - - double f1D = ( aN1Vec.fX == 0 ) ? 1 : ( aN1Vec.fY / aN1Vec.fX ); - double f2D = -f1D; - - mnFloat0Points = 4; - - int nDirection; - - BOOL bContinues = ( mnLinesAvailable || mbClosed ); - if ( bContinues ) - { - ImplFloatPoint aPointC; - - if ( mnLinesAvailable ) - aPointC = mpFloatPoint[ mnLinesAvailable - 1 ]; - else - aPointC = mpFloatPoint[ mnLines - 1 ]; - - ImplFloatPoint aOVecBC( aPointB.GetOVec( aPointC ) ); - aOVecBC *= mfWidthHalf; - ImplFloatPoint aPointR0( aPointB ); - aPointR0 -= aOVecBC; - ImplFloatPoint aPointR1( aPointB ); - aPointR1 += aOVecBC; - ImplFloatPoint aN2Vec( aPointB.GetNVec( aPointC ) ); - aN2Vec *= mfWidthHalf; - - f2D = ( fabs( aN2Vec.fX ) < 0.00000001 ) ? 1 : ( aN2Vec.fY / aN2Vec.fX ); - if ( fabs( f1D - f2D ) < 0.00000001 ) - nDirection = CURVE_STRAIGHTON; - else - { - if ( ( aN1Vec.fX * aN2Vec.fY - aN1Vec.fY * aN2Vec.fX ) > 0 ) - nDirection = CURVE_LEFT; - else - nDirection = CURVE_RIGHT; - } - if ( nDirection != CURVE_STRAIGHTON ) - { - double fWidth; - ImplFloatPoint aDestPoint; - if ( hypot( aPointR0.fX - aPointA.fX, aPointR0.fY - aPointA.fY ) > hypot( aPointR1.fX - aPointA.fX, aPointR1.fY - aPointA.fY ) ) - aDestPoint = aPointR0; - else - aDestPoint = aPointR1; - - UINT16 nFirst = 0; - if ( aN1Vec.fY > 0 ) - { - if ( nDirection != CURVE_RIGHT ) - nFirst++; - } - else - { - if ( nDirection == CURVE_RIGHT ) - nFirst++; - } - fWidth = hypot( mpFloat0[ 1 + nFirst ].fX - aDestPoint.fX, mpFloat0[ 1 + nFirst ].fY - aDestPoint.fY ); - fWidth = sqrt( fWidth * fWidth / 2 ); - if ( fWidth > mfWidthHalf ) - { - // Spitzer Winkel : - mnFloat0Points = 6; - mpFloat0[ (4 + nFirst) ^ 1 ] = aDestPoint; - aDestPoint -= aN2Vec; - mpFloat0[ 4 + nFirst ] = aDestPoint; - mpFloat0[ 1 + nFirst ] += aN1Vec; - } - else - { - // Stumpferwinkel : Schnittpunkt wird berechnet - mnFloat0Points = 5; - ImplFloatPoint aSourcePoint; - double fX = 0; - double fY; - double fBDest = 0; - double fBSource = 0; - aSourcePoint = mpFloat0[ 1 + nFirst ]; - - int nValid = 0; - - if ( fabs( aN2Vec.fX ) < 0.00000001 ) - { - fX = aDestPoint.fX; - nValid = 1; - } - else - fBDest = aDestPoint.fY - ( aN2Vec.fY / aN2Vec.fX * aDestPoint.fX ); - - if ( fabs( aN1Vec.fX ) < 0.000000001 ) - { - fX = aSourcePoint.fX; - nValid = 2; - } - else - fBSource = aSourcePoint.fY - ( aN1Vec.fY / aN1Vec.fX * aSourcePoint.fX ); - - if ( !nValid ) - fX = ( fBSource - fBDest ) / ( aN2Vec.fY / aN2Vec.fX - aN1Vec.fY / aN1Vec.fX ); - if ( nValid < 2 ) - fY = aN1Vec.fY / aN1Vec.fX * fX + fBSource; - else - fY = aN2Vec.fY / aN2Vec.fX * fX + fBDest; - - mpFloat0[ 1 + nFirst ].fX = fX; - mpFloat0[ 1 + nFirst ].fY = fY; - mpFloat0[ 4 ] = aDestPoint; - } - } - else if ( ( aN1Vec.fX - aN2Vec.fX + aN1Vec.fY - aN2Vec.fY ) != 0 ) // besitzt zweiter Richtungsvektor die gleiche Steigung aber andere - bContinues = FALSE; // Richtung, dann wird hinten noch eine halbe Linienbreite angehaengt - } - if ( !bContinues ) - { - mpFloat0[ 1 ] += aN1Vec; - mpFloat0[ 2 ] += aN1Vec; - } - } - else - { - mnFloat0Points = mnFloat1Points; - ImplFloatPoint* pTemp = mpFloat1; - mpFloat1 = mpFloat0; - mpFloat0 = pTemp; - } - if ( maLineInfo.GetStyle() == LINE_DASH ) - { - double fLenghtDone = 0; - double fLenght = ( mfDashDotLenght > 0.0 ) ? mfDashDotLenght : mfDistanceLenght; - - double fDistance; - - fDistance = hypot( mpFloat0[ 0 ].fX - mpFloat0[ 1 ].fX, mpFloat0[ 0 ].fY - mpFloat0[ 1 ].fY ); - if ( mnFloat0Points == 5 ) - { - double fDist = hypot( mpFloat0[ 2 ].fX - mpFloat0[ 3 ].fX, mpFloat0[ 2 ].fY - mpFloat0[ 3 ].fY ); - if ( fDist < fDistance ) - fDistance = fDist; - } - - if ( fDistance > fLenght ) - { - fLenghtDone = fLenght; - - ImplFloatPoint aNVec( mpFloat0[ 0 ].GetNVec( mpFloat0[ 1 ] ) ); - aNVec *= fLenght; - mnFloat1Points = mnFloat0Points; - ImplFloatPoint* pTemp = mpFloat1; - mpFloat1 = mpFloat0; - mpFloat0 = pTemp; - mnFloat0Points = 4; - mpFloat0[ 0 ] = mpFloat0[ 1 ] = mpFloat1[ 0 ]; - mpFloat0[ 1 ] += aNVec; - mpFloat0[ 2 ] = mpFloat0[ 3 ] = mpFloat1[ 3 ]; - mpFloat0[ 2 ] += aNVec; - - mpFloat1[ 0 ] = mpFloat0[ 1 ]; - mpFloat1[ 3 ] = mpFloat0[ 2 ]; - } - else - { - mnFloat1Points = 0; - fLenghtDone = fDistance; - } - - if ( mfDashDotLenght > 0.0 ) - { // Ein Dash oder Dot wurde erzeugt - mfDashDotLenght -= fLenghtDone; - if ( mfDashDotLenght == 0.0 ) - { // Komplett erzeugt - if ( mnDashCount ) - mnDashCount--; - else - mnDotCount--; - - if ( ! ( mnDashCount | mnDotCount ) ) - { - mnDashCount = maLineInfo.GetDashCount(); - mnDotCount = maLineInfo.GetDotCount(); - } - mfDistanceLenght = maLineInfo.GetDistance(); - } - } - else - { // Das erzeugte Polygon muessen wir ignorieren - mfDistanceLenght -= fLenghtDone; - if ( mfDistanceLenght == 0.0 ) - mfDashDotLenght = ( mnDashCount ) ? maLineInfo.GetDashLen() : maLineInfo.GetDotLen(); - continue; - } - } - maPolygon.SetSize( (UINT16)mnFloat0Points ); - UINT16 i = 0; - maPolygon[ i++ ] = Point( FRound( mpFloat0[ 0 ].fX ), FRound( mpFloat0[ 0 ].fY ) ); - maPolygon[ i++ ] = Point( FRound( mpFloat0[ 1 ].fX ), FRound( mpFloat0[ 1 ].fY ) ); - if ( mnFloat0Points > 4 ) - maPolygon[ i++ ] = Point( FRound( mpFloat0[ 4 ].fX ), FRound( mpFloat0[ 4 ].fY ) ); - if ( mnFloat0Points > 5 ) - maPolygon[ i++ ] = Point( FRound( mpFloat0[ 5 ].fX ), FRound( mpFloat0[ 5 ].fY ) ); - maPolygon[ i++ ] = Point( FRound( mpFloat0[ 2 ].fX ), FRound( mpFloat0[ 2 ].fY ) ); - maPolygon[ i ] = Point( FRound( mpFloat0[ 3 ].fX ), FRound( mpFloat0[ 3 ].fY ) ); - - } - else - { - if ( !mnFloat1Points ) - { - mpFloat0[ 0 ] = mpFloatPoint[ mnLinesAvailable-- ]; - mpFloat0[ 1 ] = mpFloatPoint[ mnLinesAvailable ]; - } - else - { - mpFloat0[ 0 ] = mpFloat1[ 0 ]; - mpFloat0[ 1 ] = mpFloat1[ 1 ]; - } - if ( maLineInfo.GetStyle() == LINE_DASH ) - { - double fLenghtDone = 0; - double fLenght = ( mfDashDotLenght > 0.0 ) ? mfDashDotLenght : mfDistanceLenght; - double fDistance; - fDistance = hypot( mpFloat0[ 0 ].fX - mpFloat0[ 1 ].fX, mpFloat0[ 0 ].fY - mpFloat0[ 1 ].fY ); - if ( fDistance > fLenght ) - { - fLenghtDone = fLenght; - ImplFloatPoint aNVec( mpFloat0[ 0 ].GetNVec( mpFloat0[ 1 ] ) ); - aNVec *= fLenght; - mpFloat1[ 1 ] = mpFloat0[ 1 ]; - mpFloat0[ 1 ] = mpFloat0[ 0 ]; - mpFloat0[ 1 ] += aNVec; - mpFloat1[ 0 ] = mpFloat0[ 1 ]; - mnFloat1Points = 2; - } - else - { - mnFloat1Points = 0; - fLenghtDone = fDistance; - } - if ( mfDashDotLenght > 0.0 ) - { // Ein Dash oder Dot wurde erzeugt - mfDashDotLenght -= fLenghtDone; - if ( mfDashDotLenght == 0.0 ) - { // Komplett erzeugt - if ( mnDashCount ) - mnDashCount--; - else - mnDotCount--; - - if ( ! ( mnDashCount | mnDotCount ) ) - { - mnDashCount = maLineInfo.GetDashCount(); - mnDotCount = maLineInfo.GetDotCount(); - } - mfDistanceLenght = maLineInfo.GetDistance(); - } - } - else - { // Das erzeugte Polygon muessen wir ignorieren - mfDistanceLenght -= fLenghtDone; - if ( mfDistanceLenght == 0.0 ) - mfDashDotLenght = ( mnDashCount ) ? maLineInfo.GetDashLen() : maLineInfo.GetDotLen(); - continue; - } - } - maPolygon.SetSize( 2 ); - maPolygon[ 0 ] = Point( (long)mpFloat0[ 0 ].fX, (long)mpFloat0[ 0 ].fY ); - maPolygon[ 1 ] = Point( (long)mpFloat0[ 1 ].fX, (long)mpFloat0[ 1 ].fY ); - } - return &maPolygon; - } - return NULL; -}; diff --git a/vcl/source/gdi/implncvt.hxx b/vcl/source/gdi/implncvt.hxx deleted file mode 100644 index 2d369d12f253..000000000000 --- a/vcl/source/gdi/implncvt.hxx +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: implncvt.hxx,v $ - * $Revision: 1.5 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef _SV_LINECONV_HXX -#define _SV_LINECONV_HXX - -#include <tools/poly.hxx> -#include <vcl/lineinfo.hxx> - -// -------------------- -// - ImplLineConverter -// -------------------- - -struct ImplFloatPoint; - -class ImplLineConverter -{ - BOOL mbClosed; - BOOL mbRefPoint; - INT32 mnRefDistance; - - double mfWidthHalf; - LineInfo maLineInfo; - - double mfDashDotLenght; - double mfDistanceLenght; - - UINT32 mnDashCount; - UINT32 mnDotCount; - - Polygon maPolygon; - UINT32 mnFloat0Points; - ImplFloatPoint* mpFloat0; - UINT32 mnFloat1Points; - ImplFloatPoint* mpFloat1; - - UINT32 mnLinesAvailable; - UINT32 mnLines; - - ImplFloatPoint* mpFloatPoint; - - public: - - ImplLineConverter( const Polygon& rPoly, const LineInfo& rLineInfo, const Point* pRefPoint ); - ~ImplLineConverter(); - - const Polygon* ImplGetFirst(); - const Polygon* ImplGetNext(); -}; - -#endif diff --git a/vcl/source/gdi/lineinfo.cxx b/vcl/source/gdi/lineinfo.cxx index 98f16713a145..7aa50811106b 100644 --- a/vcl/source/gdi/lineinfo.cxx +++ b/vcl/source/gdi/lineinfo.cxx @@ -34,6 +34,10 @@ #include <tools/vcompat.hxx> #include <tools/debug.hxx> #include <vcl/lineinfo.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dlinegeometry.hxx> +#include <numeric> DBG_NAME( LineInfo ) @@ -49,7 +53,8 @@ ImplLineInfo::ImplLineInfo() : mnDashLen ( 0 ), mnDotCount ( 0 ), mnDotLen ( 0 ), - mnDistance ( 0 ) + mnDistance ( 0 ), + meLineJoin ( basegfx::B2DLINEJOIN_ROUND ) { } @@ -63,7 +68,8 @@ ImplLineInfo::ImplLineInfo( const ImplLineInfo& rImplLineInfo ) : mnDashLen ( rImplLineInfo.mnDashLen ), mnDotCount ( rImplLineInfo.mnDotCount ), mnDotLen ( rImplLineInfo.mnDotLen ), - mnDistance ( rImplLineInfo.mnDistance ) + mnDistance ( rImplLineInfo.mnDistance ), + meLineJoin ( rImplLineInfo.meLineJoin ) { } @@ -209,6 +215,19 @@ void LineInfo::SetDistance( long nDistance ) // ----------------------------------------------------------------------- +void LineInfo::SetLineJoin(basegfx::B2DLineJoin eLineJoin) +{ + DBG_CHKTHIS( LineInfo, NULL ); + + if(eLineJoin != mpImplLineInfo->meLineJoin) + { + ImplMakeUnique(); + mpImplLineInfo->meLineJoin = eLineJoin; + } +} + +// ----------------------------------------------------------------------- + SvStream& operator>>( SvStream& rIStm, ImplLineInfo& rImplLineInfo ) { VersionCompat aCompat( rIStm, STREAM_READ ); @@ -225,6 +244,12 @@ SvStream& operator>>( SvStream& rIStm, ImplLineInfo& rImplLineInfo ) rIStm >> rImplLineInfo.mnDistance; } + if( aCompat.GetVersion() >= 3 ) + { + // version 3 + rIStm >> nTmp16; rImplLineInfo.meLineJoin = (basegfx::B2DLineJoin) nTmp16; + } + return rIStm; } @@ -232,7 +257,7 @@ SvStream& operator>>( SvStream& rIStm, ImplLineInfo& rImplLineInfo ) SvStream& operator<<( SvStream& rOStm, const ImplLineInfo& rImplLineInfo ) { - VersionCompat aCompat( rOStm, STREAM_WRITE, 2 ); + VersionCompat aCompat( rOStm, STREAM_WRITE, 3 ); // version 1 rOStm << (UINT16) rImplLineInfo.meStyle << rImplLineInfo.mnWidth; @@ -242,6 +267,9 @@ SvStream& operator<<( SvStream& rOStm, const ImplLineInfo& rImplLineInfo ) rOStm << rImplLineInfo.mnDotCount << rImplLineInfo.mnDotLen; rOStm << rImplLineInfo.mnDistance; + // since version3 + rOStm << (UINT16) rImplLineInfo.meLineJoin; + return rOStm; } @@ -259,3 +287,78 @@ SvStream& operator<<( SvStream& rOStm, const LineInfo& rLineInfo ) { return( rOStm << *rLineInfo.mpImplLineInfo ); } + +// ----------------------------------------------------------------------- + +bool LineInfo::isDashDotOrFatLineUsed() const +{ + return (LINE_DASH == GetStyle() || GetWidth() > 1); +} + +// ----------------------------------------------------------------------- + +void LineInfo::applyToB2DPolyPolygon( + basegfx::B2DPolyPolygon& io_rLinePolyPolygon, + basegfx::B2DPolyPolygon& o_rFillPolyPolygon) const +{ + o_rFillPolyPolygon.clear(); + + if(io_rLinePolyPolygon.count()) + { + if(LINE_DASH == GetStyle()) + { + ::std::vector< double > fDotDashArray; + const double fDashLen(GetDashLen()); + const double fDotLen(GetDotLen()); + const double fDistance(GetDistance()); + + for(sal_uInt16 a(0); a < GetDashCount(); a++) + { + fDotDashArray.push_back(fDashLen); + fDotDashArray.push_back(fDistance); + } + + for(sal_uInt16 b(0); b < 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 < io_rLinePolyPolygon.count(); c++) + { + basegfx::B2DPolyPolygon aLineTraget; + basegfx::tools::applyLineDashing( + io_rLinePolyPolygon.getB2DPolygon(c), + fDotDashArray, + &aLineTraget); + aResult.append(aLineTraget); + } + + io_rLinePolyPolygon = aResult; + } + } + + if(GetWidth() > 1 && io_rLinePolyPolygon.count()) + { + const double fHalfLineWidth((GetWidth() * 0.5) + 0.5); + + for(sal_uInt32 a(0); a < io_rLinePolyPolygon.count(); a++) + { + o_rFillPolyPolygon.append(basegfx::tools::createAreaGeometry( + io_rLinePolyPolygon.getB2DPolygon(a), + fHalfLineWidth, + GetLineJoin())); + } + + io_rLinePolyPolygon.clear(); + } + } +} + +// ----------------------------------------------------------------------- diff --git a/vcl/source/gdi/makefile.mk b/vcl/source/gdi/makefile.mk index 421505a3d500..e253f83b25ab 100755 --- a/vcl/source/gdi/makefile.mk +++ b/vcl/source/gdi/makefile.mk @@ -100,7 +100,6 @@ SLOFILES= $(EXCEPTIONSFILES) \ $(SLO)$/impbmp.obj \ $(SLO)$/imagerepository.obj \ $(SLO)$/impvect.obj \ - $(SLO)$/implncvt.obj \ $(SLO)$/lineinfo.obj \ $(SLO)$/mapmod.obj \ $(SLO)$/metaact.obj \ diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx index 82566b2b4362..1f27ad2afe7d 100644 --- a/vcl/source/gdi/metaact.cxx +++ b/vcl/source/gdi/metaact.cxx @@ -52,14 +52,6 @@ inline void ImplScalePoint( Point& rPt, double fScaleX, double fScaleY ) // ------------------------------------------------------------------------ -inline void ImplScaleSize( Size& rSz, double fScaleX, double fScaleY ) -{ - rSz.Width() = FRound( fScaleX * rSz.Width() ); - rSz.Height() = FRound( fScaleY * rSz.Height() ); -} - -// ------------------------------------------------------------------------ - inline void ImplScaleRect( Rectangle& rRect, double fScaleX, double fScaleY ) { Point aTL( rRect.TopLeft() ); @@ -69,6 +61,7 @@ inline void ImplScaleRect( Rectangle& rRect, double fScaleX, double fScaleY ) ImplScalePoint( aBR, fScaleX, fScaleY ); rRect = Rectangle( aTL, aBR ); + rRect.Justify(); } // ------------------------------------------------------------------------ @@ -85,7 +78,7 @@ inline void ImplScaleLineInfo( LineInfo& rLineInfo, double fScaleX, double fScal { if( !rLineInfo.IsDefault() ) { - const double fScale = ( fScaleX + fScaleY ) * 0.5; + const double fScale = ( fabs(fScaleX) + fabs(fScaleY) ) * 0.5; rLineInfo.SetWidth( FRound( fScale * rLineInfo.GetWidth() ) ); rLineInfo.SetDashLen( FRound( fScale * rLineInfo.GetDashLen() ) ); @@ -598,8 +591,8 @@ void MetaRoundRectAction::Move( long nHorzMove, long nVertMove ) void MetaRoundRectAction::Scale( double fScaleX, double fScaleY ) { ImplScaleRect( maRect, fScaleX, fScaleY ); - mnHorzRound = FRound( mnHorzRound * fScaleX ); - mnVertRound = FRound( mnVertRound * fScaleY ); + mnHorzRound = FRound( mnHorzRound * fabs(fScaleX) ); + mnVertRound = FRound( mnVertRound * fabs(fScaleY) ); } // ------------------------------------------------------------------------ @@ -1396,7 +1389,7 @@ void MetaTextArrayAction::Scale( double fScaleX, double fScaleY ) if ( mpDXAry && mnLen ) { for ( USHORT i = 0, nCount = mnLen; i < nCount; i++ ) - mpDXAry[ i ] = FRound( mpDXAry[ i ] * fScaleX ); + mpDXAry[ i ] = FRound( mpDXAry[ i ] * fabs(fScaleX) ); } } @@ -1524,7 +1517,7 @@ void MetaStretchTextAction::Move( long nHorzMove, long nVertMove ) void MetaStretchTextAction::Scale( double fScaleX, double fScaleY ) { ImplScalePoint( maPt, fScaleX, fScaleY ); - mnWidth = (ULONG)FRound( mnWidth * fScaleX ); + mnWidth = (ULONG)FRound( mnWidth * fabs(fScaleX) ); } // ------------------------------------------------------------------------ @@ -1717,7 +1710,7 @@ void MetaTextLineAction::Move( long nHorzMove, long nVertMove ) void MetaTextLineAction::Scale( double fScaleX, double fScaleY ) { ImplScalePoint( maPos, fScaleX, fScaleY ); - mnWidth = FRound( mnWidth * fScaleX ); + mnWidth = FRound( mnWidth * fabs(fScaleX) ); } // ------------------------------------------------------------------------ @@ -1876,8 +1869,10 @@ void MetaBmpScaleAction::Move( long nHorzMove, long nVertMove ) void MetaBmpScaleAction::Scale( double fScaleX, double fScaleY ) { - ImplScalePoint( maPt, fScaleX, fScaleY ); - ImplScaleSize( maSz, fScaleX, fScaleY ); + Rectangle aRectangle(maPt, maSz); + ImplScaleRect( aRectangle, fScaleX, fScaleY ); + maPt = aRectangle.TopLeft(); + maSz = aRectangle.GetSize(); } // ------------------------------------------------------------------------ @@ -1953,8 +1948,10 @@ void MetaBmpScalePartAction::Move( long nHorzMove, long nVertMove ) void MetaBmpScalePartAction::Scale( double fScaleX, double fScaleY ) { - ImplScalePoint( maDstPt, fScaleX, fScaleY ); - ImplScaleSize( maDstSz, fScaleX, fScaleY ); + Rectangle aRectangle(maDstPt, maDstSz); + ImplScaleRect( aRectangle, fScaleX, fScaleY ); + maDstPt = aRectangle.TopLeft(); + maDstSz = aRectangle.GetSize(); } // ------------------------------------------------------------------------ @@ -2099,8 +2096,10 @@ void MetaBmpExScaleAction::Move( long nHorzMove, long nVertMove ) void MetaBmpExScaleAction::Scale( double fScaleX, double fScaleY ) { - ImplScalePoint( maPt, fScaleX, fScaleY ); - ImplScaleSize( maSz, fScaleX, fScaleY ); + Rectangle aRectangle(maPt, maSz); + ImplScaleRect( aRectangle, fScaleX, fScaleY ); + maPt = aRectangle.TopLeft(); + maSz = aRectangle.GetSize(); } // ------------------------------------------------------------------------ @@ -2176,8 +2175,10 @@ void MetaBmpExScalePartAction::Move( long nHorzMove, long nVertMove ) void MetaBmpExScalePartAction::Scale( double fScaleX, double fScaleY ) { - ImplScalePoint( maDstPt, fScaleX, fScaleY ); - ImplScaleSize( maDstSz, fScaleX, fScaleY ); + Rectangle aRectangle(maDstPt, maDstSz); + ImplScaleRect( aRectangle, fScaleX, fScaleY ); + maDstPt = aRectangle.TopLeft(); + maDstSz = aRectangle.GetSize(); } // ------------------------------------------------------------------------ @@ -2328,8 +2329,10 @@ void MetaMaskScaleAction::Move( long nHorzMove, long nVertMove ) void MetaMaskScaleAction::Scale( double fScaleX, double fScaleY ) { - ImplScalePoint( maPt, fScaleX, fScaleY ); - ImplScaleSize( maSz, fScaleX, fScaleY ); + Rectangle aRectangle(maPt, maSz); + ImplScaleRect( aRectangle, fScaleX, fScaleY ); + maPt = aRectangle.TopLeft(); + maSz = aRectangle.GetSize(); } // ------------------------------------------------------------------------ @@ -2408,8 +2411,10 @@ void MetaMaskScalePartAction::Move( long nHorzMove, long nVertMove ) void MetaMaskScalePartAction::Scale( double fScaleX, double fScaleY ) { - ImplScalePoint( maDstPt, fScaleX, fScaleY ); - ImplScaleSize( maDstSz, fScaleX, fScaleY ); + Rectangle aRectangle(maDstPt, maDstSz); + ImplScaleRect( aRectangle, fScaleX, fScaleY ); + maDstPt = aRectangle.TopLeft(); + maDstSz = aRectangle.GetSize(); } // ------------------------------------------------------------------------ @@ -3498,9 +3503,9 @@ MetaAction* MetaFontAction::Clone() void MetaFontAction::Scale( double fScaleX, double fScaleY ) { - Size aSize( maFont.GetSize() ); - - ImplScaleSize( aSize, fScaleX, fScaleY ); + const Size aSize( + FRound(maFont.GetSize().Width() * fabs(fScaleX)), + FRound(maFont.GetSize().Height() * fabs(fScaleY))); maFont.SetSize( aSize ); } @@ -3791,14 +3796,18 @@ MetaAction* MetaFloatTransparentAction::Clone() void MetaFloatTransparentAction::Move( long nHorzMove, long nVertMove ) { maPoint.Move( nHorzMove, nVertMove ); + maMtf.Move(nHorzMove, nVertMove); } // ------------------------------------------------------------------------ void MetaFloatTransparentAction::Scale( double fScaleX, double fScaleY ) { - ImplScalePoint( maPoint, fScaleX, fScaleY ); - ImplScaleSize( maSize, fScaleX, fScaleY ); + Rectangle aRectangle(maPoint, maSize); + ImplScaleRect( aRectangle, fScaleX, fScaleY ); + maPoint = aRectangle.TopLeft(); + maSize = aRectangle.GetSize(); + maMtf.Scale(fScaleX, fScaleY); } // ------------------------------------------------------------------------ @@ -3872,8 +3881,10 @@ void MetaEPSAction::Move( long nHorzMove, long nVertMove ) void MetaEPSAction::Scale( double fScaleX, double fScaleY ) { - ImplScalePoint( maPoint, fScaleX, fScaleY ); - ImplScaleSize( maSize, fScaleX, fScaleY ); + Rectangle aRectangle(maPoint, maSize); + ImplScaleRect( aRectangle, fScaleX, fScaleY ); + maPoint = aRectangle.TopLeft(); + maSize = aRectangle.GetSize(); } // ------------------------------------------------------------------------ diff --git a/vcl/source/gdi/outdev.cxx b/vcl/source/gdi/outdev.cxx index 6298ff51a16a..91ea8419cba9 100644 --- a/vcl/source/gdi/outdev.cxx +++ b/vcl/source/gdi/outdev.cxx @@ -56,7 +56,6 @@ #include <vcl/gdimtf.hxx> #include <vcl/outdata.hxx> #include <vcl/print.hxx> -#include <implncvt.hxx> #include <vcl/outdev.h> #include <vcl/outdev.hxx> #include <vcl/unowrap.hxx> @@ -77,6 +76,8 @@ #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <vcl/unohelp.hxx> +#include <numeric> + using namespace ::com::sun::star; DBG_NAME( OutputDevice ) @@ -2330,6 +2331,130 @@ void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt ) // ----------------------------------------------------------------------- +void OutputDevice::impPaintLineGeometryWithEvtlExpand( + 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); + + for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++) + { + aFillPolyPolygon.append(basegfx::tools::createAreaGeometry( + aLinePolyPolygon.getB2DPolygon(a), + fHalfLineWidth, + rInfo.GetLineJoin())); + } + + 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, basegfx::B2DVector(1.0, 1.0), basegfx::B2DLINEJOIN_NONE, 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++) + { + const Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a)); + 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 ) { @@ -2357,47 +2482,22 @@ void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt, 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( ( aInfo.GetWidth() > 1L ) || ( LINE_DASH == aInfo.GetStyle() ) ) + if(bDashUsed || bLineWidthUsed) { - Polygon aPoly( 2 ); aPoly[ 0 ] = rStartPt; aPoly[ 1 ] = rEndPt; - GDIMetaFile* pOldMetaFile = mpMetaFile; - ImplLineConverter aLineCvt( ImplLogicToDevicePixel( aPoly ), aInfo, ( mbRefPoint ) ? &maRefPoint : NULL ); - - mpMetaFile = NULL; + basegfx::B2DPolygon aLinePolygon; + aLinePolygon.append(basegfx::B2DPoint(aStartPt.X(), aStartPt.Y())); + aLinePolygon.append(basegfx::B2DPoint(aEndPt.X(), aEndPt.Y())); - if ( aInfo.GetWidth() > 1 ) - { - const Color aOldLineColor( maLineColor ); - const Color aOldFillColor( maFillColor ); - - SetLineColor(); - ImplInitLineColor(); - SetFillColor( aOldLineColor ); - ImplInitFillColor(); - - for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() ) - mpGraphics->DrawPolygon( pPoly->GetSize(), (const SalPoint*) pPoly->GetConstPointAry(), this ); - - SetFillColor( aOldFillColor ); - SetLineColor( aOldLineColor ); - } - else - { - if ( mbInitLineColor ) - ImplInitLineColor(); - - for ( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() ) - mpGraphics->DrawLine( (*pPoly)[ 0 ].X(), (*pPoly)[ 0 ].Y(), (*pPoly)[ 1 ].X(), (*pPoly)[ 1 ].Y(), this ); - } - mpMetaFile = pOldMetaFile; + impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aLinePolygon)); } else { - const Point aStartPt( ImplLogicToDevicePixel( rStartPt ) ); - const Point aEndPt( ImplLogicToDevicePixel( rEndPt ) ); - if ( mbInitLineColor ) ImplInitLineColor(); @@ -2546,7 +2646,7 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && LINE_SOLID == rLineInfo.GetStyle()) { - DrawPolyLine(rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), basegfx::B2DLINEJOIN_ROUND); + DrawPolyLine(rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), rLineInfo.GetLineJoin()); return; } @@ -2558,7 +2658,7 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo void OutputDevice::ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo) { - USHORT nPoints = rPoly.GetSize(); + USHORT nPoints(rPoly.GetSize()); if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() ) return; @@ -2566,11 +2666,19 @@ void OutputDevice::ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineI Polygon aPoly = ImplLogicToDevicePixel( rPoly ); // #100127# LineInfo is not curve-safe, subdivide always - if( aPoly.HasFlags() ) - { - aPoly = ImplSubdivideBezier( aPoly ); - nPoints = aPoly.GetSize(); - } + // + // 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() ) @@ -2582,67 +2690,29 @@ void OutputDevice::ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineI if ( mbOutputClipped ) return; - const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) ); - const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) - && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) - && ROP_OVERPAINT == GetRasterOp() - && IsLineColor()); - - if( aInfo.GetWidth() > 1L ) - { - const Color aOldLineColor( maLineColor ); - const Color aOldFillColor( maFillColor ); - GDIMetaFile* pOldMetaFile = mpMetaFile; - ImplLineConverter aLineCvt( aPoly, aInfo, ( mbRefPoint ) ? &maRefPoint : NULL ); - - mpMetaFile = NULL; - SetLineColor(); + if ( mbInitLineColor ) ImplInitLineColor(); - SetFillColor( aOldLineColor ); - ImplInitFillColor(); - bool bDone(false); - if(bTryAA) - { - // #i101491# try AAed version - // Use old on-the-fly geometry preparation, combine with AA - bool bSuccess(true); - - for(const Polygon* pPoly = aLineCvt.ImplGetFirst(); bSuccess && pPoly; pPoly = aLineCvt.ImplGetNext()) - { - bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(pPoly->getB2DPolygon()), 0.0, this); - } - - if(bSuccess) - { - bDone = true; - } - } - - if(!bDone) - { - for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() ) - { - mpGraphics->DrawPolygon( pPoly->GetSize(), (const SalPoint*) pPoly->GetConstPointAry(), this ); - } - } + const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) ); + const bool bDashUsed(LINE_DASH == aInfo.GetStyle()); + const bool bLineWidthUsed(aInfo.GetWidth() > 1); - SetLineColor( aOldLineColor ); - SetFillColor( aOldFillColor ); - mpMetaFile = pOldMetaFile; + if(bDashUsed || bLineWidthUsed) + { + impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aPoly.getB2DPolygon())); } else { - if ( mbInitLineColor ) - ImplInitLineColor(); - if ( LINE_DASH == aInfo.GetStyle() ) + // #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() ) { - ImplLineConverter aLineCvt( aPoly, aInfo, ( mbRefPoint ) ? &maRefPoint : NULL ); - for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() ) - mpGraphics->DrawPolyLine( pPoly->GetSize(), (const SalPoint*)pPoly->GetConstPointAry(), this ); + aPoly = ImplSubdivideBezier( aPoly ); + nPoints = aPoly.GetSize(); } - else - mpGraphics->DrawPolyLine( nPoints, (const SalPoint*) aPoly.GetConstPointAry(), this ); + + mpGraphics->DrawPolyLine(nPoints, (const SalPoint*)aPoly.GetConstPointAry(), this); } if( mpAlphaVDev ) @@ -3047,7 +3117,12 @@ void OutputDevice::DrawPolyLine( SetFillColor(aOldLineColor); ImplInitFillColor(); - ImpDrawPolyPolygonWithB2DPolyPolygon(aAreaPolyPolygon); + // draw usig a loop; else the topology will paint a PolyPolygon + for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++) + { + ImpDrawPolyPolygonWithB2DPolyPolygon( + basegfx::B2DPolyPolygon(aAreaPolyPolygon.getB2DPolygon(a))); + } SetLineColor(aOldLineColor); ImplInitLineColor(); @@ -3064,14 +3139,15 @@ void OutputDevice::DrawPolyLine( } } } - - // fallback to old polygon drawing if needed. This will really - // use ImplLineConverter, but still try to AA lines - const Polygon aToolsPolygon( rB2DPolygon ); - LineInfo aLineInfo; - if( fLineWidth != 0.0 ) - aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) ); - ImpDrawPolyLineWithLineInfo( aToolsPolygon, aLineInfo ); + 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) ); + ImpDrawPolyLineWithLineInfo( aToolsPolygon, aLineInfo ); + } } // ----------------------------------------------------------------------- diff --git a/vcl/source/gdi/outdev6.cxx b/vcl/source/gdi/outdev6.cxx index 79986988afd7..2d436ea43659 100644 --- a/vcl/source/gdi/outdev6.cxx +++ b/vcl/source/gdi/outdev6.cxx @@ -1158,9 +1158,11 @@ void OutputDevice::ImplDraw2ColorFrame( const Rectangle& rRect, // ----------------------------------------------------------------------- -void OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize, +bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize, const GfxLink& rGfxLink, GDIMetaFile* pSubst ) { + bool bDrawn(true); + if ( mpMetaFile ) { GDIMetaFile aSubst; @@ -1172,20 +1174,20 @@ void OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize, } if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() ) - return; + return bDrawn; if( mbOutputClipped ) - return; + return bDrawn; Rectangle aRect( ImplLogicToDevicePixel( Rectangle( rPoint, rSize ) ) ); + if( !aRect.IsEmpty() ) { // draw the real EPS graphics - bool bDrawn = FALSE; if( rGfxLink.GetData() && rGfxLink.GetDataSize() ) { if( !mpGraphics && !ImplGetGraphics() ) - return; + return bDrawn; if( mbInitClipRegion ) ImplInitClipRegion(); @@ -1208,4 +1210,6 @@ void OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize, if( mpAlphaVDev ) mpAlphaVDev->DrawEPS( rPoint, rSize, rGfxLink, pSubst ); + + return bDrawn; } diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 4146f1764204..c0205f1f325d 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -61,11 +61,9 @@ #include <comphelper/processfactory.hxx> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/util/URL.hpp> - -#include "implncvt.hxx" - #include "cppuhelper/implbase1.hxx" #include <icc/sRGB-IEC61966-2.1.hxx> +#include <vcl/lineinfo.hxx> using namespace vcl; using namespace rtl; diff --git a/vcl/source/gdi/region.cxx b/vcl/source/gdi/region.cxx index 66865759db4b..fefbf8cdcb08 100644 --- a/vcl/source/gdi/region.cxx +++ b/vcl/source/gdi/region.cxx @@ -49,6 +49,7 @@ #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx> #include <basegfx/range/b2drange.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> // ======================================================================= // @@ -1303,9 +1304,7 @@ void Region::Move( long nHorzMove, long nVertMove ) mpImplRegion->mpPolyPoly->Move( nHorzMove, nVertMove ); else if( mpImplRegion->mpB2DPolyPoly ) { - ::basegfx::B2DHomMatrix aTransform; - aTransform.translate( nHorzMove, nVertMove ); - mpImplRegion->mpB2DPolyPoly->transform( aTransform ); + mpImplRegion->mpB2DPolyPoly->transform(basegfx::tools::createTranslateB2DHomMatrix(nHorzMove, nVertMove)); } else { @@ -1346,9 +1345,7 @@ void Region::Scale( double fScaleX, double fScaleY ) mpImplRegion->mpPolyPoly->Scale( fScaleX, fScaleY ); else if( mpImplRegion->mpB2DPolyPoly ) { - ::basegfx::B2DHomMatrix aTransform; - aTransform.scale( fScaleX, fScaleY ); - mpImplRegion->mpB2DPolyPoly->transform( aTransform ); + mpImplRegion->mpB2DPolyPoly->transform(basegfx::tools::createScaleB2DHomMatrix(fScaleX, fScaleY)); } else { diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx index 1e9572887e0b..c1f987377c67 100644 --- a/vcl/source/gdi/salgdilayout.cxx +++ b/vcl/source/gdi/salgdilayout.cxx @@ -52,7 +52,6 @@ #include <vcl/gdimtf.hxx> #include <vcl/outdata.hxx> #include <vcl/print.hxx> -#include <implncvt.hxx> #include <vcl/outdev.h> #include <vcl/outdev.hxx> #include <vcl/unowrap.hxx> diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx index 1f44b823ce44..c8748c65e2d3 100755 --- a/vcl/source/gdi/sallayout.cxx +++ b/vcl/source/gdi/sallayout.cxx @@ -44,6 +44,7 @@ #include <vcl/sallayout.hxx> #include <basegfx/polygon/b2dpolypolygon.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> #include <i18npool/lang.h> #ifndef _TL_DEBUG_HXX @@ -893,10 +894,8 @@ bool SalLayout::GetOutline( SalGraphics& rSalGraphics, { if( aPos.X() || aPos.Y() ) { - ::basegfx::B2DHomMatrix aMatrix; - aMatrix.translate( aPos.X(), aPos.Y() ); - aGlyphOutline.transform( aMatrix ); - } + aGlyphOutline.transform(basegfx::tools::createTranslateB2DHomMatrix(aPos.X(), aPos.Y())); + } // insert outline at correct position rVector.push_back( aGlyphOutline ); diff --git a/vcl/source/glyphs/gcach_ftyp.cxx b/vcl/source/glyphs/gcach_ftyp.cxx index 18857b94af8f..b92bea929c51 100644 --- a/vcl/source/glyphs/gcach_ftyp.cxx +++ b/vcl/source/glyphs/gcach_ftyp.cxx @@ -43,6 +43,7 @@ #include "tools/poly.hxx" #include "basegfx/matrix/b2dhommatrix.hxx" +#include <basegfx/matrix/b2dhommatrixtools.hxx> #include "basegfx/polygon/b2dpolypolygon.hxx" #include "osl/file.hxx" @@ -2282,9 +2283,7 @@ bool FreetypeServerFont::GetGlyphOutline( int nGlyphIndex, // convert to basegfx polypolygon // TODO: get rid of the intermediate tools polypolygon rB2DPolyPoly = aToolPolyPolygon.getB2DPolyPolygon(); - ::basegfx::B2DHomMatrix aMatrix; - aMatrix.scale( +1.0/(1<<6), -1.0/(1<<6) ); - rB2DPolyPoly.transform( aMatrix ); + rB2DPolyPoly.transform(basegfx::tools::createScaleB2DHomMatrix( +1.0/(1<<6), -1.0/(1<<6) )); return true; } diff --git a/vcl/unx/source/gdi/salgdi.cxx b/vcl/unx/source/gdi/salgdi.cxx index cb554bccea21..5fe2295a8fed 100644 --- a/vcl/unx/source/gdi/salgdi.cxx +++ b/vcl/unx/source/gdi/salgdi.cxx @@ -50,6 +50,7 @@ #include "basegfx/polygon/b2dpolygonclipper.hxx" #include "basegfx/polygon/b2dlinegeometry.hxx" #include "basegfx/matrix/b2dhommatrix.hxx" +#include <basegfx/matrix/b2dhommatrixtools.hxx> #include "basegfx/polygon/b2dpolypolygoncutter.hxx" #include <vector> @@ -1567,6 +1568,9 @@ bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const : // the used basegfx::tools::createAreaGeometry is simply too // expensive with very big polygons; fallback to caller (who // should use ImplLineConverter normally) + // AW: ImplLineConverter had to be removed since it does not even + // know LineJoins, so the fallback will now prepare the line geometry + // the same way. return false; } const XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); @@ -1579,9 +1583,7 @@ bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const : && !basegfx::fTools::equalZero( rLineWidth.getY() ) ) { // prepare for createAreaGeometry() with anisotropic linewidth - basegfx::B2DHomMatrix aAnisoMatrix; - aAnisoMatrix.scale( 1.0, rLineWidth.getX() / rLineWidth.getY() ); - aPolygon.transform( aAnisoMatrix ); + aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getX() / rLineWidth.getY())); } // special handling for hairlines to improve the drawing performance @@ -1603,9 +1605,7 @@ bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const : && !basegfx::fTools::equalZero( rLineWidth.getX() ) ) { // postprocess createAreaGeometry() for anisotropic linewidth - basegfx::B2DHomMatrix aAnisoMatrix; - aAnisoMatrix.scale( 1.0, rLineWidth.getY() / rLineWidth.getX() ); - aPolygon.transform( aAnisoMatrix ); + aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getY() / rLineWidth.getX())); } // temporarily adjust brush color to pen color diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx index d82830a9022f..12fdad65dfb1 100644 --- a/vcl/win/source/gdi/salgdi3.cxx +++ b/vcl/win/source/gdi/salgdi3.cxx @@ -65,6 +65,7 @@ #include "basegfx/polygon/b2dpolygon.hxx" #include "basegfx/polygon/b2dpolypolygon.hxx" #include "basegfx/matrix/b2dhommatrix.hxx" +#include <basegfx/matrix/b2dhommatrixtools.hxx> #include "sft.hxx" @@ -2480,9 +2481,8 @@ BOOL WinSalGraphics::GetGlyphOutline( long nIndex, // rescaling needed for the PolyPolygon conversion if( rB2DPolyPoly.count() ) { - ::basegfx::B2DHomMatrix aMatrix; - aMatrix.scale( mfFontScale/256, mfFontScale/256 ); - rB2DPolyPoly.transform( aMatrix ); + const double fFactor(mfFontScale/256); + rB2DPolyPoly.transform(basegfx::tools::createScaleB2DHomMatrix(fFactor, fFactor)); } return bRet; diff --git a/vcl/win/source/gdi/salgdi_gdiplus.cxx b/vcl/win/source/gdi/salgdi_gdiplus.cxx index 5c00c786e22d..29e4ff1d801e 100644 --- a/vcl/win/source/gdi/salgdi_gdiplus.cxx +++ b/vcl/win/source/gdi/salgdi_gdiplus.cxx @@ -62,9 +62,9 @@ // ----------------------------------------------------------------------- -void impAddB2DPolygonToGDIPlusGraphicsPath(Gdiplus::GraphicsPath& rPath, const basegfx::B2DPolygon& rPolygon) +void impAddB2DPolygonToGDIPlusGraphicsPathReal(Gdiplus::GraphicsPath& rPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin) { - const sal_uInt32 nCount(rPolygon.count()); + sal_uInt32 nCount(rPolygon.count()); if(nCount) { @@ -97,8 +97,58 @@ void impAddB2DPolygonToGDIPlusGraphicsPath(Gdiplus::GraphicsPath& rPath, const b if(a + 1 < nEdgeCount) { - aCurr = aNext; aFCurr = aFNext; + + if(bNoLineJoin) + { + rPath.StartFigure(); + } + } + } + } +} + +void impAddB2DPolygonToGDIPlusGraphicsPathInteger(Gdiplus::GraphicsPath& rPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin) +{ + sal_uInt32 nCount(rPolygon.count()); + + if(nCount) + { + const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1); + const bool bControls(rPolygon.areControlPointsUsed()); + basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0)); + Gdiplus::Point aICurr(INT(aCurr.getX()), INT(aCurr.getY())); + + for(sal_uInt32 a(0); a < nEdgeCount; a++) + { + const sal_uInt32 nNextIndex((a + 1) % nCount); + const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex)); + const Gdiplus::Point aINext(INT(aNext.getX()), INT(aNext.getY())); + + if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex))) + { + const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a)); + const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex)); + + rPath.AddBezier( + aICurr, + Gdiplus::Point(INT(aCa.getX()), INT(aCa.getY())), + Gdiplus::Point(INT(aCb.getX()), INT(aCb.getY())), + aINext); + } + else + { + rPath.AddLine(aICurr, aINext); + } + + if(a + 1 < nEdgeCount) + { + aICurr = aINext; + + if(bNoLineJoin) + { + rPath.StartFigure(); + } } } } @@ -123,7 +173,7 @@ bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly aPath.StartFigure(); // #i101491# not needed for first run } - impAddB2DPolygonToGDIPlusGraphicsPath(aPath, rPolyPolygon.getB2DPolygon(a)); + impAddB2DPolygonToGDIPlusGraphicsPathReal(aPath, rPolyPolygon.getB2DPolygon(a), false); aPath.CloseFigure(); } @@ -152,11 +202,16 @@ bool WinSalGraphics::drawPolyLine(const basegfx::B2DPolygon& rPolygon, const bas Gdiplus::Color aTestColor(255, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor)); Gdiplus::Pen aTestPen(aTestColor, Gdiplus::REAL(rLineWidths.getX())); Gdiplus::GraphicsPath aPath; + bool bNoLineJoin(false); switch(eLineJoin) { default : // basegfx::B2DLINEJOIN_NONE : { + if(basegfx::fTools::more(rLineWidths.getX(), 0.0)) + { + bNoLineJoin = true; + } break; } case basegfx::B2DLINEJOIN_BEVEL : @@ -179,9 +234,16 @@ bool WinSalGraphics::drawPolyLine(const basegfx::B2DPolygon& rPolygon, const bas } } - impAddB2DPolygonToGDIPlusGraphicsPath(aPath, rPolygon); + if(nCount > 250 && basegfx::fTools::more(rLineWidths.getX(), 1.5)) + { + impAddB2DPolygonToGDIPlusGraphicsPathInteger(aPath, rPolygon, bNoLineJoin); + } + else + { + impAddB2DPolygonToGDIPlusGraphicsPathReal(aPath, rPolygon, bNoLineJoin); + } - if(rPolygon.isClosed()) + if(rPolygon.isClosed() && !bNoLineJoin) { // #i101491# needed to create the correct line joins aPath.CloseFigure(); |