blob: e8a222f92ef18ff483ac49ea9172b8d16d112a4f [file] [log] [blame]
Hal Canaryf34131a2018-12-18 15:11:03 -05001// Copyright 2018 Google LLC.
2// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3#ifndef SkPDFUnion_DEFINED
4#define SkPDFUnion_DEFINED
5
6#include "SkPDFTypes.h"
7
8template <class T>
9class SkStorageFor {
10public:
11 const T& get() const { return *reinterpret_cast<const T*>(&fStore); }
12 T& get() { return *reinterpret_cast<T*>(&fStore); }
13 // Up to caller to keep track of status.
14 template<class... Args> void init(Args&&... args) {
15 new (&this->get()) T(std::forward<Args>(args)...);
16 }
17 void destroy() { this->get().~T(); }
18private:
19 typename std::aligned_storage<sizeof(T), alignof(T)>::type fStore;
20};
21
22// Exposed for unit testing.
23void SkPDFWriteString(SkWStream* wStream, const char* cin, size_t len);
24
25////////////////////////////////////////////////////////////////////////////////
26
27/**
28 A SkPDFUnion is a non-virtualized implementation of the
29 non-compound, non-specialized PDF Object types: Name, String,
30 Number, Boolean.
31 */
32class SkPDFUnion {
33public:
Hal Canaryac907bd2019-01-09 14:00:49 -050034 // Move contstructor and assignment operator destroy the argument
Hal Canaryf34131a2018-12-18 15:11:03 -050035 // and steal their references (if needed).
36 SkPDFUnion(SkPDFUnion&& other);
37 SkPDFUnion& operator=(SkPDFUnion&& other);
38
39 ~SkPDFUnion();
40
41 /** The following nine functions are the standard way of creating
42 SkPDFUnion objects. */
43
44 static SkPDFUnion Int(int32_t);
45
46 static SkPDFUnion Int(size_t v) { return SkPDFUnion::Int(SkToS32(v)); }
47
48 static SkPDFUnion Bool(bool);
49
50 static SkPDFUnion Scalar(SkScalar);
51
52 static SkPDFUnion ColorComponent(uint8_t);
53
54 static SkPDFUnion ColorComponentF(float);
55
56 /** These two functions do NOT take ownership of char*, and do NOT
57 copy the string. Suitable for passing in static const
58 strings. For example:
59 SkPDFUnion n = SkPDFUnion::Name("Length");
60 SkPDFUnion u = SkPDFUnion::String("Identity"); */
61
62 /** SkPDFUnion::Name(const char*) assumes that the passed string
63 is already a valid name (that is: it has no control or
64 whitespace characters). This will not copy the name. */
65 static SkPDFUnion Name(const char*);
66
67 /** SkPDFUnion::String will encode the passed string. This will
68 not copy the name. */
69 static SkPDFUnion String(const char*);
70
71 /** SkPDFUnion::Name(SkString) does not assume that the
72 passed string is already a valid name and it will escape the
73 string. */
74 static SkPDFUnion Name(SkString);
75
76 /** SkPDFUnion::String will encode the passed string. */
77 static SkPDFUnion String(SkString);
78
Hal Canary74801582018-12-18 16:30:41 -050079 static SkPDFUnion Object(std::unique_ptr<SkPDFObject>);
Hal Canaryf34131a2018-12-18 15:11:03 -050080
81 static SkPDFUnion Ref(SkPDFIndirectReference);
82
83 /** These two non-virtual methods mirror SkPDFObject's
84 corresponding virtuals. */
85 void emitObject(SkWStream*) const;
86
87 bool isName() const;
88
89private:
90 union {
91 int32_t fIntValue;
92 bool fBoolValue;
93 SkScalar fScalarValue;
94 const char* fStaticString;
95 SkStorageFor<SkString> fSkString;
96 SkPDFObject* fObject;
97 };
98 enum class Type : char {
99 /** It is an error to call emitObject() or addResources() on an
100 kDestroyed object. */
101 kDestroyed = 0,
102 kInt,
103 kColorComponent,
104 kColorComponentF,
105 kBool,
106 kScalar,
107 kName,
108 kString,
109 kNameSkS,
110 kStringSkS,
111 kObject,
112 kRef,
113 };
114 Type fType;
115
116 SkPDFUnion(Type);
117 SkPDFUnion(Type, int32_t);
118 SkPDFUnion(Type, bool);
119 SkPDFUnion(Type, SkScalar);
120 SkPDFUnion(Type, SkString);
121 // We do not now need copy constructor and copy assignment, so we
122 // will disable this functionality.
123 SkPDFUnion& operator=(const SkPDFUnion&) = delete;
124 SkPDFUnion(const SkPDFUnion&) = delete;
125};
126static_assert(sizeof(SkString) == sizeof(void*), "SkString_size");
127
128#endif // SkPDFUnion_DEFINED