diff options
Diffstat (limited to 'gfx/skia/skia/src/pdf/SkPDFResourceDict.cpp')
-rw-r--r-- | gfx/skia/skia/src/pdf/SkPDFResourceDict.cpp | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/pdf/SkPDFResourceDict.cpp b/gfx/skia/skia/src/pdf/SkPDFResourceDict.cpp new file mode 100644 index 0000000000..a4eeed3029 --- /dev/null +++ b/gfx/skia/skia/src/pdf/SkPDFResourceDict.cpp @@ -0,0 +1,96 @@ +/* + * 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 "include/core/SkStream.h" +#include "src/pdf/SkPDFResourceDict.h" +#include "src/pdf/SkPDFTypes.h" + +// Verify that the values of enum ResourceType correspond to the expected values +// as defined in the arrays below. +// If these are failing, you may need to update the kResourceTypePrefixes +// and kResourceTypeNames arrays below. +static_assert(0 == (int)SkPDFResourceType::kExtGState, "resource_type_mismatch"); +static_assert(1 == (int)SkPDFResourceType::kPattern, "resource_type_mismatch"); +static_assert(2 == (int)SkPDFResourceType::kXObject, "resource_type_mismatch"); +static_assert(3 == (int)SkPDFResourceType::kFont, "resource_type_mismatch"); + +// One extra character for the Prefix. +constexpr size_t kMaxResourceNameLength = 1 + kSkStrAppendS32_MaxSize; + +// returns pointer just past end of what's written into `dst`. +static char* get_resource_name(char dst[kMaxResourceNameLength], SkPDFResourceType type, int key) { + static const char kResourceTypePrefixes[] = { + 'G', // kExtGState + 'P', // kPattern + 'X', // kXObject + 'F' // kFont + }; + SkASSERT((unsigned)type < std::size(kResourceTypePrefixes)); + dst[0] = kResourceTypePrefixes[(unsigned)type]; + return SkStrAppendS32(dst + 1, key); +} + +void SkPDFWriteResourceName(SkWStream* dst, SkPDFResourceType type, int key) { + // One extra character for the leading '/'. + char buffer[1 + kMaxResourceNameLength]; + buffer[0] = '/'; + char* end = get_resource_name(buffer + 1, type, key); + dst->write(buffer, (size_t)(end - buffer)); +} + +static const char* resource_name(SkPDFResourceType type) { + static const char* kResourceTypeNames[] = { + "ExtGState", + "Pattern", + "XObject", + "Font" + }; + SkASSERT((unsigned)type < std::size(kResourceTypeNames)); + return kResourceTypeNames[(unsigned)type]; +} + +static SkString resource(SkPDFResourceType type, int index) { + char buffer[kMaxResourceNameLength]; + char* end = get_resource_name(buffer, type, index); + return SkString(buffer, (size_t)(end - buffer)); +} + +static void add_subdict(const std::vector<SkPDFIndirectReference>& resourceList, + SkPDFResourceType type, + SkPDFDict* dst) { + if (!resourceList.empty()) { + auto resources = SkPDFMakeDict(); + for (SkPDFIndirectReference ref : resourceList) { + resources->insertRef(resource(type, ref.fValue), ref); + } + dst->insertObject(resource_name(type), std::move(resources)); + } +} + +static std::unique_ptr<SkPDFArray> make_proc_set() { + auto procSets = SkPDFMakeArray(); + static const char kProcs[][7] = { "PDF", "Text", "ImageB", "ImageC", "ImageI"}; + procSets->reserve(std::size(kProcs)); + for (const char* proc : kProcs) { + procSets->appendName(proc); + } + return procSets; +} + +std::unique_ptr<SkPDFDict> SkPDFMakeResourceDict( + const std::vector<SkPDFIndirectReference>& graphicStateResources, + const std::vector<SkPDFIndirectReference>& shaderResources, + const std::vector<SkPDFIndirectReference>& xObjectResources, + const std::vector<SkPDFIndirectReference>& fontResources) { + auto dict = SkPDFMakeDict(); + dict->insertObject("ProcSet", make_proc_set()); + add_subdict(graphicStateResources, SkPDFResourceType::kExtGState, dict.get()); + add_subdict(shaderResources, SkPDFResourceType::kPattern, dict.get()); + add_subdict(xObjectResources, SkPDFResourceType::kXObject, dict.get()); + add_subdict(fontResources, SkPDFResourceType::kFont, dict.get()); + return dict; +} |