diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-03-03 17:58:11 -0500 |
---|---|---|
committer | Tor Lillqvist <tml@collabora.com> | 2014-03-07 08:37:49 +0200 |
commit | 9ec1c955533c8506d996e95fa312e3463898dd09 (patch) | |
tree | 0541d1ad0e1b4c006c37b53d130d8b3e7f0101b1 /drawinglayer | |
parent | 46df72612da749dc6d58bad0f33c0f9e82d389b3 (diff) |
fdo#75260: Correctly draw double lines for both Writer and Calc.
Fix all sorts of incorrect double line handling in drawinglayer in order to
draw thick-thin double line types correctly. Also change handling of border
lines in writer tables. There are still some outstanding issues but it's
much better than how it was before.
Also realized that Word and Excel handle simple thin double lines differently;
Word varies widths of all of the lines and the gap whereas Excel only has one
fixed size for its double line. For this reason I decided to add a separate
double line type (DOUBLE_THIN) to handle Excel's double line.
(cherry picked from commit 2c62596cf264ef10749d8bfdb2bb2ebef2d98fbc)
Conflicts:
cui/source/tabpages/border.cxx
sc/qa/unit/subsequent_export-test.cxx
sc/source/ui/view/tabvwsha.cxx
sw/source/core/layout/paintfrm.cxx
xmloff/source/style/bordrhdl.cxx
Change-Id: Iaaa353b6e4f998b524262bea59260b4333e0cdb4
Reviewed-on: https://gerrit.libreoffice.org/8464
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'drawinglayer')
-rw-r--r-- | drawinglayer/source/primitive2d/borderlineprimitive2d.cxx | 120 | ||||
-rw-r--r-- | drawinglayer/source/processor2d/vclpixelprocessor2d.cxx | 4 |
2 files changed, 69 insertions, 55 deletions
diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx index 290c87acb0cf..67efa09da581 100644 --- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx @@ -28,6 +28,8 @@ #include <numeric> #include <algorithm> +namespace drawinglayer { + namespace { void moveLine(basegfx::B2DPolygon& rPoly, double fGap, const basegfx::B2DVector& rVector) @@ -44,10 +46,46 @@ void moveLine(basegfx::B2DPolygon& rPoly, double fGap, const basegfx::B2DVector& } } +primitive2d::Primitive2DReference makeHairLinePrimitive( + const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd, const basegfx::B2DVector& rVector, + const basegfx::BColor& rColor, double fGap) +{ + basegfx::B2DPolygon aPolygon; + aPolygon.append(rStart); + aPolygon.append(rEnd); + moveLine(aPolygon, fGap, rVector); + + return primitive2d::Primitive2DReference(new primitive2d::PolygonHairlinePrimitive2D(aPolygon, rColor)); } -namespace drawinglayer +primitive2d::Primitive2DReference makeSolidLinePrimitive( + const basegfx::B2DPolyPolygon& rClipRegion, const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd, + const basegfx::B2DVector& rVector, const basegfx::BColor& rColor, double fLineWidth, double fGap) { + const basegfx::B2DVector aPerpendicular = basegfx::getPerpendicular(rVector); + const basegfx::B2DVector aLineWidthOffset = ((fLineWidth + 1.0) * 0.5) * aPerpendicular; + + basegfx::B2DPolygon aPolygon; + aPolygon.append(rStart + aLineWidthOffset); + aPolygon.append(rEnd + aLineWidthOffset); + aPolygon.append(rEnd - aLineWidthOffset); + aPolygon.append(rStart - aLineWidthOffset); + aPolygon.setClosed(true); + + moveLine(aPolygon, fGap, rVector); + + basegfx::B2DPolyPolygon aClipped = + basegfx::tools::clipPolygonOnPolyPolygon(aPolygon, rClipRegion, true, false); + + if (aClipped.count()) + aPolygon = aClipped.getB2DPolygon(0); + + return primitive2d::Primitive2DReference( + new primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPolygon), rColor)); +} + +} + // fdo#49438: heuristic pseudo hack static bool lcl_UseHairline(double const fW, basegfx::B2DPoint const& rStart, basegfx::B2DPoint const& rEnd, @@ -139,66 +177,42 @@ namespace drawinglayer if(isOutsideUsed() && isInsideUsed()) { - basegfx::B2DPolygon aPolygon; const double fExt = getWidth(rViewInformation); // Extend a lot: it'll be clipped later. const basegfx::B2DPoint aTmpStart(getStart() - (fExt * aVector)); const basegfx::B2DPoint aTmpEnd(getEnd() + (fExt * aVector)); - // Get which is the line to show - double nWidth = getLeftWidth(); - basegfx::BColor aColor = getRGBColorLeft(); - - bool const bIsHairline = lcl_UseHairline( - nWidth, getStart(), getEnd(), rViewInformation); - nWidth = lcl_GetCorrectedWidth(nWidth, - getStart(), getEnd(), rViewInformation); + xRetval.realloc(2); - // distance is already scaled. - double fGap = mfDistance*8.0; - - if (bIsHairline) { - // create hairline primitive - aPolygon.append( getStart() ); - aPolygon.append( getEnd() ); - - basegfx::B2DPolygon aPolygon2 = aPolygon; - moveLine(aPolygon2, fGap, aVector); - - xRetval.realloc(2); - xRetval[0] = Primitive2DReference(new PolygonHairlinePrimitive2D( - aPolygon, - aColor)); - - xRetval[1] = Primitive2DReference(new PolygonHairlinePrimitive2D( - aPolygon2, - aColor)); + // "inside" line + double fWidth = getLeftWidth(); + basegfx::BColor aColor = getRGBColorLeft(); + bool bIsHairline = lcl_UseHairline( + fWidth, getStart(), getEnd(), rViewInformation); + fWidth = lcl_GetCorrectedWidth(fWidth, + getStart(), getEnd(), rViewInformation); + + if (bIsHairline) + xRetval[0] = makeHairLinePrimitive(getStart(), getEnd(), aVector, aColor, 0.0); + else + xRetval[0] = makeSolidLinePrimitive( + aClipRegion, aTmpStart, aTmpEnd, aVector, aColor, fWidth, 0.0); } - else - { - // create filled polygon primitive - const basegfx::B2DVector aLineWidthOffset(((nWidth + 1) * 0.5) * aPerpendicular); - aPolygon.append( aTmpStart + aLineWidthOffset ); - aPolygon.append( aTmpEnd + aLineWidthOffset ); - aPolygon.append( aTmpEnd - aLineWidthOffset ); - aPolygon.append( aTmpStart - aLineWidthOffset ); - aPolygon.setClosed( true ); - - basegfx::B2DPolyPolygon aClipped = basegfx::tools::clipPolygonOnPolyPolygon( - aPolygon, aClipRegion, true, false ); - - if ( aClipped.count() ) - aPolygon = aClipped.getB2DPolygon(0); - - basegfx::B2DPolygon aPolygon2 = aPolygon; - moveLine(aPolygon2, fGap, aVector); - - xRetval.realloc(2); - xRetval[0] = Primitive2DReference( - new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPolygon), aColor)); - xRetval[1] = Primitive2DReference( - new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPolygon2), aColor)); + { + // "outside" line + double fWidth = getRightWidth(); + basegfx::BColor aColor = getRGBColorRight(); + bool bIsHairline = lcl_UseHairline( + fWidth, getStart(), getEnd(), rViewInformation); + fWidth = lcl_GetCorrectedWidth(fWidth, + getStart(), getEnd(), rViewInformation); + + if (bIsHairline) + xRetval[1] = makeHairLinePrimitive(getStart(), getEnd(), aVector, aColor, mfDistance); + else + xRetval[1] = makeSolidLinePrimitive( + aClipRegion, aTmpStart, aTmpEnd, aVector, aColor, fWidth, mfDistance); } } else diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index 9552be3d4a14..203ce5f4a5a1 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -297,13 +297,13 @@ namespace drawinglayer switch (rSource.getStyle()) { case table::BorderLineStyle::SOLID: - case table::BorderLineStyle::DOUBLE: + case table::BorderLineStyle::DOUBLE_THIN: { const basegfx::BColor aLineColor = maBColorModifierStack.getModifiedColor(rSource.getRGBColorLeft()); double nThick = rtl::math::round(rSource.getLeftWidth()); - bool bDouble = rSource.getStyle() == table::BorderLineStyle::DOUBLE; + bool bDouble = rSource.getStyle() == table::BorderLineStyle::DOUBLE_THIN; basegfx::B2DPolygon aTarget; |