EMF+: Only draw endcap outline if not filled, fix endcap scaling.

Change-Id: I4520eea08e43ccd657c1db03b258ef84612da971
Reviewed-on: https://gerrit.libreoffice.org/7726
Reviewed-by: Jan Holesovsky <kendy@collabora.com>
Tested-by: Jan Holesovsky <kendy@collabora.com>
This commit is contained in:
Andrzej Hunt
2014-01-29 18:40:21 +00:00
committed by Jan Holesovsky
parent 1984bb05de
commit 8d1ca883b1

View File

@@ -1345,29 +1345,27 @@ namespace cppcanvas
if (!rLineCap.count()) if (!rLineCap.count())
return 0.0; return 0.0;
// it seems the line caps in EMF+ are 4*larger than what // createAreaGeometryForLineStartEnd normalises the arrows height
// LibreOffice expects, and the mapping in // before scaling (i.e. scales down by rPolygon.height), hence
// createAreaGeometryForLineStartEnd scales that down, so // we pre-scale it (which means we can avoid changing the logic
// correct it // that would affect arrows rendered outside of EMF+).
// [unfortunately found no proof for this in the spec :-( - please const double fWidth = rAttributes.StrokeWidth*rLineCap.getB2DRange().getWidth();
// feel free to correct this if it causes trouble]
double fWidth = rAttributes.StrokeWidth*4;
// 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( basegfx::B2DPolyPolygon aArrow(basegfx::tools::createAreaGeometryForLineStartEnd(
rPolygon, rLineCap, bStart, rPolygon, rLineCap, bStart,
fWidth, fPolyLength, 0, NULL, rAttributes.StrokeWidth)); fWidth, fPolyLength, 0, &fConsumed, fShift));
// createAreaGeometryForLineStartEnd from some reason always sets // createAreaGeometryForLineStartEnd from some reason always sets
// the path as closed, correct it // the path as closed, correct it
aArrow.setClosed(rLineCap.isClosed()); aArrow.setClosed(rLineCap.isClosed());
ActionSharedPtr pAction(internal::PolyPolyActionFactory::createPolyPolyAction(aArrow, rParms.mrCanvas, rState, rAttributes)); // If the endcap is filled, we draw ONLY the filling, if it isn't
if (pAction) // filled we draw ONLY the outline, but never both.
{
maActions.push_back(MtfAction(pAction, rParms.mrCurrActionIndex));
rParms.mrCurrActionIndex += pAction->getActionCount()-1;
}
if (bIsFilled) if (bIsFilled)
{ {
bool bWasFillColorSet = rState.isFillColorSet; bool bWasFillColorSet = rState.isFillColorSet;
@@ -1381,8 +1379,25 @@ namespace cppcanvas
} }
rState.isFillColorSet = bWasFillColorSet; 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, void ImplRenderer::EMFPPlusDrawPolygon (const ::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms,