| 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 |