| Index: src/device/xps/SkXPSDevice.cpp
|
| diff --git a/src/device/xps/SkXPSDevice.cpp b/src/device/xps/SkXPSDevice.cpp
|
| index 73de0b3ca866ed6e7baa6f47c43fc4af7401d84c..194d23a7e7f0a899e11ed84aec7068ac4f08f811 100644
|
| --- a/src/device/xps/SkXPSDevice.cpp
|
| +++ b/src/device/xps/SkXPSDevice.cpp
|
| @@ -1386,162 +1386,6 @@ HRESULT SkXPSDevice::addXpsPathGeometry(
|
| return S_OK;
|
| }
|
|
|
| -HRESULT SkXPSDevice::drawInverseWindingPath(const SkDraw& d,
|
| - const SkPath& devicePath,
|
| - IXpsOMPath* shadedPath) {
|
| - const SkRect universeRect = SkRect::MakeLTRB(0, 0,
|
| - this->fCurrentCanvasSize.fWidth, this->fCurrentCanvasSize.fHeight);
|
| -
|
| - const XPS_RECT universeRectXps = {
|
| - 0.0f, 0.0f,
|
| - SkScalarToFLOAT(this->fCurrentCanvasSize.fWidth),
|
| - SkScalarToFLOAT(this->fCurrentCanvasSize.fHeight),
|
| - };
|
| -
|
| - //Get the geometry.
|
| - SkTScopedComPtr<IXpsOMGeometry> shadedGeometry;
|
| - HRM(shadedPath->GetGeometry(&shadedGeometry),
|
| - "Could not get shaded geometry for inverse path.");
|
| -
|
| - //Get the figures from the geometry.
|
| - SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures;
|
| - HRM(shadedGeometry->GetFigures(&shadedFigures),
|
| - "Could not get shaded figures for inverse path.");
|
| -
|
| - HRM(shadedGeometry->SetFillRule(XPS_FILL_RULE_NONZERO),
|
| - "Could not set shaded fill rule for inverse path.");
|
| -
|
| - //Take everything drawn so far, and make a shared resource out of it.
|
| - //Replace everything drawn so far with
|
| - //inverse canvas
|
| - // old canvas of everything so far
|
| - // world shaded figure, clipped to current clip
|
| - // top canvas of everything so far, clipped to path
|
| - //Note: this is not quite right when there is nothing solid in the
|
| - //canvas of everything so far, as the bit on top will allow
|
| - //the world paint to show through.
|
| -
|
| - //Create new canvas.
|
| - SkTScopedComPtr<IXpsOMCanvas> newCanvas;
|
| - HRM(this->fXpsFactory->CreateCanvas(&newCanvas),
|
| - "Could not create inverse canvas.");
|
| -
|
| - //Save the old canvas to a dictionary on the new canvas.
|
| - SkTScopedComPtr<IXpsOMDictionary> newDictionary;
|
| - HRM(this->fXpsFactory->CreateDictionary(&newDictionary),
|
| - "Could not create inverse dictionary.");
|
| - HRM(newCanvas->SetDictionaryLocal(newDictionary.get()),
|
| - "Could not set inverse dictionary.");
|
| -
|
| - const size_t size = SK_ARRAY_COUNT(L"ID" L_GUID_ID);
|
| - wchar_t buffer[size];
|
| - wchar_t id[GUID_ID_LEN];
|
| - HR(this->createId(id, GUID_ID_LEN, '_'));
|
| - swprintf_s(buffer, size, L"ID%s", id);
|
| - HRM(newDictionary->Append(buffer, this->fCurrentXpsCanvas.get()),
|
| - "Could not add canvas to inverse dictionary.");
|
| -
|
| - //Start drawing
|
| - SkTScopedComPtr<IXpsOMVisualCollection> newVisuals;
|
| - HRM(newCanvas->GetVisuals(&newVisuals),
|
| - "Could not get inverse canvas visuals.");
|
| -
|
| - //Draw old canvas from dictionary onto new canvas.
|
| - SkTScopedComPtr<IXpsOMGeometry> oldGeometry;
|
| - HRM(this->fXpsFactory->CreateGeometry(&oldGeometry),
|
| - "Could not create old inverse geometry.");
|
| -
|
| - SkTScopedComPtr<IXpsOMGeometryFigureCollection> oldFigures;
|
| - HRM(oldGeometry->GetFigures(&oldFigures),
|
| - "Could not get old inverse figures.");
|
| -
|
| - SkTScopedComPtr<IXpsOMGeometryFigure> oldFigure;
|
| - HR(this->createXpsRect(universeRect, FALSE, TRUE, &oldFigure));
|
| - HRM(oldFigures->Append(oldFigure.get()),
|
| - "Could not add old inverse figure.");
|
| -
|
| - SkTScopedComPtr<IXpsOMVisualBrush> oldBrush;
|
| - HRM(this->fXpsFactory->CreateVisualBrush(&universeRectXps,
|
| - &universeRectXps,
|
| - &oldBrush),
|
| - "Could not create old inverse brush.");
|
| -
|
| - SkTScopedComPtr<IXpsOMPath> oldPath;
|
| - HRM(this->fXpsFactory->CreatePath(&oldPath),
|
| - "Could not create old inverse path.");
|
| - HRM(oldPath->SetGeometryLocal(oldGeometry.get()),
|
| - "Could not set old inverse geometry.");
|
| - HRM(oldPath->SetFillBrushLocal(oldBrush.get()),
|
| - "Could not set old inverse fill brush.");
|
| - //the brush must be parented before setting the lookup.
|
| - HRM(newVisuals->Append(oldPath.get()),
|
| - "Could not add old inverse path to new canvas visuals.");
|
| - HRM(oldBrush->SetVisualLookup(buffer),
|
| - "Could not set old inverse brush visual lookup.");
|
| -
|
| - //Draw the clip filling shader.
|
| - SkTScopedComPtr<IXpsOMGeometryFigure> shadedFigure;
|
| - HR(this->createXpsRect(universeRect, FALSE, TRUE, &shadedFigure));
|
| - HRM(shadedFigures->Append(shadedFigure.get()),
|
| - "Could not add inverse shaded figure.");
|
| - //the geometry is already set
|
| - HR(this->clip(shadedPath, d));
|
| - HRM(newVisuals->Append(shadedPath),
|
| - "Could not add inverse shaded path to canvas visuals.");
|
| -
|
| - //Draw the old canvas on top, clipped to the original path.
|
| - SkTScopedComPtr<IXpsOMCanvas> topCanvas;
|
| - HRM(this->fXpsFactory->CreateCanvas(&topCanvas),
|
| - "Could not create top inverse canvas.");
|
| - //Clip the canvas to prevent alpha spill.
|
| - //This is the entire reason this canvas exists.
|
| - HR(this->clip(topCanvas.get(), d));
|
| -
|
| - SkTScopedComPtr<IXpsOMGeometry> topGeometry;
|
| - HRM(this->fXpsFactory->CreateGeometry(&topGeometry),
|
| - "Could not create top inverse geometry.");
|
| -
|
| - SkTScopedComPtr<IXpsOMGeometryFigureCollection> topFigures;
|
| - HRM(topGeometry->GetFigures(&topFigures),
|
| - "Could not get top inverse figures.");
|
| -
|
| - SkTScopedComPtr<IXpsOMGeometryFigure> topFigure;
|
| - HR(this->createXpsRect(universeRect, FALSE, TRUE, &topFigure));
|
| - HRM(topFigures->Append(topFigure.get()),
|
| - "Could not add old inverse figure.");
|
| -
|
| - SkTScopedComPtr<IXpsOMVisualBrush> topBrush;
|
| - HRM(this->fXpsFactory->CreateVisualBrush(&universeRectXps,
|
| - &universeRectXps,
|
| - &topBrush),
|
| - "Could not create top inverse brush.");
|
| -
|
| - SkTScopedComPtr<IXpsOMPath> topPath;
|
| - HRM(this->fXpsFactory->CreatePath(&topPath),
|
| - "Could not create top inverse path.");
|
| - HRM(topPath->SetGeometryLocal(topGeometry.get()),
|
| - "Could not set top inverse geometry.");
|
| - HRM(topPath->SetFillBrushLocal(topBrush.get()),
|
| - "Could not set top inverse fill brush.");
|
| - //the brush must be parented before setting the lookup.
|
| - HRM(newVisuals->Append(topCanvas.get()),
|
| - "Could not add top canvas to inverse canvas visuals.");
|
| - SkTScopedComPtr<IXpsOMVisualCollection> topVisuals;
|
| - HRM(topCanvas->GetVisuals(&topVisuals),
|
| - "Could not get top inverse canvas visuals.");
|
| - HRM(topVisuals->Append(topPath.get()),
|
| - "Could not add top inverse path to top canvas visuals.");
|
| - HRM(topBrush->SetVisualLookup(buffer),
|
| - "Could not set top inverse brush visual lookup.");
|
| -
|
| - HR(this->clipToPath(topPath.get(), devicePath, XPS_FILL_RULE_NONZERO));
|
| -
|
| - //swap current canvas to new canvas
|
| - this->fCurrentXpsCanvas.swap(newCanvas);
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| void SkXPSDevice::convertToPpm(const SkMaskFilter* filter,
|
| SkMatrix* matrix,
|
| SkVector* ppuScale,
|
| @@ -1845,8 +1689,9 @@ void SkXPSDevice::drawPath(const SkDraw& d,
|
| bool xpsTransformsPath = true;
|
|
|
| //Set the fill rule.
|
| + SkPath* xpsCompatiblePath = fillablePath;
|
| XPS_FILL_RULE xpsFillRule;
|
| - switch (platonicPath.getFillType()) {
|
| + switch (fillablePath->getFillType()) {
|
| case SkPath::kWinding_FillType:
|
| xpsFillRule = XPS_FILL_RULE_NONZERO;
|
| break;
|
| @@ -1854,15 +1699,17 @@ void SkXPSDevice::drawPath(const SkDraw& d,
|
| xpsFillRule = XPS_FILL_RULE_EVENODD;
|
| break;
|
| case SkPath::kInverseWinding_FillType: {
|
| - //[Fillable-path -> Device-path]
|
| - SkPath* devicePath = pathIsMutable ? fillablePath : &modifiedPath;
|
| - fillablePath->transform(matrix, devicePath);
|
| -
|
| - HRV(this->drawInverseWindingPath(d,
|
| - *devicePath,
|
| - shadedPath.get()));
|
| - return;
|
| + //[Fillable-path (inverse winding) -> XPS-path (inverse even odd)]
|
| + if (!pathIsMutable) {
|
| + xpsCompatiblePath = &modifiedPath;
|
| + pathIsMutable = true;
|
| + }
|
| + if (!Simplify(*fillablePath, xpsCompatiblePath)) {
|
| + SkDEBUGF(("Could not simplify inverse winding path."));
|
| + return;
|
| + }
|
| }
|
| + // The xpsCompatiblePath is noW inverse even odd, so fall through.
|
| case SkPath::kInverseEvenOdd_FillType: {
|
| const SkRect universe = SkRect::MakeLTRB(
|
| 0, 0,
|
| @@ -1895,11 +1742,11 @@ void SkXPSDevice::drawPath(const SkDraw& d,
|
| }
|
| }
|
|
|
| - SkPath* devicePath = fillablePath;
|
| + SkPath* devicePath = xpsCompatiblePath;
|
| if (!xpsTransformsPath) {
|
| //[Fillable-path -> Device-path]
|
| - devicePath = pathIsMutable ? fillablePath : &modifiedPath;
|
| - fillablePath->transform(matrix, devicePath);
|
| + devicePath = pathIsMutable ? xpsCompatiblePath : &modifiedPath;
|
| + xpsCompatiblePath->transform(matrix, devicePath);
|
| }
|
| HRV(this->addXpsPathGeometry(shadedFigures.get(),
|
| stroke, fill, *devicePath));
|
|
|