summaryrefslogtreecommitdiff
path: root/cppcanvas/source/mtfrenderer/emfplus.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'cppcanvas/source/mtfrenderer/emfplus.cxx')
-rw-r--r--cppcanvas/source/mtfrenderer/emfplus.cxx49
1 files changed, 32 insertions, 17 deletions
diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index 7614bbba7a00..cb0a37b89ea6 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -1336,29 +1336,27 @@ namespace cppcanvas
if (!rLineCap.count())
return 0.0;
- // it seems the line caps in EMF+ are 4*larger than what
- // LibreOffice expects, and the mapping in
- // createAreaGeometryForLineStartEnd scales that down, so
- // correct it
- // [unfortunately found no proof for this in the spec :-( - please
- // feel free to correct this if it causes trouble]
- double fWidth = rAttributes.StrokeWidth*4;
-
+ // createAreaGeometryForLineStartEnd normalises the arrows height
+ // before scaling (i.e. scales down by rPolygon.height), hence
+ // we pre-scale it (which means we can avoid changing the logic
+ // that would affect arrows rendered outside of EMF+).
+ const double fWidth = rAttributes.StrokeWidth*rLineCap.getB2DRange().getWidth();
+
+ // When drawing an outline (as opposed to a filled endCap), we also
+ // need to take account that the brush width also adds to the area
+ // of the polygon.
+ const double fShift = bIsFilled ? 0 : rAttributes.StrokeWidth;
+ double fConsumed = 0;
basegfx::B2DPolyPolygon aArrow(basegfx::tools::createAreaGeometryForLineStartEnd(
rPolygon, rLineCap, bStart,
- fWidth, fPolyLength, 0, NULL, rAttributes.StrokeWidth));
+ fWidth, fPolyLength, 0, &fConsumed, fShift));
// createAreaGeometryForLineStartEnd from some reason always sets
// the path as closed, correct it
aArrow.setClosed(rLineCap.isClosed());
- ActionSharedPtr pAction(internal::PolyPolyActionFactory::createPolyPolyAction(aArrow, rParms.mrCanvas, rState, rAttributes));
- if (pAction)
- {
- maActions.push_back(MtfAction(pAction, rParms.mrCurrActionIndex));
- rParms.mrCurrActionIndex += pAction->getActionCount()-1;
- }
-
+ // If the endcap is filled, we draw ONLY the filling, if it isn't
+ // filled we draw ONLY the outline, but never both.
if (bIsFilled)
{
bool bWasFillColorSet = rState.isFillColorSet;
@@ -1372,8 +1370,25 @@ namespace cppcanvas
}
rState.isFillColorSet = bWasFillColorSet;
}
+ else
+ {
+ ActionSharedPtr pAction(internal::PolyPolyActionFactory::createPolyPolyAction(aArrow, rParms.mrCanvas, rState, rAttributes));
+ if (pAction)
+ {
+ maActions.push_back(MtfAction(pAction, rParms.mrCurrActionIndex));
+ rParms.mrCurrActionIndex += pAction->getActionCount()-1;
+ }
+ }
- return rAttributes.StrokeWidth;
+ // There isn't any clear definition of how far the line should extend
+ // for arrows, however the following values seem to give best results
+ // (fConsumed/2 draws the line to the center-point of the endcap
+ // for filled caps -- however it is likely this will need to be
+ // changed once we start taking baseInset into account).
+ if (bIsFilled)
+ return fConsumed/2;
+ else
+ return rAttributes.StrokeWidth;
}
void ImplRenderer::EMFPPlusDrawPolygon (const ::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms,