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