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)); |