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