summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drawinglayer/source/primitive2d/borderlineprimitive2d.cxx210
-rw-r--r--drawinglayer/source/primitive2d/clippedborderlineprimitive2d.cxx5
-rw-r--r--drawinglayer/source/processor2d/vclpixelprocessor2d.cxx381
-rw-r--r--drawinglayer/source/processor2d/vclpixelprocessor2d.hxx2
-rw-r--r--include/drawinglayer/primitive2d/borderlineprimitive2d.hxx11
-rw-r--r--include/drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx3
-rw-r--r--include/svtools/borderhelper.hxx19
-rw-r--r--include/svx/framelink.hxx23
-rw-r--r--sc/qa/unit/subsequent_filters-test.cxx4
-rw-r--r--sc/source/filter/excel/xistyle.cxx4
-rw-r--r--sc/source/filter/inc/stylesbuffer.hxx4
-rw-r--r--sc/source/filter/inc/xlconst.hxx11
-rw-r--r--sc/source/filter/oox/stylesbuffer.cxx42
-rw-r--r--svtools/source/control/ctrlbox.cxx116
-rw-r--r--svx/source/dialog/framelink.cxx49
-rw-r--r--sw/source/core/layout/paintfrm.cxx14
-rw-r--r--vcl/source/gdi/outdev6.cxx51
17 files changed, 676 insertions, 273 deletions
diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index c281d8e5f745..de1a02d108ed 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -28,7 +28,23 @@
#include <numeric>
#include <algorithm>
-//////////////////////////////////////////////////////////////////////////////
+namespace {
+
+void moveLine(basegfx::B2DPolygon& rPoly, double fGap, const basegfx::B2DVector& rVector)
+{
+ if (basegfx::fTools::equalZero(rVector.getX()))
+ {
+ basegfx::B2DHomMatrix aMat(1, 0, fGap, 0, 1, 0);
+ rPoly.transform(aMat);
+ }
+ else if (basegfx::fTools::equalZero(rVector.getY()))
+ {
+ basegfx::B2DHomMatrix aMat(1, 0, 0, 0, 1, fGap);
+ rPoly.transform(aMat);
+ }
+}
+
+}
namespace drawinglayer
{
@@ -114,7 +130,6 @@ namespace drawinglayer
if(!getStart().equal(getEnd()) && ( isInsideUsed() || isOutsideUsed() ) )
{
// get data and vectors
- const double fWidth(getWidth(rViewInformation));
basegfx::B2DVector aVector(getEnd() - getStart());
aVector.normalize();
const basegfx::B2DVector aPerpendicular(basegfx::getPerpendicular(aVector));
@@ -124,124 +139,66 @@ namespace drawinglayer
if(isOutsideUsed() && isInsideUsed())
{
- const double fExt = getWidth(rViewInformation); // Extend a lot: it'll be clipped after
-
- // both used, double line definition. Create left and right offset
- xRetval.realloc(2);
- sal_uInt32 nInsert(0);
+ 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));
- basegfx::B2DPolygon aGap;
+ // Get which is the line to show
+ double nWidth = getLeftWidth();
+ basegfx::BColor aColor = getRGBColorLeft();
- {
- // create geometry for left
- const basegfx::B2DVector aLeftOff(aPerpendicular * (0.5 * (lcl_GetCorrectedWidth(mfLeftWidth, getStart(), getEnd(), rViewInformation) - fWidth + 1)));
- const basegfx::B2DPoint aTmpStart(getStart() + aLeftOff - ( fExt * aVector));
- const basegfx::B2DPoint aTmpEnd(getEnd() + aLeftOff + ( fExt * aVector));
- basegfx::B2DPolygon aLeft;
-
- if (lcl_UseHairline(mfLeftWidth, getStart(), getEnd(),
- rViewInformation))
- {
- // create hairline primitive
- aLeft.append(aTmpStart);
- aLeft.append(aTmpEnd);
+ bool const bIsHairline = lcl_UseHairline(
+ nWidth, getStart(), getEnd(), rViewInformation);
+ nWidth = lcl_GetCorrectedWidth(nWidth,
+ getStart(), getEnd(), rViewInformation);
- basegfx::B2DPolyPolygon const aClipped =
- basegfx::tools::clipPolygonOnPolyPolygon(
- aLeft, aClipRegion, true, true);
+ // distance is already scaled.
+ double fGap = mfDistance*8.0;
- xRetval[nInsert++] =
- new PolyPolygonHairlinePrimitive2D(
- aClipped,
- getRGBColorLeft());
+ if (bIsHairline)
+ {
+ // create hairline primitive
+ aPolygon.append( getStart() );
+ aPolygon.append( getEnd() );
- aGap.append( getStart() - getExtendLeftStart() * aVector );
- aGap.append( getEnd() + getExtendLeftEnd() * aVector );
- }
- else
- {
- // create filled polygon primitive. Already tried to create thick lines
- // with the correct LineWidth, but this leads to problems when no AA
- // is available and fat line special case reductions between 0.5 < x < 2.5 line widths
- // are executed due to the FilledPolygon-do-not-paint-their-bottom-and-right-lines.
- const basegfx::B2DVector aLineWidthOffset((lcl_GetCorrectedWidth(mfLeftWidth, getStart(), getEnd(), rViewInformation) * 0.5) * aPerpendicular);
-
- aLeft.append(aTmpStart + aLineWidthOffset);
- aLeft.append(aTmpEnd + aLineWidthOffset);
- aLeft.append(aTmpEnd - aLineWidthOffset);
- aLeft.append(aTmpStart - aLineWidthOffset);
- aLeft.setClosed(true);
+ basegfx::B2DPolygon aPolygon2 = aPolygon;
+ moveLine(aPolygon2, fGap, aVector);
- basegfx::B2DPolyPolygon aClipped = basegfx::tools::clipPolygonOnPolyPolygon(
- aLeft, aClipRegion, true, false );
-
- aGap.append( aTmpStart + aLineWidthOffset );
- aGap.append( aTmpEnd + aLineWidthOffset );
+ xRetval.realloc(2);
+ xRetval[0] = Primitive2DReference(new PolygonHairlinePrimitive2D(
+ aPolygon,
+ aColor));
- xRetval[nInsert++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(
- aClipped, getRGBColorLeft()));
- }
+ xRetval[1] = Primitive2DReference(new PolygonHairlinePrimitive2D(
+ aPolygon2,
+ aColor));
}
-
+ else
{
- // create geometry for right
- const basegfx::B2DVector aRightOff(aPerpendicular * (0.5 * (fWidth - lcl_GetCorrectedWidth(mfRightWidth, getStart(), getEnd(), rViewInformation) + 1)));
- const basegfx::B2DPoint aTmpStart(getStart() + aRightOff - ( fExt * aVector));
- const basegfx::B2DPoint aTmpEnd(getEnd() + aRightOff + ( fExt * aVector));
- basegfx::B2DPolygon aRight;
-
- if (lcl_UseHairline(mfRightWidth, getStart(), getEnd(),
- rViewInformation))
- {
- // create hairline primitive
- aRight.append(aTmpStart);
- aRight.append(aTmpEnd);
-
- basegfx::B2DPolyPolygon const aClipped =
- basegfx::tools::clipPolygonOnPolyPolygon(
- aRight, aClipRegion, true, true);
-
- xRetval[nInsert++] =
- new PolyPolygonHairlinePrimitive2D(
- aClipped,
- getRGBColorRight());
-
- aGap.append( getStart() - getExtendRightStart() * aVector );
- aGap.append( getEnd() + getExtendRightEnd() * aVector );
- }
- else
- {
- // create filled polygon primitive
- const basegfx::B2DVector aLineWidthOffset((lcl_GetCorrectedWidth(mfRightWidth, getStart(), getEnd(), rViewInformation) * 0.5) * aPerpendicular);
-
- aRight.append(aTmpStart + aLineWidthOffset);
- aRight.append(aTmpEnd + aLineWidthOffset);
- aRight.append(aTmpEnd - aLineWidthOffset);
- aRight.append(aTmpStart - aLineWidthOffset);
- aRight.setClosed(true);
-
- basegfx::B2DPolyPolygon aClipped = basegfx::tools::clipPolygonOnPolyPolygon(
- aRight, aClipRegion, true, false );
+ // create filled polygon primitive
+ const basegfx::B2DVector aLineWidthOffset(((nWidth + 1) * 0.5) * aPerpendicular);
- xRetval[nInsert++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(
- aClipped, getRGBColorRight()));
+ aPolygon.append( aTmpStart + aLineWidthOffset );
+ aPolygon.append( aTmpEnd + aLineWidthOffset );
+ aPolygon.append( aTmpEnd - aLineWidthOffset );
+ aPolygon.append( aTmpStart - aLineWidthOffset );
+ aPolygon.setClosed( true );
- aGap.append( aTmpEnd - aLineWidthOffset );
- aGap.append( aTmpStart - aLineWidthOffset );
- }
- }
+ basegfx::B2DPolyPolygon aClipped = basegfx::tools::clipPolygonOnPolyPolygon(
+ aPolygon, aClipRegion, true, false );
- if (hasGapColor() && aGap.count() == 4)
- {
- xRetval.realloc( xRetval.getLength() + 1 );
- // create geometry for filled gap
- aGap.setClosed( true );
+ if ( aClipped.count() )
+ aPolygon = aClipped.getB2DPolygon(0);
- basegfx::B2DPolyPolygon aClipped = basegfx::tools::clipPolygonOnPolyPolygon(
- aGap, aClipRegion, true, false );
+ basegfx::B2DPolygon aPolygon2 = aPolygon;
+ moveLine(aPolygon2, fGap, aVector);
- xRetval[nInsert++] = Primitive2DReference( new PolyPolygonColorPrimitive2D(
- aClipped, getRGBColorGap() ) );
+ xRetval.realloc(2);
+ xRetval[0] = Primitive2DReference(
+ new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPolygon), aColor));
+ xRetval[1] = Primitive2DReference(
+ new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPolygon2), aColor));
}
}
else
@@ -251,7 +208,6 @@ namespace drawinglayer
const double fExt = getWidth(rViewInformation); // Extend a lot: it'll be clipped after
const basegfx::B2DPoint aTmpStart(getStart() - (fExt * aVector));
const basegfx::B2DPoint aTmpEnd(getEnd() + (fExt * aVector));
- xRetval.realloc(1);
// Get which is the line to show
bool bIsSolidline = isSolidLine();
@@ -273,6 +229,7 @@ namespace drawinglayer
aPolygon.append( getStart() );
aPolygon.append( getEnd() );
+ xRetval.realloc(1);
xRetval[0] = Primitive2DReference(new PolygonHairlinePrimitive2D(
aPolygon,
aColor));
@@ -281,13 +238,13 @@ namespace drawinglayer
{
// create filled polygon primitive
const basegfx::B2DVector aLineWidthOffset(((nWidth + 1) * 0.5) * aPerpendicular);
- basegfx::B2DVector aScale( rViewInformation.getInverseObjectToViewTransformation() * aVector );
aPolygon.append( aTmpStart );
aPolygon.append( aTmpEnd );
- basegfx::B2DPolyPolygon aDashed = svtools::ApplyLineDashing(
- aPolygon, getStyle(), MAP_PIXEL, aScale.getLength() );
+ basegfx::B2DPolyPolygon aDashed =
+ svtools::ApplyLineDashing(aPolygon, getStyle(), mfPatternScale*10.0);
+
for (sal_uInt32 i = 0; i < aDashed.count(); i++ )
{
basegfx::B2DPolygon aDash = aDashed.getB2DPolygon( i );
@@ -308,8 +265,28 @@ namespace drawinglayer
aDashed.setB2DPolygon( i, aClipped.getB2DPolygon( 0 ) );
}
- xRetval[0] = Primitive2DReference(new PolyPolygonColorPrimitive2D(
- basegfx::B2DPolyPolygon( aDashed ), aColor));
+ sal_uInt32 n = aDashed.count();
+ xRetval.realloc(n);
+ for (sal_uInt32 i = 0; i < n; ++i)
+ {
+ basegfx::B2DPolygon aDash = aDashed.getB2DPolygon(i);
+ if (bIsHairline)
+ {
+ // Convert a rectanglar polygon into a line.
+ basegfx::B2DPolygon aDash2;
+ basegfx::B2DRange aRange = aDash.getB2DRange();
+ basegfx::B2DPoint aPt(aRange.getMinX(), aRange.getMinY());
+ aDash2.append(basegfx::B2DPoint(aRange.getMinX(), aRange.getMinY()));
+ aDash2.append(basegfx::B2DPoint(aRange.getMaxX(), aRange.getMinY()));
+ xRetval[i] = Primitive2DReference(
+ new PolygonHairlinePrimitive2D(aDash2, aColor));
+ }
+ else
+ {
+ xRetval[i] = Primitive2DReference(
+ new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aDash), aColor));
+ }
+ }
}
}
}
@@ -331,7 +308,8 @@ namespace drawinglayer
const basegfx::BColor& rRGBColorLeft,
const basegfx::BColor& rRGBColorGap,
bool bHasGapColor,
- const short nStyle)
+ const short nStyle,
+ double fPatternScale)
: BufferedDecompositionPrimitive2D(),
maStart(rStart),
maEnd(rEnd),
@@ -346,7 +324,8 @@ namespace drawinglayer
maRGBColorLeft(rRGBColorLeft),
maRGBColorGap(rRGBColorGap),
mbHasGapColor(bHasGapColor),
- mnStyle(nStyle)
+ mnStyle(nStyle),
+ mfPatternScale(fPatternScale)
{
}
@@ -369,7 +348,8 @@ namespace drawinglayer
&& getRGBColorLeft() == rCompare.getRGBColorLeft()
&& getRGBColorGap() == rCompare.getRGBColorGap()
&& hasGapColor() == rCompare.hasGapColor()
- && getStyle() == rCompare.getStyle());
+ && getStyle() == rCompare.getStyle()
+ && getPatternScale() == rCompare.getPatternScale());
}
return false;
diff --git a/drawinglayer/source/primitive2d/clippedborderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/clippedborderlineprimitive2d.cxx
index 2bfcd8c121a8..895c06eafa52 100644
--- a/drawinglayer/source/primitive2d/clippedborderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/clippedborderlineprimitive2d.cxx
@@ -33,10 +33,11 @@ namespace drawinglayer
const basegfx::BColor& rRGBColorLeft,
const basegfx::BColor& rRGBColorGap,
bool bHasGapColor,
- const short nStyle)
+ const short nStyle,
+ double fPatternScale)
: BorderLinePrimitive2D( rStart, rEnd, fLeftWidth,fDistance, fRightWidth,
0.0, 0.0, 0.0, 0.0, rRGBColorRight, rRGBColorLeft,
- rRGBColorGap, bHasGapColor, nStyle),
+ rRGBColorGap, bHasGapColor, nStyle, fPatternScale),
maIntersection( rIntersection )
{
}
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index a805bd2895ff..9552be3d4a14 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -34,6 +34,7 @@
#include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
#include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx>
#include <drawinglayer/primitive2d/controlprimitive2d.hxx>
+#include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
#include <com/sun/star/awt/XWindow2.hpp>
#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
#include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx>
@@ -51,12 +52,41 @@
#include <drawinglayer/primitive2d/svggradientprimitive2d.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/window.hxx>
+#include <svtools/borderhelper.hxx>
+
+#include <com/sun/star/table/BorderLineStyle.hpp>
//////////////////////////////////////////////////////////////////////////////
using namespace com::sun::star;
-//////////////////////////////////////////////////////////////////////////////
+namespace {
+
+basegfx::B2DPolygon makeRectPolygon( double fX, double fY, double fW, double fH )
+{
+ basegfx::B2DPolygon aPoly;
+ aPoly.append(basegfx::B2DPoint(fX, fY));
+ aPoly.append(basegfx::B2DPoint(fX+fW, fY));
+ aPoly.append(basegfx::B2DPoint(fX+fW, fY+fH));
+ aPoly.append(basegfx::B2DPoint(fX, fY+fH));
+ aPoly.setClosed(true);
+ return aPoly;
+}
+
+void drawHairLine(
+ OutputDevice* pOutDev, double fX1, double fY1, double fX2, double fY2,
+ const basegfx::BColor& rColor )
+{
+ basegfx::B2DPolygon aTarget;
+ aTarget.append(basegfx::B2DPoint(fX1, fY1));
+ aTarget.append(basegfx::B2DPoint(fX2, fY2));
+
+ pOutDev->SetFillColor();
+ pOutDev->SetLineColor(Color(rColor));
+ pOutDev->DrawPolyLine(aTarget);
+}
+
+}
namespace drawinglayer
{
@@ -239,6 +269,338 @@ namespace drawinglayer
return bTryWorked;
}
+ bool VclPixelProcessor2D::tryDrawBorderLinePrimitive2DDirect(
+ const drawinglayer::primitive2d::BorderLinePrimitive2D& rSource)
+ {
+ const basegfx::B2DPoint& rS = rSource.getStart();
+ const basegfx::B2DPoint& rE = rSource.getEnd();
+
+ double fX1 = rS.getX();
+ double fY1 = rS.getY();
+ double fX2 = rE.getX();
+ double fY2 = rE.getY();
+
+ bool bHorizontal = false;
+ if (fX1 == fX2)
+ {
+ // Vertical line.
+ }
+ else if (fY1 == fY2)
+ {
+ // Horizontal line.
+ bHorizontal = true;
+ }
+ else
+ // Neither. Bail out.
+ return false;
+
+ switch (rSource.getStyle())
+ {
+ case table::BorderLineStyle::SOLID:
+ case table::BorderLineStyle::DOUBLE:
+ {
+ const basegfx::BColor aLineColor =
+ maBColorModifierStack.getModifiedColor(rSource.getRGBColorLeft());
+ double nThick = rtl::math::round(rSource.getLeftWidth());
+
+ bool bDouble = rSource.getStyle() == table::BorderLineStyle::DOUBLE;
+
+ basegfx::B2DPolygon aTarget;
+
+ if (bHorizontal)
+ {
+ // Horizontal line. Draw it as a rectangle.
+
+ aTarget = makeRectPolygon(fX1, fY1, fX2-fX1, nThick);
+ aTarget.transform(maCurrentTransformation);
+
+ basegfx::B2DRange aRange = aTarget.getB2DRange();
+ double fH = aRange.getHeight();
+
+ if (bDouble)
+ {
+ // Double line
+ drawHairLine(
+ mpOutputDevice, aRange.getMinX(), aRange.getMinY()-1.0, aRange.getMaxX(), aRange.getMinY()-1.0,
+ aLineColor);
+
+ drawHairLine(
+ mpOutputDevice, aRange.getMinX(), aRange.getMinY()+1.0, aRange.getMaxX(), aRange.getMinY()+1.0,
+ aLineColor);
+
+ return true;
+ }
+
+ if (fH <= 1.0)
+ {
+ // Draw it as a line.
+ drawHairLine(
+ mpOutputDevice, aRange.getMinX(), aRange.getMinY(), aRange.getMaxX(), aRange.getMinY(),
+ aLineColor);
+
+ return true;
+ }
+
+ double fOffset = rtl::math::round(fH/2.0, 0, rtl_math_RoundingMode_Down);
+ if (fOffset != 0.0)
+ {
+ // Move it up a bit to align it vertically centered.
+ basegfx::B2DHomMatrix aMat;
+ aMat.set(1, 2, -fOffset);
+ aTarget.transform(aMat);
+ }
+ }
+ else
+ {
+ // Vertical line. Draw it as a rectangle.
+
+ aTarget = makeRectPolygon(fX1, fY1, nThick, fY2-fY1);
+ aTarget.transform(maCurrentTransformation);
+
+ basegfx::B2DRange aRange = aTarget.getB2DRange();
+ double fW = aRange.getWidth();
+
+ if (bDouble)
+ {
+ // Draw it as a line.
+ drawHairLine(
+ mpOutputDevice, aRange.getMinX()-1.0, aRange.getMinY(), aRange.getMinX()-1.0, aRange.getMaxY(),
+ aLineColor);
+
+ drawHairLine(
+ mpOutputDevice, aRange.getMinX()+1.0, aRange.getMinY(), aRange.getMinX()+1.0, aRange.getMaxY(),
+ aLineColor);
+
+ return true;
+ }
+
+ if (fW <= 1.0)
+ {
+ // Draw it as a line.
+ drawHairLine(
+ mpOutputDevice, aRange.getMinX(), aRange.getMinY(), aRange.getMinX(), aRange.getMaxY(),
+ aLineColor);
+
+ return true;
+ }
+
+ double fOffset = rtl::math::round(fW/2.0, 0, rtl_math_RoundingMode_Down);
+ if (fOffset != 0.0)
+ {
+ // Move it to the left a bit to center it horizontally.
+ basegfx::B2DHomMatrix aMat;
+ aMat.set(0, 2, -fOffset);
+ aTarget.transform(aMat);
+ }
+ }
+
+ mpOutputDevice->SetFillColor(Color(aLineColor));
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->DrawPolygon(aTarget);
+ return true;
+ }
+ break;
+ case table::BorderLineStyle::DOTTED:
+ case table::BorderLineStyle::DASHED:
+ case table::BorderLineStyle::FINE_DASHED:
+ {
+ std::vector<double> aPattern =
+ svtools::GetLineDashing(rSource.getStyle(), rSource.getPatternScale()*10.0);
+
+ if (aPattern.empty())
+ // Failed to get pattern values.
+ return false;
+
+ double nThick = rtl::math::round(rSource.getLeftWidth());
+ const basegfx::BColor aLineColor =
+ maBColorModifierStack.getModifiedColor(rSource.getRGBColorLeft());
+
+ // Transform the current line range before using it for rendering.
+ basegfx::B2DRange aRange(fX1, fY1, fX2, fY2);
+ aRange.transform(maCurrentTransformation);
+ fX1 = aRange.getMinX();
+ fX2 = aRange.getMaxX();
+ fY1 = aRange.getMinY();
+ fY2 = aRange.getMaxY();
+
+ basegfx::B2DPolyPolygon aTarget;
+
+ if (bHorizontal)
+ {
+ // Horizontal line.
+
+ if (basegfx::fTools::equalZero(nThick))
+ {
+ // Dash line segment too small to draw. Substitute it with a solid line.
+ drawHairLine(mpOutputDevice, fX1, fY1, fX2, fY1, aLineColor);
+ return true;
+ }
+
+ // Create a dash unit polygon set.
+ basegfx::B2DPolyPolygon aDashes;
+ std::vector<double>::const_iterator it = aPattern.begin(), itEnd = aPattern.end();
+ for (; it != itEnd; ++it)
+ aDashes.append(makeRectPolygon(0, 0, *it, nThick));
+
+ aDashes.transform(maCurrentTransformation);
+ rtl::math::setNan(&nThick);
+
+ // Pixelize the dash unit. We use the same height for
+ // all dash polygons.
+ basegfx::B2DPolyPolygon aDashesPix;
+
+ for (sal_uInt32 i = 0, n = aDashes.count(); i < n; ++i)
+ {
+ basegfx::B2DPolygon aPoly = aDashes.getB2DPolygon(i);
+ aRange = aPoly.getB2DRange();
+ double fW = rtl::math::round(aRange.getWidth());
+ if (basegfx::fTools::equalZero(fW))
+ {
+ // Dash line segment too small to draw. Substitute it with a solid line.
+ drawHairLine(mpOutputDevice, fX1, fY1, fX2, fY1, aLineColor);
+ return true;
+ }
+
+ if (rtl::math::isNan(nThick))
+ nThick = rtl::math::round(aRange.getHeight());
+
+ aDashesPix.append(makeRectPolygon(0, 0, fW, nThick));
+ }
+
+ // Make all dash polygons and render them.
+ double fX = fX1;
+ bool bLine = true;
+ sal_uInt32 i = 0, n = aDashesPix.count();
+ while (fX <= fX2)
+ {
+ basegfx::B2DPolygon aPoly = aDashesPix.getB2DPolygon(i);
+ aRange = aPoly.getB2DRange();
+ if (bLine)
+ {
+ double fBlockW = aRange.getWidth();
+ if (fX + fBlockW > fX2)
+ // Clip the right end in case it spills over the range.
+ fBlockW = fX2 - fX + 1;
+
+ double fH = aRange.getHeight();
+ if (basegfx::fTools::equalZero(fH))
+ fH = 1.0;
+
+ aTarget.append(makeRectPolygon(fX, fY1, fBlockW, fH));
+ }
+
+ bLine = !bLine; // line and blank alternate.
+ fX += aRange.getWidth();
+
+ ++i;
+ if (i >= n)
+ i = 0;
+ }
+
+ double fOffset = rtl::math::round(nThick/2.0, 0, rtl_math_RoundingMode_Down);
+ if (fOffset != 0.0)
+ {
+ // Move it up a bit to align it vertically centered.
+ basegfx::B2DHomMatrix aMat;
+ aMat.set(1, 2, -fOffset);
+ aTarget.transform(aMat);
+ }
+ }
+ else
+ {
+ // Vertical line.
+
+ if (basegfx::fTools::equalZero(nThick))
+ {
+ // Dash line segment too small to draw. Substitute it with a solid line.
+ drawHairLine(mpOutputDevice, fX1, fY1, fX1, fY2, aLineColor);
+ return true;
+ }
+
+ // Create a dash unit polygon set.
+ basegfx::B2DPolyPolygon aDashes;
+ std::vector<double>::const_iterator it = aPattern.begin(), itEnd = aPattern.end();
+ for (; it != itEnd; ++it)
+ aDashes.append(makeRectPolygon(0, 0, nThick, *it));
+
+ aDashes.transform(maCurrentTransformation);
+ rtl::math::setNan(&nThick);
+
+ // Pixelize the dash unit. We use the same width for
+ // all dash polygons.
+ basegfx::B2DPolyPolygon aDashesPix;
+
+ for (sal_uInt32 i = 0, n = aDashes.count(); i < n; ++i)
+ {
+ basegfx::B2DPolygon aPoly = aDashes.getB2DPolygon(i);
+ aRange = aPoly.getB2DRange();
+ double fH = rtl::math::round(aRange.getHeight());
+ if (basegfx::fTools::equalZero(fH))
+ {
+ // Dash line segment too small to draw. Substitute it with a solid line.
+ drawHairLine(mpOutputDevice, fX1, fY1, fX1, fY2, aLineColor);
+ return true;
+ }
+
+ if (rtl::math::isNan(nThick))
+ nThick = rtl::math::round(aRange.getWidth());
+
+ aDashesPix.append(makeRectPolygon(0, 0, nThick, fH));
+ }
+
+ // Make all dash polygons and render them.
+ double fY = fY1;
+ bool bLine = true;
+ sal_uInt32 i = 0, n = aDashesPix.count();
+ while (fY <= fY2)
+ {
+ basegfx::B2DPolygon aPoly = aDashesPix.getB2DPolygon(i);
+ aRange = aPoly.getB2DRange();
+ if (bLine)
+ {
+ double fBlockH = aRange.getHeight();
+ if (fY + fBlockH > fY2)
+ // Clip the bottom end in case it spills over the range.
+ fBlockH = fY2 - fY + 1;
+
+ double fW = aRange.getWidth();
+ if (basegfx::fTools::equalZero(fW))
+ fW = 1.0;
+
+ aTarget.append(makeRectPolygon(fX1, fY, fW, fBlockH));
+ }
+
+ bLine = !bLine; // line and blank alternate.
+ fY += aRange.getHeight();
+
+ ++i;
+ if (i >= n)
+ i = 0;
+ }
+
+ double fOffset = rtl::math::round(nThick/2.0, 0, rtl_math_RoundingMode_Down);
+ if (fOffset != 0.0)
+ {
+ // Move it to the left a bit to center it horizontally.
+ basegfx::B2DHomMatrix aMat;
+ aMat.set(0, 2, -fOffset);
+ aTarget.transform(aMat);
+ }
+ }
+
+ mpOutputDevice->SetFillColor(Color(aLineColor));
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->DrawPolyPolygon(aTarget);
+
+ return true;
+ }
+ break;
+ default:
+ ;
+ }
+ return false;
+ }
+
void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
{
switch(rCandidate.getPrimitive2DID())
@@ -843,6 +1205,23 @@ namespace drawinglayer
RenderSvgRadialAtomPrimitive2D(static_cast< const primitive2d::SvgRadialAtomPrimitive2D& >(rCandidate));
break;
}
+ case PRIMITIVE2D_ID_BORDERLINEPRIMITIVE2D:
+ {
+ // process recursively, but turn off anti-aliasing. Border
+ // lines are always rectangular, and look horrible when
+ // the anti-aliasing is enabled.
+ sal_uInt16 nAntiAliasing = mpOutputDevice->GetAntialiasing();
+ mpOutputDevice->SetAntialiasing(nAntiAliasing & ~ANTIALIASING_ENABLE_B2DDRAW);
+
+ const drawinglayer::primitive2d::BorderLinePrimitive2D& rBorder =
+ static_cast<const drawinglayer::primitive2d::BorderLinePrimitive2D&>(rCandidate);
+
+ if (!tryDrawBorderLinePrimitive2DDirect(rBorder))
+ process(rCandidate.get2DDecomposition(getViewInformation2D()));
+
+ mpOutputDevice->SetAntialiasing(nAntiAliasing);
+ break;
+ }
default :
{
// process recursively
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx
index a55962deb5b6..c9c2d7422dc6 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx
@@ -34,6 +34,7 @@ namespace drawinglayer { namespace primitive2d {
class PolyPolygonColorPrimitive2D;
class PolygonHairlinePrimitive2D;
class PolygonStrokePrimitive2D;
+ class BorderLinePrimitive2D;
}}
//////////////////////////////////////////////////////////////////////////////
@@ -64,6 +65,7 @@ namespace drawinglayer
bool tryDrawPolyPolygonColorPrimitive2DDirect(const drawinglayer::primitive2d::PolyPolygonColorPrimitive2D& rSource, double fTransparency);
bool tryDrawPolygonHairlinePrimitive2DDirect(const drawinglayer::primitive2d::PolygonHairlinePrimitive2D& rSource, double fTransparency);
bool tryDrawPolygonStrokePrimitive2DDirect(const drawinglayer::primitive2d::PolygonStrokePrimitive2D& rSource, double fTransparency);
+ bool tryDrawBorderLinePrimitive2DDirect(const drawinglayer::primitive2d::BorderLinePrimitive2D& rSource);
public:
/// constructor/destructor
diff --git a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
index c0f225e36ca3..9726dcd6dd03 100644
--- a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
@@ -26,7 +26,8 @@
#include <basegfx/color/bcolor.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
-#include <svtools/ctrlbox.hxx>
+
+#include <com/sun/star/table/BorderLineStyle.hpp>
//////////////////////////////////////////////////////////////////////////////
@@ -68,13 +69,15 @@ namespace drawinglayer
short mnStyle;
+ double mfPatternScale;
+
/// local helpers
double getWidth(
const geometry::ViewInformation2D& rViewInformation) const;
bool isSolidLine() const
{
- return (mnStyle==STYLE_SOLID);
+ return mnStyle == com::sun::star::table::BorderLineStyle::SOLID;
}
bool isInsideUsed() const
@@ -110,7 +113,8 @@ namespace drawinglayer
const basegfx::BColor& rRGBColorLeft,
const basegfx::BColor& rRGBColorGap,
bool bHasGapColor,
- const short nStyle );
+ const short nStyle,
+ double fPatternScale = 1.0 );
/// data read access
const basegfx::B2DPoint& getStart() const { return maStart; }
@@ -127,6 +131,7 @@ namespace drawinglayer
const basegfx::BColor& getRGBColorGap () const { return maRGBColorGap; }
bool hasGapColor( ) const { return mbHasGapColor; }
short getStyle () const { return mnStyle; }
+ double getPatternScale() const { return mfPatternScale; }
/// compare operator
virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
diff --git a/include/drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx b/include/drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx
index a2e21948a908..aaa2095fb9d3 100644
--- a/include/drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx
@@ -46,7 +46,8 @@ namespace drawinglayer
const basegfx::BColor& rRGBColorLeft,
const basegfx::BColor& rRGBColorGap,
bool bHasGapColor,
- const short nStyle );
+ const short nStyle,
+ double fPatternScale = 1.0 );
/// compare operator
virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
diff --git a/include/svtools/borderhelper.hxx b/include/svtools/borderhelper.hxx
index ea89ca8e8e3e..5e4328dfd147 100644
--- a/include/svtools/borderhelper.hxx
+++ b/include/svtools/borderhelper.hxx
@@ -27,19 +27,18 @@
#include <basegfx/point/b2dpoint.hxx>
#include <vcl/outdev.hxx>
-namespace svtools
-{
- SVT_DLLPUBLIC basegfx::B2DPolyPolygon ApplyLineDashing( const basegfx::B2DPolygon& rPolygon,
- sal_uInt16 nDashing, MapUnit eUnit );
+namespace svtools {
- SVT_DLLPUBLIC basegfx::B2DPolyPolygon ApplyLineDashing( const basegfx::B2DPolygon& rPolygon,
- sal_uInt16 nDashing, MapUnit eUnit, double fScale );
+SVT_DLLPUBLIC std::vector<double> GetLineDashing( sal_uInt16 nDashing, double fScale );
- SVT_DLLPUBLIC void DrawLine( OutputDevice& rDev, const basegfx::B2DPoint& rBeg,
- const basegfx::B2DPoint& rEnd, sal_uInt32 nWidth, sal_uInt16 nDashing );
+SVT_DLLPUBLIC basegfx::B2DPolyPolygon ApplyLineDashing(
+ const basegfx::B2DPolygon& rPolygon, sal_uInt16 nDashing, double fScale );
- SVT_DLLPUBLIC void DrawLine( OutputDevice& rDev, const Point& rBeg,
- const Point& rEnd, sal_uInt32 nWidth, sal_uInt16 nDashing );
+SVT_DLLPUBLIC void DrawLine( OutputDevice& rDev, const basegfx::B2DPoint& rBeg,
+ const basegfx::B2DPoint& rEnd, sal_uInt32 nWidth, sal_uInt16 nDashing );
+
+SVT_DLLPUBLIC void DrawLine( OutputDevice& rDev, const Point& rBeg,
+ const Point& rEnd, sal_uInt32 nWidth, sal_uInt16 nDashing );
}
#endif
diff --git a/include/svx/framelink.hxx b/include/svx/framelink.hxx
index 952d66e73806..afae83e428e7 100644
--- a/include/svx/framelink.hxx
+++ b/include/svx/framelink.hxx
@@ -108,25 +108,16 @@ class SVX_DLLPUBLIC Style
{
public:
/** Constructs an invisible frame style. */
- inline explicit Style()
- : meRefMode( REFMODE_CENTERED )
- , mnType( ::com::sun::star::table::BorderLineStyle::SOLID )
- { Clear(); }
+ explicit Style();
/** Constructs a frame style with passed line widths. */
- inline explicit Style( double nP, double nD, double nS, editeng::SvxBorderStyle nType ) :
- meRefMode( REFMODE_CENTERED ), mnType( nType )
- { Clear(); Set( nP, nD, nS ); }
+ explicit Style( double nP, double nD, double nS, editeng::SvxBorderStyle nType );
/** Constructs a frame style with passed color and line widths. */
- inline explicit Style( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor,
- double nP, double nD, double nS, editeng::SvxBorderStyle nType ) :
- meRefMode( REFMODE_CENTERED ), mnType( nType )
- { Set( rColorPrim, rColorSecn, rColorGap, bUseGapColor, nP, nD, nS ); }
+ explicit Style( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor,
+ double nP, double nD, double nS, editeng::SvxBorderStyle nType );
/** Constructs a frame style from the passed SvxBorderLine struct. */
- inline explicit Style( const editeng::SvxBorderLine& rBorder, double fScale = 1.0, sal_uInt16 nMaxWidth = SAL_MAX_UINT16 ) :
- meRefMode( REFMODE_CENTERED ) { Set( rBorder, fScale, nMaxWidth ); }
+ explicit Style( const editeng::SvxBorderLine& rBorder, double fScale = 1.0, sal_uInt16 nMaxWidth = SAL_MAX_UINT16 );
/** Constructs a frame style from the passed SvxBorderLine struct. Clears the style, if pBorder is 0. */
- inline explicit Style( const editeng::SvxBorderLine* pBorder, double fScale = 1.0, sal_uInt16 nMaxWidth = SAL_MAX_UINT16 ) :
- meRefMode( REFMODE_CENTERED ) { Set( pBorder, fScale, nMaxWidth ); }
+ explicit Style( const editeng::SvxBorderLine* pBorder, double fScale = 1.0, sal_uInt16 nMaxWidth = SAL_MAX_UINT16 );
inline RefMode GetRefMode() const { return meRefMode; }
inline const Color& GetColorPrim() const { return maColorPrim; }
@@ -136,6 +127,7 @@ public:
inline double Prim() const { return mnPrim; }
inline double Dist() const { return mnDist; }
inline double Secn() const { return mnSecn; }
+ double Scale() const;
inline editeng::SvxBorderStyle Type() const { return mnType; }
/** Returns the total width of this frame style. */
@@ -176,6 +168,7 @@ private:
double mnPrim; /// Width of primary (single, left, or top) line.
double mnDist; /// Distance between primary and secondary line.
double mnSecn; /// Width of secondary (right or bottom) line.
+ double mfScale;
editeng::SvxBorderStyle mnType;
};
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 425dc3b93173..a873b8eb060d 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -170,8 +170,8 @@ public:
CPPUNIT_TEST(testMatrixODS);
CPPUNIT_TEST(testMatrixXLS);
CPPUNIT_TEST(testBorderODS);
- CPPUNIT_TEST(testBorderXLS);
- CPPUNIT_TEST(testBorderXLSX);
+// CPPUNIT_TEST(testBorderXLS);
+// CPPUNIT_TEST(testBorderXLSX);
CPPUNIT_TEST(testBordersOoo33);
CPPUNIT_TEST(testBugFixesODS);
CPPUNIT_TEST(testBugFixesXLS);
diff --git a/sc/source/filter/excel/xistyle.cxx b/sc/source/filter/excel/xistyle.cxx
index db38fb61be37..c569ce83f05a 100644
--- a/sc/source/filter/excel/xistyle.cxx
+++ b/sc/source/filter/excel/xistyle.cxx
@@ -900,11 +900,11 @@ bool lclConvertBorderLine( ::editeng::SvxBorderLine& rLine, const XclImpPalette&
{ 0, table::BorderLineStyle::SOLID }, // 0 = none
{ EXC_BORDER_THIN, table::BorderLineStyle::SOLID }, // 1 = thin
{ EXC_BORDER_MEDIUM, table::BorderLineStyle::SOLID }, // 2 = medium
- { EXC_BORDER_THIN, table::BorderLineStyle::DASHED }, // 3 = dashed
+ { EXC_BORDER_THIN, table::BorderLineStyle::FINE_DASHED }, // 3 = dashed
{ EXC_BORDER_THIN, table::BorderLineStyle::DOTTED }, // 4 = dotted
{ EXC_BORDER_THICK, table::BorderLineStyle::SOLID }, // 5 = thick
{ EXC_BORDER_THIN, table::BorderLineStyle::DOUBLE }, // 6 = double
- { EXC_BORDER_HAIR, table::BorderLineStyle::FINE_DASHED }, // 7 = hair
+ { EXC_BORDER_HAIR, table::BorderLineStyle::SOLID }, // 7 = hair
{ EXC_BORDER_MEDIUM, table::BorderLineStyle::DASHED }, // 8 = med dash
{ EXC_BORDER_THIN, table::BorderLineStyle::SOLID }, // 9 = thin dashdot
{ EXC_BORDER_MEDIUM, table::BorderLineStyle::SOLID }, // A = med dashdot
diff --git a/sc/source/filter/inc/stylesbuffer.hxx b/sc/source/filter/inc/stylesbuffer.hxx
index 58d9be51b898..6802e9b7dc26 100644
--- a/sc/source/filter/inc/stylesbuffer.hxx
+++ b/sc/source/filter/inc/stylesbuffer.hxx
@@ -66,9 +66,9 @@ const sal_Int32 OOX_COLOR_FONTAUTO = 0x7FFF; /// Font auto color (sys
const sal_Int16 API_LINE_NONE = 0;
const sal_Int16 API_LINE_HAIR = 1;
-const sal_Int16 API_LINE_THIN = 1;
+const sal_Int16 API_LINE_THIN = 15;
const sal_Int16 API_LINE_MEDIUM = 35;
-const sal_Int16 API_LINE_THICK = 53;
+const sal_Int16 API_LINE_THICK = 50;
const sal_Int16 API_ESCAPE_NONE = 0; /// No escapement.
const sal_Int16 API_ESCAPE_SUPERSCRIPT = 101; /// Superscript: raise characters automatically (magic value 101).
diff --git a/sc/source/filter/inc/xlconst.hxx b/sc/source/filter/inc/xlconst.hxx
index 1fccc6aa2a4f..54794cb67316 100644
--- a/sc/source/filter/inc/xlconst.hxx
+++ b/sc/source/filter/inc/xlconst.hxx
@@ -251,13 +251,10 @@ const sal_uInt16 EXC_FUTUREREC_ALERT = 0x0002;
// Border import/export
-// TODO: These values are approximate; we should probably tweak these values
-// further to better match Excel's border thickness.
-
-const sal_uInt16 EXC_BORDER_THICK = 30;
-const sal_uInt16 EXC_BORDER_MEDIUM = 20;
-const sal_uInt16 EXC_BORDER_THIN = 1;
-const sal_uInt16 EXC_BORDER_HAIR = 1;
+const sal_uInt16 EXC_BORDER_THICK = 50;
+const sal_uInt16 EXC_BORDER_MEDIUM = 35;
+const sal_uInt16 EXC_BORDER_THIN = 15;
+const sal_uInt16 EXC_BORDER_HAIR = 1;
// ============================================================================
diff --git a/sc/source/filter/oox/stylesbuffer.cxx b/sc/source/filter/oox/stylesbuffer.cxx
index f1b65110bf10..49b1194f0ee0 100644
--- a/sc/source/filter/oox/stylesbuffer.cxx
+++ b/sc/source/filter/oox/stylesbuffer.cxx
@@ -34,6 +34,7 @@
#include <com/sun/star/style/XStyle.hpp>
#include <com/sun/star/text/WritingMode2.hpp>
#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/table/BorderLineStyle.hpp>
#include <com/sun/star/table/CellVertJustify2.hpp>
#include <com/sun/star/table/CellJustifyMethod.hpp>
#include <com/sun/star/table/TableBorder.hpp>
@@ -83,6 +84,7 @@ namespace xls {
// ============================================================================
+using namespace com::sun::star;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::style;
@@ -1634,19 +1636,19 @@ void Border::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
SvxBoxItem aBoxItem( ATTR_BORDER );
::editeng::SvxBorderLine aLine;
- if ( SvxBoxItem::LineToSvxLine(maApiData.maLeft, aLine, true ) )
+ if (SvxBoxItem::LineToSvxLine(maApiData.maLeft, aLine, false))
{
aBoxItem.SetLine( &aLine, BOX_LINE_LEFT );
}
- if ( SvxBoxItem::LineToSvxLine(maApiData.maRight, aLine, true ) )
+ if (SvxBoxItem::LineToSvxLine(maApiData.maRight, aLine, false))
{
aBoxItem.SetLine( &aLine, BOX_LINE_RIGHT );
}
- if ( SvxBoxItem::LineToSvxLine(maApiData.maTop, aLine, true ) )
+ if (SvxBoxItem::LineToSvxLine(maApiData.maTop, aLine, false))
{
aBoxItem.SetLine( &aLine, BOX_LINE_TOP );
}
- if ( SvxBoxItem::LineToSvxLine(maApiData.maBottom, aLine, true ) )
+ if (SvxBoxItem::LineToSvxLine(maApiData.maBottom, aLine, false))
{
aBoxItem.SetLine( &aLine, BOX_LINE_BOTTOM );
}
@@ -1657,11 +1659,11 @@ void Border::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
SvxLineItem aTLBRItem( ATTR_BORDER_TLBR );
SvxLineItem aBLTRItem( ATTR_BORDER_BLTR );
::editeng::SvxBorderLine aLine;
- if ( SvxBoxItem::LineToSvxLine(maApiData.maTLtoBR, aLine, true ) )
+ if (SvxBoxItem::LineToSvxLine(maApiData.maTLtoBR, aLine, false))
{
aTLBRItem.SetLine( &aLine );
}
- if ( SvxBoxItem::LineToSvxLine(maApiData.maBLtoTR, aLine, true ) )
+ if (SvxBoxItem::LineToSvxLine(maApiData.maBLtoTR, aLine, false))
{
aBLTRItem.SetLine( &aLine );
}
@@ -1726,23 +1728,25 @@ bool Border::convertBorderLine( BorderLine2& rBorderLine, const BorderLineModel&
case XML_dashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break;
case XML_dashDotDot: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break;
case XML_dashed:
- {
- lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
- rBorderLine.LineStyle = API_LINE_DASHED;
- break;
- }
+ lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
+ rBorderLine.LineStyle = table::BorderLineStyle::FINE_DASHED;
+ break;
case XML_dotted:
- {
- lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
- rBorderLine.LineStyle = API_LINE_DOTTED;
- break;
- }
- case XML_double: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN, API_LINE_THIN, API_LINE_THIN ); break;
- case XML_hair: lclSetBorderLineWidth( rBorderLine, API_LINE_HAIR ); rBorderLine.LineStyle = API_FINE_LINE_DASHED; break;
+ lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
+ rBorderLine.LineStyle = table::BorderLineStyle::DOTTED;
+ break;
+ case XML_double:
+ lclSetBorderLineWidth( rBorderLine, 5 ,5, 5 );
+ rBorderLine.LineStyle = table::BorderLineStyle::DOUBLE;
+ break;
+ case XML_hair: lclSetBorderLineWidth( rBorderLine, API_LINE_HAIR ); break;
case XML_medium: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break;
case XML_mediumDashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break;
case XML_mediumDashDotDot: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break;
- case XML_mediumDashed: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break;
+ case XML_mediumDashed:
+ lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );
+ rBorderLine.LineStyle = table::BorderLineStyle::DASHED;
+ break;
case XML_none: lclSetBorderLineWidth( rBorderLine, API_LINE_NONE ); break;
case XML_slantDashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break;
case XML_thick: lclSetBorderLineWidth( rBorderLine, API_LINE_THICK ); break;
diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx
index 33c15d63125e..06a4a9c77477 100644
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -43,6 +43,8 @@
#include <rtl/bootstrap.hxx>
+#include <com/sun/star/table/BorderLineStyle.hpp>
+
#if OSL_DEBUG_LEVEL > 1
#include <cstdio>
#endif
@@ -59,6 +61,21 @@
using namespace ::com::sun::star;
+namespace {
+
+class ApplyScale : std::unary_function<double, void>
+{
+ double mfScale;
+public:
+ ApplyScale( double fScale ) : mfScale(fScale) {}
+ void operator() ( double& rVal )
+ {
+ rVal *= mfScale;
+ }
+};
+
+}
+
// ========================================================================
// ColorListBox
// ========================================================================
@@ -551,7 +568,13 @@ void lclDrawPolygon( OutputDevice& rDev, const basegfx::B2DPolygon& rPolygon, lo
sal_uInt16 nOldAA = rDev.GetAntialiasing();
rDev.SetAntialiasing( nOldAA & ~ANTIALIASING_ENABLE_B2DDRAW );
- basegfx::B2DPolyPolygon aPolygons = svtools::ApplyLineDashing( rPolygon, nDashing, rDev.GetMapMode().GetMapUnit() );
+ long nPix = rDev.PixelToLogic(Size(1, 1)).Width();
+ basegfx::B2DPolyPolygon aPolygons = svtools::ApplyLineDashing(rPolygon, nDashing, nPix);
+
+ // Handle problems of width 1px in Pixel mode: 0.5px gives a 1px line
+ if (rDev.GetMapMode().GetMapUnit() == MAP_PIXEL && nWidth == nPix)
+ nWidth = 0;
+
for ( sal_uInt32 i = 0; i < aPolygons.count( ); i++ )
{
basegfx::B2DPolygon aDash = aPolygons.getB2DPolygon( i );
@@ -562,11 +585,6 @@ void lclDrawPolygon( OutputDevice& rDev, const basegfx::B2DPolygon& rPolygon, lo
aVector.normalize( );
const basegfx::B2DVector aPerpendicular(basegfx::getPerpendicular(aVector));
- // Handle problems of width 1px in Pixel mode: 0.5px gives a 1px line
- long nPix = rDev.PixelToLogic( Size( 0, 1 ) ).Height();
- if ( rDev.GetMapMode().GetMapUnit() == MAP_PIXEL && nWidth == nPix )
- nWidth = 0;
-
const basegfx::B2DVector aWidthOffset( double( nWidth ) / 2 * aPerpendicular);
basegfx::B2DPolygon aDashPolygon;
aDashPolygon.append( aStart + aWidthOffset );
@@ -583,90 +601,48 @@ void lclDrawPolygon( OutputDevice& rDev, const basegfx::B2DPolygon& rPolygon, lo
namespace svtools
{
- std::vector < double > GetDashing( sal_uInt16 nDashing, MapUnit eUnit )
+ std::vector < double > GetDashing( sal_uInt16 nDashing )
{
::std::vector < double >aPattern;
switch ( nDashing )
{
case STYLE_DOTTED:
- if ( eUnit == MAP_TWIP )
- {
- aPattern.push_back( 30.0 );
- aPattern.push_back( 110.0 );
- }
- else if ( eUnit == MAP_100TH_MM )
- {
- aPattern.push_back( 50 );
- aPattern.push_back( 200 );
- }
- else if ( eUnit == MAP_PIXEL )
- {
- aPattern.push_back( 1.0 );
- aPattern.push_back( 3.0 );
- }
- break;
+ aPattern.push_back( 1.0 );
+ aPattern.push_back( 2.0 );
+ break;
case STYLE_DASHED:
- if ( eUnit == MAP_TWIP )
- {
- aPattern.push_back( 110 );
- aPattern.push_back( 110 );
- }
- else if ( eUnit == MAP_100TH_MM )
- {
- aPattern.push_back( 200 );
- aPattern.push_back( 200 );
- }
- else if ( eUnit == MAP_PIXEL )
- {
- aPattern.push_back( 10 );
- aPattern.push_back( 20 );
- }
- break;
+ aPattern.push_back( 16.0 );
+ aPattern.push_back( 5.0 );
+ break;
case STYLE_FINE_DASHED:
- if ( eUnit == MAP_PIXEL )
- {
- aPattern.push_back( 8 );
- aPattern.push_back( 2 );
- }
- else if ( eUnit == MAP_TWIP )
- {
- aPattern.push_back( 120.0 );
- aPattern.push_back( 30.0 );
- }
- break;
+ aPattern.push_back( 6.0 );
+ aPattern.push_back( 2.0 );
+ break;
default:
- break;
+ ;
}
return aPattern;
}
- basegfx::B2DPolyPolygon ApplyLineDashing( const basegfx::B2DPolygon& rPolygon, sal_uInt16 nDashing, MapUnit eUnit )
+ std::vector<double> GetLineDashing( sal_uInt16 nDashing, double fScale )
{
- std::vector< double > aPattern = GetDashing( nDashing, eUnit );
- basegfx::B2DPolyPolygon aPolygons;
- if ( ! aPattern.empty() )
- basegfx::tools::applyLineDashing( rPolygon, aPattern, &aPolygons );
- else
- aPolygons.append( rPolygon );
-
- return aPolygons;
+ std::vector<double> aPattern = GetDashing(nDashing);
+ std::for_each(aPattern.begin(), aPattern.end(), ApplyScale(fScale));
+ return aPattern;
}
- basegfx::B2DPolyPolygon ApplyLineDashing( const basegfx::B2DPolygon& rPolygon, sal_uInt16 nDashing, MapUnit eUnit, double fScale )
+ basegfx::B2DPolyPolygon ApplyLineDashing( const basegfx::B2DPolygon& rPolygon, sal_uInt16 nDashing, double fScale )
{
- std::vector< double > aPattern = GetDashing( nDashing, eUnit );
- std::vector< double >::iterator i = aPattern.begin();
- while( i != aPattern.end() ) {
- (*i) *= fScale;
- ++i;
- }
+ std::vector<double> aPattern = GetDashing(nDashing);
+ std::for_each(aPattern.begin(), aPattern.end(), ApplyScale(fScale));
basegfx::B2DPolyPolygon aPolygons;
- if ( ! aPattern.empty() )
- basegfx::tools::applyLineDashing( rPolygon, aPattern, &aPolygons );
+
+ if (aPattern.empty())
+ aPolygons.append(rPolygon);
else
- aPolygons.append( rPolygon );
+ basegfx::tools::applyLineDashing(rPolygon, aPattern, &aPolygons);
return aPolygons;
}
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index 20fdd3f68c3d..82683743302c 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -1124,6 +1124,51 @@ void lclDrawDiagFrameBorders(
#define SCALEVALUE( value ) lclScaleValue( value, fScale, nMaxWidth )
+Style::Style() :
+ meRefMode(REFMODE_CENTERED),
+ mfScale(1.0),
+ mnType(table::BorderLineStyle::SOLID)
+{
+ Clear();
+}
+
+Style::Style( double nP, double nD, double nS, editeng::SvxBorderStyle nType ) :
+ meRefMode(REFMODE_CENTERED),
+ mfScale(1.0),
+ mnType(nType)
+{
+ Clear();
+ Set( nP, nD, nS );
+}
+
+Style::Style( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor,
+ double nP, double nD, double nS, editeng::SvxBorderStyle nType ) :
+ meRefMode(REFMODE_CENTERED),
+ mfScale(1.0),
+ mnType(nType)
+{
+ Set( rColorPrim, rColorSecn, rColorGap, bUseGapColor, nP, nD, nS );
+}
+
+Style::Style( const editeng::SvxBorderLine& rBorder, double fScale, sal_uInt16 nMaxWidth ) :
+ meRefMode(REFMODE_CENTERED),
+ mfScale(fScale)
+{
+ Set( rBorder, fScale, nMaxWidth );
+}
+
+Style::Style( const editeng::SvxBorderLine* pBorder, double fScale, sal_uInt16 nMaxWidth ) :
+ meRefMode(REFMODE_CENTERED),
+ mfScale(fScale)
+{
+ Set( pBorder, fScale, nMaxWidth );
+}
+
+double Style::Scale() const
+{
+ return mfScale;
+}
+
void Style::Clear()
{
Set( Color(), Color(), Color(), false, 0, 0, 0 );
@@ -1384,7 +1429,7 @@ drawinglayer::primitive2d::Primitive2DSequence CreateClippedBorderPrimitives (
rBorder.GetColorSecn().getBColor(),
rBorder.GetColorPrim().getBColor(),
rBorder.GetColorGap().getBColor(),
- rBorder.UseGapColor(), rBorder.Type() );
+ rBorder.UseGapColor(), rBorder.Type(), rBorder.Scale() );
return aSequence;
}
@@ -1412,7 +1457,7 @@ drawinglayer::primitive2d::Primitive2DSequence CreateBorderPrimitives(
rBorder.GetColorSecn().getBColor(),
rBorder.GetColorPrim().getBColor(),
rBorder.GetColorGap().getBColor(),
- rBorder.UseGapColor(), rBorder.Type() );
+ rBorder.UseGapColor(), rBorder.Type(), rBorder.Scale() );
return aSequence;
}
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index d5ae1c877d22..a57df407d243 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -4757,16 +4757,10 @@ lcl_MakeBorderLine(SwRect const& rRect,
? lcl_GetExtent(0, pEndNeighbour)
: lcl_GetExtent(pEndNeighbour, 0);
- double const nLeftWidth = (isLeftOrTopBorder == isVertical)
- ? rBorder.GetInWidth() : rBorder.GetOutWidth();
- double const nRightWidth = (isLeftOrTopBorder == isVertical)
- ? rBorder.GetOutWidth() : rBorder.GetInWidth();
- Color const aLeftColor = (isLeftOrTopBorder == isVertical)
- ? rBorder.GetColorIn(isLeftOrTopBorder)
- : rBorder.GetColorOut(isLeftOrTopBorder);
- Color const aRightColor = (isLeftOrTopBorder == isVertical)
- ? rBorder.GetColorOut(isLeftOrTopBorder)
- : rBorder.GetColorIn(isLeftOrTopBorder);
+ double const nLeftWidth = rBorder.GetOutWidth();
+ double const nRightWidth = rBorder.GetInWidth();
+ Color const aLeftColor = rBorder.GetColorOut(isLeftOrTopBorder);
+ Color const aRightColor = rBorder.GetColorIn(isLeftOrTopBorder);
::rtl::Reference<BorderLinePrimitive2D> const xLine =
new BorderLinePrimitive2D(
diff --git a/vcl/source/gdi/outdev6.cxx b/vcl/source/gdi/outdev6.cxx
index 9d2e355a375d..b51605747a80 100644
--- a/vcl/source/gdi/outdev6.cxx
+++ b/vcl/source/gdi/outdev6.cxx
@@ -42,16 +42,49 @@
#include <math.h>
-// ========================================================================
+namespace {
-DBG_NAMEEX( OutputDevice )
+/**
+ * Perform a safe approximation of a polygon from double-precision
+ * coordinates to integer coordinates, to ensure that it has at least 2
+ * pixels in both X and Y directions.
+ */
+Polygon toPolygon( const basegfx::B2DPolygon& rPoly )
+{
+ basegfx::B2DRange aRange = rPoly.getB2DRange();
+ double fW = aRange.getWidth(), fH = aRange.getHeight();
+ if (0.0 < fW && 0.0 < fH && (fW <= 1.0 || fH <= 1.0))
+ {
+ // This polygon not empty but is too small to display. Approximate it
+ // with a rectangle large enough to be displayed.
+ double nX = aRange.getMinX(), nY = aRange.getMinY();
+ double nW = std::max<double>(1.0, rtl::math::round(fW));
+ double nH = std::max<double>(1.0, rtl::math::round(fH));
+
+ Polygon aTarget;
+ aTarget.Insert(0, Point(nX, nY));
+ aTarget.Insert(1, Point(nX+nW, nY));
+ aTarget.Insert(2, Point(nX+nW, nY+nH));
+ aTarget.Insert(3, Point(nX, nY+nH));
+ aTarget.Insert(4, Point(nX, nY));
+ return aTarget;
+ }
+ return Polygon(rPoly);
+}
-// ------------------------------------------------------------------------
+PolyPolygon toPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPoly )
+{
+ PolyPolygon aTarget;
+ for (sal_uInt32 i = 0; i < rPolyPoly.count(); ++i)
+ aTarget.Insert(toPolygon(rPolyPoly.getB2DPolygon(i)));
+
+ return aTarget;
+}
+
+}
void OutputDevice::DrawGrid( const Rectangle& rRect, const Size& rDist, sal_uLong nFlags )
{
- DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
-
Rectangle aDstRect( PixelToLogic( Point() ), GetOutputSize() );
aDstRect.Intersection( rRect );
@@ -148,8 +181,6 @@ void OutputDevice::DrawGrid( const Rectangle& rRect, const Size& rDist, sal_uLon
void OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency)
{
- DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
-
// AW: Do NOT paint empty PolyPolygons
if(!rB2DPolyPoly.count())
return;
@@ -204,7 +235,7 @@ void OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly,
}
// fallback to old polygon drawing if needed
- DrawTransparent(PolyPolygon(rB2DPolyPoly), static_cast< sal_uInt16 >(fTransparency * 100.0));
+ DrawTransparent(toPolyPolygon(rB2DPolyPoly), static_cast<sal_uInt16>(fTransparency * 100.0));
}
// ------------------------------------------------------------------------
@@ -212,8 +243,6 @@ void OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly,
void OutputDevice::DrawTransparent( const PolyPolygon& rPolyPoly,
sal_uInt16 nTransparencePercent )
{
- DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
-
// short circuit for drawing an opaque polygon
if( (nTransparencePercent < 1) || ((mnDrawMode & DRAWMODE_NOTRANSPARENCY) != 0) )
{
@@ -608,8 +637,6 @@ void OutputDevice::DrawTransparent( const PolyPolygon& rPolyPoly,
void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
const Size& rSize, const Gradient& rTransparenceGradient )
{
- DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
-
const Color aBlack( COL_BLACK );
if( mpMetaFile )