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 |