| Index: src/pdf/SkPDFTypes.cpp
|
| diff --git a/src/pdf/SkPDFTypes.cpp b/src/pdf/SkPDFTypes.cpp
|
| index cd130cfc520b46f36918b80b016f7da5bf713da1..510b98b17f471d6148f7c709bf56d33cb3872679 100644
|
| --- a/src/pdf/SkPDFTypes.cpp
|
| +++ b/src/pdf/SkPDFTypes.cpp
|
| @@ -6,7 +6,6 @@
|
| * found in the LICENSE file.
|
| */
|
|
|
| -
|
| #include "SkPDFTypes.h"
|
| #include "SkStream.h"
|
|
|
| @@ -18,62 +17,271 @@
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|
| -SkPDFObjRef::SkPDFObjRef(SkPDFObject* obj) : fObj(obj) {
|
| - SkSafeRef(obj);
|
| +SkString* pun(char* x) { return reinterpret_cast<SkString*>(x); }
|
| +const SkString* pun(const char* x) {
|
| + return reinterpret_cast<const SkString*>(x);
|
| }
|
|
|
| -SkPDFObjRef::~SkPDFObjRef() {}
|
| +SkPDFUnion::SkPDFUnion(Type t) : fType(t) {}
|
|
|
| -void SkPDFObjRef::emitObject(SkWStream* stream,
|
| - const SkPDFObjNumMap& objNumMap,
|
| - const SkPDFSubstituteMap& substitutes) {
|
| - SkPDFObject* obj = substitutes.getSubstitute(fObj);
|
| - stream->writeDecAsText(objNumMap.getObjectNumber(obj));
|
| - stream->writeText(" 0 R"); // Generation number is always 0.
|
| +SkPDFUnion::~SkPDFUnion() {
|
| + switch (fType) {
|
| + case Type::kNameSkS:
|
| + case Type::kStringSkS:
|
| + pun(fSkString)->~SkString();
|
| + return;
|
| + case Type::kObjRef:
|
| + case Type::kObject:
|
| + SkSafeUnref(fObject);
|
| + return;
|
| + default:
|
| + return;
|
| + }
|
| }
|
|
|
| -void SkPDFObjRef::addResources(SkPDFObjNumMap* catalog,
|
| - const SkPDFSubstituteMap& substitutes) const {
|
| - SkPDFObject* obj = substitutes.getSubstitute(fObj);
|
| - SkASSERT(obj);
|
| - if (catalog->addObject(obj)) {
|
| - obj->addResources(catalog, substitutes);
|
| +SkPDFUnion& SkPDFUnion::operator=(SkPDFUnion&& other) {
|
| + if (this != &other) {
|
| + this->~SkPDFUnion();
|
| + SkNEW_PLACEMENT_ARGS(this, SkPDFUnion, (other.move()));
|
| }
|
| + return *this;
|
| +}
|
| +
|
| +SkPDFUnion::SkPDFUnion(SkPDFUnion&& other) {
|
| + SkASSERT(this != &other);
|
| + memcpy(this, &other, sizeof(*this));
|
| + other.fType = Type::kDestroyed;
|
| +}
|
| +
|
| +#if 0
|
| +SkPDFUnion SkPDFUnion::copy() const {
|
| + SkPDFUnion u(fType);
|
| + memcpy(&u, this, sizeof(u));
|
| + switch (fType) {
|
| + case Type::kNameSkS:
|
| + case Type::kStringSkS:
|
| + SkNEW_PLACEMENT_ARGS(pun(u.fSkString), SkString,
|
| + (*pun(fSkString)));
|
| + return u.move();
|
| + case Type::kObjRef:
|
| + case Type::kObject:
|
| + SkRef(u.fObject);
|
| + return u.move();
|
| + default:
|
| + return u.move();
|
| + }
|
| +}
|
| +SkPDFUnion& SkPDFUnion::operator=(const SkPDFUnion& other) {
|
| + return *this = other.copy();
|
| }
|
| +SkPDFUnion::SkPDFUnion(const SkPDFUnion& other) {
|
| + *this = other.copy();
|
| +}
|
| +#endif
|
|
|
| -////////////////////////////////////////////////////////////////////////////////
|
| +bool SkPDFUnion::isName() const {
|
| + return Type::kName == fType || Type::kNameSkS == fType;
|
| +}
|
|
|
| -SkPDFInt::SkPDFInt(int32_t value) : fValue(value) {}
|
| -SkPDFInt::~SkPDFInt() {}
|
| +#ifdef SK_DEBUG
|
| +// Most names need no escaping. Such names are handled as static
|
| +// const strings.
|
| +bool is_valid_name(const char* n) {
|
| + static const char kControlChars[] = "/%()<>[]{}";
|
| + while (*n) {
|
| + if (*n < '!' || *n > '~' || strchr(kControlChars, *n)) {
|
| + return false;
|
| + }
|
| + ++n;
|
| + }
|
| + return true;
|
| +}
|
| +#endif // SK_DEBUG
|
|
|
| -void SkPDFInt::emitObject(SkWStream* stream,
|
| - const SkPDFObjNumMap&,
|
| - const SkPDFSubstituteMap&) {
|
| - stream->writeDecAsText(fValue);
|
| +// Given an arbitrary string, convert it to a valid name.
|
| +static SkString escape_name(const char* name, size_t len) {
|
| + static const char kToEscape[] = "#/%()<>[]{}";
|
| + int count = 0;
|
| + const char* const end = &name[len];
|
| + for (const char* n = name; n != end; ++n) {
|
| + if (*n < '!' || *n > '~' || strchr(kToEscape, *n)) {
|
| + count += 2;
|
| + }
|
| + ++count;
|
| + }
|
| + SkString result(count);
|
| + char* s = result.writable_str();
|
| + static const char kHex[] = "0123456789ABCDEF";
|
| + for (const char* n = name; n != end; ++n) {
|
| + if (*n < '!' || *n > '~' || strchr(kToEscape, *n)) {
|
| + *s++ = '#';
|
| + *s++ = kHex[(*n >> 4) & 0xF];
|
| + *s++ = kHex[*n & 0xF];
|
| + } else {
|
| + *s++ = *n;
|
| + }
|
| + }
|
| + SkASSERT(&result.writable_str()[count] == s); // don't over-write
|
| + return result; // allocated space
|
| }
|
|
|
| -////////////////////////////////////////////////////////////////////////////////
|
| +static SkString escape_name(const SkString& name) {
|
| + return escape_name(name.c_str(), name.size());
|
| +}
|
|
|
| -SkPDFBool::SkPDFBool(bool value) : fValue(value) {}
|
| -SkPDFBool::~SkPDFBool() {}
|
| +static void write_string(SkWStream* o, const SkString& s) {
|
| + o->write(s.c_str(), s.size());
|
| +}
|
|
|
| -void SkPDFBool::emitObject(SkWStream* stream,
|
| - const SkPDFObjNumMap&,
|
| - const SkPDFSubstituteMap&) {
|
| - stream->writeText(fValue ? "true" : "false");
|
| +static SkString format_string(const SkString& s) {
|
| + return SkPDFString::FormatString(s.c_str(), s.size());
|
| }
|
|
|
| -////////////////////////////////////////////////////////////////////////////////
|
| +static SkString format_string(const char* s) {
|
| + return SkPDFString::FormatString(s, strlen(s));
|
| +}
|
|
|
| -SkPDFScalar::SkPDFScalar(SkScalar value) : fValue(value) {}
|
| -SkPDFScalar::~SkPDFScalar() {}
|
| +void SkPDFUnion::emitObject(SkWStream* stream,
|
| + const SkPDFObjNumMap& objNumMap,
|
| + const SkPDFSubstituteMap& substitutes) const {
|
| + switch (fType) {
|
| + case Type::kInt:
|
| + stream->writeDecAsText(fIntValue);
|
| + return;
|
| + case Type::kBool:
|
| + stream->writeText(fBoolValue ? "true" : "false");
|
| + return;
|
| + case Type::kScalar:
|
| + SkPDFScalar::Append(fScalarValue, stream);
|
| + return;
|
| + case Type::kName:
|
| + stream->writeText("/");
|
| + SkASSERT(is_valid_name(fStaticString));
|
| + stream->writeText(fStaticString);
|
| + return;
|
| + case Type::kString:
|
| + SkASSERT(fStaticString);
|
| + write_string(stream, format_string(fStaticString));
|
| + return;
|
| + case Type::kNameSkS:
|
| + stream->writeText("/");
|
| + write_string(stream, escape_name(*pun(fSkString)));
|
| + return;
|
| + case Type::kStringSkS:
|
| + write_string(stream, format_string(*pun(fSkString)));
|
| + return;
|
| + case Type::kObjRef:
|
| + stream->writeDecAsText(objNumMap.getObjectNumber(
|
| + substitutes.getSubstitute(fObject)));
|
| + stream->writeText(" 0 R"); // Generation number is always 0.
|
| + return;
|
| + case Type::kObject:
|
| + fObject->emitObject(stream, objNumMap, substitutes);
|
| + return;
|
| + default:
|
| + SkDEBUGFAIL("SkPDFUnion::emitObject with bad type");
|
| + }
|
| +}
|
| +
|
| +void SkPDFUnion::addResources(SkPDFObjNumMap* objNumMap,
|
| + const SkPDFSubstituteMap& substituteMap) const {
|
| + switch (fType) {
|
| + case Type::kInt:
|
| + case Type::kBool:
|
| + case Type::kScalar:
|
| + case Type::kName:
|
| + case Type::kString:
|
| + case Type::kNameSkS:
|
| + case Type::kStringSkS:
|
| + return; // These have no resources.
|
| + case Type::kObjRef: {
|
| + SkPDFObject* obj = substituteMap.getSubstitute(fObject);
|
| + if (objNumMap->addObject(obj)) {
|
| + obj->addResources(objNumMap, substituteMap);
|
| + }
|
| + return;
|
| + }
|
| + case Type::kObject:
|
| + fObject->addResources(objNumMap, substituteMap);
|
| + return;
|
| + default:
|
| + SkDEBUGFAIL("SkPDFUnion::addResources with bad type");
|
| + }
|
| +}
|
| +
|
| +SkPDFUnion SkPDFUnion::Int(int32_t value) {
|
| + SkPDFUnion u(Type::kInt);
|
| + u.fIntValue = value;
|
| + return u.move();
|
| +}
|
| +
|
| +SkPDFUnion SkPDFUnion::Bool(bool value) {
|
| + SkPDFUnion u(Type::kBool);
|
| + u.fBoolValue = value;
|
| + return u.move();
|
| +}
|
|
|
| -void SkPDFScalar::emitObject(SkWStream* stream,
|
| - const SkPDFObjNumMap&,
|
| - const SkPDFSubstituteMap&) {
|
| - SkPDFScalar::Append(fValue, stream);
|
| +SkPDFUnion SkPDFUnion::Scalar(SkScalar value) {
|
| + SkPDFUnion u(Type::kScalar);
|
| + u.fScalarValue = value;
|
| + return u.move();
|
| }
|
|
|
| +SkPDFUnion SkPDFUnion::Name(const char* value) {
|
| + SkPDFUnion u(Type::kName);
|
| + SkASSERT(value);
|
| + SkASSERT(is_valid_name(value));
|
| + u.fStaticString = value;
|
| + return u.move();
|
| +}
|
| +
|
| +SkPDFUnion SkPDFUnion::String(const char* value) {
|
| + SkPDFUnion u(Type::kString);
|
| + SkASSERT(value);
|
| + u.fStaticString = value;
|
| + return u.move();
|
| +}
|
| +
|
| +SkPDFUnion SkPDFUnion::Name(const SkString& s) {
|
| + SkPDFUnion u(Type::kNameSkS);
|
| + SkNEW_PLACEMENT_ARGS(pun(u.fSkString), SkString, (s));
|
| + return u.move();
|
| +}
|
| +
|
| +SkPDFUnion SkPDFUnion::String(const SkString& s) {
|
| + SkPDFUnion u(Type::kStringSkS);
|
| + SkNEW_PLACEMENT_ARGS(pun(u.fSkString), SkString, (s));
|
| + return u.move();
|
| +}
|
| +
|
| +SkPDFUnion SkPDFUnion::ObjRef(SkPDFObject* ptr) {
|
| + SkPDFUnion u(Type::kObjRef);
|
| + SkASSERT(ptr);
|
| + u.fObject = ptr;
|
| + return u.move();
|
| +}
|
| +
|
| +SkPDFUnion SkPDFUnion::Object(SkPDFObject* ptr) {
|
| + SkPDFUnion u(Type::kObject);
|
| + SkASSERT(ptr);
|
| + u.fObject = ptr;
|
| + return u.move();
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +void SkPDFAtom::emitObject(SkWStream* stream,
|
| + const SkPDFObjNumMap& objNumMap,
|
| + const SkPDFSubstituteMap& substitutes) {
|
| + fValue.emitObject(stream, objNumMap, substitutes);
|
| +}
|
| +void SkPDFAtom::addResources(SkPDFObjNumMap* map,
|
| + const SkPDFSubstituteMap& substitutes) const {
|
| + fValue.addResources(map, substitutes);
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| // static
|
| void SkPDFScalar::Append(SkScalar value, SkWStream* stream) {
|
| // The range of reals in PDF/A is the same as SkFixed: +/- 32,767 and
|
| @@ -125,23 +333,8 @@ void SkPDFScalar::Append(SkScalar value, SkWStream* stream) {
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|
| -SkPDFString::SkPDFString(const char value[])
|
| - : fValue(FormatString(value, strlen(value))) {
|
| -}
|
| -
|
| -SkPDFString::SkPDFString(const SkString& value)
|
| - : fValue(FormatString(value.c_str(), value.size())) {
|
| -}
|
| -
|
| -SkPDFString::~SkPDFString() {}
|
| -
|
| -void SkPDFString::emitObject(SkWStream* stream,
|
| - const SkPDFObjNumMap&,
|
| - const SkPDFSubstituteMap&) {
|
| - stream->write(fValue.c_str(), fValue.size());
|
| -}
|
| -
|
| // static
|
| +
|
| SkString SkPDFString::FormatString(const char* cin, size_t len) {
|
| SkASSERT(len <= kMaxLen);
|
|
|
| @@ -187,55 +380,25 @@ SkString SkPDFString::FormatString(const char* cin, size_t len) {
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|
| -SkPDFName::SkPDFName(const char name[]) : fValue(FormatName(SkString(name))) {}
|
| -SkPDFName::SkPDFName(const SkString& name) : fValue(FormatName(name)) {}
|
| -SkPDFName::~SkPDFName() {}
|
| -
|
| -bool SkPDFName::operator==(const SkPDFName& b) const {
|
| - return fValue == b.fValue;
|
| -}
|
| -
|
| -void SkPDFName::emitObject(SkWStream* stream,
|
| - const SkPDFObjNumMap&,
|
| - const SkPDFSubstituteMap&) {
|
| - stream->write(fValue.c_str(), fValue.size());
|
| -}
|
| -
|
| -// static
|
| -SkString SkPDFName::FormatName(const SkString& input) {
|
| - SkASSERT(input.size() <= kMaxLen);
|
| - // TODO(vandebo) If more escaping is needed, improve the linear scan.
|
| - static const char escaped[] = "#/%()<>[]{}";
|
| -
|
| - SkString result("/");
|
| - for (size_t i = 0; i < input.size(); i++) {
|
| - if (input[i] & 0x80 || input[i] < '!' || strchr(escaped, input[i])) {
|
| - result.append("#");
|
| - // Mask with 0xFF to avoid sign extension. i.e. #FFFFFF81
|
| - result.appendHex(input[i] & 0xFF, 2);
|
| - } else {
|
| - result.append(input.c_str() + i, 1);
|
| - }
|
| +SkPDFArray::SkPDFArray() {}
|
| +SkPDFArray::~SkPDFArray() {
|
| + for (SkPDFUnion& value : fValues) {
|
| + value.~SkPDFUnion();
|
| }
|
| -
|
| - return result;
|
| + fValues.reset();
|
| }
|
|
|
| -////////////////////////////////////////////////////////////////////////////////
|
| +int SkPDFArray::size() const { return fValues.count(); }
|
|
|
| -SkPDFArray::SkPDFArray() {}
|
| -SkPDFArray::~SkPDFArray() {
|
| - fValue.unrefAll();
|
| -}
|
| +void SkPDFArray::reserve(int length) { fValues.setReserve(length); }
|
|
|
| void SkPDFArray::emitObject(SkWStream* stream,
|
| const SkPDFObjNumMap& objNumMap,
|
| const SkPDFSubstituteMap& substitutes) {
|
| stream->writeText("[");
|
| - for (int i = 0; i < fValue.count(); i++) {
|
| - SkASSERT(substitutes.getSubstitute(fValue[i]) == fValue[i]);
|
| - fValue[i]->emitObject(stream, objNumMap, substitutes);
|
| - if (i + 1 < fValue.count()) {
|
| + for (int i = 0; i < fValues.count(); i++) {
|
| + fValues[i].emitObject(stream, objNumMap, substitutes);
|
| + if (i + 1 < fValues.count()) {
|
| stream->writeText(" ");
|
| }
|
| }
|
| @@ -244,68 +407,74 @@ void SkPDFArray::emitObject(SkWStream* stream,
|
|
|
| void SkPDFArray::addResources(SkPDFObjNumMap* catalog,
|
| const SkPDFSubstituteMap& substitutes) const {
|
| - for (int i = 0; i < fValue.count(); i++) {
|
| - SkASSERT(substitutes.getSubstitute(fValue[i]) == fValue[i]);
|
| - fValue[i]->addResources(catalog, substitutes);
|
| + for (const SkPDFUnion& value : fValues) {
|
| + value.addResources(catalog, substitutes);
|
| }
|
| }
|
|
|
| -void SkPDFArray::reserve(int length) {
|
| - SkASSERT(length <= kMaxLen);
|
| - fValue.setReserve(length);
|
| +void SkPDFArray::append(SkPDFUnion&& value) {
|
| + SkNEW_PLACEMENT_ARGS(fValues.append(), SkPDFUnion, (value.move()));
|
| }
|
|
|
| SkPDFObject* SkPDFArray::append(SkPDFObject* value) {
|
| - SkASSERT(fValue.count() < kMaxLen);
|
| - value->ref();
|
| - fValue.push(value);
|
| + // DEPRECATED
|
| + this->append(SkPDFUnion::Object(SkRef(value)));
|
| return value;
|
| }
|
|
|
| void SkPDFArray::appendInt(int32_t value) {
|
| - SkASSERT(fValue.count() < kMaxLen);
|
| - fValue.push(new SkPDFInt(value));
|
| + this->append(SkPDFUnion::Int(value));
|
| +}
|
| +
|
| +void SkPDFArray::appendBool(bool value) {
|
| + this->append(SkPDFUnion::Bool(value));
|
| }
|
|
|
| void SkPDFArray::appendScalar(SkScalar value) {
|
| - SkASSERT(fValue.count() < kMaxLen);
|
| - fValue.push(new SkPDFScalar(value));
|
| + this->append(SkPDFUnion::Scalar(value));
|
| }
|
|
|
| void SkPDFArray::appendName(const char name[]) {
|
| - SkASSERT(fValue.count() < kMaxLen);
|
| - fValue.push(new SkPDFName(name));
|
| + this->append(SkPDFUnion::Name(SkString(name)));
|
| }
|
|
|
| -///////////////////////////////////////////////////////////////////////////////
|
| +void SkPDFArray::appendName(const SkString& name) {
|
| + this->append(SkPDFUnion::Name(name));
|
| +}
|
|
|
| -SkPDFDict::SkPDFDict() {}
|
| +void SkPDFArray::appendString(const SkString& value) {
|
| + this->append(SkPDFUnion::String(value));
|
| +}
|
|
|
| -SkPDFDict::SkPDFDict(const char type[]) {
|
| - insertName("Type", type);
|
| +void SkPDFArray::appendString(const char value[]) {
|
| + this->append(SkPDFUnion::String(value));
|
| }
|
|
|
| -SkPDFDict::~SkPDFDict() {
|
| - clear();
|
| +void SkPDFArray::appendObject(SkPDFObject* value) {
|
| + this->append(SkPDFUnion::Object(value));
|
| }
|
|
|
| -int SkPDFDict::size() const {
|
| - return fValue.count();
|
| +void SkPDFArray::appendObjRef(SkPDFObject* value) {
|
| + this->append(SkPDFUnion::ObjRef(value));
|
| }
|
|
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +SkPDFDict::SkPDFDict() {}
|
| +
|
| +SkPDFDict::~SkPDFDict() { this->clear(); }
|
| +
|
| +SkPDFDict::SkPDFDict(const char type[]) { this->insertName("Type", type); }
|
| +
|
| void SkPDFDict::emitObject(SkWStream* stream,
|
| const SkPDFObjNumMap& objNumMap,
|
| const SkPDFSubstituteMap& substitutes) {
|
| stream->writeText("<<");
|
| - for (int i = 0; i < fValue.count(); i++) {
|
| - SkASSERT(fValue[i].key);
|
| - SkASSERT(fValue[i].value);
|
| - SkASSERT(substitutes.getSubstitute(fValue[i].key) == fValue[i].key);
|
| - SkASSERT(substitutes.getSubstitute(fValue[i].value) == fValue[i].value);
|
| - fValue[i].key->emitObject(stream, objNumMap, substitutes);
|
| + for (int i = 0; i < fRecords.count(); i++) {
|
| + fRecords[i].fKey.emitObject(stream, objNumMap, substitutes);
|
| stream->writeText(" ");
|
| - fValue[i].value->emitObject(stream, objNumMap, substitutes);
|
| - if (i + 1 < fValue.count()) {
|
| + fRecords[i].fValue.emitObject(stream, objNumMap, substitutes);
|
| + if (i + 1 < fRecords.count()) {
|
| stream->writeText("\n");
|
| }
|
| }
|
| @@ -314,72 +483,75 @@ void SkPDFDict::emitObject(SkWStream* stream,
|
|
|
| void SkPDFDict::addResources(SkPDFObjNumMap* catalog,
|
| const SkPDFSubstituteMap& substitutes) const {
|
| - for (int i = 0; i < fValue.count(); i++) {
|
| - SkASSERT(fValue[i].key);
|
| - SkASSERT(fValue[i].value);
|
| - fValue[i].key->addResources(catalog, substitutes);
|
| - SkASSERT(substitutes.getSubstitute(fValue[i].value) == fValue[i].value);
|
| - fValue[i].value->addResources(catalog, substitutes);
|
| + for (int i = 0; i < fRecords.count(); i++) {
|
| + fRecords[i].fKey.addResources(catalog, substitutes);
|
| + fRecords[i].fValue.addResources(catalog, substitutes);
|
| }
|
| }
|
|
|
| -SkPDFObject* SkPDFDict::append(SkPDFName* key, SkPDFObject* value) {
|
| - SkASSERT(key);
|
| - SkASSERT(value);
|
| - *(fValue.append()) = Rec(key, value);
|
| - return value;
|
| +void SkPDFDict::set(SkPDFUnion&& name, SkPDFUnion&& value) {
|
| + Record* rec = fRecords.append();
|
| + SkASSERT(name.isName());
|
| + SkNEW_PLACEMENT_ARGS(&rec->fKey, SkPDFUnion, (name.move()));
|
| + SkNEW_PLACEMENT_ARGS(&rec->fValue, SkPDFUnion, (value.move()));
|
| +}
|
| +
|
| +int SkPDFDict::size() const { return fRecords.count(); }
|
| +
|
| +void SkPDFDict::insertObjRef(const char key[], SkPDFObject* value) {
|
| + this->set(SkPDFUnion::Name(key), SkPDFUnion::ObjRef(value));
|
| +}
|
| +void SkPDFDict::insertObjRef(const SkString& key, SkPDFObject* value) {
|
| + this->set(SkPDFUnion::Name(key), SkPDFUnion::ObjRef(value));
|
| }
|
|
|
| -SkPDFObject* SkPDFDict::insert(SkPDFName* key, SkPDFObject* value) {
|
| - return this->append(SkRef(key), SkRef(value));
|
| +void SkPDFDict::insertObject(const char key[], SkPDFObject* value) {
|
| + this->set(SkPDFUnion::Name(key), SkPDFUnion::Object(value));
|
| +}
|
| +void SkPDFDict::insertObject(const SkString& key, SkPDFObject* value) {
|
| + this->set(SkPDFUnion::Name(key), SkPDFUnion::Object(value));
|
| }
|
|
|
| +// DEPRECATED
|
| SkPDFObject* SkPDFDict::insert(const char key[], SkPDFObject* value) {
|
| - return this->append(new SkPDFName(key), SkRef(value));
|
| + this->set(SkPDFUnion::Name(key), SkPDFUnion::Object(SkRef(value)));
|
| + return value;
|
| }
|
|
|
| void SkPDFDict::insertInt(const char key[], int32_t value) {
|
| - (void)this->append(new SkPDFName(key), new SkPDFInt(value));
|
| + this->set(SkPDFUnion::Name(key), SkPDFUnion::Int(value));
|
| +}
|
| +
|
| +void SkPDFDict::insertInt(const char key[], size_t value) {
|
| + this->insertInt(key, SkToS32(value));
|
| }
|
|
|
| void SkPDFDict::insertScalar(const char key[], SkScalar value) {
|
| - (void)this->append(new SkPDFName(key), new SkPDFScalar(value));
|
| + this->set(SkPDFUnion::Name(key), SkPDFUnion::Scalar(value));
|
| }
|
|
|
| void SkPDFDict::insertName(const char key[], const char name[]) {
|
| - (void)this->append(new SkPDFName(key), new SkPDFName(name));
|
| + this->set(SkPDFUnion::Name(key), SkPDFUnion::Name(name));
|
| }
|
|
|
| -void SkPDFDict::clear() {
|
| - for (int i = 0; i < fValue.count(); i++) {
|
| - SkASSERT(fValue[i].key);
|
| - SkASSERT(fValue[i].value);
|
| - fValue[i].key->unref();
|
| - fValue[i].value->unref();
|
| - }
|
| - fValue.reset();
|
| -}
|
| -
|
| -void SkPDFDict::remove(const char key[]) {
|
| - SkASSERT(key);
|
| - SkPDFName name(key);
|
| - for (int i = 0; i < fValue.count(); i++) {
|
| - SkASSERT(fValue[i].key);
|
| - if (*(fValue[i].key) == name) {
|
| - fValue[i].key->unref();
|
| - SkASSERT(fValue[i].value);
|
| - fValue[i].value->unref();
|
| - fValue.removeShuffle(i);
|
| - return;
|
| - }
|
| - }
|
| +void SkPDFDict::insertName(const char key[], const SkString& name) {
|
| + this->set(SkPDFUnion::Name(key), SkPDFUnion::Name(name));
|
| +}
|
| +
|
| +void SkPDFDict::insertString(const char key[], const char value[]) {
|
| + this->set(SkPDFUnion::Name(key), SkPDFUnion::String(value));
|
| +}
|
| +
|
| +void SkPDFDict::insertString(const char key[], const SkString& value) {
|
| + this->set(SkPDFUnion::Name(key), SkPDFUnion::String(value));
|
| }
|
|
|
| -void SkPDFDict::mergeFrom(const SkPDFDict& other) {
|
| - for (int i = 0; i < other.fValue.count(); i++) {
|
| - *(fValue.append()) =
|
| - Rec(SkRef(other.fValue[i].key), SkRef(other.fValue[i].value));
|
| +void SkPDFDict::clear() {
|
| + for (Record& rec : fRecords) {
|
| + rec.fKey.~SkPDFUnion();
|
| + rec.fValue.~SkPDFUnion();
|
| }
|
| + fRecords.reset();
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|