Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(696)

Side by Side Diff: src/device/xps/SkXPSDevice.cpp

Issue 484343003: XPS to use PathOps for inverse winding paths. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rebase Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef UNICODE 8 #ifndef UNICODE
9 #define UNICODE 9 #define UNICODE
10 #endif 10 #endif
(...skipping 1368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 } 1379 }
1380 } 1380 }
1381 if (NULL != xpsFigure.get()) { 1381 if (NULL != xpsFigure.get()) {
1382 HR(close_figure(segmentTypes, segmentStrokes, segmentData, 1382 HR(close_figure(segmentTypes, segmentStrokes, segmentData,
1383 stroke, fill, 1383 stroke, fill,
1384 xpsFigure.get(), xpsFigures)); 1384 xpsFigure.get(), xpsFigures));
1385 } 1385 }
1386 return S_OK; 1386 return S_OK;
1387 } 1387 }
1388 1388
1389 HRESULT SkXPSDevice::drawInverseWindingPath(const SkDraw& d,
1390 const SkPath& devicePath,
1391 IXpsOMPath* shadedPath) {
1392 const SkRect universeRect = SkRect::MakeLTRB(0, 0,
1393 this->fCurrentCanvasSize.fWidth, this->fCurrentCanvasSize.fHeight);
1394
1395 const XPS_RECT universeRectXps = {
1396 0.0f, 0.0f,
1397 SkScalarToFLOAT(this->fCurrentCanvasSize.fWidth),
1398 SkScalarToFLOAT(this->fCurrentCanvasSize.fHeight),
1399 };
1400
1401 //Get the geometry.
1402 SkTScopedComPtr<IXpsOMGeometry> shadedGeometry;
1403 HRM(shadedPath->GetGeometry(&shadedGeometry),
1404 "Could not get shaded geometry for inverse path.");
1405
1406 //Get the figures from the geometry.
1407 SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures;
1408 HRM(shadedGeometry->GetFigures(&shadedFigures),
1409 "Could not get shaded figures for inverse path.");
1410
1411 HRM(shadedGeometry->SetFillRule(XPS_FILL_RULE_NONZERO),
1412 "Could not set shaded fill rule for inverse path.");
1413
1414 //Take everything drawn so far, and make a shared resource out of it.
1415 //Replace everything drawn so far with
1416 //inverse canvas
1417 // old canvas of everything so far
1418 // world shaded figure, clipped to current clip
1419 // top canvas of everything so far, clipped to path
1420 //Note: this is not quite right when there is nothing solid in the
1421 //canvas of everything so far, as the bit on top will allow
1422 //the world paint to show through.
1423
1424 //Create new canvas.
1425 SkTScopedComPtr<IXpsOMCanvas> newCanvas;
1426 HRM(this->fXpsFactory->CreateCanvas(&newCanvas),
1427 "Could not create inverse canvas.");
1428
1429 //Save the old canvas to a dictionary on the new canvas.
1430 SkTScopedComPtr<IXpsOMDictionary> newDictionary;
1431 HRM(this->fXpsFactory->CreateDictionary(&newDictionary),
1432 "Could not create inverse dictionary.");
1433 HRM(newCanvas->SetDictionaryLocal(newDictionary.get()),
1434 "Could not set inverse dictionary.");
1435
1436 const size_t size = SK_ARRAY_COUNT(L"ID" L_GUID_ID);
1437 wchar_t buffer[size];
1438 wchar_t id[GUID_ID_LEN];
1439 HR(this->createId(id, GUID_ID_LEN, '_'));
1440 swprintf_s(buffer, size, L"ID%s", id);
1441 HRM(newDictionary->Append(buffer, this->fCurrentXpsCanvas.get()),
1442 "Could not add canvas to inverse dictionary.");
1443
1444 //Start drawing
1445 SkTScopedComPtr<IXpsOMVisualCollection> newVisuals;
1446 HRM(newCanvas->GetVisuals(&newVisuals),
1447 "Could not get inverse canvas visuals.");
1448
1449 //Draw old canvas from dictionary onto new canvas.
1450 SkTScopedComPtr<IXpsOMGeometry> oldGeometry;
1451 HRM(this->fXpsFactory->CreateGeometry(&oldGeometry),
1452 "Could not create old inverse geometry.");
1453
1454 SkTScopedComPtr<IXpsOMGeometryFigureCollection> oldFigures;
1455 HRM(oldGeometry->GetFigures(&oldFigures),
1456 "Could not get old inverse figures.");
1457
1458 SkTScopedComPtr<IXpsOMGeometryFigure> oldFigure;
1459 HR(this->createXpsRect(universeRect, FALSE, TRUE, &oldFigure));
1460 HRM(oldFigures->Append(oldFigure.get()),
1461 "Could not add old inverse figure.");
1462
1463 SkTScopedComPtr<IXpsOMVisualBrush> oldBrush;
1464 HRM(this->fXpsFactory->CreateVisualBrush(&universeRectXps,
1465 &universeRectXps,
1466 &oldBrush),
1467 "Could not create old inverse brush.");
1468
1469 SkTScopedComPtr<IXpsOMPath> oldPath;
1470 HRM(this->fXpsFactory->CreatePath(&oldPath),
1471 "Could not create old inverse path.");
1472 HRM(oldPath->SetGeometryLocal(oldGeometry.get()),
1473 "Could not set old inverse geometry.");
1474 HRM(oldPath->SetFillBrushLocal(oldBrush.get()),
1475 "Could not set old inverse fill brush.");
1476 //the brush must be parented before setting the lookup.
1477 HRM(newVisuals->Append(oldPath.get()),
1478 "Could not add old inverse path to new canvas visuals.");
1479 HRM(oldBrush->SetVisualLookup(buffer),
1480 "Could not set old inverse brush visual lookup.");
1481
1482 //Draw the clip filling shader.
1483 SkTScopedComPtr<IXpsOMGeometryFigure> shadedFigure;
1484 HR(this->createXpsRect(universeRect, FALSE, TRUE, &shadedFigure));
1485 HRM(shadedFigures->Append(shadedFigure.get()),
1486 "Could not add inverse shaded figure.");
1487 //the geometry is already set
1488 HR(this->clip(shadedPath, d));
1489 HRM(newVisuals->Append(shadedPath),
1490 "Could not add inverse shaded path to canvas visuals.");
1491
1492 //Draw the old canvas on top, clipped to the original path.
1493 SkTScopedComPtr<IXpsOMCanvas> topCanvas;
1494 HRM(this->fXpsFactory->CreateCanvas(&topCanvas),
1495 "Could not create top inverse canvas.");
1496 //Clip the canvas to prevent alpha spill.
1497 //This is the entire reason this canvas exists.
1498 HR(this->clip(topCanvas.get(), d));
1499
1500 SkTScopedComPtr<IXpsOMGeometry> topGeometry;
1501 HRM(this->fXpsFactory->CreateGeometry(&topGeometry),
1502 "Could not create top inverse geometry.");
1503
1504 SkTScopedComPtr<IXpsOMGeometryFigureCollection> topFigures;
1505 HRM(topGeometry->GetFigures(&topFigures),
1506 "Could not get top inverse figures.");
1507
1508 SkTScopedComPtr<IXpsOMGeometryFigure> topFigure;
1509 HR(this->createXpsRect(universeRect, FALSE, TRUE, &topFigure));
1510 HRM(topFigures->Append(topFigure.get()),
1511 "Could not add old inverse figure.");
1512
1513 SkTScopedComPtr<IXpsOMVisualBrush> topBrush;
1514 HRM(this->fXpsFactory->CreateVisualBrush(&universeRectXps,
1515 &universeRectXps,
1516 &topBrush),
1517 "Could not create top inverse brush.");
1518
1519 SkTScopedComPtr<IXpsOMPath> topPath;
1520 HRM(this->fXpsFactory->CreatePath(&topPath),
1521 "Could not create top inverse path.");
1522 HRM(topPath->SetGeometryLocal(topGeometry.get()),
1523 "Could not set top inverse geometry.");
1524 HRM(topPath->SetFillBrushLocal(topBrush.get()),
1525 "Could not set top inverse fill brush.");
1526 //the brush must be parented before setting the lookup.
1527 HRM(newVisuals->Append(topCanvas.get()),
1528 "Could not add top canvas to inverse canvas visuals.");
1529 SkTScopedComPtr<IXpsOMVisualCollection> topVisuals;
1530 HRM(topCanvas->GetVisuals(&topVisuals),
1531 "Could not get top inverse canvas visuals.");
1532 HRM(topVisuals->Append(topPath.get()),
1533 "Could not add top inverse path to top canvas visuals.");
1534 HRM(topBrush->SetVisualLookup(buffer),
1535 "Could not set top inverse brush visual lookup.");
1536
1537 HR(this->clipToPath(topPath.get(), devicePath, XPS_FILL_RULE_NONZERO));
1538
1539 //swap current canvas to new canvas
1540 this->fCurrentXpsCanvas.swap(newCanvas);
1541
1542 return S_OK;
1543 }
1544
1545 void SkXPSDevice::convertToPpm(const SkMaskFilter* filter, 1389 void SkXPSDevice::convertToPpm(const SkMaskFilter* filter,
1546 SkMatrix* matrix, 1390 SkMatrix* matrix,
1547 SkVector* ppuScale, 1391 SkVector* ppuScale,
1548 const SkIRect& clip, SkIRect* clipIRect) { 1392 const SkIRect& clip, SkIRect* clipIRect) {
1549 //This action is in unit space, but the ppm is specified in physical space. 1393 //This action is in unit space, but the ppm is specified in physical space.
1550 ppuScale->fX = SkScalarDiv(this->fCurrentPixelsPerMeter.fX, 1394 ppuScale->fX = SkScalarDiv(this->fCurrentPixelsPerMeter.fX,
1551 this->fCurrentUnitsPerMeter.fX); 1395 this->fCurrentUnitsPerMeter.fX);
1552 ppuScale->fY = SkScalarDiv(this->fCurrentPixelsPerMeter.fY, 1396 ppuScale->fY = SkScalarDiv(this->fCurrentPixelsPerMeter.fY,
1553 this->fCurrentUnitsPerMeter.fY); 1397 this->fCurrentUnitsPerMeter.fY);
1554 1398
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 } 1682 }
1839 1683
1840 //Get the figures from the shaded geometry. 1684 //Get the figures from the shaded geometry.
1841 SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1685 SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures;
1842 HRVM(shadedGeometry->GetFigures(&shadedFigures), 1686 HRVM(shadedGeometry->GetFigures(&shadedFigures),
1843 "Could not get shaded figures for shaded path."); 1687 "Could not get shaded figures for shaded path.");
1844 1688
1845 bool xpsTransformsPath = true; 1689 bool xpsTransformsPath = true;
1846 1690
1847 //Set the fill rule. 1691 //Set the fill rule.
1692 SkPath* xpsCompatiblePath = fillablePath;
1848 XPS_FILL_RULE xpsFillRule; 1693 XPS_FILL_RULE xpsFillRule;
1849 switch (platonicPath.getFillType()) { 1694 switch (fillablePath->getFillType()) {
1850 case SkPath::kWinding_FillType: 1695 case SkPath::kWinding_FillType:
1851 xpsFillRule = XPS_FILL_RULE_NONZERO; 1696 xpsFillRule = XPS_FILL_RULE_NONZERO;
1852 break; 1697 break;
1853 case SkPath::kEvenOdd_FillType: 1698 case SkPath::kEvenOdd_FillType:
1854 xpsFillRule = XPS_FILL_RULE_EVENODD; 1699 xpsFillRule = XPS_FILL_RULE_EVENODD;
1855 break; 1700 break;
1856 case SkPath::kInverseWinding_FillType: { 1701 case SkPath::kInverseWinding_FillType: {
1857 //[Fillable-path -> Device-path] 1702 //[Fillable-path (inverse winding) -> XPS-path (inverse even odd)]
1858 SkPath* devicePath = pathIsMutable ? fillablePath : &modifiedPath; 1703 if (!pathIsMutable) {
1859 fillablePath->transform(matrix, devicePath); 1704 xpsCompatiblePath = &modifiedPath;
1860 1705 pathIsMutable = true;
1861 HRV(this->drawInverseWindingPath(d, 1706 }
1862 *devicePath, 1707 if (!Simplify(*fillablePath, xpsCompatiblePath)) {
1863 shadedPath.get())); 1708 SkDEBUGF(("Could not simplify inverse winding path."));
1864 return; 1709 return;
1710 }
1865 } 1711 }
1712 // The xpsCompatiblePath is noW inverse even odd, so fall through.
1866 case SkPath::kInverseEvenOdd_FillType: { 1713 case SkPath::kInverseEvenOdd_FillType: {
1867 const SkRect universe = SkRect::MakeLTRB( 1714 const SkRect universe = SkRect::MakeLTRB(
1868 0, 0, 1715 0, 0,
1869 this->fCurrentCanvasSize.fWidth, 1716 this->fCurrentCanvasSize.fWidth,
1870 this->fCurrentCanvasSize.fHeight); 1717 this->fCurrentCanvasSize.fHeight);
1871 SkTScopedComPtr<IXpsOMGeometryFigure> addOneFigure; 1718 SkTScopedComPtr<IXpsOMGeometryFigure> addOneFigure;
1872 HRV(this->createXpsRect(universe, FALSE, TRUE, &addOneFigure)); 1719 HRV(this->createXpsRect(universe, FALSE, TRUE, &addOneFigure));
1873 HRVM(shadedFigures->Append(addOneFigure.get()), 1720 HRVM(shadedFigures->Append(addOneFigure.get()),
1874 "Could not add even-odd flip figure to shaded path."); 1721 "Could not add even-odd flip figure to shaded path.");
1875 xpsTransformsPath = false; 1722 xpsTransformsPath = false;
(...skipping 12 matching lines...) Expand all
1888 HRV(this->createXpsTransform(matrix, &xpsTransform)); 1735 HRV(this->createXpsTransform(matrix, &xpsTransform));
1889 1736
1890 if (xpsTransform.get()) { 1737 if (xpsTransform.get()) {
1891 HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()), 1738 HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()),
1892 "Could not set transform on shaded path."); 1739 "Could not set transform on shaded path.");
1893 } else { 1740 } else {
1894 xpsTransformsPath = false; 1741 xpsTransformsPath = false;
1895 } 1742 }
1896 } 1743 }
1897 1744
1898 SkPath* devicePath = fillablePath; 1745 SkPath* devicePath = xpsCompatiblePath;
1899 if (!xpsTransformsPath) { 1746 if (!xpsTransformsPath) {
1900 //[Fillable-path -> Device-path] 1747 //[Fillable-path -> Device-path]
1901 devicePath = pathIsMutable ? fillablePath : &modifiedPath; 1748 devicePath = pathIsMutable ? xpsCompatiblePath : &modifiedPath;
1902 fillablePath->transform(matrix, devicePath); 1749 xpsCompatiblePath->transform(matrix, devicePath);
1903 } 1750 }
1904 HRV(this->addXpsPathGeometry(shadedFigures.get(), 1751 HRV(this->addXpsPathGeometry(shadedFigures.get(),
1905 stroke, fill, *devicePath)); 1752 stroke, fill, *devicePath));
1906 1753
1907 HRV(this->clip(shadedPath.get(), d)); 1754 HRV(this->clip(shadedPath.get(), d));
1908 1755
1909 //Add the path to the active visual collection. 1756 //Add the path to the active visual collection.
1910 SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 1757 SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
1911 HRVM(this->fCurrentXpsCanvas->GetVisuals(&currentVisuals), 1758 HRVM(this->fCurrentXpsCanvas->GetVisuals(&currentVisuals),
1912 "Could not get current visuals for shaded path."); 1759 "Could not get current visuals for shaded path.");
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
2430 IID_PPV_ARGS(&this->fXpsFactory)), 2277 IID_PPV_ARGS(&this->fXpsFactory)),
2431 "Could not create factory for layer."); 2278 "Could not create factory for layer.");
2432 2279
2433 HRVM(this->fXpsFactory->CreateCanvas(&this->fCurrentXpsCanvas), 2280 HRVM(this->fXpsFactory->CreateCanvas(&this->fCurrentXpsCanvas),
2434 "Could not create canvas for layer."); 2281 "Could not create canvas for layer.");
2435 } 2282 }
2436 2283
2437 bool SkXPSDevice::allowImageFilter(const SkImageFilter*) { 2284 bool SkXPSDevice::allowImageFilter(const SkImageFilter*) {
2438 return false; 2285 return false;
2439 } 2286 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698