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