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 | 9 |
10 #include "SkAnnotationKeys.h" | 10 #include "SkAnnotationKeys.h" |
(...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 SkPDFUtils::ClosePath(&content.entry()->fContent); | 873 SkPDFUtils::ClosePath(&content.entry()->fContent); |
874 SkPDFUtils::StrokePath(&content.entry()->fContent); | 874 SkPDFUtils::StrokePath(&content.entry()->fContent); |
875 } | 875 } |
876 break; | 876 break; |
877 default: | 877 default: |
878 SkASSERT(false); | 878 SkASSERT(false); |
879 } | 879 } |
880 } | 880 } |
881 | 881 |
882 static SkPDFDict* create_link_annotation(const SkRect& translatedRect) { | 882 static SkPDFDict* create_link_annotation(const SkRect& translatedRect) { |
883 SkAutoTUnref<SkPDFDict> annotation(new SkPDFDict("Annot")); | 883 sk_sp<SkPDFDict> annotation(new SkPDFDict("Annot")); |
884 annotation->insertName("Subtype", "Link"); | 884 annotation->insertName("Subtype", "Link"); |
885 | 885 |
886 SkAutoTUnref<SkPDFArray> border(new SkPDFArray); | 886 sk_sp<SkPDFArray> border(new SkPDFArray); |
887 border->reserve(3); | 887 border->reserve(3); |
888 border->appendInt(0); // Horizontal corner radius. | 888 border->appendInt(0); // Horizontal corner radius. |
889 border->appendInt(0); // Vertical corner radius. | 889 border->appendInt(0); // Vertical corner radius. |
890 border->appendInt(0); // Width, 0 = no border. | 890 border->appendInt(0); // Width, 0 = no border. |
891 annotation->insertObject("Border", border.release()); | 891 annotation->insertObject("Border", border.release()); |
892 | 892 |
893 SkAutoTUnref<SkPDFArray> rect(new SkPDFArray); | 893 sk_sp<SkPDFArray> rect(new SkPDFArray); |
894 rect->reserve(4); | 894 rect->reserve(4); |
895 rect->appendScalar(translatedRect.fLeft); | 895 rect->appendScalar(translatedRect.fLeft); |
896 rect->appendScalar(translatedRect.fTop); | 896 rect->appendScalar(translatedRect.fTop); |
897 rect->appendScalar(translatedRect.fRight); | 897 rect->appendScalar(translatedRect.fRight); |
898 rect->appendScalar(translatedRect.fBottom); | 898 rect->appendScalar(translatedRect.fBottom); |
899 annotation->insertObject("Rect", rect.release()); | 899 annotation->insertObject("Rect", rect.release()); |
900 | 900 |
901 return annotation.release(); | 901 return annotation.release(); |
902 } | 902 } |
903 | 903 |
904 static SkPDFDict* create_link_to_url(const SkData* urlData, const SkRect& r) { | 904 static SkPDFDict* create_link_to_url(const SkData* urlData, const SkRect& r) { |
905 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r)); | 905 sk_sp<SkPDFDict> annotation(create_link_annotation(r)); |
906 | 906 |
907 SkString url(static_cast<const char *>(urlData->data()), | 907 SkString url(static_cast<const char *>(urlData->data()), |
908 urlData->size() - 1); | 908 urlData->size() - 1); |
909 SkAutoTUnref<SkPDFDict> action(new SkPDFDict("Action")); | 909 sk_sp<SkPDFDict> action(new SkPDFDict("Action")); |
910 action->insertName("S", "URI"); | 910 action->insertName("S", "URI"); |
911 action->insertString("URI", url); | 911 action->insertString("URI", url); |
912 annotation->insertObject("A", action.release()); | 912 annotation->insertObject("A", action.release()); |
913 return annotation.release(); | 913 return annotation.release(); |
914 } | 914 } |
915 | 915 |
916 static SkPDFDict* create_link_named_dest(const SkData* nameData, | 916 static SkPDFDict* create_link_named_dest(const SkData* nameData, |
917 const SkRect& r) { | 917 const SkRect& r) { |
918 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r)); | 918 sk_sp<SkPDFDict> annotation(create_link_annotation(r)); |
919 SkString name(static_cast<const char *>(nameData->data()), | 919 SkString name(static_cast<const char *>(nameData->data()), |
920 nameData->size() - 1); | 920 nameData->size() - 1); |
921 annotation->insertName("Dest", name); | 921 annotation->insertName("Dest", name); |
922 return annotation.release(); | 922 return annotation.release(); |
923 } | 923 } |
924 | 924 |
925 void SkPDFDevice::drawRect(const SkDraw& d, | 925 void SkPDFDevice::drawRect(const SkDraw& d, |
926 const SkRect& rect, | 926 const SkRect& rect, |
927 const SkPaint& srcPaint) { | 927 const SkPaint& srcPaint) { |
928 SkPaint paint = srcPaint; | 928 SkPaint paint = srcPaint; |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1139 // Compute matrix from the two rectangles | 1139 // Compute matrix from the two rectangles |
1140 if (src) { | 1140 if (src) { |
1141 tmpSrc = *src; | 1141 tmpSrc = *src; |
1142 } else { | 1142 } else { |
1143 tmpSrc = imageBounds; | 1143 tmpSrc = imageBounds; |
1144 } | 1144 } |
1145 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); | 1145 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); |
1146 | 1146 |
1147 // clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if | 1147 // clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if |
1148 // needed (if the src was clipped). No check needed if src==null. | 1148 // needed (if the src was clipped). No check needed if src==null. |
1149 SkAutoTUnref<const SkImage> autoImageUnref; | 1149 sk_sp<const SkImage> autoImageUnref; |
1150 if (src) { | 1150 if (src) { |
1151 if (!imageBounds.contains(*src)) { | 1151 if (!imageBounds.contains(*src)) { |
1152 if (!tmpSrc.intersect(imageBounds)) { | 1152 if (!tmpSrc.intersect(imageBounds)) { |
1153 return; // nothing to draw | 1153 return; // nothing to draw |
1154 } | 1154 } |
1155 // recompute dst, based on the smaller tmpSrc | 1155 // recompute dst, based on the smaller tmpSrc |
1156 matrix.mapRect(&tmpDst, tmpSrc); | 1156 matrix.mapRect(&tmpDst, tmpSrc); |
1157 } | 1157 } |
1158 | 1158 |
1159 // since we may need to clamp to the borders of the src rect within | 1159 // since we may need to clamp to the borders of the src rect within |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1441 SkPath shape; | 1441 SkPath shape; |
1442 shape.addRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y), | 1442 shape.addRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y), |
1443 SkIntToScalar(device->width()), | 1443 SkIntToScalar(device->width()), |
1444 SkIntToScalar(device->height()))); | 1444 SkIntToScalar(device->height()))); |
1445 content.setShape(shape); | 1445 content.setShape(shape); |
1446 } | 1446 } |
1447 if (!content.needSource()) { | 1447 if (!content.needSource()) { |
1448 return; | 1448 return; |
1449 } | 1449 } |
1450 | 1450 |
1451 SkAutoTUnref<SkPDFFormXObject> xObject(new SkPDFFormXObject(pdfDevice)); | 1451 sk_sp<SkPDFFormXObject> xObject(new SkPDFFormXObject(pdfDevice)); |
1452 SkPDFUtils::DrawFormXObject(this->addXObjectResource(xObject.get()), | 1452 SkPDFUtils::DrawFormXObject(this->addXObjectResource(xObject.get()), |
1453 &content.entry()->fContent); | 1453 &content.entry()->fContent); |
1454 | 1454 |
1455 // Merge glyph sets from the drawn device. | 1455 // Merge glyph sets from the drawn device. |
1456 fFontGlyphUsage->merge(pdfDevice->getFontGlyphUsage()); | 1456 fFontGlyphUsage->merge(pdfDevice->getFontGlyphUsage()); |
1457 } | 1457 } |
1458 | 1458 |
1459 SkImageInfo SkPDFDevice::imageInfo() const { | 1459 SkImageInfo SkPDFDevice::imageInfo() const { |
1460 return fLegacyBitmap.info(); | 1460 return fLegacyBitmap.info(); |
1461 } | 1461 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1520 &fonts); | 1520 &fonts); |
1521 } | 1521 } |
1522 | 1522 |
1523 const SkTDArray<SkPDFFont*>& SkPDFDevice::getFontResources() const { | 1523 const SkTDArray<SkPDFFont*>& SkPDFDevice::getFontResources() const { |
1524 return fFontResources; | 1524 return fFontResources; |
1525 } | 1525 } |
1526 | 1526 |
1527 SkPDFArray* SkPDFDevice::copyMediaBox() const { | 1527 SkPDFArray* SkPDFDevice::copyMediaBox() const { |
1528 // should this be a singleton? | 1528 // should this be a singleton? |
1529 | 1529 |
1530 SkAutoTUnref<SkPDFArray> mediaBox(new SkPDFArray); | 1530 sk_sp<SkPDFArray> mediaBox(new SkPDFArray); |
1531 mediaBox->reserve(4); | 1531 mediaBox->reserve(4); |
1532 mediaBox->appendInt(0); | 1532 mediaBox->appendInt(0); |
1533 mediaBox->appendInt(0); | 1533 mediaBox->appendInt(0); |
1534 mediaBox->appendInt(fPageSize.fWidth); | 1534 mediaBox->appendInt(fPageSize.fWidth); |
1535 mediaBox->appendInt(fPageSize.fHeight); | 1535 mediaBox->appendInt(fPageSize.fHeight); |
1536 return mediaBox.release(); | 1536 return mediaBox.release(); |
1537 } | 1537 } |
1538 | 1538 |
1539 SkStreamAsset* SkPDFDevice::content() const { | 1539 SkStreamAsset* SkPDFDevice::content() const { |
1540 SkDynamicMemoryWStream buffer; | 1540 SkDynamicMemoryWStream buffer; |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1704 for (const RectWithData& linkToDestination : fLinkToDestinations) { | 1704 for (const RectWithData& linkToDestination : fLinkToDestinations) { |
1705 SkRect r; | 1705 SkRect r; |
1706 fInitialTransform.mapRect(&r, linkToDestination.rect); | 1706 fInitialTransform.mapRect(&r, linkToDestination.rect); |
1707 array->appendObject( | 1707 array->appendObject( |
1708 create_link_named_dest(linkToDestination.data.get(), r)); | 1708 create_link_named_dest(linkToDestination.data.get(), r)); |
1709 } | 1709 } |
1710 } | 1710 } |
1711 | 1711 |
1712 void SkPDFDevice::appendDestinations(SkPDFDict* dict, SkPDFObject* page) const { | 1712 void SkPDFDevice::appendDestinations(SkPDFDict* dict, SkPDFObject* page) const { |
1713 for (const NamedDestination& dest : fNamedDestinations) { | 1713 for (const NamedDestination& dest : fNamedDestinations) { |
1714 SkAutoTUnref<SkPDFArray> pdfDest(new SkPDFArray); | 1714 sk_sp<SkPDFArray> pdfDest(new SkPDFArray); |
1715 pdfDest->reserve(5); | 1715 pdfDest->reserve(5); |
1716 pdfDest->appendObjRef(SkRef(page)); | 1716 pdfDest->appendObjRef(SkRef(page)); |
1717 pdfDest->appendName("XYZ"); | 1717 pdfDest->appendName("XYZ"); |
1718 SkPoint p = fInitialTransform.mapXY(dest.point.x(), dest.point.y()); | 1718 SkPoint p = fInitialTransform.mapXY(dest.point.x(), dest.point.y()); |
1719 pdfDest->appendScalar(p.x()); | 1719 pdfDest->appendScalar(p.x()); |
1720 pdfDest->appendScalar(p.y()); | 1720 pdfDest->appendScalar(p.y()); |
1721 pdfDest->appendInt(0); // Leave zoom unchanged | 1721 pdfDest->appendInt(0); // Leave zoom unchanged |
1722 SkString name(static_cast<const char*>(dest.nameData->data())); | 1722 SkString name(static_cast<const char*>(dest.nameData->data())); |
1723 dict->insertObject(name, pdfDest.release()); | 1723 dict->insertObject(name, pdfDest.release()); |
1724 } | 1724 } |
(...skipping 12 matching lines...) Expand all Loading... |
1737 void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, | 1737 void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, |
1738 SkPDFFormXObject* mask, | 1738 SkPDFFormXObject* mask, |
1739 const SkClipStack* clipStack, | 1739 const SkClipStack* clipStack, |
1740 const SkRegion& clipRegion, | 1740 const SkRegion& clipRegion, |
1741 SkXfermode::Mode mode, | 1741 SkXfermode::Mode mode, |
1742 bool invertClip) { | 1742 bool invertClip) { |
1743 if (clipRegion.isEmpty() && !invertClip) { | 1743 if (clipRegion.isEmpty() && !invertClip) { |
1744 return; | 1744 return; |
1745 } | 1745 } |
1746 | 1746 |
1747 SkAutoTUnref<SkPDFObject> sMaskGS(SkPDFGraphicState::GetSMaskGraphicState( | 1747 sk_sp<SkPDFObject> sMaskGS(SkPDFGraphicState::GetSMaskGraphicState( |
1748 mask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode)); | 1748 mask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode)); |
1749 | 1749 |
1750 SkMatrix identity; | 1750 SkMatrix identity; |
1751 identity.reset(); | 1751 identity.reset(); |
1752 SkPaint paint; | 1752 SkPaint paint; |
1753 paint.setXfermodeMode(mode); | 1753 paint.setXfermodeMode(mode); |
1754 ScopedContentEntry content(this, clipStack, clipRegion, identity, paint); | 1754 ScopedContentEntry content(this, clipStack, clipRegion, identity, paint); |
1755 if (!content.entry()) { | 1755 if (!content.entry()) { |
1756 return; | 1756 return; |
1757 } | 1757 } |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1901 // objects which is fine since the xobject will already be clipped. However | 1901 // objects which is fine since the xobject will already be clipped. However |
1902 // if source has shape, we need to clip it too, so a copy of the clip is | 1902 // if source has shape, we need to clip it too, so a copy of the clip is |
1903 // saved. | 1903 // saved. |
1904 SkClipStack clipStack = contentEntries->fState.fClipStack; | 1904 SkClipStack clipStack = contentEntries->fState.fClipStack; |
1905 SkRegion clipRegion = contentEntries->fState.fClipRegion; | 1905 SkRegion clipRegion = contentEntries->fState.fClipRegion; |
1906 | 1906 |
1907 SkMatrix identity; | 1907 SkMatrix identity; |
1908 identity.reset(); | 1908 identity.reset(); |
1909 SkPaint stockPaint; | 1909 SkPaint stockPaint; |
1910 | 1910 |
1911 SkAutoTUnref<SkPDFFormXObject> srcFormXObject; | 1911 sk_sp<SkPDFFormXObject> srcFormXObject; |
1912 if (isContentEmpty()) { | 1912 if (isContentEmpty()) { |
1913 // If nothing was drawn and there's no shape, then the draw was a | 1913 // If nothing was drawn and there's no shape, then the draw was a |
1914 // no-op, but dst needs to be restored for that to be true. | 1914 // no-op, but dst needs to be restored for that to be true. |
1915 // If there is shape, then an empty source with Src, SrcIn, SrcOut, | 1915 // If there is shape, then an empty source with Src, SrcIn, SrcOut, |
1916 // DstIn, DstAtop or Modulate reduces to Clear and DstOut or SrcAtop | 1916 // DstIn, DstAtop or Modulate reduces to Clear and DstOut or SrcAtop |
1917 // reduces to Dst. | 1917 // reduces to Dst. |
1918 if (shape == nullptr || xfermode == SkXfermode::kDstOut_Mode || | 1918 if (shape == nullptr || xfermode == SkXfermode::kDstOut_Mode || |
1919 xfermode == SkXfermode::kSrcATop_Mode) { | 1919 xfermode == SkXfermode::kSrcATop_Mode) { |
1920 ScopedContentEntry content(this, &fExistingClipStack, | 1920 ScopedContentEntry content(this, &fExistingClipStack, |
1921 fExistingClipRegion, identity, | 1921 fExistingClipRegion, identity, |
(...skipping 13 matching lines...) Expand all Loading... |
1935 // without alpha. | 1935 // without alpha. |
1936 if (xfermode == SkXfermode::kSrcATop_Mode) { | 1936 if (xfermode == SkXfermode::kSrcATop_Mode) { |
1937 // TODO(vandebo): In order to properly support SrcATop we have to track | 1937 // TODO(vandebo): In order to properly support SrcATop we have to track |
1938 // the shape of what's been drawn at all times. It's the intersection of | 1938 // the shape of what's been drawn at all times. It's the intersection of |
1939 // the non-transparent parts of the device and the outlines (shape) of | 1939 // the non-transparent parts of the device and the outlines (shape) of |
1940 // all images and devices drawn. | 1940 // all images and devices drawn. |
1941 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst, | 1941 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst, |
1942 &fExistingClipStack, fExistingClipRegion, | 1942 &fExistingClipStack, fExistingClipRegion, |
1943 SkXfermode::kSrcOver_Mode, true); | 1943 SkXfermode::kSrcOver_Mode, true); |
1944 } else { | 1944 } else { |
1945 SkAutoTUnref<SkPDFFormXObject> dstMaskStorage; | 1945 sk_sp<SkPDFFormXObject> dstMaskStorage; |
1946 SkPDFFormXObject* dstMask = srcFormXObject.get(); | 1946 SkPDFFormXObject* dstMask = srcFormXObject.get(); |
1947 if (shape != nullptr) { | 1947 if (shape != nullptr) { |
1948 // Draw shape into a form-xobject. | 1948 // Draw shape into a form-xobject. |
1949 SkDraw d; | 1949 SkDraw d; |
1950 d.fMatrix = &identity; | 1950 d.fMatrix = &identity; |
1951 d.fClip = &clipRegion; | 1951 d.fClip = &clipRegion; |
1952 d.fClipStack = &clipStack; | 1952 d.fClipStack = &clipStack; |
1953 SkPaint filledPaint; | 1953 SkPaint filledPaint; |
1954 filledPaint.setColor(SK_ColorBLACK); | 1954 filledPaint.setColor(SK_ColorBLACK); |
1955 filledPaint.setStyle(SkPaint::kFill_Style); | 1955 filledPaint.setStyle(SkPaint::kFill_Style); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2036 NOT_IMPLEMENTED(paint.getMaskFilter() != nullptr, false); | 2036 NOT_IMPLEMENTED(paint.getMaskFilter() != nullptr, false); |
2037 NOT_IMPLEMENTED(paint.getColorFilter() != nullptr, false); | 2037 NOT_IMPLEMENTED(paint.getColorFilter() != nullptr, false); |
2038 | 2038 |
2039 entry->fMatrix = matrix; | 2039 entry->fMatrix = matrix; |
2040 entry->fClipStack = clipStack; | 2040 entry->fClipStack = clipStack; |
2041 entry->fClipRegion = clipRegion; | 2041 entry->fClipRegion = clipRegion; |
2042 entry->fColor = SkColorSetA(paint.getColor(), 0xFF); | 2042 entry->fColor = SkColorSetA(paint.getColor(), 0xFF); |
2043 entry->fShaderIndex = -1; | 2043 entry->fShaderIndex = -1; |
2044 | 2044 |
2045 // PDF treats a shader as a color, so we only set one or the other. | 2045 // PDF treats a shader as a color, so we only set one or the other. |
2046 SkAutoTUnref<SkPDFObject> pdfShader; | 2046 sk_sp<SkPDFObject> pdfShader; |
2047 const SkShader* shader = paint.getShader(); | 2047 const SkShader* shader = paint.getShader(); |
2048 SkColor color = paint.getColor(); | 2048 SkColor color = paint.getColor(); |
2049 if (shader) { | 2049 if (shader) { |
2050 // PDF positions patterns relative to the initial transform, so | 2050 // PDF positions patterns relative to the initial transform, so |
2051 // we need to apply the current transform to the shader parameters. | 2051 // we need to apply the current transform to the shader parameters. |
2052 SkMatrix transform = matrix; | 2052 SkMatrix transform = matrix; |
2053 transform.postConcat(fInitialTransform); | 2053 transform.postConcat(fInitialTransform); |
2054 | 2054 |
2055 // PDF doesn't support kClamp_TileMode, so we simulate it by making | 2055 // PDF doesn't support kClamp_TileMode, so we simulate it by making |
2056 // a pattern the size of the current clip. | 2056 // a pattern the size of the current clip. |
(...skipping 30 matching lines...) Expand all Loading... |
2087 gradientInfo.fColorOffsets = nullptr; | 2087 gradientInfo.fColorOffsets = nullptr; |
2088 gradientInfo.fColorCount = 1; | 2088 gradientInfo.fColorCount = 1; |
2089 if (shader->asAGradient(&gradientInfo) == | 2089 if (shader->asAGradient(&gradientInfo) == |
2090 SkShader::kColor_GradientType) { | 2090 SkShader::kColor_GradientType) { |
2091 entry->fColor = SkColorSetA(gradientColor, 0xFF); | 2091 entry->fColor = SkColorSetA(gradientColor, 0xFF); |
2092 color = gradientColor; | 2092 color = gradientColor; |
2093 } | 2093 } |
2094 } | 2094 } |
2095 } | 2095 } |
2096 | 2096 |
2097 SkAutoTUnref<SkPDFGraphicState> newGraphicState; | 2097 sk_sp<SkPDFGraphicState> newGraphicState; |
2098 if (color == paint.getColor()) { | 2098 if (color == paint.getColor()) { |
2099 newGraphicState.reset( | 2099 newGraphicState.reset( |
2100 SkPDFGraphicState::GetGraphicStateForPaint(fCanon, paint)); | 2100 SkPDFGraphicState::GetGraphicStateForPaint(fCanon, paint)); |
2101 } else { | 2101 } else { |
2102 SkPaint newPaint = paint; | 2102 SkPaint newPaint = paint; |
2103 newPaint.setColor(color); | 2103 newPaint.setColor(color); |
2104 newGraphicState.reset( | 2104 newGraphicState.reset( |
2105 SkPDFGraphicState::GetGraphicStateForPaint(fCanon, newPaint)); | 2105 SkPDFGraphicState::GetGraphicStateForPaint(fCanon, newPaint)); |
2106 } | 2106 } |
2107 int resourceIndex = addGraphicStateResource(newGraphicState.get()); | 2107 int resourceIndex = addGraphicStateResource(newGraphicState.get()); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2151 SkPDFResourceDict::kFont_ResourceType, | 2151 SkPDFResourceDict::kFont_ResourceType, |
2152 fontIndex).c_str()); | 2152 fontIndex).c_str()); |
2153 contentEntry->fContent.writeText(" "); | 2153 contentEntry->fContent.writeText(" "); |
2154 SkPDFUtils::AppendScalar(paint.getTextSize(), &contentEntry->fContent); | 2154 SkPDFUtils::AppendScalar(paint.getTextSize(), &contentEntry->fContent); |
2155 contentEntry->fContent.writeText(" Tf\n"); | 2155 contentEntry->fContent.writeText(" Tf\n"); |
2156 contentEntry->fState.fFont = fFontResources[fontIndex]; | 2156 contentEntry->fState.fFont = fFontResources[fontIndex]; |
2157 } | 2157 } |
2158 } | 2158 } |
2159 | 2159 |
2160 int SkPDFDevice::getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID) { | 2160 int SkPDFDevice::getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID) { |
2161 SkAutoTUnref<SkPDFFont> newFont( | 2161 sk_sp<SkPDFFont> newFont( |
2162 SkPDFFont::GetFontResource(fCanon, typeface, glyphID)); | 2162 SkPDFFont::GetFontResource(fCanon, typeface, glyphID)); |
2163 int resourceIndex = fFontResources.find(newFont.get()); | 2163 int resourceIndex = fFontResources.find(newFont.get()); |
2164 if (resourceIndex < 0) { | 2164 if (resourceIndex < 0) { |
2165 resourceIndex = fFontResources.count(); | 2165 resourceIndex = fFontResources.count(); |
2166 fFontResources.push(newFont.get()); | 2166 fFontResources.push(newFont.get()); |
2167 newFont.get()->ref(); | 2167 newFont.get()->ref(); |
2168 } | 2168 } |
2169 return resourceIndex; | 2169 return resourceIndex; |
2170 } | 2170 } |
2171 | 2171 |
2172 static SkSize rect_to_size(const SkRect& r) { | 2172 static SkSize rect_to_size(const SkRect& r) { |
2173 return SkSize::Make(r.width(), r.height()); | 2173 return SkSize::Make(r.width(), r.height()); |
2174 } | 2174 } |
2175 | 2175 |
2176 static const SkImage* color_filter(const SkImage* image, | 2176 static const SkImage* color_filter(const SkImage* image, |
2177 SkColorFilter* colorFilter) { | 2177 SkColorFilter* colorFilter) { |
2178 SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster( | 2178 sk_sp<SkSurface> surface(SkSurface::NewRaster( |
2179 SkImageInfo::MakeN32Premul(image->dimensions()))); | 2179 SkImageInfo::MakeN32Premul(image->dimensions()))); |
2180 if (!surface) { | 2180 if (!surface) { |
2181 return image; | 2181 return image; |
2182 } | 2182 } |
2183 SkCanvas* canvas = surface->getCanvas(); | 2183 SkCanvas* canvas = surface->getCanvas(); |
2184 canvas->clear(SK_ColorTRANSPARENT); | 2184 canvas->clear(SK_ColorTRANSPARENT); |
2185 SkPaint paint; | 2185 SkPaint paint; |
2186 paint.setColorFilter(colorFilter); | 2186 paint.setColorFilter(colorFilter); |
2187 canvas->drawImage(image, 0, 0, &paint); | 2187 canvas->drawImage(image, 0, 0, &paint); |
2188 canvas->flush(); | 2188 canvas->flush(); |
2189 return surface->newImageSnapshot(); | 2189 return surface->newImageSnapshot(); |
2190 } | 2190 } |
2191 | 2191 |
2192 //////////////////////////////////////////////////////////////////////////////// | 2192 //////////////////////////////////////////////////////////////////////////////// |
2193 void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix, | 2193 void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix, |
2194 const SkClipStack* clipStack, | 2194 const SkClipStack* clipStack, |
2195 const SkRegion& origClipRegion, | 2195 const SkRegion& origClipRegion, |
2196 const SkImage* image, | 2196 const SkImage* image, |
2197 const SkIRect* srcRect, | 2197 const SkIRect* srcRect, |
2198 const SkPaint& paint) { | 2198 const SkPaint& paint) { |
2199 SkASSERT(image); | 2199 SkASSERT(image); |
2200 #ifdef SK_PDF_IMAGE_STATS | 2200 #ifdef SK_PDF_IMAGE_STATS |
2201 gDrawImageCalls.fetch_add(1); | 2201 gDrawImageCalls.fetch_add(1); |
2202 #endif | 2202 #endif |
2203 SkMatrix matrix = origMatrix; | 2203 SkMatrix matrix = origMatrix; |
2204 SkRegion perspectiveBounds; | 2204 SkRegion perspectiveBounds; |
2205 const SkRegion* clipRegion = &origClipRegion; | 2205 const SkRegion* clipRegion = &origClipRegion; |
2206 SkAutoTUnref<const SkImage> autoImageUnref; | 2206 sk_sp<const SkImage> autoImageUnref; |
2207 | 2207 |
2208 if (srcRect) { | 2208 if (srcRect) { |
2209 autoImageUnref.reset(image->newSubset(*srcRect)); | 2209 autoImageUnref.reset(image->newSubset(*srcRect)); |
2210 if (!autoImageUnref) { | 2210 if (!autoImageUnref) { |
2211 return; | 2211 return; |
2212 } | 2212 } |
2213 image = autoImageUnref.get(); | 2213 image = autoImageUnref.get(); |
2214 } | 2214 } |
2215 // Rasterize the bitmap using perspective in a new bitmap. | 2215 // Rasterize the bitmap using perspective in a new bitmap. |
2216 if (origMatrix.hasPerspective()) { | 2216 if (origMatrix.hasPerspective()) { |
(...skipping 30 matching lines...) Expand all Loading... |
2247 | 2247 |
2248 // TODO(edisonn): A better approach would be to use a bitmap shader | 2248 // TODO(edisonn): A better approach would be to use a bitmap shader |
2249 // (in clamp mode) and draw a rect over the entire bounding box. Then | 2249 // (in clamp mode) and draw a rect over the entire bounding box. Then |
2250 // intersect perspectiveOutline to the clip. That will avoid introducing | 2250 // intersect perspectiveOutline to the clip. That will avoid introducing |
2251 // alpha to the image while still giving good behavior at the edge of | 2251 // alpha to the image while still giving good behavior at the edge of |
2252 // the image. Avoiding alpha will reduce the pdf size and generation | 2252 // the image. Avoiding alpha will reduce the pdf size and generation |
2253 // CPU time some. | 2253 // CPU time some. |
2254 | 2254 |
2255 SkISize wh = rect_to_size(physicalPerspectiveBounds).toCeil(); | 2255 SkISize wh = rect_to_size(physicalPerspectiveBounds).toCeil(); |
2256 | 2256 |
2257 SkAutoTUnref<SkSurface> surface( | 2257 sk_sp<SkSurface> surface( |
2258 SkSurface::NewRaster(SkImageInfo::MakeN32Premul(wh))); | 2258 SkSurface::NewRaster(SkImageInfo::MakeN32Premul(wh))); |
2259 if (!surface) { | 2259 if (!surface) { |
2260 return; | 2260 return; |
2261 } | 2261 } |
2262 SkCanvas* canvas = surface->getCanvas(); | 2262 SkCanvas* canvas = surface->getCanvas(); |
2263 canvas->clear(SK_ColorTRANSPARENT); | 2263 canvas->clear(SK_ColorTRANSPARENT); |
2264 | 2264 |
2265 SkScalar deltaX = bounds.left(); | 2265 SkScalar deltaX = bounds.left(); |
2266 SkScalar deltaY = bounds.top(); | 2266 SkScalar deltaY = bounds.top(); |
2267 | 2267 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2316 // TODO(https://bug.skia.org/4378): implement colorfilter on other | 2316 // TODO(https://bug.skia.org/4378): implement colorfilter on other |
2317 // draw calls. This code here works for all | 2317 // draw calls. This code here works for all |
2318 // drawBitmap*()/drawImage*() calls amd ImageFilters (which | 2318 // drawBitmap*()/drawImage*() calls amd ImageFilters (which |
2319 // rasterize a layer on this backend). Fortuanely, this seems | 2319 // rasterize a layer on this backend). Fortuanely, this seems |
2320 // to be how Chromium impements most color-filters. | 2320 // to be how Chromium impements most color-filters. |
2321 autoImageUnref.reset(color_filter(image, colorFilter)); | 2321 autoImageUnref.reset(color_filter(image, colorFilter)); |
2322 image = autoImageUnref.get(); | 2322 image = autoImageUnref.get(); |
2323 // TODO(halcanary): de-dupe this by caching filtered images. | 2323 // TODO(halcanary): de-dupe this by caching filtered images. |
2324 // (maybe in the resource cache?) | 2324 // (maybe in the resource cache?) |
2325 } | 2325 } |
2326 SkAutoTUnref<SkPDFObject> pdfimage(SkSafeRef(fCanon->findPDFBitmap(image))); | 2326 sk_sp<SkPDFObject> pdfimage(SkSafeRef(fCanon->findPDFBitmap(image))); |
2327 if (!pdfimage) { | 2327 if (!pdfimage) { |
2328 pdfimage.reset(SkPDFCreateBitmapObject( | 2328 pdfimage.reset(SkPDFCreateBitmapObject( |
2329 image, fCanon->getPixelSerializer())); | 2329 image, fCanon->getPixelSerializer())); |
2330 if (!pdfimage) { | 2330 if (!pdfimage) { |
2331 return; | 2331 return; |
2332 } | 2332 } |
2333 fCanon->addPDFBitmap(image->uniqueID(), pdfimage.get()); | 2333 fCanon->addPDFBitmap(image->uniqueID(), pdfimage.get()); |
2334 } | 2334 } |
2335 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), | 2335 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), |
2336 &content.entry()->fContent); | 2336 &content.entry()->fContent); |
2337 } | 2337 } |
OLD | NEW |