diff --git a/src/pdf/SkPDFDocument.cpp b/src/pdf/SkPDFDocument.cpp index c4a5d448a5..c522b39516 100644 --- a/src/pdf/SkPDFDocument.cpp +++ b/src/pdf/SkPDFDocument.cpp @@ -89,9 +89,13 @@ public: : fCat(cat), fOut(out), fBaseOffset(SkToOffT(out->bytesWritten())) { } - void stream(SkPDFObject* obj) { - fCat->setFileOffset(obj, this->offset()); - obj->emit(fOut, fCat, true); + void stream(SkPDFObject* object) { + fCat->setFileOffset(object, this->offset()); + SkPDFObject* realObject = fCat->getSubstituteObject(object); + fCat->emitObjectNumber(fOut, realObject); + fOut->writeText(" obj\n"); + realObject->emitObject(fOut, fCat); + fOut->writeText("\nendobj\n"); } off_t offset() { diff --git a/src/pdf/SkPDFTypes.cpp b/src/pdf/SkPDFTypes.cpp index 4a84876b20..b0763a3c59 100644 --- a/src/pdf/SkPDFTypes.cpp +++ b/src/pdf/SkPDFTypes.cpp @@ -19,32 +19,9 @@ /////////////////////////////////////////////////////////////////////////////// -void SkPDFObject::emit(SkWStream* stream, SkPDFCatalog* catalog, - bool indirect) { - SkPDFObject* realObject = catalog->getSubstituteObject(this); - if (indirect) { - realObject->emitIndirectObject(stream, catalog); - } else { - realObject->emitObject(stream, catalog); - } -} - -size_t SkPDFObject::getOutputSize(SkPDFCatalog* catalog, bool indirect) { - SkDynamicMemoryWStream buffer; - emit(&buffer, catalog, indirect); - return buffer.getOffset(); -} - void SkPDFObject::getResources(const SkTSet& knownResourceObjects, SkTSet* newResourceObjects) {} -void SkPDFObject::emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog) { - catalog->emitObjectNumber(stream, this); - stream->writeText(" obj\n"); - emit(stream, catalog, false); - stream->writeText("\nendobj\n"); -} - void SkPDFObject::AddResourceHelper(SkPDFObject* resource, SkTDArray* list) { list->push(resource); @@ -70,6 +47,8 @@ void SkPDFObject::GetResourcesHelper( } } +//////////////////////////////////////////////////////////////////////////////// + SkPDFObjRef::SkPDFObjRef(SkPDFObject* obj) : fObj(obj) { SkSafeRef(obj); } @@ -81,6 +60,8 @@ void SkPDFObjRef::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { stream->writeText(" R"); } +//////////////////////////////////////////////////////////////////////////////// + SkPDFInt::SkPDFInt(int32_t value) : fValue(value) {} SkPDFInt::~SkPDFInt() {} @@ -88,6 +69,8 @@ void SkPDFInt::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { stream->writeDecAsText(fValue); } +//////////////////////////////////////////////////////////////////////////////// + SkPDFBool::SkPDFBool(bool value) : fValue(value) {} SkPDFBool::~SkPDFBool() {} @@ -99,6 +82,8 @@ void SkPDFBool::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { } } +//////////////////////////////////////////////////////////////////////////////// + SkPDFScalar::SkPDFScalar(SkScalar value) : fValue(value) {} SkPDFScalar::~SkPDFScalar() {} @@ -155,6 +140,8 @@ void SkPDFScalar::Append(SkScalar value, SkWStream* stream) { #endif // SK_ALLOW_LARGE_PDF_SCALARS } +//////////////////////////////////////////////////////////////////////////////// + SkPDFString::SkPDFString(const char value[]) : fValue(FormatString(value, strlen(value))) { } @@ -238,6 +225,8 @@ SkString SkPDFString::DoFormatString(const void* input, size_t len, return result; } +//////////////////////////////////////////////////////////////////////////////// + SkPDFName::SkPDFName(const char name[]) : fValue(FormatName(SkString(name))) {} SkPDFName::SkPDFName(const SkString& name) : fValue(FormatName(name)) {} SkPDFName::~SkPDFName() {} @@ -270,6 +259,8 @@ SkString SkPDFName::FormatName(const SkString& input) { return result; } +//////////////////////////////////////////////////////////////////////////////// + SkPDFArray::SkPDFArray() {} SkPDFArray::~SkPDFArray() { fValue.unrefAll(); @@ -278,7 +269,7 @@ SkPDFArray::~SkPDFArray() { void SkPDFArray::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { stream->writeText("["); for (int i = 0; i < fValue.count(); i++) { - fValue[i]->emit(stream, catalog, false); + catalog->getSubstituteObject(fValue[i])->emitObject(stream, catalog); if (i + 1 < fValue.count()) { stream->writeText(" "); } @@ -338,7 +329,6 @@ int SkPDFDict::size() const { return fValue.count(); } - void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { SkAutoMutexAcquire lock(fMutex); // If another thread triggers a // resize while this thread is in @@ -350,7 +340,8 @@ void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { SkASSERT(fValue[i].value); fValue[i].key->emitObject(stream, catalog); stream->writeText(" "); - fValue[i].value->emit(stream, catalog, false); + catalog->getSubstituteObject(fValue[i].value) + ->emitObject(stream, catalog); stream->writeText("\n"); } stream->writeText(">>"); diff --git a/src/pdf/SkPDFTypes.h b/src/pdf/SkPDFTypes.h index ce1ca86e6e..b0ce0b97d0 100644 --- a/src/pdf/SkPDFTypes.h +++ b/src/pdf/SkPDFTypes.h @@ -30,12 +30,12 @@ class SkPDFObject : public SkRefCnt { public: SK_DECLARE_INST_COUNT(SkPDFObject) - /** Return the size (number of bytes) of this object in the final output - * file. Only used for testing. + /** Subclasses must implement this method to print the object to the + * PDF file. * @param catalog The object catalog to use. - * @param indirect If true, output an object identifier with the object. + * @param stream The writable output stream to send the output to. */ - size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); + virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog) = 0; /** For non-primitive objects (i.e. objects defined outside this file), * this method will add to newResourceObjects any objects that this method @@ -49,23 +49,6 @@ public: virtual void getResources(const SkTSet& knownResourceObjects, SkTSet* newResourceObjects); - /** Emit this object unless the catalog has a substitute object, in which - * case emit that. - * @see emitObject - */ - void emit(SkWStream* stream, SkPDFCatalog* catalog, bool indirect); - - /** Helper function to output an indirect object. - * @param catalog The object catalog to use. - * @param stream The writable output stream to send the output to. - */ - void emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog); - - /** Helper function to find the size of an indirect object. - * @param catalog The object catalog to use. - */ - size_t getIndirectOutputSize(SkPDFCatalog* catalog); - /** Static helper function to add a resource to a list. The list takes * a reference. * @param resource The resource to add. @@ -88,14 +71,7 @@ public: const SkTSet& knownResourceObjects, SkTSet* newResourceObjects); -protected: - /** Subclasses must implement this method to print the object to the - * PDF file. - * @param catalog The object catalog to use. - * @param stream The writable output stream to send the output to. - */ - virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog) = 0; - +private: typedef SkRefCnt INHERITED; }; diff --git a/tests/PDFPrimitivesTest.cpp b/tests/PDFPrimitivesTest.cpp index 3610dd9581..f15f06090d 100644 --- a/tests/PDFPrimitivesTest.cpp +++ b/tests/PDFPrimitivesTest.cpp @@ -69,6 +69,29 @@ static bool stream_contains(const SkDynamicMemoryWStream& stream, return false; } +static void emit_object(SkPDFObject* object, + SkWStream* stream, + SkPDFCatalog* catalog, + bool indirect) { + SkPDFObject* realObject = catalog->getSubstituteObject(object); + if (indirect) { + catalog->emitObjectNumber(stream, realObject); + stream->writeText(" obj\n"); + realObject->emitObject(stream, catalog); + stream->writeText("\nendobj\n"); + } else { + realObject->emitObject(stream, catalog); + } +} + +static size_t get_output_size(SkPDFObject* object, + SkPDFCatalog* catalog, + bool indirect) { + SkDynamicMemoryWStream buffer; + emit_object(object, &buffer, catalog, indirect); + return buffer.getOffset(); +} + static void CheckObjectOutput(skiatest::Reporter* reporter, SkPDFObject* obj, const char* expectedData, size_t expectedSize, bool indirect, bool compression) { @@ -77,11 +100,11 @@ static void CheckObjectOutput(skiatest::Reporter* reporter, SkPDFObject* obj, docFlags = SkTBitOr(docFlags, SkPDFDocument::kFavorSpeedOverSize_Flags); } SkPDFCatalog catalog(docFlags); - size_t directSize = obj->getOutputSize(&catalog, false); + size_t directSize = get_output_size(obj, &catalog, false); REPORTER_ASSERT(reporter, directSize == expectedSize); SkDynamicMemoryWStream buffer; - obj->emit(&buffer, &catalog, false); + emit_object(obj, &buffer, &catalog, false); REPORTER_ASSERT(reporter, directSize == buffer.getOffset()); REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedData, directSize)); @@ -95,12 +118,12 @@ static void CheckObjectOutput(skiatest::Reporter* reporter, SkPDFObject* obj, catalog.addObject(obj, false); - size_t indirectSize = obj->getOutputSize(&catalog, true); + size_t indirectSize = get_output_size(obj, &catalog, true); REPORTER_ASSERT(reporter, indirectSize == directSize + headerLen + footerLen); buffer.reset(); - obj->emit(&buffer, &catalog, true); + emit_object(obj, &buffer, &catalog, true); REPORTER_ASSERT(reporter, indirectSize == buffer.getOffset()); REPORTER_ASSERT(reporter, stream_equals(buffer, 0, header, headerLen)); REPORTER_ASSERT(reporter, stream_equals(buffer, headerLen, expectedData, @@ -227,18 +250,18 @@ static void TestSubstitute(skiatest::Reporter* reporter) { catalog.setSubstitute(proxy.get(), stub.get()); SkDynamicMemoryWStream buffer; - proxy->emit(&buffer, &catalog, false); + emit_object(proxy, &buffer, &catalog, false); SkTSet* substituteResources = catalog.getSubstituteList(false); for (int i = 0; i < substituteResources->count(); ++i) { - (*substituteResources)[i]->emit(&buffer, &catalog, true); + emit_object((*substituteResources)[i], &buffer, &catalog, true); } char objectResult[] = "2 0 obj\n<>\nendobj\n"; catalog.setFileOffset(proxy.get(), 0); - size_t outputSize = catalog.getSubstituteObject(proxy.get()) - ->getOutputSize(&catalog, true); + size_t outputSize = get_output_size( + catalog.getSubstituteObject(proxy.get()), &catalog, true); REPORTER_ASSERT(reporter, outputSize == strlen(objectResult)); char expectedResult[] =