| 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 "SkData.h" |    8 #include "SkData.h" | 
|    9 #include "SkDeflate.h" |    9 #include "SkDeflate.h" | 
|   10 #include "SkPDFTypes.h" |   10 #include "SkPDFTypes.h" | 
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  106             buffer[1] = kHex[(*n >> 4) & 0xF]; |  106             buffer[1] = kHex[(*n >> 4) & 0xF]; | 
|  107             buffer[2] = kHex[*n & 0xF]; |  107             buffer[2] = kHex[*n & 0xF]; | 
|  108             o->write(buffer, sizeof(buffer)); |  108             o->write(buffer, sizeof(buffer)); | 
|  109         } else { |  109         } else { | 
|  110             o->write(n, 1); |  110             o->write(n, 1); | 
|  111         } |  111         } | 
|  112     } |  112     } | 
|  113 } |  113 } | 
|  114  |  114  | 
|  115 void SkPDFUnion::emitObject(SkWStream* stream, |  115 void SkPDFUnion::emitObject(SkWStream* stream, | 
|  116                             const SkPDFObjNumMap& objNumMap, |  116                             const SkPDFObjNumMap& objNumMap) const { | 
|  117                             const SkPDFSubstituteMap& substitutes) const { |  | 
|  118     switch (fType) { |  117     switch (fType) { | 
|  119         case Type::kInt: |  118         case Type::kInt: | 
|  120             stream->writeDecAsText(fIntValue); |  119             stream->writeDecAsText(fIntValue); | 
|  121             return; |  120             return; | 
|  122         case Type::kColorComponent: |  121         case Type::kColorComponent: | 
|  123             SkPDFUtils::AppendColorComponent(SkToU8(fIntValue), stream); |  122             SkPDFUtils::AppendColorComponent(SkToU8(fIntValue), stream); | 
|  124             return; |  123             return; | 
|  125         case Type::kBool: |  124         case Type::kBool: | 
|  126             stream->writeText(fBoolValue ? "true" : "false"); |  125             stream->writeText(fBoolValue ? "true" : "false"); | 
|  127             return; |  126             return; | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  140             return; |  139             return; | 
|  141         case Type::kNameSkS: |  140         case Type::kNameSkS: | 
|  142             stream->writeText("/"); |  141             stream->writeText("/"); | 
|  143             write_name_escaped(stream, pun(fSkString)->c_str()); |  142             write_name_escaped(stream, pun(fSkString)->c_str()); | 
|  144             return; |  143             return; | 
|  145         case Type::kStringSkS: |  144         case Type::kStringSkS: | 
|  146             SkPDFUtils::WriteString(stream, pun(fSkString)->c_str(), |  145             SkPDFUtils::WriteString(stream, pun(fSkString)->c_str(), | 
|  147                                     pun(fSkString)->size()); |  146                                     pun(fSkString)->size()); | 
|  148             return; |  147             return; | 
|  149         case Type::kObjRef: |  148         case Type::kObjRef: | 
|  150             stream->writeDecAsText(objNumMap.getObjectNumber( |  149             stream->writeDecAsText(objNumMap.getObjectNumber(fObject)); | 
|  151                     substitutes.getSubstitute(fObject))); |  | 
|  152             stream->writeText(" 0 R");  // Generation number is always 0. |  150             stream->writeText(" 0 R");  // Generation number is always 0. | 
|  153             return; |  151             return; | 
|  154         case Type::kObject: |  152         case Type::kObject: | 
|  155             fObject->emitObject(stream, objNumMap, substitutes); |  153             fObject->emitObject(stream, objNumMap); | 
|  156             return; |  154             return; | 
|  157         default: |  155         default: | 
|  158             SkDEBUGFAIL("SkPDFUnion::emitObject with bad type"); |  156             SkDEBUGFAIL("SkPDFUnion::emitObject with bad type"); | 
|  159     } |  157     } | 
|  160 } |  158 } | 
|  161  |  159  | 
|  162 void SkPDFUnion::addResources(SkPDFObjNumMap* objNumMap, |  160 void SkPDFUnion::addResources(SkPDFObjNumMap* objNumMap) const { | 
|  163                               const SkPDFSubstituteMap& substituteMap) const { |  | 
|  164     switch (fType) { |  161     switch (fType) { | 
|  165         case Type::kInt: |  162         case Type::kInt: | 
|  166         case Type::kColorComponent: |  163         case Type::kColorComponent: | 
|  167         case Type::kBool: |  164         case Type::kBool: | 
|  168         case Type::kScalar: |  165         case Type::kScalar: | 
|  169         case Type::kName: |  166         case Type::kName: | 
|  170         case Type::kString: |  167         case Type::kString: | 
|  171         case Type::kNameSkS: |  168         case Type::kNameSkS: | 
|  172         case Type::kStringSkS: |  169         case Type::kStringSkS: | 
|  173             return;  // These have no resources. |  170             return;  // These have no resources. | 
|  174         case Type::kObjRef: { |  171         case Type::kObjRef: | 
|  175             SkPDFObject* obj = substituteMap.getSubstitute(fObject); |  172             objNumMap->addObjectRecursively(fObject); | 
|  176             objNumMap->addObjectRecursively(obj, substituteMap); |  | 
|  177             return; |  173             return; | 
|  178         } |  | 
|  179         case Type::kObject: |  174         case Type::kObject: | 
|  180             fObject->addResources(objNumMap, substituteMap); |  175             fObject->addResources(objNumMap); | 
|  181             return; |  176             return; | 
|  182         default: |  177         default: | 
|  183             SkDEBUGFAIL("SkPDFUnion::addResources with bad type"); |  178             SkDEBUGFAIL("SkPDFUnion::addResources with bad type"); | 
|  184     } |  179     } | 
|  185 } |  180 } | 
|  186  |  181  | 
|  187 SkPDFUnion SkPDFUnion::Int(int32_t value) { |  182 SkPDFUnion SkPDFUnion::Int(int32_t value) { | 
|  188     SkPDFUnion u(Type::kInt); |  183     SkPDFUnion u(Type::kInt); | 
|  189     u.fIntValue = value; |  184     u.fIntValue = value; | 
|  190     return u; |  185     return u; | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  246     SkPDFUnion u(Type::kObject); |  241     SkPDFUnion u(Type::kObject); | 
|  247     SkASSERT(objSp.get()); |  242     SkASSERT(objSp.get()); | 
|  248     u.fObject = objSp.release();  // take ownership into union{} |  243     u.fObject = objSp.release();  // take ownership into union{} | 
|  249     return u; |  244     return u; | 
|  250 } |  245 } | 
|  251  |  246  | 
|  252 //////////////////////////////////////////////////////////////////////////////// |  247 //////////////////////////////////////////////////////////////////////////////// | 
|  253  |  248  | 
|  254 #if 0  // Enable if needed. |  249 #if 0  // Enable if needed. | 
|  255 void SkPDFAtom::emitObject(SkWStream* stream, |  250 void SkPDFAtom::emitObject(SkWStream* stream, | 
|  256                            const SkPDFObjNumMap& objNumMap, |  251                            const SkPDFObjNumMap& objNumMap) const { | 
|  257                            const SkPDFSubstituteMap& substitutes) const { |  252     fValue.emitObject(stream, objNumMap); | 
|  258     fValue.emitObject(stream, objNumMap, substitutes); |  | 
|  259 } |  253 } | 
|  260 void SkPDFAtom::addResources(SkPDFObjNumMap* map, |  254 void SkPDFAtom::addResources(SkPDFObjNumMap* map) const { | 
|  261                              const SkPDFSubstituteMap& substitutes) const { |  255     fValue.addResources(map); | 
|  262     fValue.addResources(map, substitutes); |  | 
|  263 } |  256 } | 
|  264 #endif  // 0 |  257 #endif  // 0 | 
|  265  |  258  | 
|  266 //////////////////////////////////////////////////////////////////////////////// |  259 //////////////////////////////////////////////////////////////////////////////// | 
|  267  |  260  | 
|  268 SkPDFArray::SkPDFArray() { SkDEBUGCODE(fDumped = false;) } |  261 SkPDFArray::SkPDFArray() { SkDEBUGCODE(fDumped = false;) } | 
|  269  |  262  | 
|  270 SkPDFArray::~SkPDFArray() { this->drop(); } |  263 SkPDFArray::~SkPDFArray() { this->drop(); } | 
|  271  |  264  | 
|  272 void SkPDFArray::drop() { |  265 void SkPDFArray::drop() { | 
|  273     fValues.reset(); |  266     fValues.reset(); | 
|  274     SkDEBUGCODE(fDumped = true;) |  267     SkDEBUGCODE(fDumped = true;) | 
|  275 } |  268 } | 
|  276  |  269  | 
|  277 int SkPDFArray::size() const { return fValues.count(); } |  270 int SkPDFArray::size() const { return fValues.count(); } | 
|  278  |  271  | 
|  279 void SkPDFArray::reserve(int length) { |  272 void SkPDFArray::reserve(int length) { | 
|  280     // TODO(halcanary): implement SkTArray<T>::reserve() or change the |  273     // TODO(halcanary): implement SkTArray<T>::reserve() or change the | 
|  281     // contstructor of SkPDFArray to take reserve size. |  274     // contstructor of SkPDFArray to take reserve size. | 
|  282 } |  275 } | 
|  283  |  276  | 
|  284 void SkPDFArray::emitObject(SkWStream* stream, |  277 void SkPDFArray::emitObject(SkWStream* stream, | 
|  285                             const SkPDFObjNumMap& objNumMap, |  278                             const SkPDFObjNumMap& objNumMap) const { | 
|  286                             const SkPDFSubstituteMap& substitutes) const { |  | 
|  287     SkASSERT(!fDumped); |  279     SkASSERT(!fDumped); | 
|  288     stream->writeText("["); |  280     stream->writeText("["); | 
|  289     for (int i = 0; i < fValues.count(); i++) { |  281     for (int i = 0; i < fValues.count(); i++) { | 
|  290         fValues[i].emitObject(stream, objNumMap, substitutes); |  282         fValues[i].emitObject(stream, objNumMap); | 
|  291         if (i + 1 < fValues.count()) { |  283         if (i + 1 < fValues.count()) { | 
|  292             stream->writeText(" "); |  284             stream->writeText(" "); | 
|  293         } |  285         } | 
|  294     } |  286     } | 
|  295     stream->writeText("]"); |  287     stream->writeText("]"); | 
|  296 } |  288 } | 
|  297  |  289  | 
|  298 void SkPDFArray::addResources(SkPDFObjNumMap* catalog, |  290 void SkPDFArray::addResources(SkPDFObjNumMap* catalog) const { | 
|  299                               const SkPDFSubstituteMap& substitutes) const { |  | 
|  300     SkASSERT(!fDumped); |  291     SkASSERT(!fDumped); | 
|  301     for (const SkPDFUnion& value : fValues) { |  292     for (const SkPDFUnion& value : fValues) { | 
|  302         value.addResources(catalog, substitutes); |  293         value.addResources(catalog); | 
|  303     } |  294     } | 
|  304 } |  295 } | 
|  305  |  296  | 
|  306 void SkPDFArray::append(SkPDFUnion&& value) { |  297 void SkPDFArray::append(SkPDFUnion&& value) { | 
|  307     fValues.emplace_back(std::move(value)); |  298     fValues.emplace_back(std::move(value)); | 
|  308 } |  299 } | 
|  309  |  300  | 
|  310 void SkPDFArray::appendInt(int32_t value) { |  301 void SkPDFArray::appendInt(int32_t value) { | 
|  311     this->append(SkPDFUnion::Int(value)); |  302     this->append(SkPDFUnion::Int(value)); | 
|  312 } |  303 } | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  357 } |  348 } | 
|  358  |  349  | 
|  359 SkPDFDict::SkPDFDict(const char type[]) { |  350 SkPDFDict::SkPDFDict(const char type[]) { | 
|  360     SkDEBUGCODE(fDumped = false;) |  351     SkDEBUGCODE(fDumped = false;) | 
|  361     if (type) { |  352     if (type) { | 
|  362         this->insertName("Type", type); |  353         this->insertName("Type", type); | 
|  363     } |  354     } | 
|  364 } |  355 } | 
|  365  |  356  | 
|  366 void SkPDFDict::emitObject(SkWStream* stream, |  357 void SkPDFDict::emitObject(SkWStream* stream, | 
|  367                            const SkPDFObjNumMap& objNumMap, |  358                            const SkPDFObjNumMap& objNumMap) const { | 
|  368                            const SkPDFSubstituteMap& substitutes) const { |  | 
|  369     stream->writeText("<<"); |  359     stream->writeText("<<"); | 
|  370     this->emitAll(stream, objNumMap, substitutes); |  360     this->emitAll(stream, objNumMap); | 
|  371     stream->writeText(">>"); |  361     stream->writeText(">>"); | 
|  372 } |  362 } | 
|  373  |  363  | 
|  374 void SkPDFDict::emitAll(SkWStream* stream, |  364 void SkPDFDict::emitAll(SkWStream* stream, | 
|  375                         const SkPDFObjNumMap& objNumMap, |  365                         const SkPDFObjNumMap& objNumMap) const { | 
|  376                         const SkPDFSubstituteMap& substitutes) const { |  | 
|  377     SkASSERT(!fDumped); |  366     SkASSERT(!fDumped); | 
|  378     for (int i = 0; i < fRecords.count(); i++) { |  367     for (int i = 0; i < fRecords.count(); i++) { | 
|  379         fRecords[i].fKey.emitObject(stream, objNumMap, substitutes); |  368         fRecords[i].fKey.emitObject(stream, objNumMap); | 
|  380         stream->writeText(" "); |  369         stream->writeText(" "); | 
|  381         fRecords[i].fValue.emitObject(stream, objNumMap, substitutes); |  370         fRecords[i].fValue.emitObject(stream, objNumMap); | 
|  382         if (i + 1 < fRecords.count()) { |  371         if (i + 1 < fRecords.count()) { | 
|  383             stream->writeText("\n"); |  372             stream->writeText("\n"); | 
|  384         } |  373         } | 
|  385     } |  374     } | 
|  386 } |  375 } | 
|  387  |  376  | 
|  388 void SkPDFDict::addResources(SkPDFObjNumMap* catalog, |  377 void SkPDFDict::addResources(SkPDFObjNumMap* catalog) const { | 
|  389                              const SkPDFSubstituteMap& substitutes) const { |  | 
|  390     SkASSERT(!fDumped); |  378     SkASSERT(!fDumped); | 
|  391     for (int i = 0; i < fRecords.count(); i++) { |  379     for (int i = 0; i < fRecords.count(); i++) { | 
|  392         fRecords[i].fKey.addResources(catalog, substitutes); |  380         fRecords[i].fKey.addResources(catalog); | 
|  393         fRecords[i].fValue.addResources(catalog, substitutes); |  381         fRecords[i].fValue.addResources(catalog); | 
|  394     } |  382     } | 
|  395 } |  383 } | 
|  396  |  384  | 
|  397 SkPDFDict::Record::Record(SkPDFUnion&& k, SkPDFUnion&& v) |  385 SkPDFDict::Record::Record(SkPDFUnion&& k, SkPDFUnion&& v) | 
|  398     : fKey(std::move(k)), fValue(std::move(v)) {} |  386     : fKey(std::move(k)), fValue(std::move(v)) {} | 
|  399  |  387  | 
|  400 int SkPDFDict::size() const { return fRecords.count(); } |  388 int SkPDFDict::size() const { return fRecords.count(); } | 
|  401  |  389  | 
|  402 void SkPDFDict::insertObjRef(const char key[], sk_sp<SkPDFObject> objSp) { |  390 void SkPDFDict::insertObjRef(const char key[], sk_sp<SkPDFObject> objSp) { | 
|  403     fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::ObjRef(std::move(ob
     jSp))); |  391     fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::ObjRef(std::move(ob
     jSp))); | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  456 SkPDFSharedStream::~SkPDFSharedStream() { this->drop(); } |  444 SkPDFSharedStream::~SkPDFSharedStream() { this->drop(); } | 
