xref: /aosp_15_r20/external/skia/src/pdf/SkPDFUnion.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 // 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 "include/core/SkScalar.h"
7 #include "include/core/SkString.h"
8 #include "include/private/base/SkTo.h"
9 
10 #include <cstddef>
11 #include <cstdint>
12 #include <memory>
13 
14 class SkPDFObject;
15 class SkWStream;
16 struct SkPDFIndirectReference;
17 
18 /**
19    A SkPDFUnion is a non-virtualized implementation of the
20    non-compound, non-specialized PDF Object types: Name, String,
21    Number, Boolean.
22  */
23 class SkPDFUnion {
24 public:
25     // Move constructor and assignment operator destroy the argument
26     // and steal their references (if needed).
27     SkPDFUnion(SkPDFUnion&&);
28     SkPDFUnion& operator=(SkPDFUnion&&);
29 
30     ~SkPDFUnion();
31 
32     /** The following nine functions are the standard way of creating
33         SkPDFUnion objects. */
34 
35     static SkPDFUnion Int(int32_t);
36 
Int(size_t v)37     static SkPDFUnion Int(size_t v) { return SkPDFUnion::Int(SkToS32(v)); }
38 
39     static SkPDFUnion Bool(bool);
40 
41     static SkPDFUnion Scalar(SkScalar);
42 
43     static SkPDFUnion ColorComponent(uint8_t);
44 
45     static SkPDFUnion ColorComponentF(float);
46 
47     /** These two functions do NOT take ownership of char*, and do NOT
48         copy the string.  Suitable for passing in static const
49         strings. For example:
50           SkPDFUnion n = SkPDFUnion::Name("Length");
51           SkPDFUnion u = SkPDFUnion::String("Identity"); */
52 
53     /** SkPDFUnion::Name(const char*) assumes that the passed string
54         is already a valid name (that is: it has no control or
55         whitespace characters).  This will not copy the name. */
56     static SkPDFUnion Name(const char*);
57 
58     /** SkPDFUnion::String will encode the passed string.  This will not copy. */
59     static SkPDFUnion ByteString(const char*);
60     static SkPDFUnion TextString(const char*);
61 
62     /** SkPDFUnion::Name(SkString) does not assume that the
63         passed string is already a valid name and it will escape the
64         string. */
65     static SkPDFUnion Name(SkString);
66 
67     /** SkPDFUnion::String will encode the passed string. */
68     static SkPDFUnion ByteString(SkString);
69     static SkPDFUnion TextString(SkString);
70 
71     static SkPDFUnion Object(std::unique_ptr<SkPDFObject>);
72 
73     static SkPDFUnion Ref(SkPDFIndirectReference);
74 
75     /** These two non-virtual methods mirror SkPDFObject's
76         corresponding virtuals. */
77     void emitObject(SkWStream*) const;
78 
79     bool isName() const;
80 
81 private:
82     using PDFObject = std::unique_ptr<SkPDFObject>;
83     union {
84         int32_t fIntValue;
85         bool fBoolValue;
86         SkScalar fScalarValue;
87         const char* fStaticString;
88         SkString fSkString;
89         PDFObject fObject;
90     };
91     enum class Type : char {
92         /** It is an error to call emitObject() or addResources() on an kDestroyed object. */
93         kDestroyed = 0,
94         kInt,
95         kColorComponent,
96         kColorComponentF,
97         kBool,
98         kScalar,
99         kName,
100         kByteString,
101         kTextString,
102         kNameSkS,
103         kByteStringSkS,
104         kTextStringSkS,
105         kObject,
106         kRef,
107     };
108     Type fType;
109 
110     SkPDFUnion(Type, int32_t);
111     SkPDFUnion(Type, bool);
112     SkPDFUnion(Type, SkScalar);
113     SkPDFUnion(Type, const char*);
114     SkPDFUnion(Type, SkString);
115     SkPDFUnion(Type, PDFObject);
116 
117     SkPDFUnion& operator=(const SkPDFUnion&) = delete;
118     SkPDFUnion(const SkPDFUnion&) = delete;
119 };
120 static_assert(sizeof(SkString) == sizeof(void*), "SkString_size");
121 
122 #endif  // SkPDFUnion_DEFINED
123