diff -r 000000000000 -r 6474c204b198 gfx/skia/trunk/src/pdf/SkPDFResourceDict.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/skia/trunk/src/pdf/SkPDFResourceDict.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,124 @@ +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkPDFResourceDict.h" +#include "SkPostConfig.h" + +// Sanity check that the values of enum SkPDFResourceType correspond to the +// expected values as defined in the arrays below. +// If these are failing, you may need to update the resource_type_prefixes +// and resource_type_names arrays below. +SK_COMPILE_ASSERT(SkPDFResourceDict::kExtGState_ResourceType == 0, + resource_type_mismatch); +SK_COMPILE_ASSERT(SkPDFResourceDict::kPattern_ResourceType == 1, + resource_type_mismatch); +SK_COMPILE_ASSERT(SkPDFResourceDict::kXObject_ResourceType == 2, + resource_type_mismatch); +SK_COMPILE_ASSERT(SkPDFResourceDict::kFont_ResourceType == 3, + resource_type_mismatch); + +static const char resource_type_prefixes[] = { + 'G', + 'P', + 'X', + 'F' +}; + +static const char* resource_type_names[] = { + "ExtGState", + "Pattern", + "XObject", + "Font" +}; + +static char get_resource_type_prefix( + SkPDFResourceDict::SkPDFResourceType type) { + SkASSERT(type >= 0); + SkASSERT(type < SkPDFResourceDict::kResourceTypeCount); + + return resource_type_prefixes[type]; +} + +static const char* get_resource_type_name( + SkPDFResourceDict::SkPDFResourceType type) { + SkASSERT(type >= 0); + SkASSERT(type < SkPDFResourceDict::kResourceTypeCount); + + return resource_type_names[type]; +} + +SkPDFResourceDict::SkPDFResourceDict() : SkPDFDict() { + const char procs[][7] = {"PDF", "Text", "ImageB", "ImageC", "ImageI"}; + SkPDFArray* procSets = SkNEW(SkPDFArray()); + + procSets->reserve(SK_ARRAY_COUNT(procs)); + for (size_t i = 0; i < SK_ARRAY_COUNT(procs); i++) { + procSets->appendName(procs[i]); + } + insert("ProcSets", procSets)->unref(); + + // Actual sub-dicts will be lazily added later + fTypes.setCount(kResourceTypeCount); + for (int i=0; i < kResourceTypeCount; i++) { + fTypes[i] = NULL; + } +} + +SkPDFObject* SkPDFResourceDict::insertResourceAsReference( + SkPDFResourceType type, int key, SkPDFObject* value) { + SkAutoTUnref ref(SkNEW_ARGS(SkPDFObjRef, (value))); + insertResource(type, key, ref); + fResources.add(value); + + return value; +} + +void SkPDFResourceDict::getReferencedResources( + const SkTSet& knownResourceObjects, + SkTSet* newResourceObjects, + bool recursive) const { + // TODO: reserve not correct if we need to recursively explore. + newResourceObjects->setReserve(newResourceObjects->count() + + fResources.count()); + + for (int i = 0; i < fResources.count(); i++) { + if (!knownResourceObjects.contains(fResources[i]) && + !newResourceObjects->contains(fResources[i])) { + newResourceObjects->add(fResources[i]); + fResources[i]->ref(); + if (recursive) { + fResources[i]->getResources(knownResourceObjects, + newResourceObjects); + } + } + } +} + +SkString SkPDFResourceDict::getResourceName( + SkPDFResourceType type, int key) { + SkString keyString; + keyString.printf("%c%d", get_resource_type_prefix(type), key); + return keyString; +} + +SkPDFObject* SkPDFResourceDict::insertResource( + SkPDFResourceType type, int key, SkPDFObject* value) { + SkPDFDict* typeDict = fTypes[type]; + if (NULL == typeDict) { + SkAutoTUnref newDict(SkNEW(SkPDFDict())); + SkAutoTUnref typeName( + SkNEW_ARGS(SkPDFName, (get_resource_type_name(type)))); + insert(typeName, newDict); // ref counting handled here + fTypes[type] = newDict; + typeDict = newDict.get(); + } + + SkAutoTUnref keyName( + SkNEW_ARGS(SkPDFName, (getResourceName(type, key)))); + typeDict->insert(keyName, value); + return value; +}