1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2013 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkStream.h" 9cb93a386Sopenharmony_ci#include "src/pdf/SkPDFResourceDict.h" 10cb93a386Sopenharmony_ci#include "src/pdf/SkPDFTypes.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci// Verify that the values of enum ResourceType correspond to the expected values 13cb93a386Sopenharmony_ci// as defined in the arrays below. 14cb93a386Sopenharmony_ci// If these are failing, you may need to update the kResourceTypePrefixes 15cb93a386Sopenharmony_ci// and kResourceTypeNames arrays below. 16cb93a386Sopenharmony_cistatic_assert(0 == (int)SkPDFResourceType::kExtGState, "resource_type_mismatch"); 17cb93a386Sopenharmony_cistatic_assert(1 == (int)SkPDFResourceType::kPattern, "resource_type_mismatch"); 18cb93a386Sopenharmony_cistatic_assert(2 == (int)SkPDFResourceType::kXObject, "resource_type_mismatch"); 19cb93a386Sopenharmony_cistatic_assert(3 == (int)SkPDFResourceType::kFont, "resource_type_mismatch"); 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ci// One extra character for the Prefix. 22cb93a386Sopenharmony_ciconstexpr size_t kMaxResourceNameLength = 1 + kSkStrAppendS32_MaxSize; 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci// returns pointer just past end of what's written into `dst`. 25cb93a386Sopenharmony_cistatic char* get_resource_name(char dst[kMaxResourceNameLength], SkPDFResourceType type, int key) { 26cb93a386Sopenharmony_ci static const char kResourceTypePrefixes[] = { 27cb93a386Sopenharmony_ci 'G', // kExtGState 28cb93a386Sopenharmony_ci 'P', // kPattern 29cb93a386Sopenharmony_ci 'X', // kXObject 30cb93a386Sopenharmony_ci 'F' // kFont 31cb93a386Sopenharmony_ci }; 32cb93a386Sopenharmony_ci SkASSERT((unsigned)type < SK_ARRAY_COUNT(kResourceTypePrefixes)); 33cb93a386Sopenharmony_ci dst[0] = kResourceTypePrefixes[(unsigned)type]; 34cb93a386Sopenharmony_ci return SkStrAppendS32(dst + 1, key); 35cb93a386Sopenharmony_ci} 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_civoid SkPDFWriteResourceName(SkWStream* dst, SkPDFResourceType type, int key) { 38cb93a386Sopenharmony_ci // One extra character for the leading '/'. 39cb93a386Sopenharmony_ci char buffer[1 + kMaxResourceNameLength]; 40cb93a386Sopenharmony_ci buffer[0] = '/'; 41cb93a386Sopenharmony_ci char* end = get_resource_name(buffer + 1, type, key); 42cb93a386Sopenharmony_ci dst->write(buffer, (size_t)(end - buffer)); 43cb93a386Sopenharmony_ci} 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_cistatic const char* resource_name(SkPDFResourceType type) { 46cb93a386Sopenharmony_ci static const char* kResourceTypeNames[] = { 47cb93a386Sopenharmony_ci "ExtGState", 48cb93a386Sopenharmony_ci "Pattern", 49cb93a386Sopenharmony_ci "XObject", 50cb93a386Sopenharmony_ci "Font" 51cb93a386Sopenharmony_ci }; 52cb93a386Sopenharmony_ci SkASSERT((unsigned)type < SK_ARRAY_COUNT(kResourceTypeNames)); 53cb93a386Sopenharmony_ci return kResourceTypeNames[(unsigned)type]; 54cb93a386Sopenharmony_ci} 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_cistatic SkString resource(SkPDFResourceType type, int index) { 57cb93a386Sopenharmony_ci char buffer[kMaxResourceNameLength]; 58cb93a386Sopenharmony_ci char* end = get_resource_name(buffer, type, index); 59cb93a386Sopenharmony_ci return SkString(buffer, (size_t)(end - buffer)); 60cb93a386Sopenharmony_ci} 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_cistatic void add_subdict(const std::vector<SkPDFIndirectReference>& resourceList, 63cb93a386Sopenharmony_ci SkPDFResourceType type, 64cb93a386Sopenharmony_ci SkPDFDict* dst) { 65cb93a386Sopenharmony_ci if (!resourceList.empty()) { 66cb93a386Sopenharmony_ci auto resources = SkPDFMakeDict(); 67cb93a386Sopenharmony_ci for (SkPDFIndirectReference ref : resourceList) { 68cb93a386Sopenharmony_ci resources->insertRef(resource(type, ref.fValue), ref); 69cb93a386Sopenharmony_ci } 70cb93a386Sopenharmony_ci dst->insertObject(resource_name(type), std::move(resources)); 71cb93a386Sopenharmony_ci } 72cb93a386Sopenharmony_ci} 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_cistatic std::unique_ptr<SkPDFArray> make_proc_set() { 75cb93a386Sopenharmony_ci auto procSets = SkPDFMakeArray(); 76cb93a386Sopenharmony_ci static const char kProcs[][7] = { "PDF", "Text", "ImageB", "ImageC", "ImageI"}; 77cb93a386Sopenharmony_ci procSets->reserve(SK_ARRAY_COUNT(kProcs)); 78cb93a386Sopenharmony_ci for (const char* proc : kProcs) { 79cb93a386Sopenharmony_ci procSets->appendName(proc); 80cb93a386Sopenharmony_ci } 81cb93a386Sopenharmony_ci return procSets; 82cb93a386Sopenharmony_ci} 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_cistd::unique_ptr<SkPDFDict> SkPDFMakeResourceDict( 85cb93a386Sopenharmony_ci const std::vector<SkPDFIndirectReference>& graphicStateResources, 86cb93a386Sopenharmony_ci const std::vector<SkPDFIndirectReference>& shaderResources, 87cb93a386Sopenharmony_ci const std::vector<SkPDFIndirectReference>& xObjectResources, 88cb93a386Sopenharmony_ci const std::vector<SkPDFIndirectReference>& fontResources) { 89cb93a386Sopenharmony_ci auto dict = SkPDFMakeDict(); 90cb93a386Sopenharmony_ci dict->insertObject("ProcSet", make_proc_set()); 91cb93a386Sopenharmony_ci add_subdict(graphicStateResources, SkPDFResourceType::kExtGState, dict.get()); 92cb93a386Sopenharmony_ci add_subdict(shaderResources, SkPDFResourceType::kPattern, dict.get()); 93cb93a386Sopenharmony_ci add_subdict(xObjectResources, SkPDFResourceType::kXObject, dict.get()); 94cb93a386Sopenharmony_ci add_subdict(fontResources, SkPDFResourceType::kFont, dict.get()); 95cb93a386Sopenharmony_ci return dict; 96cb93a386Sopenharmony_ci} 97