| 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 #include "SkPDFDevice.h" | 8 #include "SkPDFDevice.h" |
| 9 #include "SkAnnotationKeys.h" | 9 #include "SkAnnotationKeys.h" |
| 10 #include "SkBitmapDevice.h" | 10 #include "SkBitmapDevice.h" |
| (...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 fDstFormXObject(nullptr) { | 557 fDstFormXObject(nullptr) { |
| 558 init(clipStack, clipRegion, matrix, paint, hasText); | 558 init(clipStack, clipRegion, matrix, paint, hasText); |
| 559 } | 559 } |
| 560 | 560 |
| 561 ~ScopedContentEntry() { | 561 ~ScopedContentEntry() { |
| 562 if (fContentEntry) { | 562 if (fContentEntry) { |
| 563 SkPath* shape = &fShape; | 563 SkPath* shape = &fShape; |
| 564 if (shape->isEmpty()) { | 564 if (shape->isEmpty()) { |
| 565 shape = nullptr; | 565 shape = nullptr; |
| 566 } | 566 } |
| 567 fDevice->finishContentEntry(fXfermode, fDstFormXObject, shape); | 567 fDevice->finishContentEntry(fXfermode, std::move(fDstFormXObject), s
hape); |
| 568 } | 568 } |
| 569 SkSafeUnref(fDstFormXObject); | |
| 570 } | 569 } |
| 571 | 570 |
| 572 SkPDFDevice::ContentEntry* entry() { return fContentEntry; } | 571 SkPDFDevice::ContentEntry* entry() { return fContentEntry; } |
| 573 | 572 |
| 574 /* Returns true when we explicitly need the shape of the drawing. */ | 573 /* Returns true when we explicitly need the shape of the drawing. */ |
| 575 bool needShape() { | 574 bool needShape() { |
| 576 switch (fXfermode) { | 575 switch (fXfermode) { |
| 577 case SkXfermode::kClear_Mode: | 576 case SkXfermode::kClear_Mode: |
| 578 case SkXfermode::kSrc_Mode: | 577 case SkXfermode::kSrc_Mode: |
| 579 case SkXfermode::kSrcIn_Mode: | 578 case SkXfermode::kSrcIn_Mode: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 602 * devices have rectangular shape. | 601 * devices have rectangular shape. |
| 603 */ | 602 */ |
| 604 void setShape(const SkPath& shape) { | 603 void setShape(const SkPath& shape) { |
| 605 fShape = shape; | 604 fShape = shape; |
| 606 } | 605 } |
| 607 | 606 |
| 608 private: | 607 private: |
| 609 SkPDFDevice* fDevice; | 608 SkPDFDevice* fDevice; |
| 610 SkPDFDevice::ContentEntry* fContentEntry; | 609 SkPDFDevice::ContentEntry* fContentEntry; |
| 611 SkXfermode::Mode fXfermode; | 610 SkXfermode::Mode fXfermode; |
| 612 SkPDFObject* fDstFormXObject; | 611 sk_sp<SkPDFObject> fDstFormXObject; |
| 613 SkPath fShape; | 612 SkPath fShape; |
| 614 | 613 |
| 615 void init(const SkClipStack* clipStack, const SkRegion& clipRegion, | 614 void init(const SkClipStack* clipStack, const SkRegion& clipRegion, |
| 616 const SkMatrix& matrix, const SkPaint& paint, bool hasText) { | 615 const SkMatrix& matrix, const SkPaint& paint, bool hasText) { |
| 617 // Shape has to be flatten before we get here. | 616 // Shape has to be flatten before we get here. |
| 618 if (matrix.hasPerspective()) { | 617 if (matrix.hasPerspective()) { |
| 619 NOT_IMPLEMENTED(!matrix.hasPerspective(), false); | 618 NOT_IMPLEMENTED(!matrix.hasPerspective(), false); |
| 620 return; | 619 return; |
| 621 } | 620 } |
| 622 if (paint.getXfermode()) { | 621 if (paint.getXfermode()) { |
| (...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1599 this->makeResourceDict(), inverseTransform, nullptr
); | 1598 this->makeResourceDict(), inverseTransform, nullptr
); |
| 1600 // We always draw the form xobjects that we create back into the device, so | 1599 // We always draw the form xobjects that we create back into the device, so |
| 1601 // we simply preserve the font usage instead of pulling it out and merging | 1600 // we simply preserve the font usage instead of pulling it out and merging |
| 1602 // it back in later. | 1601 // it back in later. |
| 1603 this->cleanUp(); // Reset this device to have no content. | 1602 this->cleanUp(); // Reset this device to have no content. |
| 1604 this->init(); | 1603 this->init(); |
| 1605 return xobject; | 1604 return xobject; |
| 1606 } | 1605 } |
| 1607 | 1606 |
| 1608 void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, | 1607 void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, |
| 1609 SkPDFObject* mask, | 1608 sk_sp<SkPDFObject> mask, |
| 1610 const SkClipStack* clipStack, | 1609 const SkClipStack* clipStack, |
| 1611 const SkRegion& clipRegion, | 1610 const SkRegion& clipRegion, |
| 1612 SkXfermode::Mode mode, | 1611 SkXfermode::Mode mode, |
| 1613 bool invertClip) { | 1612 bool invertClip) { |
| 1614 if (clipRegion.isEmpty() && !invertClip) { | 1613 if (clipRegion.isEmpty() && !invertClip) { |
| 1615 return; | 1614 return; |
| 1616 } | 1615 } |
| 1617 | 1616 |
| 1618 sk_sp<SkPDFDict> sMaskGS = SkPDFGraphicState::GetSMaskGraphicState( | 1617 sk_sp<SkPDFDict> sMaskGS = SkPDFGraphicState::GetSMaskGraphicState( |
| 1619 mask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode, fDocument->ca
non()); | 1618 std::move(mask), invertClip, |
| 1619 SkPDFGraphicState::kAlpha_SMaskMode, fDocument->canon()); |
| 1620 | 1620 |
| 1621 SkMatrix identity; | 1621 SkMatrix identity; |
| 1622 identity.reset(); | 1622 identity.reset(); |
| 1623 SkPaint paint; | 1623 SkPaint paint; |
| 1624 paint.setXfermodeMode(mode); | 1624 paint.setXfermodeMode(mode); |
| 1625 ScopedContentEntry content(this, clipStack, clipRegion, identity, paint); | 1625 ScopedContentEntry content(this, clipStack, clipRegion, identity, paint); |
| 1626 if (!content.entry()) { | 1626 if (!content.entry()) { |
| 1627 return; | 1627 return; |
| 1628 } | 1628 } |
| 1629 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), | 1629 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), |
| 1630 &content.entry()->fContent); | 1630 &content.entry()->fContent); |
| 1631 SkPDFUtils::DrawFormXObject(xObjectIndex, &content.entry()->fContent); | 1631 SkPDFUtils::DrawFormXObject(xObjectIndex, &content.entry()->fContent); |
| 1632 | 1632 |
| 1633 // Call makeNoSmaskGraphicState() instead of | 1633 // Call makeNoSmaskGraphicState() instead of |
| 1634 // SkPDFGraphicState::MakeNoSmaskGraphicState so that the canon | 1634 // SkPDFGraphicState::MakeNoSmaskGraphicState so that the canon |
| 1635 // can deduplicate. | 1635 // can deduplicate. |
| 1636 sMaskGS = fDocument->canon()->makeNoSmaskGraphicState(); | 1636 sMaskGS = fDocument->canon()->makeNoSmaskGraphicState(); |
| 1637 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), | 1637 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), |
| 1638 &content.entry()->fContent); | 1638 &content.entry()->fContent); |
| 1639 } | 1639 } |
| 1640 | 1640 |
| 1641 SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* cli
pStack, | 1641 SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* cli
pStack, |
| 1642 const SkRegion& clipRegion, | 1642 const SkRegion& clipRegion, |
| 1643 const SkMatrix& matrix, | 1643 const SkMatrix& matrix, |
| 1644 const SkPaint& paint, | 1644 const SkPaint& paint, |
| 1645 bool hasText, | 1645 bool hasText, |
| 1646 SkPDFObject** dst) { | 1646 sk_sp<SkPDFObject>* dst) { |
| 1647 *dst = nullptr; | 1647 *dst = nullptr; |
| 1648 if (clipRegion.isEmpty()) { | 1648 if (clipRegion.isEmpty()) { |
| 1649 return nullptr; | 1649 return nullptr; |
| 1650 } | 1650 } |
| 1651 | 1651 |
| 1652 // The clip stack can come from an SkDraw where it is technically optional. | 1652 // The clip stack can come from an SkDraw where it is technically optional. |
| 1653 SkClipStack synthesizedClipStack; | 1653 SkClipStack synthesizedClipStack; |
| 1654 if (clipStack == nullptr) { | 1654 if (clipStack == nullptr) { |
| 1655 if (clipRegion == fExistingClipRegion) { | 1655 if (clipRegion == fExistingClipRegion) { |
| 1656 clipStack = &fExistingClipStack; | 1656 clipStack = &fExistingClipStack; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1677 if (xfermode == SkXfermode::kClear_Mode || | 1677 if (xfermode == SkXfermode::kClear_Mode || |
| 1678 xfermode == SkXfermode::kSrc_Mode || | 1678 xfermode == SkXfermode::kSrc_Mode || |
| 1679 xfermode == SkXfermode::kSrcIn_Mode || | 1679 xfermode == SkXfermode::kSrcIn_Mode || |
| 1680 xfermode == SkXfermode::kDstIn_Mode || | 1680 xfermode == SkXfermode::kDstIn_Mode || |
| 1681 xfermode == SkXfermode::kSrcOut_Mode || | 1681 xfermode == SkXfermode::kSrcOut_Mode || |
| 1682 xfermode == SkXfermode::kDstOut_Mode || | 1682 xfermode == SkXfermode::kDstOut_Mode || |
| 1683 xfermode == SkXfermode::kSrcATop_Mode || | 1683 xfermode == SkXfermode::kSrcATop_Mode || |
| 1684 xfermode == SkXfermode::kDstATop_Mode || | 1684 xfermode == SkXfermode::kDstATop_Mode || |
| 1685 xfermode == SkXfermode::kModulate_Mode) { | 1685 xfermode == SkXfermode::kModulate_Mode) { |
| 1686 if (!isContentEmpty()) { | 1686 if (!isContentEmpty()) { |
| 1687 // TODO(halcanary): make this safer. | 1687 *dst = this->makeFormXObjectFromDevice(); |
| 1688 *dst = this->makeFormXObjectFromDevice().release(); | |
| 1689 SkASSERT(isContentEmpty()); | 1688 SkASSERT(isContentEmpty()); |
| 1690 } else if (xfermode != SkXfermode::kSrc_Mode && | 1689 } else if (xfermode != SkXfermode::kSrc_Mode && |
| 1691 xfermode != SkXfermode::kSrcOut_Mode) { | 1690 xfermode != SkXfermode::kSrcOut_Mode) { |
| 1692 // Except for Src and SrcOut, if there isn't anything already there, | 1691 // Except for Src and SrcOut, if there isn't anything already there, |
| 1693 // then we're done. | 1692 // then we're done. |
| 1694 return nullptr; | 1693 return nullptr; |
| 1695 } | 1694 } |
| 1696 } | 1695 } |
| 1697 // TODO(vandebo): Figure out how/if we can handle the following modes: | 1696 // TODO(vandebo): Figure out how/if we can handle the following modes: |
| 1698 // Xor, Plus. | 1697 // Xor, Plus. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1709 entry = fContentEntries.emplace_back(); | 1708 entry = fContentEntries.emplace_back(); |
| 1710 } else { | 1709 } else { |
| 1711 entry = fContentEntries.emplace_front(); | 1710 entry = fContentEntries.emplace_front(); |
| 1712 } | 1711 } |
| 1713 populateGraphicStateEntryFromPaint(matrix, *clipStack, clipRegion, paint, | 1712 populateGraphicStateEntryFromPaint(matrix, *clipStack, clipRegion, paint, |
| 1714 hasText, &entry->fState); | 1713 hasText, &entry->fState); |
| 1715 return entry; | 1714 return entry; |
| 1716 } | 1715 } |
| 1717 | 1716 |
| 1718 void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode, | 1717 void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode, |
| 1719 SkPDFObject* dst, | 1718 sk_sp<SkPDFObject> dst, |
| 1720 SkPath* shape) { | 1719 SkPath* shape) { |
| 1721 if (xfermode != SkXfermode::kClear_Mode && | 1720 if (xfermode != SkXfermode::kClear_Mode && |
| 1722 xfermode != SkXfermode::kSrc_Mode && | 1721 xfermode != SkXfermode::kSrc_Mode && |
| 1723 xfermode != SkXfermode::kDstOver_Mode && | 1722 xfermode != SkXfermode::kDstOver_Mode && |
| 1724 xfermode != SkXfermode::kSrcIn_Mode && | 1723 xfermode != SkXfermode::kSrcIn_Mode && |
| 1725 xfermode != SkXfermode::kDstIn_Mode && | 1724 xfermode != SkXfermode::kDstIn_Mode && |
| 1726 xfermode != SkXfermode::kSrcOut_Mode && | 1725 xfermode != SkXfermode::kSrcOut_Mode && |
| 1727 xfermode != SkXfermode::kDstOut_Mode && | 1726 xfermode != SkXfermode::kDstOut_Mode && |
| 1728 xfermode != SkXfermode::kSrcATop_Mode && | 1727 xfermode != SkXfermode::kSrcATop_Mode && |
| 1729 xfermode != SkXfermode::kDstATop_Mode && | 1728 xfermode != SkXfermode::kDstATop_Mode && |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1766 // If nothing was drawn and there's no shape, then the draw was a | 1765 // If nothing was drawn and there's no shape, then the draw was a |
| 1767 // no-op, but dst needs to be restored for that to be true. | 1766 // no-op, but dst needs to be restored for that to be true. |
| 1768 // If there is shape, then an empty source with Src, SrcIn, SrcOut, | 1767 // If there is shape, then an empty source with Src, SrcIn, SrcOut, |
| 1769 // DstIn, DstAtop or Modulate reduces to Clear and DstOut or SrcAtop | 1768 // DstIn, DstAtop or Modulate reduces to Clear and DstOut or SrcAtop |
| 1770 // reduces to Dst. | 1769 // reduces to Dst. |
| 1771 if (shape == nullptr || xfermode == SkXfermode::kDstOut_Mode || | 1770 if (shape == nullptr || xfermode == SkXfermode::kDstOut_Mode || |
| 1772 xfermode == SkXfermode::kSrcATop_Mode) { | 1771 xfermode == SkXfermode::kSrcATop_Mode) { |
| 1773 ScopedContentEntry content(this, &fExistingClipStack, | 1772 ScopedContentEntry content(this, &fExistingClipStack, |
| 1774 fExistingClipRegion, identity, | 1773 fExistingClipRegion, identity, |
| 1775 stockPaint); | 1774 stockPaint); |
| 1776 SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst), | 1775 // TODO: addXObjectResource take sk_sp |
| 1776 SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()), |
| 1777 &content.entry()->fContent); | 1777 &content.entry()->fContent); |
| 1778 return; | 1778 return; |
| 1779 } else { | 1779 } else { |
| 1780 xfermode = SkXfermode::kClear_Mode; | 1780 xfermode = SkXfermode::kClear_Mode; |
| 1781 } | 1781 } |
| 1782 } else { | 1782 } else { |
| 1783 SkASSERT(fContentEntries.count() == 1); | 1783 SkASSERT(fContentEntries.count() == 1); |
| 1784 srcFormXObject = this->makeFormXObjectFromDevice(); | 1784 srcFormXObject = this->makeFormXObjectFromDevice(); |
| 1785 } | 1785 } |
| 1786 | 1786 |
| 1787 // TODO(vandebo) srcFormXObject may contain alpha, but here we want it | 1787 // TODO(vandebo) srcFormXObject may contain alpha, but here we want it |
| 1788 // without alpha. | 1788 // without alpha. |
| 1789 if (xfermode == SkXfermode::kSrcATop_Mode) { | 1789 if (xfermode == SkXfermode::kSrcATop_Mode) { |
| 1790 // TODO(vandebo): In order to properly support SrcATop we have to track | 1790 // TODO(vandebo): In order to properly support SrcATop we have to track |
| 1791 // the shape of what's been drawn at all times. It's the intersection of | 1791 // the shape of what's been drawn at all times. It's the intersection of |
| 1792 // the non-transparent parts of the device and the outlines (shape) of | 1792 // the non-transparent parts of the device and the outlines (shape) of |
| 1793 // all images and devices drawn. | 1793 // all images and devices drawn. |
| 1794 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst, | 1794 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst, |
| 1795 &fExistingClipStack, fExistingClipRegion, | 1795 &fExistingClipStack, fExistingClipRegion, |
| 1796 SkXfermode::kSrcOver_Mode, true); | 1796 SkXfermode::kSrcOver_Mode, true); |
| 1797 } else { | 1797 } else { |
| 1798 sk_sp<SkPDFObject> dstMaskStorage; | |
| 1799 SkPDFObject* dstMask = srcFormXObject.get(); | |
| 1800 if (shape != nullptr) { | 1798 if (shape != nullptr) { |
| 1801 // Draw shape into a form-xobject. | 1799 // Draw shape into a form-xobject. |
| 1802 SkRasterClip rc(clipRegion); | 1800 SkRasterClip rc(clipRegion); |
| 1803 SkDraw d; | 1801 SkDraw d; |
| 1804 d.fMatrix = &identity; | 1802 d.fMatrix = &identity; |
| 1805 d.fRC = &rc; | 1803 d.fRC = &rc; |
| 1806 d.fClipStack = &clipStack; | 1804 d.fClipStack = &clipStack; |
| 1807 SkPaint filledPaint; | 1805 SkPaint filledPaint; |
| 1808 filledPaint.setColor(SK_ColorBLACK); | 1806 filledPaint.setColor(SK_ColorBLACK); |
| 1809 filledPaint.setStyle(SkPaint::kFill_Style); | 1807 filledPaint.setStyle(SkPaint::kFill_Style); |
| 1810 this->drawPath(d, *shape, filledPaint, nullptr, true); | 1808 this->drawPath(d, *shape, filledPaint, nullptr, true); |
| 1809 drawFormXObjectWithMask(addXObjectResource(dst.get()), |
| 1810 this->makeFormXObjectFromDevice(), |
| 1811 &fExistingClipStack, fExistingClipRegion, |
| 1812 SkXfermode::kSrcOver_Mode, true); |
| 1811 | 1813 |
| 1812 dstMaskStorage = this->makeFormXObjectFromDevice(); | 1814 } else { |
| 1813 dstMask = dstMaskStorage.get(); | 1815 drawFormXObjectWithMask(addXObjectResource(dst.get()), srcFormXObjec
t, |
| 1816 &fExistingClipStack, fExistingClipRegion, |
| 1817 SkXfermode::kSrcOver_Mode, true); |
| 1814 } | 1818 } |
| 1815 drawFormXObjectWithMask(addXObjectResource(dst), dstMask, | |
| 1816 &fExistingClipStack, fExistingClipRegion, | |
| 1817 SkXfermode::kSrcOver_Mode, true); | |
| 1818 } | 1819 } |
| 1819 | 1820 |
| 1820 if (xfermode == SkXfermode::kClear_Mode) { | 1821 if (xfermode == SkXfermode::kClear_Mode) { |
| 1821 return; | 1822 return; |
| 1822 } else if (xfermode == SkXfermode::kSrc_Mode || | 1823 } else if (xfermode == SkXfermode::kSrc_Mode || |
| 1823 xfermode == SkXfermode::kDstATop_Mode) { | 1824 xfermode == SkXfermode::kDstATop_Mode) { |
| 1824 ScopedContentEntry content(this, &fExistingClipStack, | 1825 ScopedContentEntry content(this, &fExistingClipStack, |
| 1825 fExistingClipRegion, identity, stockPaint); | 1826 fExistingClipRegion, identity, stockPaint); |
| 1826 if (content.entry()) { | 1827 if (content.entry()) { |
| 1827 SkPDFUtils::DrawFormXObject( | 1828 SkPDFUtils::DrawFormXObject( |
| 1828 this->addXObjectResource(srcFormXObject.get()), | 1829 this->addXObjectResource(srcFormXObject.get()), |
| 1829 &content.entry()->fContent); | 1830 &content.entry()->fContent); |
| 1830 } | 1831 } |
| 1831 if (xfermode == SkXfermode::kSrc_Mode) { | 1832 if (xfermode == SkXfermode::kSrc_Mode) { |
| 1832 return; | 1833 return; |
| 1833 } | 1834 } |
| 1834 } else if (xfermode == SkXfermode::kSrcATop_Mode) { | 1835 } else if (xfermode == SkXfermode::kSrcATop_Mode) { |
| 1835 ScopedContentEntry content(this, &fExistingClipStack, | 1836 ScopedContentEntry content(this, &fExistingClipStack, |
| 1836 fExistingClipRegion, identity, stockPaint); | 1837 fExistingClipRegion, identity, stockPaint); |
| 1837 if (content.entry()) { | 1838 if (content.entry()) { |
| 1838 SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst), | 1839 SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()), |
| 1839 &content.entry()->fContent); | 1840 &content.entry()->fContent); |
| 1840 } | 1841 } |
| 1841 } | 1842 } |
| 1842 | 1843 |
| 1843 SkASSERT(xfermode == SkXfermode::kSrcIn_Mode || | 1844 SkASSERT(xfermode == SkXfermode::kSrcIn_Mode || |
| 1844 xfermode == SkXfermode::kDstIn_Mode || | 1845 xfermode == SkXfermode::kDstIn_Mode || |
| 1845 xfermode == SkXfermode::kSrcOut_Mode || | 1846 xfermode == SkXfermode::kSrcOut_Mode || |
| 1846 xfermode == SkXfermode::kDstOut_Mode || | 1847 xfermode == SkXfermode::kDstOut_Mode || |
| 1847 xfermode == SkXfermode::kSrcATop_Mode || | 1848 xfermode == SkXfermode::kSrcATop_Mode || |
| 1848 xfermode == SkXfermode::kDstATop_Mode || | 1849 xfermode == SkXfermode::kDstATop_Mode || |
| 1849 xfermode == SkXfermode::kModulate_Mode); | 1850 xfermode == SkXfermode::kModulate_Mode); |
| 1850 | 1851 |
| 1851 if (xfermode == SkXfermode::kSrcIn_Mode || | 1852 if (xfermode == SkXfermode::kSrcIn_Mode || |
| 1852 xfermode == SkXfermode::kSrcOut_Mode || | 1853 xfermode == SkXfermode::kSrcOut_Mode || |
| 1853 xfermode == SkXfermode::kSrcATop_Mode) { | 1854 xfermode == SkXfermode::kSrcATop_Mode) { |
| 1854 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst, | 1855 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), |
| 1856 std::move(dst), |
| 1855 &fExistingClipStack, fExistingClipRegion, | 1857 &fExistingClipStack, fExistingClipRegion, |
| 1856 SkXfermode::kSrcOver_Mode, | 1858 SkXfermode::kSrcOver_Mode, |
| 1857 xfermode == SkXfermode::kSrcOut_Mode); | 1859 xfermode == SkXfermode::kSrcOut_Mode); |
| 1860 return; |
| 1858 } else { | 1861 } else { |
| 1859 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode; | 1862 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode; |
| 1863 int resourceID = addXObjectResource(dst.get()); |
| 1860 if (xfermode == SkXfermode::kModulate_Mode) { | 1864 if (xfermode == SkXfermode::kModulate_Mode) { |
| 1861 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), | 1865 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), |
| 1862 dst, &fExistingClipStack, | 1866 std::move(dst), &fExistingClipStack, |
| 1863 fExistingClipRegion, | 1867 fExistingClipRegion, |
| 1864 SkXfermode::kSrcOver_Mode, false); | 1868 SkXfermode::kSrcOver_Mode, false); |
| 1865 mode = SkXfermode::kMultiply_Mode; | 1869 mode = SkXfermode::kMultiply_Mode; |
| 1866 } | 1870 } |
| 1867 drawFormXObjectWithMask(addXObjectResource(dst), srcFormXObject.get(), | 1871 drawFormXObjectWithMask(resourceID, std::move(srcFormXObject), |
| 1868 &fExistingClipStack, fExistingClipRegion, mode, | 1872 &fExistingClipStack, fExistingClipRegion, mode, |
| 1869 xfermode == SkXfermode::kDstOut_Mode); | 1873 xfermode == SkXfermode::kDstOut_Mode); |
| 1874 return; |
| 1870 } | 1875 } |
| 1871 } | 1876 } |
| 1872 | 1877 |
| 1873 bool SkPDFDevice::isContentEmpty() { | 1878 bool SkPDFDevice::isContentEmpty() { |
| 1874 if (!fContentEntries.front() || fContentEntries.front()->fContent.getOffset(
) == 0) { | 1879 if (!fContentEntries.front() || fContentEntries.front()->fContent.getOffset(
) == 0) { |
| 1875 SkASSERT(fContentEntries.count() <= 1); | 1880 SkASSERT(fContentEntries.count() <= 1); |
| 1876 return true; | 1881 return true; |
| 1877 } | 1882 } |
| 1878 return false; | 1883 return false; |
| 1879 } | 1884 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1911 | 1916 |
| 1912 // We need to apply the initial transform to bounds in order to get | 1917 // We need to apply the initial transform to bounds in order to get |
| 1913 // bounds in a consistent coordinate system. | 1918 // bounds in a consistent coordinate system. |
| 1914 SkRect boundsTemp; | 1919 SkRect boundsTemp; |
| 1915 boundsTemp.set(bounds); | 1920 boundsTemp.set(bounds); |
| 1916 fInitialTransform.mapRect(&boundsTemp); | 1921 fInitialTransform.mapRect(&boundsTemp); |
| 1917 boundsTemp.roundOut(&bounds); | 1922 boundsTemp.roundOut(&bounds); |
| 1918 | 1923 |
| 1919 SkScalar rasterScale = | 1924 SkScalar rasterScale = |
| 1920 SkIntToScalar(fRasterDpi) / DPI_FOR_RASTER_SCALE_ONE; | 1925 SkIntToScalar(fRasterDpi) / DPI_FOR_RASTER_SCALE_ONE; |
| 1921 pdfShader.reset(SkPDFShader::GetPDFShader( | 1926 pdfShader = SkPDFShader::GetPDFShader( |
| 1922 fDocument, fRasterDpi, shader, transform, bounds, rasterScale)); | 1927 fDocument, fRasterDpi, shader, transform, bounds, rasterScale); |
| 1923 | 1928 |
| 1924 if (pdfShader.get()) { | 1929 if (pdfShader.get()) { |
| 1925 // pdfShader has been canonicalized so we can directly compare | 1930 // pdfShader has been canonicalized so we can directly compare |
| 1926 // pointers. | 1931 // pointers. |
| 1927 int resourceIndex = fShaderResources.find(pdfShader.get()); | 1932 int resourceIndex = fShaderResources.find(pdfShader.get()); |
| 1928 if (resourceIndex < 0) { | 1933 if (resourceIndex < 0) { |
| 1929 resourceIndex = fShaderResources.count(); | 1934 resourceIndex = fShaderResources.count(); |
| 1930 fShaderResources.push(pdfShader.get()); | 1935 fShaderResources.push(pdfShader.get()); |
| 1931 pdfShader.get()->ref(); | 1936 pdfShader.get()->ref(); |
| 1932 } | 1937 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1974 int result = fGraphicStateResources.find(gs); | 1979 int result = fGraphicStateResources.find(gs); |
| 1975 if (result < 0) { | 1980 if (result < 0) { |
| 1976 result = fGraphicStateResources.count(); | 1981 result = fGraphicStateResources.count(); |
| 1977 fGraphicStateResources.push(gs); | 1982 fGraphicStateResources.push(gs); |
| 1978 gs->ref(); | 1983 gs->ref(); |
| 1979 } | 1984 } |
| 1980 return result; | 1985 return result; |
| 1981 } | 1986 } |
| 1982 | 1987 |
| 1983 int SkPDFDevice::addXObjectResource(SkPDFObject* xObject) { | 1988 int SkPDFDevice::addXObjectResource(SkPDFObject* xObject) { |
| 1989 // TODO(halcanary): make this take a sk_sp<SkPDFObject> |
| 1984 // Assumes that xobject has been canonicalized (so we can directly compare | 1990 // Assumes that xobject has been canonicalized (so we can directly compare |
| 1985 // pointers). | 1991 // pointers). |
| 1986 int result = fXObjectResources.find(xObject); | 1992 int result = fXObjectResources.find(xObject); |
| 1987 if (result < 0) { | 1993 if (result < 0) { |
| 1988 result = fXObjectResources.count(); | 1994 result = fXObjectResources.count(); |
| 1989 fXObjectResources.push(xObject); | 1995 fXObjectResources.push(SkRef(xObject)); |
| 1990 xObject->ref(); | |
| 1991 } | 1996 } |
| 1992 return result; | 1997 return result; |
| 1993 } | 1998 } |
| 1994 | 1999 |
| 1995 void SkPDFDevice::updateFont(const SkPaint& paint, uint16_t glyphID, | 2000 void SkPDFDevice::updateFont(const SkPaint& paint, uint16_t glyphID, |
| 1996 SkPDFDevice::ContentEntry* contentEntry) { | 2001 SkPDFDevice::ContentEntry* contentEntry) { |
| 1997 SkTypeface* typeface = paint.getTypeface(); | 2002 SkTypeface* typeface = paint.getTypeface(); |
| 1998 if (contentEntry->fState.fFont == nullptr || | 2003 if (contentEntry->fState.fFont == nullptr || |
| 1999 contentEntry->fState.fTextSize != paint.getTextSize() || | 2004 contentEntry->fState.fTextSize != paint.getTextSize() || |
| 2000 !contentEntry->fState.fFont->hasGlyph(glyphID)) { | 2005 !contentEntry->fState.fFont->hasGlyph(glyphID)) { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2227 } | 2232 } |
| 2228 | 2233 |
| 2229 sk_sp<SkSpecialImage> SkPDFDevice::makeSpecial(const SkImage* image) { | 2234 sk_sp<SkSpecialImage> SkPDFDevice::makeSpecial(const SkImage* image) { |
| 2230 return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(image->width(), image->
height()), | 2235 return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(image->width(), image->
height()), |
| 2231 image->makeNonTextureImage()); | 2236 image->makeNonTextureImage()); |
| 2232 } | 2237 } |
| 2233 | 2238 |
| 2234 sk_sp<SkSpecialImage> SkPDFDevice::snapSpecial() { | 2239 sk_sp<SkSpecialImage> SkPDFDevice::snapSpecial() { |
| 2235 return nullptr; | 2240 return nullptr; |
| 2236 } | 2241 } |
| OLD | NEW |