| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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(¤tVisuals), | 1758 HRVM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), |
| 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 Loading... |
| 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 } |
| OLD | NEW |