|  457  |  445  | 
|  458 void SkPDFSharedStream::drop() { |  446 void SkPDFSharedStream::drop() { | 
|  459     fAsset = nullptr;; |  447     fAsset = nullptr;; | 
|  460     fDict.drop(); |  448     fDict.drop(); | 
|  461 } |  449 } | 
|  462  |  450  | 
|  463 #ifdef SK_PDF_LESS_COMPRESSION |  451 #ifdef SK_PDF_LESS_COMPRESSION | 
|  464 void SkPDFSharedStream::emitObject( |  452 void SkPDFSharedStream::emitObject( | 
|  465         SkWStream* stream, |  453         SkWStream* stream, | 
|  466         const SkPDFObjNumMap& objNumMap, |  454         const SkPDFObjNumMap& objNumMap) const { | 
|  467         const SkPDFSubstituteMap& substitutes) const { |  | 
|  468     SkASSERT(fAsset); |  455     SkASSERT(fAsset); | 
|  469     std::unique_ptr<SkStreamAsset> dup(fAsset->duplicate()); |  456     std::unique_ptr<SkStreamAsset> dup(fAsset->duplicate()); | 
|  470     SkASSERT(dup && dup->hasLength()); |  457     SkASSERT(dup && dup->hasLength()); | 
|  471     size_t length = dup->getLength(); |  458     size_t length = dup->getLength(); | 
|  472     stream->writeText("<<"); |  459     stream->writeText("<<"); | 
|  473     fDict.emitAll(stream, objNumMap, substitutes); |  460     fDict.emitAll(stream, objNumMap); | 
|  474     stream->writeText("\n"); |  461     stream->writeText("\n"); | 
|  475     SkPDFUnion::Name("Length").emitObject( |  462     SkPDFUnion::Name("Length").emitObject(stream, objNumMap); | 
|  476             stream, objNumMap, substitutes); |  | 
|  477     stream->writeText(" "); |  463     stream->writeText(" "); | 
|  478     SkPDFUnion::Int(length).emitObject( |  464     SkPDFUnion::Int(length).emitObject(stream, objNumMap); | 
|  479             stream, objNumMap, substitutes); |  | 
|  480     stream->writeText("\n>>stream\n"); |  465     stream->writeText("\n>>stream\n"); | 
|  481     SkStreamCopy(stream, dup.get()); |  466     SkStreamCopy(stream, dup.get()); | 
|  482     stream->writeText("\nendstream"); |  467     stream->writeText("\nendstream"); | 
|  483 } |  468 } | 
|  484 #else |  469 #else | 
|  485 void SkPDFSharedStream::emitObject( |  470 void SkPDFSharedStream::emitObject( | 
|  486         SkWStream* stream, |  471         SkWStream* stream, | 
|  487         const SkPDFObjNumMap& objNumMap, |  472         const SkPDFObjNumMap& objNumMap) const { | 
|  488         const SkPDFSubstituteMap& substitutes) const { |  | 
|  489     SkASSERT(fAsset); |  473     SkASSERT(fAsset); | 
|  490     SkDynamicMemoryWStream buffer; |  474     SkDynamicMemoryWStream buffer; | 
|  491     SkDeflateWStream deflateWStream(&buffer); |  475     SkDeflateWStream deflateWStream(&buffer); | 
|  492     // Since emitObject is const, this function doesn't change the dictionary. |  476     // Since emitObject is const, this function doesn't change the dictionary. | 
|  493     std::unique_ptr<SkStreamAsset> dup(fAsset->duplicate());  // Cheap copy |  477     std::unique_ptr<SkStreamAsset> dup(fAsset->duplicate());  // Cheap copy | 
|  494     SkASSERT(dup); |  478     SkASSERT(dup); | 
|  495     SkStreamCopy(&deflateWStream, dup.get()); |  479     SkStreamCopy(&deflateWStream, dup.get()); | 
|  496     deflateWStream.finalize(); |  480     deflateWStream.finalize(); | 
|  497     size_t length = buffer.bytesWritten(); |  481     size_t length = buffer.bytesWritten(); | 
|  498     stream->writeText("<<"); |  482     stream->writeText("<<"); | 
|  499     fDict.emitAll(stream, objNumMap, substitutes); |  483     fDict.emitAll(stream, objNumMap); | 
|  500     stream->writeText("\n"); |  484     stream->writeText("\n"); | 
|  501     SkPDFUnion::Name("Length").emitObject(stream, objNumMap, substitutes); |  485     SkPDFUnion::Name("Length").emitObject(stream, objNumMap); | 
|  502     stream->writeText(" "); |  486     stream->writeText(" "); | 
|  503     SkPDFUnion::Int(length).emitObject(stream, objNumMap, substitutes); |  487     SkPDFUnion::Int(length).emitObject(stream, objNumMap); | 
|  504     stream->writeText("\n"); |  488     stream->writeText("\n"); | 
|  505     SkPDFUnion::Name("Filter").emitObject(stream, objNumMap, substitutes); |  489     SkPDFUnion::Name("Filter").emitObject(stream, objNumMap); | 
|  506     stream->writeText(" "); |  490     stream->writeText(" "); | 
|  507     SkPDFUnion::Name("FlateDecode").emitObject(stream, objNumMap, substitutes); |  491     SkPDFUnion::Name("FlateDecode").emitObject(stream, objNumMap); | 
|  508     stream->writeText(">>"); |  492     stream->writeText(">>"); | 
|  509     stream->writeText(" stream\n"); |  493     stream->writeText(" stream\n"); | 
|  510     buffer.writeToStream(stream); |  494     buffer.writeToStream(stream); | 
|  511     stream->writeText("\nendstream"); |  495     stream->writeText("\nendstream"); | 
|  512 } |  496 } | 
|  513 #endif |  497 #endif | 
|  514  |  498  | 
|  515 void SkPDFSharedStream::addResources( |  499 void SkPDFSharedStream::addResources( | 
|  516         SkPDFObjNumMap* catalog, const SkPDFSubstituteMap& substitutes) const { |  500         SkPDFObjNumMap* catalog) const { | 
|  517     SkASSERT(fAsset); |  501     SkASSERT(fAsset); | 
|  518     fDict.addResources(catalog, substitutes); |  502     fDict.addResources(catalog); | 
|  519 } |  503 } | 
|  520  |  504  | 
|  521  |  505  | 
|  522 //////////////////////////////////////////////////////////////////////////////// |  506 //////////////////////////////////////////////////////////////////////////////// | 
|  523  |  507  | 
|  524 SkPDFStream:: SkPDFStream(sk_sp<SkData> data) { |  508 SkPDFStream:: SkPDFStream(sk_sp<SkData> data) { | 
|  525     this->setData(std::unique_ptr<SkStreamAsset>( |  509     this->setData(std::unique_ptr<SkStreamAsset>( | 
|  526                           new SkMemoryStream(std::move(data)))); |  510                           new SkMemoryStream(std::move(data)))); | 
|  527 } |  511 } | 
|  528  |  512  | 
|  529 SkPDFStream::SkPDFStream(std::unique_ptr<SkStreamAsset> stream) { |  513 SkPDFStream::SkPDFStream(std::unique_ptr<SkStreamAsset> stream) { | 
|  530     this->setData(std::move(stream)); |  514     this->setData(std::move(stream)); | 
|  531 } |  515 } | 
|  532  |  516  | 
|  533 SkPDFStream::SkPDFStream() {} |  517 SkPDFStream::SkPDFStream() {} | 
|  534  |  518  | 
|  535 SkPDFStream::~SkPDFStream() {} |  519 SkPDFStream::~SkPDFStream() {} | 
|  536  |  520  | 
|  537 void SkPDFStream::addResources( |  521 void SkPDFStream::addResources(SkPDFObjNumMap* catalog) const { | 
|  538         SkPDFObjNumMap* catalog, const SkPDFSubstituteMap& substitutes) const { |  | 
|  539     SkASSERT(fCompressedData); |  522     SkASSERT(fCompressedData); | 
|  540     fDict.addResources(catalog, substitutes); |  523     fDict.addResources(catalog); | 
|  541 } |  524 } | 
|  542  |  525  | 
|  543 void SkPDFStream::drop() { |  526 void SkPDFStream::drop() { | 
|  544     fCompressedData.reset(nullptr); |  527     fCompressedData.reset(nullptr); | 
|  545     fDict.drop(); |  528     fDict.drop(); | 
|  546 } |  529 } | 
|  547  |  530  | 
|  548 void SkPDFStream::emitObject(SkWStream* stream, |  531 void SkPDFStream::emitObject(SkWStream* stream, | 
|  549                              const SkPDFObjNumMap& objNumMap, |  532                              const SkPDFObjNumMap& objNumMap) const { | 
|  550                              const SkPDFSubstituteMap& substitutes) const { |  | 
|  551     SkASSERT(fCompressedData); |  533     SkASSERT(fCompressedData); | 
|  552     fDict.emitObject(stream, objNumMap, substitutes); |  534     fDict.emitObject(stream, objNumMap); | 
|  553     // duplicate (a cheap operation) preserves const on fCompressedData. |  535     // duplicate (a cheap operation) preserves const on fCompressedData. | 
|  554     std::unique_ptr<SkStreamAsset> dup(fCompressedData->duplicate()); |  536     std::unique_ptr<SkStreamAsset> dup(fCompressedData->duplicate()); | 
|  555     SkASSERT(dup); |  537     SkASSERT(dup); | 
|  556     SkASSERT(dup->hasLength()); |  538     SkASSERT(dup->hasLength()); | 
|  557     stream->writeText(" stream\n"); |  539     stream->writeText(" stream\n"); | 
|  558     stream->writeStream(dup.get(), dup->getLength()); |  540     stream->writeStream(dup.get(), dup->getLength()); | 
|  559     stream->writeText("\nendstream"); |  541     stream->writeText("\nendstream"); | 
|  560 } |  542 } | 
|  561  |  543  | 
|  562 void SkPDFStream::setData(std::unique_ptr<SkStreamAsset> stream) { |  544 void SkPDFStream::setData(std::unique_ptr<SkStreamAsset> stream) { | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|  587         return; |  569         return; | 
|  588     } |  570     } | 
|  589     fCompressedData.reset(compressedData.detachAsStream()); |  571     fCompressedData.reset(compressedData.detachAsStream()); | 
|  590     fDict.insertName("Filter", "FlateDecode"); |  572     fDict.insertName("Filter", "FlateDecode"); | 
|  591     fDict.insertInt("Length", compressedLength); |  573     fDict.insertInt("Length", compressedLength); | 
|  592     #endif |  574     #endif | 
|  593 } |  575 } | 
|  594  |  576  | 
|  595 //////////////////////////////////////////////////////////////////////////////// |  577 //////////////////////////////////////////////////////////////////////////////// | 
|  596  |  578  | 
|  597 SkPDFSubstituteMap::~SkPDFSubstituteMap() { |  | 
|  598     fSubstituteMap.foreach( |  | 
|  599             [](SkPDFObject*, SkPDFObject** v) { (*v)->unref(); }); |  | 
|  600 } |  | 
|  601  |  | 
|  602 void SkPDFSubstituteMap::setSubstitute(SkPDFObject* original, |  | 
|  603                                        SkPDFObject* substitute) { |  | 
|  604     SkASSERT(original != substitute); |  | 
|  605     SkASSERT(!fSubstituteMap.find(original)); |  | 
|  606     fSubstituteMap.set(original, SkRef(substitute)); |  | 
|  607 } |  | 
|  608  |  | 
|  609 SkPDFObject* SkPDFSubstituteMap::getSubstitute(SkPDFObject* object) const { |  | 
|  610     SkPDFObject** found = fSubstituteMap.find(object); |  | 
|  611     return found ? *found : object; |  | 
|  612 } |  | 
|  613  |  | 
|  614 //////////////////////////////////////////////////////////////////////////////// |  | 
|  615  |  | 
|  616 bool SkPDFObjNumMap::addObject(SkPDFObject* obj) { |  579 bool SkPDFObjNumMap::addObject(SkPDFObject* obj) { | 
|  617     if (fObjectNumbers.find(obj)) { |  580     if (fObjectNumbers.find(obj)) { | 
|  618         return false; |  581         return false; | 
|  619     } |  582     } | 
|  620     fObjectNumbers.set(obj, fObjectNumbers.count() + 1); |  583     fObjectNumbers.set(obj, fObjectNumbers.count() + 1); | 
|  621     fObjects.emplace_back(sk_ref_sp(obj)); |  584     fObjects.emplace_back(sk_ref_sp(obj)); | 
|  622     return true; |  585     return true; | 
|  623 } |  586 } | 
|  624  |  587  | 
|  625 void SkPDFObjNumMap::addObjectRecursively(SkPDFObject* obj, |  588 void SkPDFObjNumMap::addObjectRecursively(SkPDFObject* obj) { | 
|  626                                           const SkPDFSubstituteMap& subs) { |  | 
|  627     if (obj && this->addObject(obj)) { |  589     if (obj && this->addObject(obj)) { | 
|  628         obj->addResources(this, subs); |  590         obj->addResources(this); | 
|  629     } |  591     } | 
|  630 } |  592 } | 
|  631  |  593  | 
|  632 int32_t SkPDFObjNumMap::getObjectNumber(SkPDFObject* obj) const { |  594 int32_t SkPDFObjNumMap::getObjectNumber(SkPDFObject* obj) const { | 
|  633     int32_t* objectNumberFound = fObjectNumbers.find(obj); |  595     int32_t* objectNumberFound = fObjectNumbers.find(obj); | 
|  634     SkASSERT(objectNumberFound); |  596     SkASSERT(objectNumberFound); | 
|  635     return *objectNumberFound; |  597     return *objectNumberFound; | 
|  636 } |  598 } | 
|  637  |  599  | 
|  638 #ifdef SK_PDF_IMAGE_STATS |  600 #ifdef SK_PDF_IMAGE_STATS | 
|  639 SkAtomic<int> gDrawImageCalls(0); |  601 SkAtomic<int> gDrawImageCalls(0); | 
|  640 SkAtomic<int> gJpegImageObjects(0); |  602 SkAtomic<int> gJpegImageObjects(0); | 
|  641 SkAtomic<int> gRegularImageObjects(0); |  603 SkAtomic<int> gRegularImageObjects(0); | 
|  642  |  604  | 
|  643 void SkPDFImageDumpStats() { |  605 void SkPDFImageDumpStats() { | 
|  644     SkDebugf("\ntotal PDF drawImage/drawBitmap calls: %d\n" |  606     SkDebugf("\ntotal PDF drawImage/drawBitmap calls: %d\n" | 
|  645              "total PDF jpeg images: %d\n" |  607              "total PDF jpeg images: %d\n" | 
|  646              "total PDF regular images: %d\n", |  608              "total PDF regular images: %d\n", | 
|  647              gDrawImageCalls.load(), |  609              gDrawImageCalls.load(), | 
|  648              gJpegImageObjects.load(), |  610              gJpegImageObjects.load(), | 
|  649              gRegularImageObjects.load()); |  611              gRegularImageObjects.load()); | 
|  650 } |  612 } | 
|  651 #endif // SK_PDF_IMAGE_STATS |  613 #endif // SK_PDF_IMAGE_STATS | 
| OLD | NEW |