summaryrefslogtreecommitdiffstats
path: root/gfx/skia/skia/src/pdf/SkPDFResourceDict.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/skia/skia/src/pdf/SkPDFResourceDict.cpp')
-rw-r--r--gfx/skia/skia/src/pdf/SkPDFResourceDict.cpp96
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;
+}