Chromium Code Reviews| 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 75 } | 75 } |
| 76 | 76 |
| 77 fSubstitutes.safeUnrefAll(); | 77 fSubstitutes.safeUnrefAll(); |
| 78 | 78 |
| 79 fDocCatalog->unref(); | 79 fDocCatalog->unref(); |
| 80 SkSafeUnref(fTrailerDict); | 80 SkSafeUnref(fTrailerDict); |
| 81 SkDELETE(fFirstPageResources); | 81 SkDELETE(fFirstPageResources); |
| 82 SkDELETE(fOtherPageResources); | 82 SkDELETE(fOtherPageResources); |
| 83 } | 83 } |
| 84 | 84 |
| 85 namespace { | |
| 86 class Streamer { | |
| 87 public: | |
| 88 Streamer(SkPDFCatalog* cat, SkWStream* out) | |
| 89 : fCat(cat), fOut(out), fBaseOffset(SkToOffT(out->bytesWritten())) { | |
| 90 } | |
| 91 void stream(SkPDFObject* obj) { | |
|
djsollen
2015/01/13 13:49:47
nit: space between functions
hal.canary
2015/01/13 14:00:26
Done.
| |
| 92 fCat->setFileOffset(obj, this->offset()); | |
| 93 obj->emit(fOut, fCat, true); | |
| 94 } | |
| 95 off_t offset() { | |
| 96 return SkToOffT(fOut->bytesWritten()) - fBaseOffset; | |
| 97 } | |
| 98 | |
| 99 private: | |
| 100 SkPDFCatalog* const fCat; | |
| 101 SkWStream* const fOut; | |
| 102 const off_t fBaseOffset; | |
| 103 }; | |
| 104 } // namespace | |
| 105 | |
| 85 bool SkPDFDocument::emitPDF(SkWStream* stream) { | 106 bool SkPDFDocument::emitPDF(SkWStream* stream) { |
| 86 if (fPages.isEmpty()) { | 107 if (fPages.isEmpty()) { |
| 87 return false; | 108 return false; |
| 88 } | 109 } |
| 89 for (int i = 0; i < fPages.count(); i++) { | 110 for (int i = 0; i < fPages.count(); i++) { |
| 90 if (fPages[i] == NULL) { | 111 if (fPages[i] == NULL) { |
| 91 return false; | 112 return false; |
| 92 } | 113 } |
| 93 } | 114 } |
| 94 | 115 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 151 | 172 |
| 152 if (dests->size() > 0) { | 173 if (dests->size() > 0) { |
| 153 SkPDFDict* raw_dests = dests.get(); | 174 SkPDFDict* raw_dests = dests.get(); |
| 154 fFirstPageResources->add(dests.detach()); // Transfer ownership. | 175 fFirstPageResources->add(dests.detach()); // Transfer ownership. |
| 155 fCatalog->addObject(raw_dests, true /* onFirstPage */); | 176 fCatalog->addObject(raw_dests, true /* onFirstPage */); |
| 156 fDocCatalog->insert("Dests", SkNEW_ARGS(SkPDFObjRef, (raw_dests)))-> unref(); | 177 fDocCatalog->insert("Dests", SkNEW_ARGS(SkPDFObjRef, (raw_dests)))-> unref(); |
| 157 } | 178 } |
| 158 | 179 |
| 159 // Build font subsetting info before proceeding. | 180 // Build font subsetting info before proceeding. |
| 160 perform_font_subsetting(fCatalog.get(), fPages, &fSubstitutes); | 181 perform_font_subsetting(fCatalog.get(), fPages, &fSubstitutes); |
| 161 | |
| 162 // Figure out the size of things and inform the catalog of file offsets. | |
| 163 off_t fileOffset = SkToOffT(this->headerSize()); | |
| 164 fileOffset += SkToOffT(fCatalog->setFileOffset(fDocCatalog, fileOffset)) ; | |
| 165 fileOffset += SkToOffT(fCatalog->setFileOffset(fPages[0], fileOffset)); | |
| 166 fileOffset += fPages[0]->getPageSize(fCatalog.get(), fileOffset); | |
| 167 for (int i = 0; i < fFirstPageResources->count(); i++) { | |
| 168 fileOffset += SkToOffT(fCatalog->setFileOffset((*fFirstPageResources )[i], fileOffset)); | |
| 169 } | |
| 170 // Add the size of resources of substitute objects used on page 1. | |
| 171 fileOffset += fCatalog->setSubstituteResourcesOffsets(fileOffset, true); | |
| 172 if (fPages.count() > 1) { | |
| 173 // TODO(vandebo): For linearized format, save the start of the | |
| 174 // first page xref table and calculate the size. | |
| 175 } | |
| 176 | |
| 177 for (int i = 0; i < fPageTree.count(); i++) { | |
| 178 fileOffset += SkToOffT(fCatalog->setFileOffset(fPageTree[i], fileOff set)); | |
| 179 } | |
| 180 | |
| 181 for (int i = 1; i < fPages.count(); i++) { | |
| 182 fileOffset += fPages[i]->getPageSize(fCatalog.get(), fileOffset); | |
| 183 } | |
| 184 | |
| 185 for (int i = 0; i < fOtherPageResources->count(); i++) { | |
| 186 fileOffset += SkToOffT(fCatalog->setFileOffset((*fOtherPageResources )[i], fileOffset)); | |
| 187 } | |
| 188 | |
| 189 fileOffset += fCatalog->setSubstituteResourcesOffsets(fileOffset, false) ; | |
| 190 fXRefFileOffset = fileOffset; | |
| 191 } | 182 } |
| 192 | 183 |
| 184 Streamer out(fCatalog, stream); | |
| 193 emitHeader(stream); | 185 emitHeader(stream); |
| 194 fDocCatalog->emitIndirectObject(stream, fCatalog.get()); | 186 |
| 195 fPages[0]->emitIndirectObject(stream, fCatalog.get()); | 187 out.stream(fDocCatalog); |
| 196 fPages[0]->emitPage(stream, fCatalog.get()); | 188 out.stream(fPages[0]); |
| 189 out.stream(fPages[0]->getContentStream()); | |
| 190 | |
| 197 for (int i = 0; i < fFirstPageResources->count(); i++) { | 191 for (int i = 0; i < fFirstPageResources->count(); i++) { |
| 198 (*fFirstPageResources)[i]->emit(stream, fCatalog.get(), true); | 192 out.stream((*fFirstPageResources)[i]); |
| 199 } | 193 } |
| 200 fCatalog->emitSubstituteResources(stream, true); | 194 |
| 195 SkTSet<SkPDFObject*>* firstPageSubstituteResources = | |
| 196 fCatalog->getSubstituteList(true); | |
| 197 for (int i = 0; i < firstPageSubstituteResources->count(); ++i) { | |
| 198 out.stream((*firstPageSubstituteResources)[i]); | |
| 199 } | |
| 201 // TODO(vandebo): Support linearized format | 200 // TODO(vandebo): Support linearized format |
| 202 // if (fPages.size() > 1) { | 201 // if (fPages.size() > 1) { |
| 203 // // TODO(vandebo): Save the file offset for the first page xref table. | 202 // // TODO(vandebo): Save the file offset for the first page xref table. |
| 204 // fCatalog->emitXrefTable(stream, true); | 203 // fCatalog->emitXrefTable(stream, true); |
| 205 // } | 204 // } |
| 206 | 205 |
| 207 for (int i = 0; i < fPageTree.count(); i++) { | 206 for (int i = 0; i < fPageTree.count(); i++) { |
| 208 fPageTree[i]->emitIndirectObject(stream, fCatalog.get()); | 207 out.stream(fPageTree[i]); |
| 209 } | 208 } |
| 210 | 209 |
| 211 for (int i = 1; i < fPages.count(); i++) { | 210 for (int i = 1; i < fPages.count(); i++) { |
| 212 fPages[i]->emitPage(stream, fCatalog.get()); | 211 out.stream(fPages[i]->getContentStream()); |
| 213 } | 212 } |
| 214 | 213 |
| 215 for (int i = 0; i < fOtherPageResources->count(); i++) { | 214 for (int i = 0; i < fOtherPageResources->count(); i++) { |
| 216 (*fOtherPageResources)[i]->emit(stream, fCatalog.get(), true); | 215 out.stream((*fOtherPageResources)[i]); |
| 217 } | 216 } |
| 218 | 217 |
| 219 fCatalog->emitSubstituteResources(stream, false); | 218 SkTSet<SkPDFObject*>* otherSubstituteResources = |
| 219 fCatalog->getSubstituteList(false); | |
| 220 for (int i = 0; i < otherSubstituteResources->count(); ++i) { | |
| 221 out.stream((*otherSubstituteResources)[i]); | |
| 222 } | |
| 223 | |
| 224 fXRefFileOffset = out.offset(); | |
| 220 int64_t objCount = fCatalog->emitXrefTable(stream, fPages.count() > 1); | 225 int64_t objCount = fCatalog->emitXrefTable(stream, fPages.count() > 1); |
| 221 emitFooter(stream, objCount); | 226 emitFooter(stream, objCount); |
| 222 return true; | 227 return true; |
| 223 } | 228 } |
| 224 | 229 |
| 225 bool SkPDFDocument::setPage(int pageNumber, SkPDFDevice* pdfDevice) { | 230 bool SkPDFDocument::setPage(int pageNumber, SkPDFDevice* pdfDevice) { |
| 226 if (!fPageTree.isEmpty()) { | 231 if (!fPageTree.isEmpty()) { |
| 227 return false; | 232 return false; |
| 228 } | 233 } |
| 229 | 234 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 fTrailerDict->insertInt("Size", int(objCount)); | 343 fTrailerDict->insertInt("Size", int(objCount)); |
| 339 fTrailerDict->insert("Root", new SkPDFObjRef(fDocCatalog))->unref(); | 344 fTrailerDict->insert("Root", new SkPDFObjRef(fDocCatalog))->unref(); |
| 340 } | 345 } |
| 341 | 346 |
| 342 stream->writeText("trailer\n"); | 347 stream->writeText("trailer\n"); |
| 343 fTrailerDict->emitObject(stream, fCatalog.get()); | 348 fTrailerDict->emitObject(stream, fCatalog.get()); |
| 344 stream->writeText("\nstartxref\n"); | 349 stream->writeText("\nstartxref\n"); |
| 345 stream->writeBigDecAsText(fXRefFileOffset); | 350 stream->writeBigDecAsText(fXRefFileOffset); |
| 346 stream->writeText("\n%%EOF"); | 351 stream->writeText("\n%%EOF"); |
| 347 } | 352 } |
| OLD | NEW |