Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Side by Side Diff: src/pdf/SkPDFDevice.cpp

Issue 2112943002: SkPDF: Glyph Useage Map improvements (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pdf/SkPDFDevice.h ('k') | src/pdf/SkPDFDocument.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 637 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 }; 648 };
649 649
650 //////////////////////////////////////////////////////////////////////////////// 650 ////////////////////////////////////////////////////////////////////////////////
651 651
652 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFDocument* do c, bool flip) 652 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFDocument* do c, bool flip)
653 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry)) 653 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry))
654 , fPageSize(pageSize) 654 , fPageSize(pageSize)
655 , fContentSize(pageSize) 655 , fContentSize(pageSize)
656 , fExistingClipRegion(SkIRect::MakeSize(pageSize)) 656 , fExistingClipRegion(SkIRect::MakeSize(pageSize))
657 , fClipStack(nullptr) 657 , fClipStack(nullptr)
658 , fFontGlyphUsage(new SkPDFGlyphSetMap)
659 , fRasterDpi(rasterDpi) 658 , fRasterDpi(rasterDpi)
660 , fDocument(doc) { 659 , fDocument(doc) {
661 SkASSERT(pageSize.width() > 0); 660 SkASSERT(pageSize.width() > 0);
662 SkASSERT(pageSize.height() > 0); 661 SkASSERT(pageSize.height() > 0);
663 fLegacyBitmap.setInfo( 662 fLegacyBitmap.setInfo(
664 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height())); 663 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height()));
665 if (flip) { 664 if (flip) {
666 // Skia generally uses the top left as the origin but PDF 665 // Skia generally uses the top left as the origin but PDF
667 // natively has the origin at the bottom left. This matrix 666 // natively has the origin at the bottom left. This matrix
668 // corrects for that. But that only needs to be done once, we 667 // corrects for that. But that only needs to be done once, we
669 // don't do it when layering. 668 // don't do it when layering.
670 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight)); 669 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight));
671 fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1); 670 fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1);
672 } else { 671 } else {
673 fInitialTransform.setIdentity(); 672 fInitialTransform.setIdentity();
674 } 673 }
675 } 674 }
676 675
677 SkPDFDevice::~SkPDFDevice() { 676 SkPDFDevice::~SkPDFDevice() {
678 this->cleanUp(true); 677 this->cleanUp();
679 } 678 }
680 679
681 void SkPDFDevice::init() { 680 void SkPDFDevice::init() {
682 fContentEntries.reset(); 681 fContentEntries.reset();
683 if (fFontGlyphUsage.get() == nullptr) {
684 fFontGlyphUsage.reset(new SkPDFGlyphSetMap);
685 }
686 } 682 }
687 683
688 void SkPDFDevice::cleanUp(bool clearFontUsage) { 684 void SkPDFDevice::cleanUp() {
689 fGraphicStateResources.unrefAll(); 685 fGraphicStateResources.unrefAll();
690 fXObjectResources.unrefAll(); 686 fXObjectResources.unrefAll();
691 fFontResources.unrefAll(); 687 fFontResources.unrefAll();
692 fShaderResources.unrefAll(); 688 fShaderResources.unrefAll();
693
694 if (clearFontUsage) {
695 fFontGlyphUsage->reset();
696 }
697 } 689 }
698 690
699 void SkPDFDevice::drawAnnotation(const SkDraw& d, const SkRect& rect, const char key[], 691 void SkPDFDevice::drawAnnotation(const SkDraw& d, const SkRect& rect, const char key[],
700 SkData* value) { 692 SkData* value) {
701 if (0 == rect.width() && 0 == rect.height()) { 693 if (0 == rect.width() && 0 == rect.height()) {
702 handlePointAnnotation({ rect.x(), rect.y() }, *d.fMatrix, key, value); 694 handlePointAnnotation({ rect.x(), rect.y() }, *d.fMatrix, key, value);
703 } else { 695 } else {
704 SkPath path; 696 SkPath path;
705 path.addRect(rect); 697 path.addRect(rect);
706 handlePathAnnotation(path, d, key, value); 698 handlePathAnnotation(path, d, key, value);
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 1159
1168 SkPaint::GlyphCacheProc glyphCacheProc = textPaint.getGlyphCacheProc(true); 1160 SkPaint::GlyphCacheProc glyphCacheProc = textPaint.getGlyphCacheProc(true);
1169 align_text(glyphCacheProc, textPaint, glyphIDs, numGlyphs, &x, &y); 1161 align_text(glyphCacheProc, textPaint, glyphIDs, numGlyphs, &x, &y);
1170 content.entry()->fContent.writeText("BT\n"); 1162 content.entry()->fContent.writeText("BT\n");
1171 set_text_transform(x, y, textPaint.getTextSkewX(), 1163 set_text_transform(x, y, textPaint.getTextSkewX(),
1172 &content.entry()->fContent); 1164 &content.entry()->fContent);
1173 int consumedGlyphCount = 0; 1165 int consumedGlyphCount = 0;
1174 1166
1175 SkTDArray<uint16_t> glyphIDsCopy(glyphIDs, numGlyphs); 1167 SkTDArray<uint16_t> glyphIDsCopy(glyphIDs, numGlyphs);
1176 1168
1169 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage();
1170
1177 while (numGlyphs > consumedGlyphCount) { 1171 while (numGlyphs > consumedGlyphCount) {
1178 this->updateFont(textPaint, glyphIDs[consumedGlyphCount], content.entry( )); 1172 this->updateFont(textPaint, glyphIDs[consumedGlyphCount], content.entry( ));
1179 SkPDFFont* font = content.entry()->fState.fFont; 1173 SkPDFFont* font = content.entry()->fState.fFont;
1180 1174
1181 int availableGlyphs = font->glyphsToPDFFontEncoding( 1175 int availableGlyphs = font->glyphsToPDFFontEncoding(
1182 glyphIDsCopy.begin() + consumedGlyphCount, 1176 glyphIDsCopy.begin() + consumedGlyphCount,
1183 numGlyphs - consumedGlyphCount); 1177 numGlyphs - consumedGlyphCount);
1184 fFontGlyphUsage->noteGlyphUsage( 1178 fontGlyphUsage->noteGlyphUsage(
1185 font, glyphIDsCopy.begin() + consumedGlyphCount, 1179 font, glyphIDsCopy.begin() + consumedGlyphCount,
1186 availableGlyphs); 1180 availableGlyphs);
1187 write_wide_string(&content.entry()->fContent, 1181 write_wide_string(&content.entry()->fContent,
1188 glyphIDsCopy.begin() + consumedGlyphCount, 1182 glyphIDsCopy.begin() + consumedGlyphCount,
1189 availableGlyphs, font->multiByteGlyphs()); 1183 availableGlyphs, font->multiByteGlyphs());
1190 consumedGlyphCount += availableGlyphs; 1184 consumedGlyphCount += availableGlyphs;
1191 content.entry()->fContent.writeText(" Tj\n"); 1185 content.entry()->fContent.writeText(" Tj\n");
1192 } 1186 }
1193 content.entry()->fContent.writeText("ET\n"); 1187 content.entry()->fContent.writeText("ET\n");
1194 } 1188 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 } 1230 }
1237 1231
1238 SkGlyphStorage storage(0); 1232 SkGlyphStorage storage(0);
1239 const uint16_t* glyphIDs = nullptr; 1233 const uint16_t* glyphIDs = nullptr;
1240 size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphID s); 1234 size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphID s);
1241 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 1235 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
1242 1236
1243 SkPaint::GlyphCacheProc glyphCacheProc = textPaint.getGlyphCacheProc(true); 1237 SkPaint::GlyphCacheProc glyphCacheProc = textPaint.getGlyphCacheProc(true);
1244 content.entry()->fContent.writeText("BT\n"); 1238 content.entry()->fContent.writeText("BT\n");
1245 this->updateFont(textPaint, glyphIDs[0], content.entry()); 1239 this->updateFont(textPaint, glyphIDs[0], content.entry());
1240 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage();
1246 for (size_t i = 0; i < numGlyphs; i++) { 1241 for (size_t i = 0; i < numGlyphs; i++) {
1247 SkPDFFont* font = content.entry()->fState.fFont; 1242 SkPDFFont* font = content.entry()->fState.fFont;
1248 uint16_t encodedValue = glyphIDs[i]; 1243 uint16_t encodedValue = glyphIDs[i];
1249 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { 1244 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) {
1250 // The current pdf font cannot encode the current glyph. 1245 // The current pdf font cannot encode the current glyph.
1251 // Try to get a pdf font which can encode the current glyph. 1246 // Try to get a pdf font which can encode the current glyph.
1252 this->updateFont(textPaint, glyphIDs[i], content.entry()); 1247 this->updateFont(textPaint, glyphIDs[i], content.entry());
1253 font = content.entry()->fState.fFont; 1248 font = content.entry()->fState.fFont;
1254 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { 1249 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) {
1255 SkDEBUGFAIL("PDF could not encode glyph."); 1250 SkDEBUGFAIL("PDF could not encode glyph.");
1256 continue; 1251 continue;
1257 } 1252 }
1258 } 1253 }
1259 1254
1260 fFontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1); 1255 fontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1);
1261 SkScalar x = offset.x() + pos[i * scalarsPerPos]; 1256 SkScalar x = offset.x() + pos[i * scalarsPerPos];
1262 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos + 1] : 0); 1257 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos + 1] : 0);
1263 1258
1264 align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y); 1259 align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y);
1265 set_text_transform(x, y, textPaint.getTextSkewX(), &content.entry()->fCo ntent); 1260 set_text_transform(x, y, textPaint.getTextSkewX(), &content.entry()->fCo ntent);
1266 write_wide_string(&content.entry()->fContent, &encodedValue, 1, 1261 write_wide_string(&content.entry()->fContent, &encodedValue, 1,
1267 font->multiByteGlyphs()); 1262 font->multiByteGlyphs());
1268 content.entry()->fContent.writeText(" Tj\n"); 1263 content.entry()->fContent.writeText(" Tj\n");
1269 } 1264 }
1270 content.entry()->fContent.writeText("ET\n"); 1265 content.entry()->fContent.writeText("ET\n");
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 SkIntToScalar(device->height()))); 1313 SkIntToScalar(device->height())));
1319 content.setShape(shape); 1314 content.setShape(shape);
1320 } 1315 }
1321 if (!content.needSource()) { 1316 if (!content.needSource()) {
1322 return; 1317 return;
1323 } 1318 }
1324 1319
1325 auto xObject = sk_make_sp<SkPDFFormXObject>(pdfDevice); 1320 auto xObject = sk_make_sp<SkPDFFormXObject>(pdfDevice);
1326 SkPDFUtils::DrawFormXObject(this->addXObjectResource(xObject.get()), 1321 SkPDFUtils::DrawFormXObject(this->addXObjectResource(xObject.get()),
1327 &content.entry()->fContent); 1322 &content.entry()->fContent);
1328
1329 // Merge glyph sets from the drawn device.
1330 fFontGlyphUsage->merge(pdfDevice->getFontGlyphUsage());
1331 } 1323 }
1332 1324
1333 SkImageInfo SkPDFDevice::imageInfo() const { 1325 SkImageInfo SkPDFDevice::imageInfo() const {
1334 return fLegacyBitmap.info(); 1326 return fLegacyBitmap.info();
1335 } 1327 }
1336 1328
1337 void SkPDFDevice::onAttachToCanvas(SkCanvas* canvas) { 1329 void SkPDFDevice::onAttachToCanvas(SkCanvas* canvas) {
1338 INHERITED::onAttachToCanvas(canvas); 1330 INHERITED::onAttachToCanvas(canvas);
1339 1331
1340 // Canvas promises that this ptr is valid until onDetachFromCanvas is called 1332 // Canvas promises that this ptr is valid until onDetachFromCanvas is called
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1551 SkString name(static_cast<const char*>(dest.nameData->data())); 1543 SkString name(static_cast<const char*>(dest.nameData->data()));
1552 dict->insertObject(name, std::move(pdfDest)); 1544 dict->insertObject(name, std::move(pdfDest));
1553 } 1545 }
1554 } 1546 }
1555 1547
1556 SkPDFFormXObject* SkPDFDevice::createFormXObjectFromDevice() { 1548 SkPDFFormXObject* SkPDFDevice::createFormXObjectFromDevice() {
1557 SkPDFFormXObject* xobject = new SkPDFFormXObject(this); 1549 SkPDFFormXObject* xobject = new SkPDFFormXObject(this);
1558 // We always draw the form xobjects that we create back into the device, so 1550 // We always draw the form xobjects that we create back into the device, so
1559 // we simply preserve the font usage instead of pulling it out and merging 1551 // we simply preserve the font usage instead of pulling it out and merging
1560 // it back in later. 1552 // it back in later.
1561 cleanUp(false); // Reset this device to have no content. 1553 cleanUp(); // Reset this device to have no content.
1562 init(); 1554 init();
1563 return xobject; 1555 return xobject;
1564 } 1556 }
1565 1557
1566 void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, 1558 void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
1567 SkPDFFormXObject* mask, 1559 SkPDFFormXObject* mask,
1568 const SkClipStack* clipStack, 1560 const SkClipStack* clipStack,
1569 const SkRegion& clipRegion, 1561 const SkRegion& clipRegion,
1570 SkXfermode::Mode mode, 1562 SkXfermode::Mode mode,
1571 bool invertClip) { 1563 bool invertClip) {
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
2136 if (!pdfimage) { 2128 if (!pdfimage) {
2137 return; 2129 return;
2138 } 2130 }
2139 fDocument->serialize(pdfimage); // serialize images early. 2131 fDocument->serialize(pdfimage); // serialize images early.
2140 fDocument->canon()->addPDFBitmap(key, pdfimage); 2132 fDocument->canon()->addPDFBitmap(key, pdfimage);
2141 } 2133 }
2142 // TODO(halcanary): addXObjectResource() should take a sk_sp<SkPDFObject> 2134 // TODO(halcanary): addXObjectResource() should take a sk_sp<SkPDFObject>
2143 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), 2135 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()),
2144 &content.entry()->fContent); 2136 &content.entry()->fContent);
2145 } 2137 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFDevice.h ('k') | src/pdf/SkPDFDocument.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698