|  | /* | 
|  | * 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; | 
|  | } |