OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkPDFCatalog.h" | 10 #include "SkPDFCatalog.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 SkPDFFont* subsetFont = | 32 SkPDFFont* subsetFont = |
33 entry->fFont->getFontSubset(entry->fGlyphSet); | 33 entry->fFont->getFontSubset(entry->fGlyphSet); |
34 if (subsetFont) { | 34 if (subsetFont) { |
35 catalog->setSubstitute(entry->fFont, subsetFont); | 35 catalog->setSubstitute(entry->fFont, subsetFont); |
36 substitutes->push(subsetFont); // Transfer ownership to substitutes | 36 substitutes->push(subsetFont); // Transfer ownership to substitutes |
37 } | 37 } |
38 entry = iterator.next(); | 38 entry = iterator.next(); |
39 } | 39 } |
40 } | 40 } |
41 | 41 |
42 SkPDFDocument::SkPDFDocument() {} | |
43 | |
44 SkPDFDocument::~SkPDFDocument() { fPageDevices.unrefAll(); } | |
45 | |
46 static void emit_pdf_header(SkWStream* stream) { | 42 static void emit_pdf_header(SkWStream* stream) { |
47 stream->writeText("%PDF-1.4\n%"); | 43 stream->writeText("%PDF-1.4\n%"); |
48 // The PDF spec recommends including a comment with four bytes, all | 44 // The PDF spec recommends including a comment with four bytes, all |
49 // with their high bits set. This is "Skia" with the high bits set. | 45 // with their high bits set. This is "Skia" with the high bits set. |
50 stream->write32(0xD3EBE9E1); | 46 stream->write32(0xD3EBE9E1); |
51 stream->writeText("\n"); | 47 stream->writeText("\n"); |
52 } | 48 } |
53 | 49 |
54 static void emit_pdf_footer(SkWStream* stream, | 50 static void emit_pdf_footer(SkWStream* stream, |
55 SkPDFCatalog* catalog, | 51 SkPDFCatalog* catalog, |
56 SkPDFObject* docCatalog, | 52 SkPDFObject* docCatalog, |
57 int64_t objCount, | 53 int64_t objCount, |
58 int32_t xRefFileOffset) { | 54 int32_t xRefFileOffset) { |
59 SkPDFDict trailerDict; | 55 SkPDFDict trailerDict; |
60 // TODO(vandebo): Linearized format will take a Prev entry too. | 56 // TODO(vandebo): Linearized format will take a Prev entry too. |
61 // TODO(vandebo): PDF/A requires an ID entry. | 57 // TODO(vandebo): PDF/A requires an ID entry. |
62 trailerDict.insertInt("Size", int(objCount)); | 58 trailerDict.insertInt("Size", int(objCount)); |
63 trailerDict.insert("Root", new SkPDFObjRef(docCatalog))->unref(); | 59 trailerDict.insert("Root", new SkPDFObjRef(docCatalog))->unref(); |
64 | 60 |
65 stream->writeText("trailer\n"); | 61 stream->writeText("trailer\n"); |
66 trailerDict.emitObject(stream, catalog); | 62 trailerDict.emitObject(stream, catalog); |
67 stream->writeText("\nstartxref\n"); | 63 stream->writeText("\nstartxref\n"); |
68 stream->writeBigDecAsText(xRefFileOffset); | 64 stream->writeBigDecAsText(xRefFileOffset); |
69 stream->writeText("\n%%EOF"); | 65 stream->writeText("\n%%EOF"); |
70 } | 66 } |
71 | 67 |
72 bool SkPDFDocument::emitPDF(SkWStream* stream) { | 68 bool SkPDFDocument::EmitPDF(const SkTDArray<SkPDFDevice*>& pageDevices, |
73 // SkTDArray<SkPDFDevice*> fPageDevices; | 69 SkWStream* stream) { |
74 if (fPageDevices.isEmpty()) { | 70 if (pageDevices.isEmpty()) { |
75 return false; | 71 return false; |
76 } | 72 } |
77 SkTDArray<SkPDFPage*> pages; | 73 SkTDArray<SkPDFPage*> pages; |
78 for (int i = 0; i < fPageDevices.count(); i++) { | 74 for (int i = 0; i < pageDevices.count(); i++) { |
| 75 SkASSERT(pageDevices[i]); |
79 // Reference from new passed to pages. | 76 // Reference from new passed to pages. |
80 pages.push(SkNEW_ARGS(SkPDFPage, (fPageDevices[i]))); | 77 pages.push(SkNEW_ARGS(SkPDFPage, (pageDevices[i]))); |
81 } | 78 } |
82 SkPDFCatalog catalog; | 79 SkPDFCatalog catalog; |
83 | 80 |
84 SkTDArray<SkPDFDict*> pageTree; | 81 SkTDArray<SkPDFDict*> pageTree; |
85 SkAutoTUnref<SkPDFDict> docCatalog(SkNEW_ARGS(SkPDFDict, ("Catalog"))); | 82 SkAutoTUnref<SkPDFDict> docCatalog(SkNEW_ARGS(SkPDFDict, ("Catalog"))); |
86 SkTSet<SkPDFObject*> firstPageResources; | 83 SkTSet<SkPDFObject*> firstPageResources; |
87 SkTSet<SkPDFObject*> otherPageResources; | 84 SkTSet<SkPDFObject*> otherPageResources; |
88 SkTDArray<SkPDFObject*> substitutes; | 85 SkTDArray<SkPDFObject*> substitutes; |
89 catalog.addObject(docCatalog.get(), true); | 86 catalog.addObject(docCatalog.get(), true); |
90 | 87 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 | 184 |
188 firstPageResources.safeUnrefAll(); | 185 firstPageResources.safeUnrefAll(); |
189 otherPageResources.safeUnrefAll(); | 186 otherPageResources.safeUnrefAll(); |
190 | 187 |
191 substitutes.unrefAll(); | 188 substitutes.unrefAll(); |
192 docCatalog.reset(NULL); | 189 docCatalog.reset(NULL); |
193 return true; | 190 return true; |
194 } | 191 } |
195 | 192 |
196 // TODO(halcanary): expose notEmbeddableCount in SkDocument | 193 // TODO(halcanary): expose notEmbeddableCount in SkDocument |
197 void SkPDFDocument::getCountOfFontTypes( | 194 void SkPDFDocument::GetCountOfFontTypes( |
| 195 const SkTDArray<SkPDFDevice*>& pageDevices, |
198 int counts[SkAdvancedTypefaceMetrics::kOther_Font + 1], | 196 int counts[SkAdvancedTypefaceMetrics::kOther_Font + 1], |
199 int* notSubsettableCount, | 197 int* notSubsettableCount, |
200 int* notEmbeddableCount) const { | 198 int* notEmbeddableCount) { |
201 sk_bzero(counts, sizeof(int) * | 199 sk_bzero(counts, sizeof(int) * |
202 (SkAdvancedTypefaceMetrics::kOther_Font + 1)); | 200 (SkAdvancedTypefaceMetrics::kOther_Font + 1)); |
203 SkTDArray<SkFontID> seenFonts; | 201 SkTDArray<SkFontID> seenFonts; |
204 int notSubsettable = 0; | 202 int notSubsettable = 0; |
205 int notEmbeddable = 0; | 203 int notEmbeddable = 0; |
206 | 204 |
207 for (int pageNumber = 0; pageNumber < fPageDevices.count(); pageNumber++) { | 205 for (int pageNumber = 0; pageNumber < pageDevices.count(); pageNumber++) { |
208 const SkTDArray<SkPDFFont*>& fontResources = | 206 const SkTDArray<SkPDFFont*>& fontResources = |
209 fPageDevices[pageNumber]->getFontResources(); | 207 pageDevices[pageNumber]->getFontResources(); |
210 for (int font = 0; font < fontResources.count(); font++) { | 208 for (int font = 0; font < fontResources.count(); font++) { |
211 SkFontID fontID = fontResources[font]->typeface()->uniqueID(); | 209 SkFontID fontID = fontResources[font]->typeface()->uniqueID(); |
212 if (seenFonts.find(fontID) == -1) { | 210 if (seenFonts.find(fontID) == -1) { |
213 counts[fontResources[font]->getType()]++; | 211 counts[fontResources[font]->getType()]++; |
214 seenFonts.push(fontID); | 212 seenFonts.push(fontID); |
215 if (!fontResources[font]->canSubset()) { | 213 if (!fontResources[font]->canSubset()) { |
216 notSubsettable++; | 214 notSubsettable++; |
217 } | 215 } |
218 if (!fontResources[font]->canEmbed()) { | 216 if (!fontResources[font]->canEmbed()) { |
219 notEmbeddable++; | 217 notEmbeddable++; |
220 } | 218 } |
221 } | 219 } |
222 } | 220 } |
223 } | 221 } |
224 if (notSubsettableCount) { | 222 if (notSubsettableCount) { |
225 *notSubsettableCount = notSubsettable; | 223 *notSubsettableCount = notSubsettable; |
226 | 224 |
227 } | 225 } |
228 if (notEmbeddableCount) { | 226 if (notEmbeddableCount) { |
229 *notEmbeddableCount = notEmbeddable; | 227 *notEmbeddableCount = notEmbeddable; |
230 } | 228 } |
231 } | 229 } |
OLD | NEW |