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" |
11 #include "SkColor.h" | 11 #include "SkColor.h" |
12 #include "SkColorFilter.h" | 12 #include "SkColorFilter.h" |
13 #include "SkClipStack.h" | 13 #include "SkClipStack.h" |
14 #include "SkDraw.h" | 14 #include "SkDraw.h" |
15 #include "SkGlyphCache.h" | 15 #include "SkGlyphCache.h" |
16 #include "SkPaint.h" | 16 #include "SkPaint.h" |
17 #include "SkPath.h" | 17 #include "SkPath.h" |
18 #include "SkPathOps.h" | 18 #include "SkPathOps.h" |
19 #include "SkPDFBitmap.h" | 19 #include "SkPDFBitmap.h" |
20 #include "SkPDFCanon.h" | 20 #include "SkPDFCanon.h" |
| 21 #include "SkPDFDocument.h" |
21 #include "SkPDFFont.h" | 22 #include "SkPDFFont.h" |
22 #include "SkPDFFormXObject.h" | 23 #include "SkPDFFormXObject.h" |
23 #include "SkPDFGraphicState.h" | 24 #include "SkPDFGraphicState.h" |
24 #include "SkPDFResourceDict.h" | 25 #include "SkPDFResourceDict.h" |
25 #include "SkPDFShader.h" | 26 #include "SkPDFShader.h" |
26 #include "SkPDFStream.h" | 27 #include "SkPDFStream.h" |
27 #include "SkPDFTypes.h" | 28 #include "SkPDFTypes.h" |
28 #include "SkPDFUtils.h" | 29 #include "SkPDFUtils.h" |
29 #include "SkRasterClip.h" | 30 #include "SkRasterClip.h" |
30 #include "SkRect.h" | 31 #include "SkRect.h" |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 // TODO: should we return true if there is a colorfilter? | 577 // TODO: should we return true if there is a colorfilter? |
577 return layerPaint.getImageFilter() != nullptr; | 578 return layerPaint.getImageFilter() != nullptr; |
578 } | 579 } |
579 | 580 |
580 SkBaseDevice* SkPDFDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint
* layerPaint) { | 581 SkBaseDevice* SkPDFDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint
* layerPaint) { |
581 if (cinfo.fForImageFilter || | 582 if (cinfo.fForImageFilter || |
582 (layerPaint && not_supported_for_layers(*layerPaint))) { | 583 (layerPaint && not_supported_for_layers(*layerPaint))) { |
583 return nullptr; | 584 return nullptr; |
584 } | 585 } |
585 SkISize size = SkISize::Make(cinfo.fInfo.width(), cinfo.fInfo.height()); | 586 SkISize size = SkISize::Make(cinfo.fInfo.width(), cinfo.fInfo.height()); |
586 return SkPDFDevice::Create(size, fRasterDpi, fCanon); | 587 return SkPDFDevice::Create(size, fRasterDpi, fDocument); |
587 } | 588 } |
588 | 589 |
| 590 SkPDFCanon* SkPDFDevice::getCanon() const { return fDocument->canon(); } |
| 591 |
589 | 592 |
590 struct ContentEntry { | 593 struct ContentEntry { |
591 GraphicStateEntry fState; | 594 GraphicStateEntry fState; |
592 SkDynamicMemoryWStream fContent; | 595 SkDynamicMemoryWStream fContent; |
593 SkAutoTDelete<ContentEntry> fNext; | 596 SkAutoTDelete<ContentEntry> fNext; |
594 | 597 |
595 // If the stack is too deep we could get Stack Overflow. | 598 // If the stack is too deep we could get Stack Overflow. |
596 // So we manually destruct the object. | 599 // So we manually destruct the object. |
597 ~ContentEntry() { | 600 ~ContentEntry() { |
598 ContentEntry* val = fNext.detach(); | 601 ContentEntry* val = fNext.detach(); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 paint.getXfermode()->asMode(&fXfermode); | 695 paint.getXfermode()->asMode(&fXfermode); |
693 } | 696 } |
694 fContentEntry = fDevice->setUpContentEntry(clipStack, clipRegion, | 697 fContentEntry = fDevice->setUpContentEntry(clipStack, clipRegion, |
695 matrix, paint, hasText, | 698 matrix, paint, hasText, |
696 &fDstFormXObject); | 699 &fDstFormXObject); |
697 } | 700 } |
698 }; | 701 }; |
699 | 702 |
700 //////////////////////////////////////////////////////////////////////////////// | 703 //////////////////////////////////////////////////////////////////////////////// |
701 | 704 |
702 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFCanon* canon
, bool flip) | 705 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFDocument* do
c, bool flip) |
703 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry)) | 706 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry)) |
704 , fPageSize(pageSize) | 707 , fPageSize(pageSize) |
705 , fContentSize(pageSize) | 708 , fContentSize(pageSize) |
706 , fExistingClipRegion(SkIRect::MakeSize(pageSize)) | 709 , fExistingClipRegion(SkIRect::MakeSize(pageSize)) |
707 , fLastContentEntry(nullptr) | 710 , fLastContentEntry(nullptr) |
708 , fLastMarginContentEntry(nullptr) | 711 , fLastMarginContentEntry(nullptr) |
709 , fDrawingArea(kContent_DrawingArea) | 712 , fDrawingArea(kContent_DrawingArea) |
710 , fClipStack(nullptr) | 713 , fClipStack(nullptr) |
711 , fFontGlyphUsage(new SkPDFGlyphSetMap) | 714 , fFontGlyphUsage(new SkPDFGlyphSetMap) |
712 , fRasterDpi(rasterDpi) | 715 , fRasterDpi(rasterDpi) |
713 , fCanon(canon) { | 716 , fDocument(doc) { |
714 SkASSERT(pageSize.width() > 0); | 717 SkASSERT(pageSize.width() > 0); |
715 SkASSERT(pageSize.height() > 0); | 718 SkASSERT(pageSize.height() > 0); |
716 fLegacyBitmap.setInfo( | 719 fLegacyBitmap.setInfo( |
717 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height())); | 720 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height())); |
718 if (flip) { | 721 if (flip) { |
719 // Skia generally uses the top left as the origin but PDF | 722 // Skia generally uses the top left as the origin but PDF |
720 // natively has the origin at the bottom left. This matrix | 723 // natively has the origin at the bottom left. This matrix |
721 // corrects for that. But that only needs to be done once, we | 724 // corrects for that. But that only needs to be done once, we |
722 // don't do it when layering. | 725 // don't do it when layering. |
723 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight)); | 726 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight)); |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1031 SkPDFUtils::PaintPath(paint.getStyle(), pathPtr->getFillType(), | 1034 SkPDFUtils::PaintPath(paint.getStyle(), pathPtr->getFillType(), |
1032 &content.entry()->fContent); | 1035 &content.entry()->fContent); |
1033 } | 1036 } |
1034 | 1037 |
1035 void SkPDFDevice::drawBitmapRect(const SkDraw& draw, | 1038 void SkPDFDevice::drawBitmapRect(const SkDraw& draw, |
1036 const SkBitmap& bitmap, | 1039 const SkBitmap& bitmap, |
1037 const SkRect* src, | 1040 const SkRect* src, |
1038 const SkRect& dst, | 1041 const SkRect& dst, |
1039 const SkPaint& srcPaint, | 1042 const SkPaint& srcPaint, |
1040 SkCanvas::SrcRectConstraint constraint) { | 1043 SkCanvas::SrcRectConstraint constraint) { |
1041 const SkImage* image = fCanon->bitmapToImage(bitmap); | 1044 const SkImage* image = fDocument->canon()->bitmapToImage(bitmap); |
1042 if (!image) { | 1045 if (!image) { |
1043 return; | 1046 return; |
1044 } | 1047 } |
1045 // ownership of this image is retained by the canon. | 1048 // ownership of this image is retained by the canon. |
1046 this->drawImageRect(draw, image, src, dst, srcPaint, constraint); | 1049 this->drawImageRect(draw, image, src, dst, srcPaint, constraint); |
1047 } | 1050 } |
1048 | 1051 |
1049 void SkPDFDevice::drawBitmap(const SkDraw& d, | 1052 void SkPDFDevice::drawBitmap(const SkDraw& d, |
1050 const SkBitmap& bitmap, | 1053 const SkBitmap& bitmap, |
1051 const SkMatrix& matrix, | 1054 const SkMatrix& matrix, |
1052 const SkPaint& srcPaint) { | 1055 const SkPaint& srcPaint) { |
1053 SkPaint paint = srcPaint; | 1056 SkPaint paint = srcPaint; |
1054 if (bitmap.isOpaque()) { | 1057 if (bitmap.isOpaque()) { |
1055 replace_srcmode_on_opaque_paint(&paint); | 1058 replace_srcmode_on_opaque_paint(&paint); |
1056 } | 1059 } |
1057 | 1060 |
1058 if (d.fClip->isEmpty()) { | 1061 if (d.fClip->isEmpty()) { |
1059 return; | 1062 return; |
1060 } | 1063 } |
1061 | 1064 |
1062 SkMatrix transform = matrix; | 1065 SkMatrix transform = matrix; |
1063 transform.postConcat(*d.fMatrix); | 1066 transform.postConcat(*d.fMatrix); |
1064 const SkImage* image = fCanon->bitmapToImage(bitmap); | 1067 const SkImage* image = fDocument->canon()->bitmapToImage(bitmap); |
1065 if (!image) { | 1068 if (!image) { |
1066 return; | 1069 return; |
1067 } | 1070 } |
1068 this->internalDrawImage(transform, d.fClipStack, *d.fClip, image, nullptr, | 1071 this->internalDrawImage(transform, d.fClipStack, *d.fClip, image, nullptr, |
1069 paint); | 1072 paint); |
1070 } | 1073 } |
1071 | 1074 |
1072 void SkPDFDevice::drawSprite(const SkDraw& d, | 1075 void SkPDFDevice::drawSprite(const SkDraw& d, |
1073 const SkBitmap& bitmap, | 1076 const SkBitmap& bitmap, |
1074 int x, | 1077 int x, |
1075 int y, | 1078 int y, |
1076 const SkPaint& srcPaint) { | 1079 const SkPaint& srcPaint) { |
1077 SkPaint paint = srcPaint; | 1080 SkPaint paint = srcPaint; |
1078 if (bitmap.isOpaque()) { | 1081 if (bitmap.isOpaque()) { |
1079 replace_srcmode_on_opaque_paint(&paint); | 1082 replace_srcmode_on_opaque_paint(&paint); |
1080 } | 1083 } |
1081 | 1084 |
1082 if (d.fClip->isEmpty()) { | 1085 if (d.fClip->isEmpty()) { |
1083 return; | 1086 return; |
1084 } | 1087 } |
1085 | 1088 |
1086 SkMatrix matrix; | 1089 SkMatrix matrix; |
1087 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); | 1090 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); |
1088 const SkImage* image = fCanon->bitmapToImage(bitmap); | 1091 const SkImage* image = fDocument->canon()->bitmapToImage(bitmap); |
1089 if (!image) { | 1092 if (!image) { |
1090 return; | 1093 return; |
1091 } | 1094 } |
1092 this->internalDrawImage(matrix, d.fClipStack, *d.fClip, image, nullptr, | 1095 this->internalDrawImage(matrix, d.fClipStack, *d.fClip, image, nullptr, |
1093 paint); | 1096 paint); |
1094 } | 1097 } |
1095 | 1098 |
1096 void SkPDFDevice::drawImage(const SkDraw& draw, | 1099 void SkPDFDevice::drawImage(const SkDraw& draw, |
1097 const SkImage* image, | 1100 const SkImage* image, |
1098 SkScalar x, | 1101 SkScalar x, |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1252 device->drawText(d, text, len, x, y, transparent); | 1255 device->drawText(d, text, len, x, y, transparent); |
1253 break; | 1256 break; |
1254 default: | 1257 default: |
1255 SkFAIL("unknown text encoding"); | 1258 SkFAIL("unknown text encoding"); |
1256 } | 1259 } |
1257 } | 1260 } |
1258 | 1261 |
1259 | 1262 |
1260 void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, | 1263 void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, |
1261 SkScalar x, SkScalar y, const SkPaint& srcPaint) { | 1264 SkScalar x, SkScalar y, const SkPaint& srcPaint) { |
1262 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) { | 1265 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fDocument->canon())
) { |
1263 // https://bug.skia.org/3866 | 1266 // https://bug.skia.org/3866 |
1264 SkPath path; | 1267 SkPath path; |
1265 srcPaint.getTextPath(text, len, x, y, &path); | 1268 srcPaint.getTextPath(text, len, x, y, &path); |
1266 this->drawPath(d, path, srcPaint, &SkMatrix::I(), true); | 1269 this->drawPath(d, path, srcPaint, &SkMatrix::I(), true); |
1267 // Draw text transparently to make it copyable/searchable/accessable. | 1270 // Draw text transparently to make it copyable/searchable/accessable. |
1268 draw_transparent_text(this, d, text, len, x, y, srcPaint); | 1271 draw_transparent_text(this, d, text, len, x, y, srcPaint); |
1269 return; | 1272 return; |
1270 } | 1273 } |
1271 SkPaint paint = srcPaint; | 1274 SkPaint paint = srcPaint; |
1272 replace_srcmode_on_opaque_paint(&paint); | 1275 replace_srcmode_on_opaque_paint(&paint); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1313 content.entry()->fContent.writeText(encodedString.c_str()); | 1316 content.entry()->fContent.writeText(encodedString.c_str()); |
1314 consumedGlyphCount += availableGlyphs; | 1317 consumedGlyphCount += availableGlyphs; |
1315 content.entry()->fContent.writeText(" Tj\n"); | 1318 content.entry()->fContent.writeText(" Tj\n"); |
1316 } | 1319 } |
1317 content.entry()->fContent.writeText("ET\n"); | 1320 content.entry()->fContent.writeText("ET\n"); |
1318 } | 1321 } |
1319 | 1322 |
1320 void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, | 1323 void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, |
1321 const SkScalar pos[], int scalarsPerPos, | 1324 const SkScalar pos[], int scalarsPerPos, |
1322 const SkPoint& offset, const SkPaint& srcPaint) { | 1325 const SkPoint& offset, const SkPaint& srcPaint) { |
1323 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) { | 1326 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fDocument->canon())
) { |
1324 const SkPoint* positions = reinterpret_cast<const SkPoint*>(pos); | 1327 const SkPoint* positions = reinterpret_cast<const SkPoint*>(pos); |
1325 SkAutoTMalloc<SkPoint> positionsBuffer; | 1328 SkAutoTMalloc<SkPoint> positionsBuffer; |
1326 if (2 != scalarsPerPos) { | 1329 if (2 != scalarsPerPos) { |
1327 int glyphCount = srcPaint.textToGlyphs(text, len, NULL); | 1330 int glyphCount = srcPaint.textToGlyphs(text, len, NULL); |
1328 positionsBuffer.reset(glyphCount); | 1331 positionsBuffer.reset(glyphCount); |
1329 for (int i = 0; i < glyphCount; ++i) { | 1332 for (int i = 0; i < glyphCount; ++i) { |
1330 positionsBuffer[i].set(pos[i], 0.0f); | 1333 positionsBuffer[i].set(pos[i], 0.0f); |
1331 } | 1334 } |
1332 positions = &positionsBuffer[0]; | 1335 positions = &positionsBuffer[0]; |
1333 } | 1336 } |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1736 SkPDFFormXObject* mask, | 1739 SkPDFFormXObject* mask, |
1737 const SkClipStack* clipStack, | 1740 const SkClipStack* clipStack, |
1738 const SkRegion& clipRegion, | 1741 const SkRegion& clipRegion, |
1739 SkXfermode::Mode mode, | 1742 SkXfermode::Mode mode, |
1740 bool invertClip) { | 1743 bool invertClip) { |
1741 if (clipRegion.isEmpty() && !invertClip) { | 1744 if (clipRegion.isEmpty() && !invertClip) { |
1742 return; | 1745 return; |
1743 } | 1746 } |
1744 | 1747 |
1745 auto sMaskGS = SkPDFGraphicState::GetSMaskGraphicState( | 1748 auto sMaskGS = SkPDFGraphicState::GetSMaskGraphicState( |
1746 mask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode, fCanon); | 1749 mask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode, fDocument->ca
non()); |
1747 | 1750 |
1748 SkMatrix identity; | 1751 SkMatrix identity; |
1749 identity.reset(); | 1752 identity.reset(); |
1750 SkPaint paint; | 1753 SkPaint paint; |
1751 paint.setXfermodeMode(mode); | 1754 paint.setXfermodeMode(mode); |
1752 ScopedContentEntry content(this, clipStack, clipRegion, identity, paint); | 1755 ScopedContentEntry content(this, clipStack, clipRegion, identity, paint); |
1753 if (!content.entry()) { | 1756 if (!content.entry()) { |
1754 return; | 1757 return; |
1755 } | 1758 } |
1756 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), | 1759 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), |
1757 &content.entry()->fContent); | 1760 &content.entry()->fContent); |
1758 SkPDFUtils::DrawFormXObject(xObjectIndex, &content.entry()->fContent); | 1761 SkPDFUtils::DrawFormXObject(xObjectIndex, &content.entry()->fContent); |
1759 | 1762 |
1760 // Call makeNoSmaskGraphicState() instead of | 1763 // Call makeNoSmaskGraphicState() instead of |
1761 // SkPDFGraphicState::MakeNoSmaskGraphicState so that the canon | 1764 // SkPDFGraphicState::MakeNoSmaskGraphicState so that the canon |
1762 // can deduplicate. | 1765 // can deduplicate. |
1763 sMaskGS = fCanon->makeNoSmaskGraphicState(); | 1766 sMaskGS = fDocument->canon()->makeNoSmaskGraphicState(); |
1764 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), | 1767 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), |
1765 &content.entry()->fContent); | 1768 &content.entry()->fContent); |
1766 } | 1769 } |
1767 | 1770 |
1768 ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* clipStack, | 1771 ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* clipStack, |
1769 const SkRegion& clipRegion, | 1772 const SkRegion& clipRegion, |
1770 const SkMatrix& matrix, | 1773 const SkMatrix& matrix, |
1771 const SkPaint& paint, | 1774 const SkPaint& paint, |
1772 bool hasText, | 1775 bool hasText, |
1773 SkPDFFormXObject** dst) { | 1776 SkPDFFormXObject** dst) { |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2060 // We need to apply the initial transform to bounds in order to get | 2063 // We need to apply the initial transform to bounds in order to get |
2061 // bounds in a consistent coordinate system. | 2064 // bounds in a consistent coordinate system. |
2062 SkRect boundsTemp; | 2065 SkRect boundsTemp; |
2063 boundsTemp.set(bounds); | 2066 boundsTemp.set(bounds); |
2064 fInitialTransform.mapRect(&boundsTemp); | 2067 fInitialTransform.mapRect(&boundsTemp); |
2065 boundsTemp.roundOut(&bounds); | 2068 boundsTemp.roundOut(&bounds); |
2066 | 2069 |
2067 SkScalar rasterScale = | 2070 SkScalar rasterScale = |
2068 SkIntToScalar(fRasterDpi) / DPI_FOR_RASTER_SCALE_ONE; | 2071 SkIntToScalar(fRasterDpi) / DPI_FOR_RASTER_SCALE_ONE; |
2069 pdfShader.reset(SkPDFShader::GetPDFShader( | 2072 pdfShader.reset(SkPDFShader::GetPDFShader( |
2070 fCanon, fRasterDpi, *shader, transform, bounds, rasterScale)); | 2073 fDocument, fRasterDpi, *shader, transform, bounds, rasterScale))
; |
2071 | 2074 |
2072 if (pdfShader.get()) { | 2075 if (pdfShader.get()) { |
2073 // pdfShader has been canonicalized so we can directly compare | 2076 // pdfShader has been canonicalized so we can directly compare |
2074 // pointers. | 2077 // pointers. |
2075 int resourceIndex = fShaderResources.find(pdfShader.get()); | 2078 int resourceIndex = fShaderResources.find(pdfShader.get()); |
2076 if (resourceIndex < 0) { | 2079 if (resourceIndex < 0) { |
2077 resourceIndex = fShaderResources.count(); | 2080 resourceIndex = fShaderResources.count(); |
2078 fShaderResources.push(pdfShader.get()); | 2081 fShaderResources.push(pdfShader.get()); |
2079 pdfShader.get()->ref(); | 2082 pdfShader.get()->ref(); |
2080 } | 2083 } |
(...skipping 10 matching lines...) Expand all Loading... |
2091 SkShader::kColor_GradientType) { | 2094 SkShader::kColor_GradientType) { |
2092 entry->fColor = SkColorSetA(gradientColor, 0xFF); | 2095 entry->fColor = SkColorSetA(gradientColor, 0xFF); |
2093 color = gradientColor; | 2096 color = gradientColor; |
2094 } | 2097 } |
2095 } | 2098 } |
2096 } | 2099 } |
2097 | 2100 |
2098 sk_sp<SkPDFGraphicState> newGraphicState; | 2101 sk_sp<SkPDFGraphicState> newGraphicState; |
2099 if (color == paint.getColor()) { | 2102 if (color == paint.getColor()) { |
2100 newGraphicState.reset( | 2103 newGraphicState.reset( |
2101 SkPDFGraphicState::GetGraphicStateForPaint(fCanon, paint)); | 2104 SkPDFGraphicState::GetGraphicStateForPaint(fDocument->canon(), p
aint)); |
2102 } else { | 2105 } else { |
2103 SkPaint newPaint = paint; | 2106 SkPaint newPaint = paint; |
2104 newPaint.setColor(color); | 2107 newPaint.setColor(color); |
2105 newGraphicState.reset( | 2108 newGraphicState.reset( |
2106 SkPDFGraphicState::GetGraphicStateForPaint(fCanon, newPaint)); | 2109 SkPDFGraphicState::GetGraphicStateForPaint(fDocument->canon(), n
ewPaint)); |
2107 } | 2110 } |
2108 int resourceIndex = addGraphicStateResource(newGraphicState.get()); | 2111 int resourceIndex = addGraphicStateResource(newGraphicState.get()); |
2109 entry->fGraphicStateIndex = resourceIndex; | 2112 entry->fGraphicStateIndex = resourceIndex; |
2110 | 2113 |
2111 if (hasText) { | 2114 if (hasText) { |
2112 entry->fTextScaleX = paint.getTextScaleX(); | 2115 entry->fTextScaleX = paint.getTextScaleX(); |
2113 entry->fTextFill = paint.getStyle(); | 2116 entry->fTextFill = paint.getStyle(); |
2114 } else { | 2117 } else { |
2115 entry->fTextScaleX = 0; | 2118 entry->fTextScaleX = 0; |
2116 } | 2119 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2153 fontIndex).c_str()); | 2156 fontIndex).c_str()); |
2154 contentEntry->fContent.writeText(" "); | 2157 contentEntry->fContent.writeText(" "); |
2155 SkPDFUtils::AppendScalar(paint.getTextSize(), &contentEntry->fContent); | 2158 SkPDFUtils::AppendScalar(paint.getTextSize(), &contentEntry->fContent); |
2156 contentEntry->fContent.writeText(" Tf\n"); | 2159 contentEntry->fContent.writeText(" Tf\n"); |
2157 contentEntry->fState.fFont = fFontResources[fontIndex]; | 2160 contentEntry->fState.fFont = fFontResources[fontIndex]; |
2158 } | 2161 } |
2159 } | 2162 } |
2160 | 2163 |
2161 int SkPDFDevice::getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID) { | 2164 int SkPDFDevice::getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID) { |
2162 sk_sp<SkPDFFont> newFont( | 2165 sk_sp<SkPDFFont> newFont( |
2163 SkPDFFont::GetFontResource(fCanon, typeface, glyphID)); | 2166 SkPDFFont::GetFontResource(fDocument->canon(), typeface, glyphID)); |
2164 int resourceIndex = fFontResources.find(newFont.get()); | 2167 int resourceIndex = fFontResources.find(newFont.get()); |
2165 if (resourceIndex < 0) { | 2168 if (resourceIndex < 0) { |
2166 resourceIndex = fFontResources.count(); | 2169 resourceIndex = fFontResources.count(); |
2167 fFontResources.push(newFont.get()); | 2170 fFontResources.push(newFont.get()); |
2168 newFont.get()->ref(); | 2171 newFont.get()->ref(); |
2169 } | 2172 } |
2170 return resourceIndex; | 2173 return resourceIndex; |
2171 } | 2174 } |
2172 | 2175 |
2173 static SkSize rect_to_size(const SkRect& r) { | 2176 static SkSize rect_to_size(const SkRect& r) { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2317 // TODO(https://bug.skia.org/4378): implement colorfilter on other | 2320 // TODO(https://bug.skia.org/4378): implement colorfilter on other |
2318 // draw calls. This code here works for all | 2321 // draw calls. This code here works for all |
2319 // drawBitmap*()/drawImage*() calls amd ImageFilters (which | 2322 // drawBitmap*()/drawImage*() calls amd ImageFilters (which |
2320 // rasterize a layer on this backend). Fortuanely, this seems | 2323 // rasterize a layer on this backend). Fortuanely, this seems |
2321 // to be how Chromium impements most color-filters. | 2324 // to be how Chromium impements most color-filters. |
2322 autoImageUnref.reset(color_filter(image, colorFilter)); | 2325 autoImageUnref.reset(color_filter(image, colorFilter)); |
2323 image = autoImageUnref.get(); | 2326 image = autoImageUnref.get(); |
2324 // TODO(halcanary): de-dupe this by caching filtered images. | 2327 // TODO(halcanary): de-dupe this by caching filtered images. |
2325 // (maybe in the resource cache?) | 2328 // (maybe in the resource cache?) |
2326 } | 2329 } |
2327 sk_sp<SkPDFObject> pdfimage(SkSafeRef(fCanon->findPDFBitmap(image))); | 2330 sk_sp<SkPDFObject> pdfimage(SkSafeRef(fDocument->canon()->findPDFBitmap(imag
e))); |
2328 if (!pdfimage) { | 2331 if (!pdfimage) { |
2329 pdfimage.reset(SkPDFCreateBitmapObject( | 2332 pdfimage.reset(SkPDFCreateBitmapObject( |
2330 image, fCanon->getPixelSerializer())); | 2333 image, fDocument->canon()->getPixelSerializer()))
; |
2331 if (!pdfimage) { | 2334 if (!pdfimage) { |
2332 return; | 2335 return; |
2333 } | 2336 } |
2334 fCanon->addPDFBitmap(image->uniqueID(), pdfimage.get()); | 2337 #if SK_PDF_SERIALIZE_IMAGES_EARLY // TODO(halcanary): enable. |
| 2338 sk_sp<SkData> encodedImage(image->refEncodedData()); |
| 2339 if (!encodedImage) { |
| 2340 fDocument->serialize(pdfimage); |
| 2341 } |
| 2342 #endif |
| 2343 fDocument->canon()->addPDFBitmap(image->uniqueID(), pdfimage.get()); |
2335 } | 2344 } |
2336 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), | 2345 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), |
2337 &content.entry()->fContent); | 2346 &content.entry()->fContent); |
2338 } | 2347 } |
OLD | NEW |