summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-03-03 17:58:11 -0500
committerKohei Yoshida <kohei.yoshida@collabora.com>2014-03-04 22:02:37 -0500
commit2c62596cf264ef10749d8bfdb2bb2ebef2d98fbc (patch)
tree1311156cb36884d0dde2b022467d7d0de6d799df
parentfb052ae6174e4c96157ef6973f02c1d3cd4d9ba2 (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. Change-Id: Iaaa353b6e4f998b524262bea59260b4333e0cdb4
-rw-r--r--cui/source/tabpages/border.cxx1
-rw-r--r--drawinglayer/source/primitive2d/borderlineprimitive2d.cxx120
-rw-r--r--drawinglayer/source/processor2d/vclpixelprocessor2d.cxx4
-rw-r--r--editeng/source/items/borderline.cxx5
-rw-r--r--editeng/source/items/frmitems.cxx2
-rw-r--r--include/xmloff/xmltoken.hxx1
-rw-r--r--offapi/com/sun/star/table/BorderLineStyle.idl10
-rw-r--r--sc/qa/unit/subsequent_export-test.cxx4
-rw-r--r--sc/source/filter/excel/xistyle.cxx2
-rw-r--r--sc/source/filter/html/htmlexp.cxx1
-rw-r--r--sc/source/filter/lotus/lotattr.cxx2
-rw-r--r--sc/source/filter/oox/stylesbuffer.cxx4
-rw-r--r--sc/source/ui/view/tabvwsha.cxx2
-rw-r--r--sw/source/core/layout/paintfrm.cxx117
-rw-r--r--xmloff/source/core/xmltoken.cxx1
-rw-r--r--xmloff/source/style/bordrhdl.cxx5
16 files changed, 208 insertions, 73 deletions
diff --git a/cui/source/tabpages/border.cxx b/cui/source/tabpages/border.cxx
index 3f8881bc4657..fd7b9057aeac 100644
--- a/cui/source/tabpages/border.cxx
+++ b/cui/source/tabpages/border.cxx
@@ -1045,6 +1045,7 @@ void SvxBorderTabPage::FillLineListBox_Impl()
// Double lines
{ DOUBLE, 10, &sameColor, &sameColor, &sameDistColor },
+ { DOUBLE_THIN, 10, &sameColor, &sameColor, &sameDistColor },
{ THINTHICK_SMALLGAP, 20, &sameColor, &sameColor, &sameDistColor },
{ THINTHICK_MEDIUMGAP, 0, &sameColor, &sameColor, &sameDistColor },
{ THINTHICK_LARGEGAP, 0, &sameColor, &sameColor, &sameDistColor },
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 4605aee96eca..e7c5e7674ba6 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;
diff --git a/editeng/source/items/borderline.cxx b/editeng/source/items/borderline.cxx
index 2da1753d4f20..b919e58b5aab 100644
--- a/editeng/source/items/borderline.cxx
+++ b/editeng/source/items/borderline.cxx
@@ -316,6 +316,10 @@ BorderWidthImpl SvxBorderLine::getWidthImpl( SvxBorderStyle nStyle )
1.0/3.0, 1.0/3.0, 1.0/3.0 );
break;
+ case DOUBLE_THIN:
+ aImpl = BorderWidthImpl(CHANGE_DIST, 10.0, 10.0, 1.0);
+ break;
+
case THINTHICK_SMALLGAP:
aImpl = BorderWidthImpl( CHANGE_LINE1, 1.0,
THINTHICK_SMALLGAP_line2, THINTHICK_SMALLGAP_gap );
@@ -429,6 +433,7 @@ void SvxBorderLine::GuessLinesWidths( SvxBorderStyle nStyle, sal_uInt16 nOut, sa
static const SvxBorderStyle aDoubleStyles[] =
{
DOUBLE,
+ DOUBLE_THIN,
THINTHICK_SMALLGAP,
THINTHICK_MEDIUMGAP,
THINTHICK_LARGEGAP,
diff --git a/editeng/source/items/frmitems.cxx b/editeng/source/items/frmitems.cxx
index e8443204d62e..57bd705c3b55 100644
--- a/editeng/source/items/frmitems.cxx
+++ b/editeng/source/items/frmitems.cxx
@@ -1834,7 +1834,7 @@ SvxBoxItem::LineToSvxLine(const ::com::sun::star::table::BorderLine2& rLine, Svx
rSvxLine.SetWidth( bConvert? MM100_TO_TWIP_UNSIGNED( rLine.LineWidth ) : rLine.LineWidth );
// fdo#46112: double does not necessarily mean symmetric
// for backwards compatibility
- bGuessWidth = (DOUBLE == nStyle) &&
+ bGuessWidth = ((DOUBLE == nStyle || DOUBLE_THIN == nStyle)) &&
(rLine.InnerLineWidth > 0) && (rLine.OuterLineWidth > 0);
}
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 225e37413a4f..39a6dc9e6422 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -647,6 +647,7 @@ namespace xmloff { namespace token {
XML_DOTTED,
XML_DOUBLE,
XML_DOUBLE_SIDED,
+ XML_DOUBLE_THIN,
XML_DOWN,
XML_DRAFT,
XML_DRAW,
diff --git a/offapi/com/sun/star/table/BorderLineStyle.idl b/offapi/com/sun/star/table/BorderLineStyle.idl
index 7613272043d1..0c37c67519e2 100644
--- a/offapi/com/sun/star/table/BorderLineStyle.idl
+++ b/offapi/com/sun/star/table/BorderLineStyle.idl
@@ -41,7 +41,8 @@ constants BorderLineStyle
*/
const short DASHED = 2;
- /** Double border line.
+ /** Double border line. Widths of the lines and the gap are all equal,
+ and vary equally with the total width.
*/
const short DOUBLE = 3;
@@ -95,9 +96,14 @@ constants BorderLineStyle
*/
const short FINE_DASHED = 14;
+ /** Double border line consisting of two fixed thin lines separated by a
+ variable gap.
+ */
+ const short DOUBLE_THIN = 15;
+
/** Maximum valid border line style value.
*/
- const short BORDER_LINE_STYLE_MAX = 14;
+ const short BORDER_LINE_STYLE_MAX = 15;
};
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index 3a669ba6bafb..f2f653b76a18 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -1015,7 +1015,7 @@ const char* toBorderName( sal_Int16 eStyle )
case table::BorderLineStyle::SOLID: return "SOLID";
case table::BorderLineStyle::DOTTED: return "DOTTED";
case table::BorderLineStyle::DASHED: return "DASHED";
- case table::BorderLineStyle::DOUBLE: return "DOUBLE";
+ case table::BorderLineStyle::DOUBLE_THIN: return "DOUBLE_THIN";
case table::BorderLineStyle::FINE_DASHED: return "FINE_DASHED";
default:
;
@@ -1046,7 +1046,7 @@ void ScExportTest::testExcelCellBorders( sal_uLong nFormatType )
{ 19, table::BorderLineStyle::DASHED, 35L }, // medium dashed
{ 21, table::BorderLineStyle::SOLID, 35L }, // medium
{ 23, table::BorderLineStyle::SOLID, 50L }, // thick
- { 25, table::BorderLineStyle::DOUBLE, -1L }, // double (don't check width)
+ { 25, table::BorderLineStyle::DOUBLE_THIN, -1L }, // double (don't check width)
};
for (size_t i = 0; i < SAL_N_ELEMENTS(aChecks); ++i)
diff --git a/sc/source/filter/excel/xistyle.cxx b/sc/source/filter/excel/xistyle.cxx
index 5b2d03ccaa33..f1cae7f5b90d 100644
--- a/sc/source/filter/excel/xistyle.cxx
+++ b/sc/source/filter/excel/xistyle.cxx
@@ -903,7 +903,7 @@ bool lclConvertBorderLine( ::editeng::SvxBorderLine& rLine, const XclImpPalette&
{ 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_THICK, table::BorderLineStyle::DOUBLE_THIN }, // 6 = double
{ 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
diff --git a/sc/source/filter/html/htmlexp.cxx b/sc/source/filter/html/htmlexp.cxx
index 269f924096fc..00e160d40144 100644
--- a/sc/source/filter/html/htmlexp.cxx
+++ b/sc/source/filter/html/htmlexp.cxx
@@ -513,6 +513,7 @@ OString ScHTMLExport::BorderToStyle(const char* pBorderName,
aOut.append("dashed");
break;
case table::BorderLineStyle::DOUBLE:
+ case table::BorderLineStyle::DOUBLE_THIN:
case table::BorderLineStyle::THINTHICK_SMALLGAP:
case table::BorderLineStyle::THINTHICK_MEDIUMGAP:
case table::BorderLineStyle::THINTHICK_LARGEGAP:
diff --git a/sc/source/filter/lotus/lotattr.cxx b/sc/source/filter/lotus/lotattr.cxx
index bc17dff927d5..cdc804aa613c 100644
--- a/sc/source/filter/lotus/lotattr.cxx
+++ b/sc/source/filter/lotus/lotattr.cxx
@@ -169,7 +169,7 @@ void LotAttrCache::LotusToScBorderLine( sal_uInt8 nLine, ::editeng::SvxBorderLin
case 2: aBL.SetWidth( DEF_LINE_WIDTH_2 ); break;
case 3:
{
- aBL.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
+ aBL.SetBorderLineStyle(table::BorderLineStyle::DOUBLE_THIN);
aBL.SetWidth( DEF_LINE_WIDTH_1 );
}
break;
diff --git a/sc/source/filter/oox/stylesbuffer.cxx b/sc/source/filter/oox/stylesbuffer.cxx
index 5b8447ffacd4..dfa5570afa2b 100644
--- a/sc/source/filter/oox/stylesbuffer.cxx
+++ b/sc/source/filter/oox/stylesbuffer.cxx
@@ -1736,8 +1736,8 @@ bool Border::convertBorderLine( BorderLine2& rBorderLine, const BorderLineModel&
rBorderLine.LineStyle = table::BorderLineStyle::DOTTED;
break;
case XML_double:
- lclSetBorderLineWidth( rBorderLine, 5 ,5, 5 );
- rBorderLine.LineStyle = table::BorderLineStyle::DOUBLE;
+ lclSetBorderLineWidth( rBorderLine, 10, 30, 10 );
+ rBorderLine.LineStyle = table::BorderLineStyle::DOUBLE_THIN;
break;
case XML_hair: lclSetBorderLineWidth( rBorderLine, API_LINE_HAIR ); break;
case XML_medium: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break;
diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx
index 7bd88aca8b14..7dae366edba2 100644
--- a/sc/source/ui/view/tabvwsha.cxx
+++ b/sc/source/ui/view/tabvwsha.cxx
@@ -490,7 +490,7 @@ void ScTabViewShell::ExecuteCellFormatDlg(SfxRequest& rReq, const OString &rName
aBorderStyles.push_back(table::BorderLineStyle::DOTTED);
aBorderStyles.push_back(table::BorderLineStyle::DASHED);
aBorderStyles.push_back(table::BorderLineStyle::FINE_DASHED);
- aBorderStyles.push_back(table::BorderLineStyle::DOUBLE);
+ aBorderStyles.push_back(table::BorderLineStyle::DOUBLE_THIN);
SfxIntegerListItem aBorderStylesItem(SID_ATTR_BORDER_STYLES, aBorderStyles);
pOldSet->Put(aBorderStylesItem);
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 11d76f449ae6..b090ae1161d8 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -2258,6 +2258,11 @@ struct SwLineEntry
SwTwips mnKey;
SwTwips mnStartPos;
SwTwips mnEndPos;
+ SwTwips mnOffset;
+
+ bool mbOffsetPerp;
+ bool mbOffsetStart;
+ bool mbOffsetEnd;
svx::frame::Style maAttribute;
@@ -2279,6 +2284,10 @@ SwLineEntry::SwLineEntry( SwTwips nKey,
: mnKey( nKey ),
mnStartPos( nStartPos ),
mnEndPos( nEndPos ),
+ mnOffset( 0 ),
+ mbOffsetPerp(false),
+ mbOffsetStart(false),
+ mbOffsetEnd(false),
maAttribute( rAttribute )
{
}
@@ -2361,6 +2370,8 @@ class SwTabFrmPainter
svx::frame::Style*,
bool bHori ) const;
+ void AdjustTopLeftFrames();
+
public:
SwTabFrmPainter( const SwTabFrm& rTabFrm );
@@ -2371,6 +2382,7 @@ SwTabFrmPainter::SwTabFrmPainter( const SwTabFrm& rTabFrm )
: mrTabFrm( rTabFrm )
{
HandleFrame( rTabFrm );
+ AdjustTopLeftFrames();
}
void SwTabFrmPainter::HandleFrame( const SwLayoutFrm& rLayoutFrm )
@@ -2479,6 +2491,45 @@ void SwTabFrmPainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) const
aEnd.Y() = rEntry.mnEndPos;
}
+ svx::frame::Style aStyles[ 7 ];
+ aStyles[ 0 ] = rEntryStyle;
+ FindStylesForLine( aStart, aEnd, aStyles, bHori );
+
+ // Account for double line thicknesses for the top- and left-most borders.
+ if (rEntry.mnOffset)
+ {
+ if (bHori)
+ {
+ if (rEntry.mbOffsetPerp)
+ {
+ // Apply offset in perpendicular direction.
+ aStart.Y() -= rEntry.mnOffset;
+ aEnd.Y() -= rEntry.mnOffset;
+ }
+ if (rEntry.mbOffsetStart)
+ // Apply offset at the start of a border.
+ aStart.X() -= rEntry.mnOffset;
+ if (rEntry.mbOffsetEnd)
+ // Apply offset at the end of a border.
+ aEnd.X() += rEntry.mnOffset;
+ }
+ else
+ {
+ if (rEntry.mbOffsetPerp)
+ {
+ // Apply offset in perpendicular direction.
+ aStart.X() -= rEntry.mnOffset;
+ aEnd.X() -= rEntry.mnOffset;
+ }
+ if (rEntry.mbOffsetStart)
+ // Apply offset at the start of a border.
+ aStart.Y() -= rEntry.mnOffset;
+ if (rEntry.mbOffsetEnd)
+ // Apply offset at the end of a border.
+ aEnd.Y() += rEntry.mnOffset;
+ }
+ }
+
SwRect aRepaintRect( aStart, aEnd );
// the repaint rectangle has to be moved a bit for the centered lines:
@@ -2499,10 +2550,6 @@ void SwTabFrmPainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) const
continue;
}
- svx::frame::Style aStyles[ 7 ];
- aStyles[ 0 ] = rEntryStyle;
- FindStylesForLine( aStart, aEnd, aStyles, bHori );
-
// subsidiary lines
const Color* pTmpColor = 0;
if (0 == aStyles[ 0 ].GetWidth())
@@ -2742,6 +2789,54 @@ void SwTabFrmPainter::FindStylesForLine( const Point& rStartPoint,
}
}
+namespace {
+
+void calcOffsetForDoubleLine( SwLineEntryMap& rLines )
+{
+ SwLineEntryMap aNewLines;
+ SwLineEntryMap::iterator it = rLines.begin(), itEnd = rLines.end();
+ bool bFirst = true;
+ for (; it != itEnd; ++it)
+ {
+ if (bFirst)
+ {
+ // First line needs to be offset to account for double line thickness.
+ SwLineEntrySet aNewSet;
+ const SwLineEntrySet& rSet = it->second;
+ SwLineEntrySet::iterator itSet = rSet.begin(), itSetEnd = rSet.end();
+ size_t nEntryCount = rSet.size();
+ for (size_t i = 0; itSet != itSetEnd; ++itSet, ++i)
+ {
+ SwLineEntry aLine = *itSet;
+ aLine.mnOffset = static_cast<SwTwips>(aLine.maAttribute.Dist());
+ aLine.mbOffsetPerp = true;
+
+ if (i == 0)
+ aLine.mbOffsetStart = true;
+ if (i == nEntryCount - 1)
+ aLine.mbOffsetEnd = true;
+
+ aNewSet.insert(aLine);
+ }
+
+ aNewLines.insert(SwLineEntryMap::value_type(it->first, aNewSet));
+ }
+ else
+ aNewLines.insert(SwLineEntryMap::value_type(it->first, it->second));
+
+ bFirst = false;
+ }
+ rLines.swap(aNewLines);
+}
+
+}
+
+void SwTabFrmPainter::AdjustTopLeftFrames()
+{
+ calcOffsetForDoubleLine(maHoriLines);
+ calcOffsetForDoubleLine(maVertLines);
+}
+
// special case: #i9860#
// first line in follow table without repeated headlines
static bool lcl_IsFirstRowInFollowTableWithoutRepeatedHeadlines(
@@ -2775,10 +2870,16 @@ void SwTabFrmPainter::Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem )
bool const bVert = mrTabFrm.IsVertical();
bool const bR2L = mrTabFrm.IsRightToLeft();
- svx::frame::Style aL( rBoxItem.GetLeft() );
- svx::frame::Style aR( rBoxItem.GetRight() );
- svx::frame::Style aT( rBoxItem.GetTop() );
- svx::frame::Style aB( rBoxItem.GetBottom() );
+ SwViewShell* pViewShell = mrTabFrm.getRootFrm()->GetCurrShell();
+ OutputDevice* pOutDev = pViewShell->GetOut();
+ const MapMode& rMapMode = pOutDev->GetMapMode();
+ const Fraction& rFracX = rMapMode.GetScaleX();
+ const Fraction& rFracY = rMapMode.GetScaleY();
+
+ svx::frame::Style aL(rBoxItem.GetLeft(), rFracX);
+ svx::frame::Style aR(rBoxItem.GetRight(), rFracY);
+ svx::frame::Style aT(rBoxItem.GetTop(), rFracX);
+ svx::frame::Style aB(rBoxItem.GetBottom(), rFracY);
aR.MirrorSelf();
aB.MirrorSelf();
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 1e35261a7b33..56148dc5d094 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -651,6 +651,7 @@ namespace xmloff { namespace token {
TOKEN( "dotted", XML_DOTTED ),
TOKEN( "double", XML_DOUBLE ),
TOKEN( "double-sided", XML_DOUBLE_SIDED ),
+ TOKEN( "double-thin", XML_DOUBLE_THIN ),
TOKEN( "down", XML_DOWN ),
TOKEN( "draft", XML_DRAFT ),
TOKEN( "draw", XML_DRAW ),
diff --git a/xmloff/source/style/bordrhdl.cxx b/xmloff/source/style/bordrhdl.cxx
index 7ec68c028185..6d6caf2aeefa 100644
--- a/xmloff/source/style/bordrhdl.cxx
+++ b/xmloff/source/style/bordrhdl.cxx
@@ -43,6 +43,7 @@ SvXMLEnumMapEntry pXML_BorderStyles[] =
{ XML_HIDDEN, table::BorderLineStyle::NONE },
{ XML_SOLID, table::BorderLineStyle::SOLID },
{ XML_DOUBLE, table::BorderLineStyle::DOUBLE },
+ { XML_DOUBLE_THIN, table::BorderLineStyle::DOUBLE_THIN },
{ XML_DOTTED, table::BorderLineStyle::DOTTED },
{ XML_DASHED, table::BorderLineStyle::DASHED },
{ XML_GROOVE, table::BorderLineStyle::ENGRAVED },
@@ -136,6 +137,7 @@ bool XMLBorderWidthHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValu
switch ( aBorderLine.LineStyle )
{
case table::BorderLineStyle::DOUBLE:
+ case table::BorderLineStyle::DOUBLE_THIN:
case table::BorderLineStyle::THINTHICK_SMALLGAP:
case table::BorderLineStyle::THINTHICK_MEDIUMGAP:
case table::BorderLineStyle::THINTHICK_LARGEGAP:
@@ -323,6 +325,9 @@ bool XMLBorderHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValue, co
case table::BorderLineStyle::FINE_DASHED:
eStyleToken = XML_FINE_DASHED;
break;
+ case table::BorderLineStyle::DOUBLE_THIN:
+ eStyleToken = XML_DOUBLE_THIN;
+ break;
case table::BorderLineStyle::SOLID:
default:
break;