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