| /* | |
| * 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<SkPDFObjRef> ref(SkNEW_ARGS(SkPDFObjRef, (value))); | |
| insertResource(type, key, ref); | |
| fResources.add(value); | |
| return value; | |
| } | |
| void SkPDFResourceDict::getReferencedResources( | |
| const SkTSet<SkPDFObject*>& knownResourceObjects, | |
| SkTSet<SkPDFObject*>* 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<SkPDFDict> newDict(SkNEW(SkPDFDict())); | |
| SkAutoTUnref<SkPDFName> typeName( | |
| SkNEW_ARGS(SkPDFName, (get_resource_type_name(type)))); | |
| insert(typeName, newDict); // ref counting handled here | |
| fTypes[type] = newDict; | |
| typeDict = newDict.get(); | |
| } | |
| SkAutoTUnref<SkPDFName> keyName( | |
| SkNEW_ARGS(SkPDFName, (getResourceName(type, key)))); | |
| typeDict->insert(keyName, value); | |
| return value; | |
| } |