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 "SkPathEffect.h" | 18 #include "SkPathEffect.h" |
19 #include "SkPathOps.h" | 19 #include "SkPathOps.h" |
20 #include "SkPDFBitmap.h" | 20 #include "SkPDFBitmap.h" |
21 #include "SkPDFCanon.h" | 21 #include "SkPDFCanon.h" |
| 22 #include "SkPDFDocument.h" |
22 #include "SkPDFFont.h" | 23 #include "SkPDFFont.h" |
23 #include "SkPDFFormXObject.h" | 24 #include "SkPDFFormXObject.h" |
24 #include "SkPDFGraphicState.h" | 25 #include "SkPDFGraphicState.h" |
25 #include "SkPDFResourceDict.h" | 26 #include "SkPDFResourceDict.h" |
26 #include "SkPDFShader.h" | 27 #include "SkPDFShader.h" |
27 #include "SkPDFStream.h" | 28 #include "SkPDFStream.h" |
28 #include "SkPDFTypes.h" | 29 #include "SkPDFTypes.h" |
29 #include "SkPDFUtils.h" | 30 #include "SkPDFUtils.h" |
30 #include "SkRasterClip.h" | 31 #include "SkRasterClip.h" |
31 #include "SkRect.h" | 32 #include "SkRect.h" |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 // TODO: should we return true if there is a colorfilter? | 578 // TODO: should we return true if there is a colorfilter? |
578 return layerPaint.getImageFilter() != nullptr; | 579 return layerPaint.getImageFilter() != nullptr; |
579 } | 580 } |
580 | 581 |
581 SkBaseDevice* SkPDFDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint
* layerPaint) { | 582 SkBaseDevice* SkPDFDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint
* layerPaint) { |
582 if (cinfo.fForImageFilter || | 583 if (cinfo.fForImageFilter || |
583 (layerPaint && not_supported_for_layers(*layerPaint))) { | 584 (layerPaint && not_supported_for_layers(*layerPaint))) { |
584 return nullptr; | 585 return nullptr; |
585 } | 586 } |
586 SkISize size = SkISize::Make(cinfo.fInfo.width(), cinfo.fInfo.height()); | 587 SkISize size = SkISize::Make(cinfo.fInfo.width(), cinfo.fInfo.height()); |
587 return SkPDFDevice::Create(size, fRasterDpi, fCanon); | 588 return SkPDFDevice::Create(size, fRasterDpi, fDocument); |
588 } | 589 } |
589 | 590 |
| 591 SkPDFCanon* SkPDFDevice::getCanon() const { return fDocument->canon(); } |
| 592 |
590 | 593 |
591 struct ContentEntry { | 594 struct ContentEntry { |
592 GraphicStateEntry fState; | 595 GraphicStateEntry fState; |
593 SkDynamicMemoryWStream fContent; | 596 SkDynamicMemoryWStream fContent; |
594 SkAutoTDelete<ContentEntry> fNext; | 597 SkAutoTDelete<ContentEntry> fNext; |
595 | 598 |
596 // If the stack is too deep we could get Stack Overflow. | 599 // If the stack is too deep we could get Stack Overflow. |
597 // So we manually destruct the object. | 600 // So we manually destruct the object. |
598 ~ContentEntry() { | 601 ~ContentEntry() { |
599 ContentEntry* val = fNext.release(); | 602 ContentEntry* val = fNext.release(); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 paint.getXfermode()->asMode(&fXfermode); | 696 paint.getXfermode()->asMode(&fXfermode); |
694 } | 697 } |
695 fContentEntry = fDevice->setUpContentEntry(clipStack, clipRegion, | 698 fContentEntry = fDevice->setUpContentEntry(clipStack, clipRegion, |
696 matrix, paint, hasText, | 699 matrix, paint, hasText, |
697 &fDstFormXObject); | 700 &fDstFormXObject); |
698 } | 701 } |
699 }; | 702 }; |
700 | 703 |
701 //////////////////////////////////////////////////////////////////////////////// | 704 //////////////////////////////////////////////////////////////////////////////// |
702 | 705 |
703 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFCanon* canon
, bool flip) | 706 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFDocument* do
c, bool flip) |
704 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry)) | 707 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry)) |
705 , fPageSize(pageSize) | 708 , fPageSize(pageSize) |
706 , fContentSize(pageSize) | 709 , fContentSize(pageSize) |
707 , fExistingClipRegion(SkIRect::MakeSize(pageSize)) | 710 , fExistingClipRegion(SkIRect::MakeSize(pageSize)) |
708 , fLastContentEntry(nullptr) | 711 , fLastContentEntry(nullptr) |
709 , fLastMarginContentEntry(nullptr) | 712 , fLastMarginContentEntry(nullptr) |
710 , fDrawingArea(kContent_DrawingArea) | 713 , fDrawingArea(kContent_DrawingArea) |
711 , fClipStack(nullptr) | 714 , fClipStack(nullptr) |
712 , fFontGlyphUsage(new SkPDFGlyphSetMap) | 715 , fFontGlyphUsage(new SkPDFGlyphSetMap) |
713 , fRasterDpi(rasterDpi) | 716 , fRasterDpi(rasterDpi) |
714 , fCanon(canon) { | 717 , fDocument(doc) { |
715 SkASSERT(pageSize.width() > 0); | 718 SkASSERT(pageSize.width() > 0); |
716 SkASSERT(pageSize.height() > 0); | 719 SkASSERT(pageSize.height() > 0); |
717 fLegacyBitmap.setInfo( | 720 fLegacyBitmap.setInfo( |
718 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height())); | 721 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height())); |
719 if (flip) { | 722 if (flip) { |
720 // Skia generally uses the top left as the origin but PDF | 723 // Skia generally uses the top left as the origin but PDF |
721 // natively has the origin at the bottom left. This matrix | 724 // natively has the origin at the bottom left. This matrix |
722 // corrects for that. But that only needs to be done once, we | 725 // corrects for that. But that only needs to be done once, we |
723 // don't do it when layering. | 726 // don't do it when layering. |
724 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight)); | 727 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight)); |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 if (bitmap.isOpaque()) { | 1053 if (bitmap.isOpaque()) { |
1051 replace_srcmode_on_opaque_paint(&paint); | 1054 replace_srcmode_on_opaque_paint(&paint); |
1052 } | 1055 } |
1053 | 1056 |
1054 if (d.fClip->isEmpty()) { | 1057 if (d.fClip->isEmpty()) { |
1055 return; | 1058 return; |
1056 } | 1059 } |
1057 | 1060 |
1058 SkMatrix transform = matrix; | 1061 SkMatrix transform = matrix; |
1059 transform.postConcat(*d.fMatrix); | 1062 transform.postConcat(*d.fMatrix); |
1060 const SkImage* image = fCanon->bitmapToImage(bitmap); | 1063 const SkImage* image = fDocument->canon()->bitmapToImage(bitmap); |
1061 if (!image) { | 1064 if (!image) { |
1062 return; | 1065 return; |
1063 } | 1066 } |
1064 this->internalDrawImage(transform, d.fClipStack, *d.fClip, image, nullptr, | 1067 this->internalDrawImage(transform, d.fClipStack, *d.fClip, image, nullptr, |
1065 paint); | 1068 paint); |
1066 } | 1069 } |
1067 | 1070 |
1068 void SkPDFDevice::drawSprite(const SkDraw& d, | 1071 void SkPDFDevice::drawSprite(const SkDraw& d, |
1069 const SkBitmap& bitmap, | 1072 const SkBitmap& bitmap, |
1070 int x, | 1073 int x, |
1071 int y, | 1074 int y, |
1072 const SkPaint& srcPaint) { | 1075 const SkPaint& srcPaint) { |
1073 SkPaint paint = srcPaint; | 1076 SkPaint paint = srcPaint; |
1074 if (bitmap.isOpaque()) { | 1077 if (bitmap.isOpaque()) { |
1075 replace_srcmode_on_opaque_paint(&paint); | 1078 replace_srcmode_on_opaque_paint(&paint); |
1076 } | 1079 } |
1077 | 1080 |
1078 if (d.fClip->isEmpty()) { | 1081 if (d.fClip->isEmpty()) { |
1079 return; | 1082 return; |
1080 } | 1083 } |
1081 | 1084 |
1082 SkMatrix matrix; | 1085 SkMatrix matrix; |
1083 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); | 1086 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); |
1084 const SkImage* image = fCanon->bitmapToImage(bitmap); | 1087 const SkImage* image = fDocument->canon()->bitmapToImage(bitmap); |
1085 if (!image) { | 1088 if (!image) { |
1086 return; | 1089 return; |
1087 } | 1090 } |
1088 this->internalDrawImage(matrix, d.fClipStack, *d.fClip, image, nullptr, | 1091 this->internalDrawImage(matrix, d.fClipStack, *d.fClip, image, nullptr, |
1089 paint); | 1092 paint); |
1090 } | 1093 } |
1091 | 1094 |
1092 void SkPDFDevice::drawImage(const SkDraw& draw, | 1095 void SkPDFDevice::drawImage(const SkDraw& draw, |
1093 const SkImage* image, | 1096 const SkImage* image, |
1094 SkScalar x, | 1097 SkScalar x, |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 device->drawText(d, text, len, x, y, transparent); | 1192 device->drawText(d, text, len, x, y, transparent); |
1190 break; | 1193 break; |
1191 default: | 1194 default: |
1192 SkFAIL("unknown text encoding"); | 1195 SkFAIL("unknown text encoding"); |
1193 } | 1196 } |
1194 } | 1197 } |
1195 | 1198 |
1196 | 1199 |
1197 void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, | 1200 void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, |
1198 SkScalar x, SkScalar y, const SkPaint& srcPaint) { | 1201 SkScalar x, SkScalar y, const SkPaint& srcPaint) { |
1199 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) { | 1202 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fDocument->canon())
) { |
1200 // https://bug.skia.org/3866 | 1203 // https://bug.skia.org/3866 |
1201 SkPath path; | 1204 SkPath path; |
1202 srcPaint.getTextPath(text, len, x, y, &path); | 1205 srcPaint.getTextPath(text, len, x, y, &path); |
1203 this->drawPath(d, path, srcPaint, &SkMatrix::I(), true); | 1206 this->drawPath(d, path, srcPaint, &SkMatrix::I(), true); |
1204 // Draw text transparently to make it copyable/searchable/accessable. | 1207 // Draw text transparently to make it copyable/searchable/accessable. |
1205 draw_transparent_text(this, d, text, len, x, y, srcPaint); | 1208 draw_transparent_text(this, d, text, len, x, y, srcPaint); |
1206 return; | 1209 return; |
1207 } | 1210 } |
1208 SkPaint paint = srcPaint; | 1211 SkPaint paint = srcPaint; |
1209 replace_srcmode_on_opaque_paint(&paint); | 1212 replace_srcmode_on_opaque_paint(&paint); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1250 content.entry()->fContent.writeText(encodedString.c_str()); | 1253 content.entry()->fContent.writeText(encodedString.c_str()); |
1251 consumedGlyphCount += availableGlyphs; | 1254 consumedGlyphCount += availableGlyphs; |
1252 content.entry()->fContent.writeText(" Tj\n"); | 1255 content.entry()->fContent.writeText(" Tj\n"); |
1253 } | 1256 } |
1254 content.entry()->fContent.writeText("ET\n"); | 1257 content.entry()->fContent.writeText("ET\n"); |
1255 } | 1258 } |
1256 | 1259 |
1257 void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, | 1260 void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, |
1258 const SkScalar pos[], int scalarsPerPos, | 1261 const SkScalar pos[], int scalarsPerPos, |
1259 const SkPoint& offset, const SkPaint& srcPaint) { | 1262 const SkPoint& offset, const SkPaint& srcPaint) { |
1260 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) { | 1263 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fDocument->canon())
) { |
1261 const SkPoint* positions = reinterpret_cast<const SkPoint*>(pos); | 1264 const SkPoint* positions = reinterpret_cast<const SkPoint*>(pos); |
1262 SkAutoTMalloc<SkPoint> positionsBuffer; | 1265 SkAutoTMalloc<SkPoint> positionsBuffer; |
1263 if (2 != scalarsPerPos) { | 1266 if (2 != scalarsPerPos) { |
1264 int glyphCount = srcPaint.textToGlyphs(text, len, NULL); | 1267 int glyphCount = srcPaint.textToGlyphs(text, len, NULL); |
1265 positionsBuffer.reset(glyphCount); | 1268 positionsBuffer.reset(glyphCount); |
1266 for (int i = 0; i < glyphCount; ++i) { | 1269 for (int i = 0; i < glyphCount; ++i) { |
1267 positionsBuffer[i].set(pos[i], 0.0f); | 1270 positionsBuffer[i].set(pos[i], 0.0f); |
1268 } | 1271 } |
1269 positions = &positionsBuffer[0]; | 1272 positions = &positionsBuffer[0]; |
1270 } | 1273 } |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1673 SkPDFFormXObject* mask, | 1676 SkPDFFormXObject* mask, |
1674 const SkClipStack* clipStack, | 1677 const SkClipStack* clipStack, |
1675 const SkRegion& clipRegion, | 1678 const SkRegion& clipRegion, |
1676 SkXfermode::Mode mode, | 1679 SkXfermode::Mode mode, |
1677 bool invertClip) { | 1680 bool invertClip) { |
1678 if (clipRegion.isEmpty() && !invertClip) { | 1681 if (clipRegion.isEmpty() && !invertClip) { |
1679 return; | 1682 return; |
1680 } | 1683 } |
1681 | 1684 |
1682 auto sMaskGS = SkPDFGraphicState::GetSMaskGraphicState( | 1685 auto sMaskGS = SkPDFGraphicState::GetSMaskGraphicState( |
1683 mask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode, fCanon); | 1686 mask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode, fDocument->ca
non()); |
1684 | 1687 |
1685 SkMatrix identity; | 1688 SkMatrix identity; |
1686 identity.reset(); | 1689 identity.reset(); |
1687 SkPaint paint; | 1690 SkPaint paint; |
1688 paint.setXfermodeMode(mode); | 1691 paint.setXfermodeMode(mode); |
1689 ScopedContentEntry content(this, clipStack, clipRegion, identity, paint); | 1692 ScopedContentEntry content(this, clipStack, clipRegion, identity, paint); |
1690 if (!content.entry()) { | 1693 if (!content.entry()) { |
1691 return; | 1694 return; |
1692 } | 1695 } |
1693 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), | 1696 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), |
1694 &content.entry()->fContent); | 1697 &content.entry()->fContent); |
1695 SkPDFUtils::DrawFormXObject(xObjectIndex, &content.entry()->fContent); | 1698 SkPDFUtils::DrawFormXObject(xObjectIndex, &content.entry()->fContent); |
1696 | 1699 |
1697 // Call makeNoSmaskGraphicState() instead of | 1700 // Call makeNoSmaskGraphicState() instead of |
1698 // SkPDFGraphicState::MakeNoSmaskGraphicState so that the canon | 1701 // SkPDFGraphicState::MakeNoSmaskGraphicState so that the canon |
1699 // can deduplicate. | 1702 // can deduplicate. |
1700 sMaskGS = fCanon->makeNoSmaskGraphicState(); | 1703 sMaskGS = fDocument->canon()->makeNoSmaskGraphicState(); |
1701 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), | 1704 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), |
1702 &content.entry()->fContent); | 1705 &content.entry()->fContent); |
1703 } | 1706 } |
1704 | 1707 |
1705 ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* clipStack, | 1708 ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* clipStack, |
1706 const SkRegion& clipRegion, | 1709 const SkRegion& clipRegion, |
1707 const SkMatrix& matrix, | 1710 const SkMatrix& matrix, |
1708 const SkPaint& paint, | 1711 const SkPaint& paint, |
1709 bool hasText, | 1712 bool hasText, |
1710 SkPDFFormXObject** dst) { | 1713 SkPDFFormXObject** dst) { |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1997 // We need to apply the initial transform to bounds in order to get | 2000 // We need to apply the initial transform to bounds in order to get |
1998 // bounds in a consistent coordinate system. | 2001 // bounds in a consistent coordinate system. |
1999 SkRect boundsTemp; | 2002 SkRect boundsTemp; |
2000 boundsTemp.set(bounds); | 2003 boundsTemp.set(bounds); |
2001 fInitialTransform.mapRect(&boundsTemp); | 2004 fInitialTransform.mapRect(&boundsTemp); |
2002 boundsTemp.roundOut(&bounds); | 2005 boundsTemp.roundOut(&bounds); |
2003 | 2006 |
2004 SkScalar rasterScale = | 2007 SkScalar rasterScale = |
2005 SkIntToScalar(fRasterDpi) / DPI_FOR_RASTER_SCALE_ONE; | 2008 SkIntToScalar(fRasterDpi) / DPI_FOR_RASTER_SCALE_ONE; |
2006 pdfShader.reset(SkPDFShader::GetPDFShader( | 2009 pdfShader.reset(SkPDFShader::GetPDFShader( |
2007 fCanon, fRasterDpi, *shader, transform, bounds, rasterScale)); | 2010 fDocument, fRasterDpi, *shader, transform, bounds, rasterScale))
; |
2008 | 2011 |
2009 if (pdfShader.get()) { | 2012 if (pdfShader.get()) { |
2010 // pdfShader has been canonicalized so we can directly compare | 2013 // pdfShader has been canonicalized so we can directly compare |
2011 // pointers. | 2014 // pointers. |
2012 int resourceIndex = fShaderResources.find(pdfShader.get()); | 2015 int resourceIndex = fShaderResources.find(pdfShader.get()); |
2013 if (resourceIndex < 0) { | 2016 if (resourceIndex < 0) { |
2014 resourceIndex = fShaderResources.count(); | 2017 resourceIndex = fShaderResources.count(); |
2015 fShaderResources.push(pdfShader.get()); | 2018 fShaderResources.push(pdfShader.get()); |
2016 pdfShader.get()->ref(); | 2019 pdfShader.get()->ref(); |
2017 } | 2020 } |
(...skipping 10 matching lines...) Expand all Loading... |
2028 SkShader::kColor_GradientType) { | 2031 SkShader::kColor_GradientType) { |
2029 entry->fColor = SkColorSetA(gradientColor, 0xFF); | 2032 entry->fColor = SkColorSetA(gradientColor, 0xFF); |
2030 color = gradientColor; | 2033 color = gradientColor; |
2031 } | 2034 } |
2032 } | 2035 } |
2033 } | 2036 } |
2034 | 2037 |
2035 sk_sp<SkPDFGraphicState> newGraphicState; | 2038 sk_sp<SkPDFGraphicState> newGraphicState; |
2036 if (color == paint.getColor()) { | 2039 if (color == paint.getColor()) { |
2037 newGraphicState.reset( | 2040 newGraphicState.reset( |
2038 SkPDFGraphicState::GetGraphicStateForPaint(fCanon, paint)); | 2041 SkPDFGraphicState::GetGraphicStateForPaint(fDocument->canon(), p
aint)); |
2039 } else { | 2042 } else { |
2040 SkPaint newPaint = paint; | 2043 SkPaint newPaint = paint; |
2041 newPaint.setColor(color); | 2044 newPaint.setColor(color); |
2042 newGraphicState.reset( | 2045 newGraphicState.reset( |
2043 SkPDFGraphicState::GetGraphicStateForPaint(fCanon, newPaint)); | 2046 SkPDFGraphicState::GetGraphicStateForPaint(fDocument->canon(), n
ewPaint)); |
2044 } | 2047 } |
2045 int resourceIndex = addGraphicStateResource(newGraphicState.get()); | 2048 int resourceIndex = addGraphicStateResource(newGraphicState.get()); |
2046 entry->fGraphicStateIndex = resourceIndex; | 2049 entry->fGraphicStateIndex = resourceIndex; |
2047 | 2050 |
2048 if (hasText) { | 2051 if (hasText) { |
2049 entry->fTextScaleX = paint.getTextScaleX(); | 2052 entry->fTextScaleX = paint.getTextScaleX(); |
2050 entry->fTextFill = paint.getStyle(); | 2053 entry->fTextFill = paint.getStyle(); |
2051 } else { | 2054 } else { |
2052 entry->fTextScaleX = 0; | 2055 entry->fTextScaleX = 0; |
2053 } | 2056 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2090 fontIndex).c_str()); | 2093 fontIndex).c_str()); |
2091 contentEntry->fContent.writeText(" "); | 2094 contentEntry->fContent.writeText(" "); |
2092 SkPDFUtils::AppendScalar(paint.getTextSize(), &contentEntry->fContent); | 2095 SkPDFUtils::AppendScalar(paint.getTextSize(), &contentEntry->fContent); |
2093 contentEntry->fContent.writeText(" Tf\n"); | 2096 contentEntry->fContent.writeText(" Tf\n"); |
2094 contentEntry->fState.fFont = fFontResources[fontIndex]; | 2097 contentEntry->fState.fFont = fFontResources[fontIndex]; |
2095 } | 2098 } |
2096 } | 2099 } |
2097 | 2100 |
2098 int SkPDFDevice::getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID) { | 2101 int SkPDFDevice::getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID) { |
2099 sk_sp<SkPDFFont> newFont( | 2102 sk_sp<SkPDFFont> newFont( |
2100 SkPDFFont::GetFontResource(fCanon, typeface, glyphID)); | 2103 SkPDFFont::GetFontResource(fDocument->canon(), typeface, glyphID)); |
2101 int resourceIndex = fFontResources.find(newFont.get()); | 2104 int resourceIndex = fFontResources.find(newFont.get()); |
2102 if (resourceIndex < 0) { | 2105 if (resourceIndex < 0) { |
2103 resourceIndex = fFontResources.count(); | 2106 resourceIndex = fFontResources.count(); |
2104 fFontResources.push(newFont.get()); | 2107 fFontResources.push(newFont.get()); |
2105 newFont.get()->ref(); | 2108 newFont.get()->ref(); |
2106 } | 2109 } |
2107 return resourceIndex; | 2110 return resourceIndex; |
2108 } | 2111 } |
2109 | 2112 |
2110 static SkSize rect_to_size(const SkRect& r) { | 2113 static SkSize rect_to_size(const SkRect& r) { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2254 // TODO(https://bug.skia.org/4378): implement colorfilter on other | 2257 // TODO(https://bug.skia.org/4378): implement colorfilter on other |
2255 // draw calls. This code here works for all | 2258 // draw calls. This code here works for all |
2256 // drawBitmap*()/drawImage*() calls amd ImageFilters (which | 2259 // drawBitmap*()/drawImage*() calls amd ImageFilters (which |
2257 // rasterize a layer on this backend). Fortuanely, this seems | 2260 // rasterize a layer on this backend). Fortuanely, this seems |
2258 // to be how Chromium impements most color-filters. | 2261 // to be how Chromium impements most color-filters. |
2259 autoImageUnref.reset(color_filter(image, colorFilter)); | 2262 autoImageUnref.reset(color_filter(image, colorFilter)); |
2260 image = autoImageUnref.get(); | 2263 image = autoImageUnref.get(); |
2261 // TODO(halcanary): de-dupe this by caching filtered images. | 2264 // TODO(halcanary): de-dupe this by caching filtered images. |
2262 // (maybe in the resource cache?) | 2265 // (maybe in the resource cache?) |
2263 } | 2266 } |
2264 sk_sp<SkPDFObject> pdfimage(SkSafeRef(fCanon->findPDFBitmap(image))); | 2267 sk_sp<SkPDFObject> pdfimage(SkSafeRef(fDocument->canon()->findPDFBitmap(imag
e))); |
2265 if (!pdfimage) { | 2268 if (!pdfimage) { |
2266 pdfimage.reset(SkPDFCreateBitmapObject( | 2269 pdfimage.reset(SkPDFCreateBitmapObject( |
2267 image, fCanon->getPixelSerializer())); | 2270 image, fDocument->canon()->getPixelSerializer()))
; |
2268 if (!pdfimage) { | 2271 if (!pdfimage) { |
2269 return; | 2272 return; |
2270 } | 2273 } |
2271 fCanon->addPDFBitmap(image->uniqueID(), pdfimage.get()); | 2274 #if SK_PDF_SERIALIZE_IMAGES_EARLY // TODO(halcanary): enable. |
| 2275 sk_sp<SkData> encodedImage(image->refEncodedData()); |
| 2276 if (!encodedImage) { |
| 2277 fDocument->serialize(pdfimage); |
| 2278 } |
| 2279 #endif |
| 2280 fDocument->canon()->addPDFBitmap(image->uniqueID(), pdfimage.get()); |
2272 } | 2281 } |
2273 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), | 2282 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), |
2274 &content.entry()->fContent); | 2283 &content.entry()->fContent); |
2275 } | 2284 } |
OLD | NEW |