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 |