diff options
Diffstat (limited to 'src/pdf')
-rw-r--r-- | src/pdf/BUILD.bazel | 14 | ||||
-rw-r--r-- | src/pdf/SkJpegInfo.h | 18 | ||||
-rw-r--r-- | src/pdf/SkJpegInfo_libjpegturbo.cpp | 59 | ||||
-rw-r--r-- | src/pdf/SkJpegInfo_none.cpp | 120 | ||||
-rw-r--r-- | src/pdf/SkPDFBitmap.cpp | 139 | ||||
-rw-r--r-- | src/pdf/SkPDFBitmap.h | 24 | ||||
-rw-r--r-- | src/pdf/SkPDFDocumentPriv.h | 4 | ||||
-rw-r--r-- | src/pdf/SkPDFTypes.cpp | 4 | ||||
-rw-r--r-- | src/pdf/SkPDFTypes.h | 1 |
9 files changed, 143 insertions, 240 deletions
diff --git a/src/pdf/BUILD.bazel b/src/pdf/BUILD.bazel index b41f5aac18..38f6f081cb 100644 --- a/src/pdf/BUILD.bazel +++ b/src/pdf/BUILD.bazel @@ -38,7 +38,6 @@ PDF_FILES = [ "SkPDFMetadata.h", "SkPDFResourceDict.cpp", "SkPDFResourceDict.h", - "SkJpegInfo.h", "SkPDFShader.cpp", "SkPDFShader.h", "SkPDFSubsetFont.cpp", @@ -60,11 +59,13 @@ split_srcs_and_hdrs( files = PDF_FILES, ) +#TODO: remove after Chromium no longer references this. skia_filegroup( name = "jpeg_info_libjpeg", srcs = ["SkJpegInfo_libjpegturbo.cpp"], ) +#TODO: remove after Chromium no longer references this. skia_filegroup( name = "jpeg_info_none", srcs = ["SkJpegInfo_none.cpp"], @@ -74,10 +75,7 @@ skia_filegroup( name = "srcs", srcs = [ ":pdf_srcs", - ] + select({ - "//src/codec:jpeg_decode_codec": [":jpeg_info_libjpeg"], - "//conditions:default": [":jpeg_info_none"], - }), + ], visibility = ["//src:__pkg__"], ) @@ -113,7 +111,11 @@ selects.config_setting_group( skia_cc_deps( name = "deps", visibility = ["//src:__pkg__"], - deps = ["@zlib_skia//:zlib"] + select({ + deps = [ + "@zlib_skia//:zlib", + #"//src/codec:jpeg_decode", + #"//src/encode:jpeg_encode", + ] + select({ ":uses_harfbuzz": ["@harfbuzz"], "//conditions:default": [], }), diff --git a/src/pdf/SkJpegInfo.h b/src/pdf/SkJpegInfo.h index 736575d42f..17155e4830 100644 --- a/src/pdf/SkJpegInfo.h +++ b/src/pdf/SkJpegInfo.h @@ -7,22 +7,4 @@ #ifndef SkJpegInfo_DEFINED #define SkJpegInfo_DEFINED -#include "include/codec/SkEncodedOrigin.h" -#include "include/private/SkEncodedInfo.h" - -#include <cstddef> - -struct SkISize; - -/** Returns true if the data seems to be a valid JPEG image with a known colorType. - - @param [out] size Image size in pixels - @param [out] colorType Encoded color type (kGray_Color, kYUV_Color, several others). - @param [out] orientation EXIF Orientation of the image. -*/ -bool SkGetJpegInfo(const void* data, size_t len, - SkISize* size, - SkEncodedInfo::Color* colorType, - SkEncodedOrigin* orientation); - #endif // SkJpegInfo_DEFINED diff --git a/src/pdf/SkJpegInfo_libjpegturbo.cpp b/src/pdf/SkJpegInfo_libjpegturbo.cpp index 41e73757df..020c041a5a 100644 --- a/src/pdf/SkJpegInfo_libjpegturbo.cpp +++ b/src/pdf/SkJpegInfo_libjpegturbo.cpp @@ -7,62 +7,3 @@ * This file can parse information from a JPEG using libjpeg (which must be compiled in). */ -#include "src/pdf/SkJpegInfo.h" - -#include "include/codec/SkEncodedOrigin.h" -#include "include/core/SkSize.h" -#include "include/core/SkStream.h" -#include "include/core/SkTypes.h" -#include "include/private/SkEncodedInfo.h" -#include "include/private/base/SkTo.h" -#include "src/codec/SkJpegCodec.h" -#include "src/codec/SkJpegConstants.h" -#include "src/codec/SkJpegDecoderMgr.h" -#include "src/codec/SkJpegPriv.h" - -#include <cstddef> -#include <csetjmp> - -extern "C" { - #include "jpeglib.h" // NO_G3_REWRITE -} - -bool SkGetJpegInfo(const void* data, size_t len, - SkISize* size, - SkEncodedInfo::Color* colorType, - SkEncodedOrigin* orientation) { - if (!SkJpegCodec::IsJpeg(data, len)) { - return false; - } - - SkMemoryStream stream(data, len); - JpegDecoderMgr decoderMgr(&stream); - // libjpeg errors will be caught and reported here - skjpeg_error_mgr::AutoPushJmpBuf jmp(decoderMgr.errorMgr()); - if (setjmp(jmp)) { - return false; - } - decoderMgr.init(); - jpeg_decompress_struct* dinfo = decoderMgr.dinfo(); - jpeg_save_markers(dinfo, kExifMarker, 0xFFFF); - jpeg_save_markers(dinfo, kICCMarker, 0xFFFF); - jpeg_save_markers(dinfo, kMpfMarker, 0xFFFF); - jpeg_save_markers(dinfo, kGainmapMarker, 0xFFFF); - if (JPEG_HEADER_OK != jpeg_read_header(dinfo, true)) { - return false; - } - SkEncodedInfo::Color encodedColorType; - if (!decoderMgr.getEncodedColor(&encodedColorType)) { - return false; // Unable to interpret the color channels as colors. - } - if (colorType) { - *colorType = encodedColorType; - } - if (orientation) { - *orientation = SkJpegPriv::get_exif_orientation(dinfo); - } - if (size) { - *size = {SkToS32(dinfo->image_width), SkToS32(dinfo->image_height)}; - } - return true; -} diff --git a/src/pdf/SkJpegInfo_none.cpp b/src/pdf/SkJpegInfo_none.cpp index b0e3cba263..78e44cd483 100644 --- a/src/pdf/SkJpegInfo_none.cpp +++ b/src/pdf/SkJpegInfo_none.cpp @@ -8,123 +8,3 @@ * it. This does not need Skia to be built with a JPEG library. */ -#include "src/pdf/SkJpegInfo.h" - -#include "include/codec/SkEncodedOrigin.h" -#include "include/core/SkSize.h" -#include "include/private/base/SkTo.h" - -namespace { -class JpegSegment { -public: - JpegSegment(const void* data, size_t size) - : fData(static_cast<const char*>(data)) - , fSize(size) - , fOffset(0) - , fLength(0) {} - bool read() { - if (!this->readBigendianUint16(&fMarker)) { - return false; - } - if (JpegSegment::StandAloneMarker(fMarker)) { - fLength = 0; - fBuffer = nullptr; - return true; - } - if (!this->readBigendianUint16(&fLength) || fLength < 2) { - return false; - } - fLength -= 2; // Length includes itself for some reason. - if (fOffset + fLength > fSize) { - return false; // Segment too long. - } - fBuffer = &fData[fOffset]; - fOffset += fLength; - return true; - } - - bool isSOF() { - return (fMarker & 0xFFF0) == 0xFFC0 && fMarker != 0xFFC4 && - fMarker != 0xFFC8 && fMarker != 0xFFCC; - } - uint16_t marker() { return fMarker; } - uint16_t length() { return fLength; } - const char* data() { return fBuffer; } - - static uint16_t GetBigendianUint16(const char* ptr) { - // "the most significant byte shall come first" - return (static_cast<uint8_t>(ptr[0]) << 8) | - static_cast<uint8_t>(ptr[1]); - } - -private: - const char* const fData; - const size_t fSize; - size_t fOffset; - const char* fBuffer; - uint16_t fMarker; - uint16_t fLength; - - bool readBigendianUint16(uint16_t* value) { - if (fOffset + 2 > fSize) { - return false; - } - *value = JpegSegment::GetBigendianUint16(&fData[fOffset]); - fOffset += 2; - return true; - } - static bool StandAloneMarker(uint16_t marker) { - // RST[m] markers or SOI, EOI, TEM - return (marker & 0xFFF8) == 0xFFD0 || marker == 0xFFD8 || - marker == 0xFFD9 || marker == 0xFF01; - } -}; -} // namespace - -bool SkGetJpegInfo(const void* data, size_t len, - SkISize* size, - SkEncodedInfo::Color* colorType, - SkEncodedOrigin* orientation) { - static const uint16_t kSOI = 0xFFD8; - static const uint16_t kAPP0 = 0xFFE0; - JpegSegment segment(data, len); - if (!segment.read() || segment.marker() != kSOI) { - return false; // not a JPEG - } - if (!segment.read() || segment.marker() != kAPP0) { - return false; // not an APP0 segment - } - static const char kJfif[] = {'J', 'F', 'I', 'F', '\0'}; - SkASSERT(segment.data()); - if (SkToSizeT(segment.length()) < sizeof(kJfif) || - 0 != memcmp(segment.data(), kJfif, sizeof(kJfif))) { - return false; // Not JFIF JPEG - } - do { - if (!segment.read()) { - return false; // malformed JPEG - } - } while (!segment.isSOF()); - if (segment.length() < 6) { - return false; // SOF segment is short - } - if (8 != segment.data()[0]) { - return false; // Only support 8-bit precision - } - int numberOfComponents = segment.data()[5]; - if (numberOfComponents != 1 && numberOfComponents != 3) { - return false; // Invalid JFIF - } - if (size) { - *size = {JpegSegment::GetBigendianUint16(&segment.data()[3]), - JpegSegment::GetBigendianUint16(&segment.data()[1])}; - } - if (colorType) { - *colorType = numberOfComponents == 3 ? SkEncodedInfo::kYUV_Color - : SkEncodedInfo::kGray_Color; - } - if (orientation) { - *orientation = kTopLeft_SkEncodedOrigin; - } - return true; -} diff --git a/src/pdf/SkPDFBitmap.cpp b/src/pdf/SkPDFBitmap.cpp index 8806150ce0..a3f4632e25 100644 --- a/src/pdf/SkPDFBitmap.cpp +++ b/src/pdf/SkPDFBitmap.cpp @@ -7,26 +7,34 @@ #include "src/pdf/SkPDFBitmap.h" +#include "include/codec/SkCodec.h" #include "include/codec/SkEncodedImageFormat.h" +#include "include/codec/SkJpegDecoder.h" #include "include/core/SkBitmap.h" #include "include/core/SkData.h" #include "include/core/SkExecutor.h" #include "include/core/SkImage.h" #include "include/core/SkStream.h" +#include "include/encode/SkICC.h" #include "include/encode/SkJpegEncoder.h" #include "include/private/SkColorData.h" #include "include/private/base/SkTo.h" #include "src/core/SkImageInfoPriv.h" #include "src/pdf/SkDeflate.h" -#include "src/pdf/SkJpegInfo.h" #include "src/pdf/SkPDFDocumentPriv.h" #include "src/pdf/SkPDFTypes.h" +#include "src/pdf/SkPDFUnion.h" #include "src/pdf/SkPDFUtils.h" -//////////////////////////////////////////////////////////////////////////////// + +/*static*/ const SkEncodedInfo& SkPDFBitmap::GetEncodedInfo(SkCodec& codec) { + return codec.getEncodedInfo(); +} + +namespace { // write a single byte to a stream n times. -static void fill_stream(SkWStream* out, char value, size_t n) { +void fill_stream(SkWStream* out, char value, size_t n) { char buffer[4096]; memset(buffer, value, sizeof(buffer)); for (size_t i = 0; i < n / sizeof(buffer); ++i) { @@ -44,7 +52,7 @@ static void fill_stream(SkWStream* out, char value, size_t n) { channel goes to black, and the should-be-transparent pixels are rendered as grey because of the separate soft mask and color resizing. e.g.: gm/bitmappremul.cpp */ -static SkColor get_neighbor_avg_color(const SkPixmap& bm, int xOrig, int yOrig) { +SkColor get_neighbor_avg_color(const SkPixmap& bm, int xOrig, int yOrig) { SkASSERT(kBGRA_8888_SkColorType == bm.colorType()); unsigned r = 0, g = 0, b = 0, n = 0; // Clamp the range to the edge of the bitmap. @@ -68,24 +76,22 @@ static SkColor get_neighbor_avg_color(const SkPixmap& bm, int xOrig, int yOrig) : SK_ColorTRANSPARENT; } -namespace { enum class SkPDFStreamFormat { DCT, Flate, Uncompressed }; -} template <typename T> -static void emit_image_stream(SkPDFDocument* doc, - SkPDFIndirectReference ref, - T writeStream, - SkISize size, - const char* colorSpace, - SkPDFIndirectReference sMask, - int length, - SkPDFStreamFormat format) { +void emit_image_stream(SkPDFDocument* doc, + SkPDFIndirectReference ref, + T writeStream, + SkISize size, + SkPDFUnion&& colorSpace, + SkPDFIndirectReference sMask, + int length, + SkPDFStreamFormat format) { SkPDFDict pdfDict("XObject"); pdfDict.insertName("Subtype", "Image"); pdfDict.insertInt("Width", size.width()); pdfDict.insertInt("Height", size.height()); - pdfDict.insertName("ColorSpace", colorSpace); + pdfDict.insertUnion("ColorSpace", std::move(colorSpace)); if (sMask) { pdfDict.insertRef("SMask", sMask); } @@ -113,7 +119,7 @@ static void emit_image_stream(SkPDFDocument* doc, doc->emitStream(pdfDict, std::move(writeStream), ref); } -static void do_deflated_alpha(const SkPixmap& pm, SkPDFDocument* doc, SkPDFIndirectReference ref) { +void do_deflated_alpha(const SkPixmap& pm, SkPDFDocument* doc, SkPDFIndirectReference ref) { SkPDF::Metadata::CompressionLevel compressionLevel = doc->metadata().fCompressionLevel; SkPDFStreamFormat format = compressionLevel == SkPDF::Metadata::CompressionLevel::None ? SkPDFStreamFormat::Uncompressed @@ -156,14 +162,37 @@ static void do_deflated_alpha(const SkPixmap& pm, SkPDFDocument* doc, SkPDFIndir #endif int length = SkToInt(buffer.bytesWritten()); emit_image_stream(doc, ref, [&buffer](SkWStream* stream) { buffer.writeToAndReset(stream); }, - pm.info().dimensions(), "DeviceGray", SkPDFIndirectReference(), - length, format); + pm.info().dimensions(), SkPDFUnion::Name("DeviceGray"), + SkPDFIndirectReference(), length, format); } -static void do_deflated_image(const SkPixmap& pm, - SkPDFDocument* doc, - bool isOpaque, - SkPDFIndirectReference ref) { +SkPDFUnion write_icc_profile(SkPDFDocument* doc, sk_sp<SkData>&& icc, int channels) { + SkPDFIndirectReference iccStreamRef; + { + static SkMutex iccProfileMapMutex; + SkAutoMutexExclusive lock(iccProfileMapMutex); + + SkPDFIndirectReference* ref = doc->fICCProfileMap.find(SkPDFIccProfileKey{icc}); + if (ref) { + iccStreamRef = *ref; + } else { + std::unique_ptr<SkPDFDict> iccStreamDict = SkPDFMakeDict(); + iccStreamDict->insertInt("N", channels); + iccStreamRef = SkPDFStreamOut(std::move(iccStreamDict), SkMemoryStream::Make(icc), doc); + doc->fICCProfileMap.set(SkPDFIccProfileKey{icc}, iccStreamRef); + } + } + + std::unique_ptr<SkPDFArray> iccPDF = SkPDFMakeArray(); + iccPDF->appendName("ICCBased"); + iccPDF->appendRef(iccStreamRef); + return SkPDFUnion::Object(std::move(iccPDF)); +} + +void do_deflated_image(const SkPixmap& pm, + SkPDFDocument* doc, + bool isOpaque, + SkPDFIndirectReference ref) { SkPDFIndirectReference sMask; if (!isOpaque) { sMask = doc->reserveRef(); @@ -179,18 +208,22 @@ static void do_deflated_image(const SkPixmap& pm, deflateWStream.emplace(&buffer, SkToInt(compressionLevel)); stream = &*deflateWStream; } - const char* colorSpace = "DeviceGray"; + SkPDFUnion colorSpace = SkPDFUnion::Name("DeviceGray"); + int channels; switch (pm.colorType()) { case kAlpha_8_SkColorType: + channels = 1; fill_stream(stream, '\x00', pm.width() * pm.height()); break; case kGray_8_SkColorType: + channels = 1; SkASSERT(sMask.fValue = -1); SkASSERT(pm.rowBytes() == (size_t)pm.width()); stream->write(pm.addr8(), pm.width() * pm.height()); break; default: - colorSpace = "DeviceRGB"; + colorSpace = SkPDFUnion::Name("DeviceRGB"); + channels = 3; SkASSERT(pm.alphaType() == kUnpremul_SkAlphaType); SkASSERT(pm.colorType() == kBGRA_8888_SkColorType); SkASSERT(pm.rowBytes() == (size_t)pm.width() * 4); @@ -219,26 +252,40 @@ static void do_deflated_image(const SkPixmap& pm, if (deflateWStream) { deflateWStream->finalize(); } + + if (pm.colorSpace()) { + skcms_ICCProfile iccProfile; + pm.colorSpace()->toProfile(&iccProfile); + sk_sp<SkData> iccData = SkWriteICCProfile(&iccProfile, ""); + colorSpace = write_icc_profile(doc, std::move(iccData), channels); + } + #ifdef SK_PDF_BASE85_BINARY SkPDFUtils::Base85Encode(buffer.detachAsStream(), &buffer); #endif int length = SkToInt(buffer.bytesWritten()); emit_image_stream(doc, ref, [&buffer](SkWStream* stream) { buffer.writeToAndReset(stream); }, - pm.info().dimensions(), colorSpace, sMask, length, format); + pm.info().dimensions(), std::move(colorSpace), sMask, length, format); if (!isOpaque) { do_deflated_alpha(pm, doc, sMask); } } -static bool do_jpeg(sk_sp<SkData> data, SkPDFDocument* doc, SkISize size, - SkPDFIndirectReference ref) { - SkISize jpegSize; - SkEncodedInfo::Color jpegColorType; - SkEncodedOrigin exifOrientation; - if (!SkGetJpegInfo(data->data(), data->size(), &jpegSize, - &jpegColorType, &exifOrientation)) { +bool do_jpeg(sk_sp<SkData> data, SkColorSpace* imageColorSpace, SkPDFDocument* doc, SkISize size, + SkPDFIndirectReference ref) { + static constexpr const SkCodecs::Decoder decoders[] = { + SkJpegDecoder::Decoder(), + }; + std::unique_ptr<SkCodec> codec = SkCodec::MakeFromData(data, decoders); + if (!codec) { return false; } + + SkISize jpegSize = codec->dimensions(); + const SkEncodedInfo& encodedInfo = SkPDFBitmap::GetEncodedInfo(*codec); + SkEncodedInfo::Color jpegColorType = encodedInfo.color(); + SkEncodedOrigin exifOrientation = codec->getOrigin(); + bool yuv = jpegColorType == SkEncodedInfo::kYUV_Color; bool goodColorType = yuv || jpegColorType == SkEncodedInfo::kGray_Color; if (jpegSize != size // Safety check. @@ -252,14 +299,28 @@ static bool do_jpeg(sk_sp<SkData> data, SkPDFDocument* doc, SkISize size, data = buffer.detachAsData(); #endif + int channels = yuv ? 3 : 1; + SkPDFUnion colorSpace = yuv ? SkPDFUnion::Name("DeviceRGB") : SkPDFUnion::Name("DeviceGray"); + if (sk_sp<SkData> encodedIccProfileData = encodedInfo.profileData()) { + colorSpace = write_icc_profile(doc, std::move(encodedIccProfileData), channels); + } else if (const skcms_ICCProfile* codecIccProfile = codec->getICCProfile()) { + sk_sp<SkData> codecIccData = SkWriteICCProfile(codecIccProfile, ""); + colorSpace = write_icc_profile(doc, std::move(codecIccData), channels); + } else if (imageColorSpace) { + skcms_ICCProfile imageIccProfile; + imageColorSpace->toProfile(&imageIccProfile); + sk_sp<SkData> imageIccData = SkWriteICCProfile(&imageIccProfile, ""); + colorSpace = write_icc_profile(doc, std::move(imageIccData), channels); + } + emit_image_stream(doc, ref, [&data](SkWStream* dst) { dst->write(data->data(), data->size()); }, - jpegSize, yuv ? "DeviceRGB" : "DeviceGray", + jpegSize, std::move(colorSpace), SkPDFIndirectReference(), SkToInt(data->size()), SkPDFStreamFormat::DCT); return true; } -static SkBitmap to_pixels(const SkImage* image) { +SkBitmap to_pixels(const SkImage* image) { SkBitmap bm; int w = image->width(), h = image->height(); @@ -273,7 +334,8 @@ static SkBitmap to_pixels(const SkImage* image) { default: { // TODO: makeColorSpace(sRGB) or actually tag the images SkAlphaType at = bm.isOpaque() ? kOpaque_SkAlphaType : kUnpremul_SkAlphaType; - bm.allocPixels(SkImageInfo::Make(w, h, kBGRA_8888_SkColorType, at)); + bm.allocPixels( + SkImageInfo::Make(w, h, kBGRA_8888_SkColorType, at, image->refColorSpace())); } } // TODO: support GPU images in PDFs @@ -291,8 +353,9 @@ void serialize_image(const SkImage* img, SkASSERT(doc); SkASSERT(encodingQuality >= 0); SkISize dimensions = img->dimensions(); + if (sk_sp<SkData> data = img->refEncodedData()) { - if (do_jpeg(std::move(data), doc, dimensions, ref)) { + if (do_jpeg(std::move(data), img->colorSpace(), doc, dimensions, ref)) { return; } } @@ -304,7 +367,7 @@ void serialize_image(const SkImage* img, jOpts.fQuality = encodingQuality; SkDynamicMemoryWStream stream; if (SkJpegEncoder::Encode(&stream, pm, jOpts)) { - if (do_jpeg(stream.detachAsData(), doc, dimensions, ref)) { + if (do_jpeg(stream.detachAsData(), pm.colorSpace(), doc, dimensions, ref)) { return; } } @@ -312,6 +375,8 @@ void serialize_image(const SkImage* img, do_deflated_image(pm, doc, isOpaque, ref); } +} // namespace + SkPDFIndirectReference SkPDFSerializeImage(const SkImage* img, SkPDFDocument* doc, int encodingQuality) { diff --git a/src/pdf/SkPDFBitmap.h b/src/pdf/SkPDFBitmap.h index bc2c57bd3b..d310d7b6a6 100644 --- a/src/pdf/SkPDFBitmap.h +++ b/src/pdf/SkPDFBitmap.h @@ -7,8 +7,13 @@ #ifndef SkPDFBitmap_DEFINED #define SkPDFBitmap_DEFINED +#include "include/core/SkData.h" +#include "src/core/SkChecksum.h" + +class SkCodec; class SkImage; class SkPDFDocument; +struct SkEncodedInfo; struct SkPDFIndirectReference; /** @@ -19,4 +24,23 @@ SkPDFIndirectReference SkPDFSerializeImage(const SkImage* img, SkPDFDocument* doc, int encodingQuality = 101); +class SkPDFBitmap { +public: + static const SkEncodedInfo& GetEncodedInfo(SkCodec&); +}; + +struct SkPDFIccProfileKey { + sk_sp<SkData> fData; + bool operator==(const SkPDFIccProfileKey& that) const { + return fData->equals(that.fData.get()); + } + bool operator!=(const SkPDFIccProfileKey& rhs) const { return !(*this == rhs); } + + struct Hash { + uint32_t operator()(const SkPDFIccProfileKey& k) const { + return SkChecksum::Hash32(k.fData->data(), k.fData->size()); + } + }; +}; + #endif // SkPDFBitmap_DEFINED diff --git a/src/pdf/SkPDFDocumentPriv.h b/src/pdf/SkPDFDocumentPriv.h index dffc239c3e..4d8e5eb892 100644 --- a/src/pdf/SkPDFDocumentPriv.h +++ b/src/pdf/SkPDFDocumentPriv.h @@ -12,6 +12,7 @@ #include "include/docs/SkPDFDocument.h" #include "include/private/base/SkMutex.h" #include "src/core/SkTHash.h" +#include "src/pdf/SkPDFBitmap.h" #include "src/pdf/SkPDFGraphicState.h" #include "src/pdf/SkPDFMetadata.h" #include "src/pdf/SkPDFShader.h" @@ -149,6 +150,9 @@ public: SkPDFIndirectReference, SkPDFGradientShader::KeyHash> fGradientPatternMap; skia_private::THashMap<SkBitmapKey, SkPDFIndirectReference> fPDFBitmapMap; + skia_private::THashMap<SkPDFIccProfileKey, + SkPDFIndirectReference, + SkPDFIccProfileKey::Hash> fICCProfileMap; skia_private::THashMap<uint32_t, std::unique_ptr<SkAdvancedTypefaceMetrics>> fTypefaceMetrics; skia_private::THashMap<uint32_t, std::vector<SkString>> fType1GlyphNames; skia_private::THashMap<uint32_t, std::vector<SkUnichar>> fToUnicodeMap; diff --git a/src/pdf/SkPDFTypes.cpp b/src/pdf/SkPDFTypes.cpp index 79c402a9ad..d9b6d854b8 100644 --- a/src/pdf/SkPDFTypes.cpp +++ b/src/pdf/SkPDFTypes.cpp @@ -527,6 +527,10 @@ void SkPDFDict::insertTextString(const char key[], SkString value) { fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::TextString(std::move(value))); } +void SkPDFDict::insertUnion(const char key[], SkPDFUnion&& value) { + fRecords.emplace_back(SkPDFUnion::Name(key), std::move(value)); +} + //////////////////////////////////////////////////////////////////////////////// diff --git a/src/pdf/SkPDFTypes.h b/src/pdf/SkPDFTypes.h index 370c94878f..579434ba8e 100644 --- a/src/pdf/SkPDFTypes.h +++ b/src/pdf/SkPDFTypes.h @@ -186,6 +186,7 @@ public: void insertTextString(const char key[], const char value[]); void insertByteString(const char key[], SkString value); void insertTextString(const char key[], SkString value); + void insertUnion(const char key[], SkPDFUnion&&); private: std::vector<std::pair<SkPDFUnion, SkPDFUnion>> fRecords; |