Switch SkPDFStream's internal storage from SkStream to SkData
Motivation: This makes SkPDFStream thread-safe for two threads serializing it at once, since a SkStream has an internal position. Updated SkPDFFont, SkPDFGraphicState, and SkPDFPage's use of SkPDFStream to use the SkData constructor rather than the SkStream constructor (saving a memcpy). BUG=skia:2683 R=mtklein@google.com, djsollen@google.com Author: halcanary@google.com Review URL: https://codereview.chromium.org/340783013
This commit is contained in:
parent
11a005ee01
commit
c1dfa14b64
@ -18,6 +18,7 @@
|
|||||||
'../src/core', # needed to get SkGlyphCache.h and SkTextFormatParams.h
|
'../src/core', # needed to get SkGlyphCache.h and SkTextFormatParams.h
|
||||||
'../src/pdf',
|
'../src/pdf',
|
||||||
'../src/utils', # needed to get SkBitSet.h
|
'../src/utils', # needed to get SkBitSet.h
|
||||||
|
'../src/images', # needed to get SkStreamHelpers.h
|
||||||
],
|
],
|
||||||
'sources': [
|
'sources': [
|
||||||
'pdf.gypi', # Makes the gypi appear in IDEs (but does not modify the build).
|
'pdf.gypi', # Makes the gypi appear in IDEs (but does not modify the build).
|
||||||
|
@ -150,8 +150,8 @@ int8_t hexToBin(uint8_t c) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkStream* handleType1Stream(SkStream* srcStream, size_t* headerLen,
|
static SkData* handle_type1_stream(SkStream* srcStream, size_t* headerLen,
|
||||||
size_t* dataLen, size_t* trailerLen) {
|
size_t* dataLen, size_t* trailerLen) {
|
||||||
// srcStream may be backed by a file or a unseekable fd, so we may not be
|
// srcStream may be backed by a file or a unseekable fd, so we may not be
|
||||||
// able to use skip(), rewind(), or getMemoryBase(). read()ing through
|
// able to use skip(), rewind(), or getMemoryBase(). read()ing through
|
||||||
// the input only once is doable, but very ugly. Furthermore, it'd be nice
|
// the input only once is doable, but very ugly. Furthermore, it'd be nice
|
||||||
@ -199,26 +199,43 @@ SkStream* handleType1Stream(SkStream* srcStream, size_t* headerLen,
|
|||||||
SkAutoDataUnref aud(data);
|
SkAutoDataUnref aud(data);
|
||||||
|
|
||||||
if (parsePFB(src, srcLen, headerLen, dataLen, trailerLen)) {
|
if (parsePFB(src, srcLen, headerLen, dataLen, trailerLen)) {
|
||||||
SkMemoryStream* result =
|
static const int kPFBSectionHeaderLength = 6;
|
||||||
new SkMemoryStream(*headerLen + *dataLen + *trailerLen);
|
const size_t length = *headerLen + *dataLen + *trailerLen;
|
||||||
memcpy((char*)result->getAtPos(), src + 6, *headerLen);
|
SkASSERT(length > 0);
|
||||||
result->seek(*headerLen);
|
SkASSERT(length + (2 * kPFBSectionHeaderLength) <= srcLen);
|
||||||
memcpy((char*)result->getAtPos(), src + 6 + *headerLen + 6, *dataLen);
|
|
||||||
result->seek(*headerLen + *dataLen);
|
SkAutoTMalloc<uint8_t> buffer(length);
|
||||||
memcpy((char*)result->getAtPos(), src + 6 + *headerLen + 6 + *dataLen,
|
|
||||||
*trailerLen);
|
const uint8_t* const srcHeader = src + kPFBSectionHeaderLength;
|
||||||
result->rewind();
|
// There is a six-byte section header before header and data
|
||||||
return result;
|
// (but not trailer) that we're not going to copy.
|
||||||
|
const uint8_t* const srcData
|
||||||
|
= srcHeader + *headerLen + kPFBSectionHeaderLength;
|
||||||
|
const uint8_t* const srcTrailer = srcData + *headerLen;
|
||||||
|
|
||||||
|
uint8_t* const resultHeader = buffer.get();
|
||||||
|
uint8_t* const resultData = resultHeader + *headerLen;
|
||||||
|
uint8_t* const resultTrailer = resultData + *dataLen;
|
||||||
|
|
||||||
|
SkASSERT(resultTrailer + *trailerLen == resultHeader + length);
|
||||||
|
|
||||||
|
memcpy(resultHeader, srcHeader, *headerLen);
|
||||||
|
memcpy(resultData, srcData, *dataLen);
|
||||||
|
memcpy(resultTrailer, srcTrailer, *trailerLen);
|
||||||
|
|
||||||
|
return SkData::NewFromMalloc(buffer.detach(), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A PFA has to be converted for PDF.
|
// A PFA has to be converted for PDF.
|
||||||
size_t hexDataLen;
|
size_t hexDataLen;
|
||||||
if (parsePFA((const char*)src, srcLen, headerLen, &hexDataLen, dataLen,
|
if (parsePFA((const char*)src, srcLen, headerLen, &hexDataLen, dataLen,
|
||||||
trailerLen)) {
|
trailerLen)) {
|
||||||
SkMemoryStream* result =
|
const size_t length = *headerLen + *dataLen + *trailerLen;
|
||||||
new SkMemoryStream(*headerLen + *dataLen + *trailerLen);
|
SkASSERT(length > 0);
|
||||||
memcpy((char*)result->getAtPos(), src, *headerLen);
|
SkAutoTMalloc<uint8_t> buffer(length);
|
||||||
result->seek(*headerLen);
|
|
||||||
|
memcpy(buffer.get(), src, *headerLen);
|
||||||
|
uint8_t* const resultData = &(buffer[*headerLen]);
|
||||||
|
|
||||||
const uint8_t* hexData = src + *headerLen;
|
const uint8_t* hexData = src + *headerLen;
|
||||||
const uint8_t* trailer = hexData + hexDataLen;
|
const uint8_t* trailer = hexData + hexDataLen;
|
||||||
@ -236,21 +253,19 @@ SkStream* handleType1Stream(SkStream* srcStream, size_t* headerLen,
|
|||||||
} else {
|
} else {
|
||||||
dataByte |= curNibble;
|
dataByte |= curNibble;
|
||||||
highNibble = true;
|
highNibble = true;
|
||||||
((char *)result->getAtPos())[outputOffset++] = dataByte;
|
resultData[outputOffset++] = dataByte;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!highNibble) {
|
if (!highNibble) {
|
||||||
((char *)result->getAtPos())[outputOffset++] = dataByte;
|
resultData[outputOffset++] = dataByte;
|
||||||
}
|
}
|
||||||
SkASSERT(outputOffset == *dataLen);
|
SkASSERT(outputOffset == *dataLen);
|
||||||
result->seek(*headerLen + outputOffset);
|
|
||||||
|
|
||||||
memcpy((char *)result->getAtPos(), src + *headerLen + hexDataLen,
|
uint8_t* const resultTrailer = &(buffer[*headerLen + outputOffset]);
|
||||||
*trailerLen);
|
memcpy(resultTrailer, src + *headerLen + hexDataLen, *trailerLen);
|
||||||
result->rewind();
|
|
||||||
return result;
|
return SkData::NewFromMalloc(buffer.detach(), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,9 +571,8 @@ static SkPDFStream* generate_tounicode_cmap(
|
|||||||
append_cmap_sections(glyphToUnicode, subset, &cmap, multiByteGlyphs,
|
append_cmap_sections(glyphToUnicode, subset, &cmap, multiByteGlyphs,
|
||||||
firstGlyphID, lastGlyphID);
|
firstGlyphID, lastGlyphID);
|
||||||
append_cmap_footer(&cmap);
|
append_cmap_footer(&cmap);
|
||||||
SkAutoTUnref<SkMemoryStream> cmapStream(new SkMemoryStream());
|
SkAutoTUnref<SkData> cmapData(cmap.copyToData());
|
||||||
cmapStream->setData(cmap.copyToData())->unref();
|
return new SkPDFStream(cmapData.get());
|
||||||
return new SkPDFStream(cmapStream.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (SK_SFNTLY_SUBSETTER)
|
#if defined (SK_SFNTLY_SUBSETTER)
|
||||||
@ -574,6 +588,7 @@ static size_t get_subset_font_stream(const char* fontName,
|
|||||||
SkPDFStream** fontStream) {
|
SkPDFStream** fontStream) {
|
||||||
int ttcIndex;
|
int ttcIndex;
|
||||||
SkAutoTUnref<SkStream> fontData(typeface->openStream(&ttcIndex));
|
SkAutoTUnref<SkStream> fontData(typeface->openStream(&ttcIndex));
|
||||||
|
SkASSERT(fontData.get());
|
||||||
|
|
||||||
size_t fontSize = fontData->getLength();
|
size_t fontSize = fontData->getLength();
|
||||||
|
|
||||||
@ -1295,7 +1310,7 @@ bool SkPDFType1Font::addFontDescriptor(int16_t defaultWidth) {
|
|||||||
size_t data SK_INIT_TO_AVOID_WARNING;
|
size_t data SK_INIT_TO_AVOID_WARNING;
|
||||||
size_t trailer SK_INIT_TO_AVOID_WARNING;
|
size_t trailer SK_INIT_TO_AVOID_WARNING;
|
||||||
SkAutoTUnref<SkStream> rawFontData(typeface()->openStream(&ttcIndex));
|
SkAutoTUnref<SkStream> rawFontData(typeface()->openStream(&ttcIndex));
|
||||||
SkStream* fontData = handleType1Stream(rawFontData.get(), &header, &data,
|
SkData* fontData = handle_type1_stream(rawFontData.get(), &header, &data,
|
||||||
&trailer);
|
&trailer);
|
||||||
if (fontData == NULL) {
|
if (fontData == NULL) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
* found in the LICENSE file.
|
* found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "SkData.h"
|
||||||
#include "SkPDFFormXObject.h"
|
#include "SkPDFFormXObject.h"
|
||||||
#include "SkPDFGraphicState.h"
|
#include "SkPDFGraphicState.h"
|
||||||
#include "SkPDFUtils.h"
|
#include "SkPDFUtils.h"
|
||||||
#include "SkStream.h"
|
|
||||||
#include "SkTypes.h"
|
#include "SkTypes.h"
|
||||||
|
|
||||||
static const char* blend_mode_from_xfermode(SkXfermode::Mode mode) {
|
static const char* blend_mode_from_xfermode(SkXfermode::Mode mode) {
|
||||||
@ -121,8 +121,9 @@ SkPDFObject* SkPDFGraphicState::GetInvertFunction() {
|
|||||||
domainAndRange->appendInt(1);
|
domainAndRange->appendInt(1);
|
||||||
|
|
||||||
static const char psInvert[] = "{1 exch sub}";
|
static const char psInvert[] = "{1 exch sub}";
|
||||||
SkAutoTUnref<SkMemoryStream> psInvertStream(
|
// Do not copy the trailing '\0' into the SkData.
|
||||||
new SkMemoryStream(&psInvert, strlen(psInvert), true));
|
SkAutoTUnref<SkData> psInvertStream(
|
||||||
|
SkData::NewWithCopy(psInvert, strlen(psInvert)));
|
||||||
|
|
||||||
invertFunction = new SkPDFStream(psInvertStream.get());
|
invertFunction = new SkPDFStream(psInvertStream.get());
|
||||||
invertFunction->insertInt("FunctionType", 4);
|
invertFunction->insertInt("FunctionType", 4);
|
||||||
|
@ -512,7 +512,7 @@ SkPDFImage::SkPDFImage(SkStream* stream,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stream != NULL) {
|
if (stream != NULL) {
|
||||||
setData(stream);
|
this->setData(stream);
|
||||||
fStreamValid = true;
|
fStreamValid = true;
|
||||||
} else {
|
} else {
|
||||||
fStreamValid = false;
|
fStreamValid = false;
|
||||||
@ -598,13 +598,11 @@ bool SkPDFImage::populate(SkPDFCatalog* catalog) {
|
|||||||
SkAutoTUnref<SkData> data(fEncoder(&pixelRefOffset, subset));
|
SkAutoTUnref<SkData> data(fEncoder(&pixelRefOffset, subset));
|
||||||
if (data.get() && data->size() < get_uncompressed_size(fBitmap,
|
if (data.get() && data->size() < get_uncompressed_size(fBitmap,
|
||||||
fSrcRect)) {
|
fSrcRect)) {
|
||||||
SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream,
|
this->setData(data.get());
|
||||||
(data)));
|
|
||||||
setData(stream.get());
|
|
||||||
|
|
||||||
insertName("Filter", "DCTDecode");
|
insertName("Filter", "DCTDecode");
|
||||||
insertInt("ColorTransform", kNoColorTransform);
|
insertInt("ColorTransform", kNoColorTransform);
|
||||||
insertInt("Length", getData()->getLength());
|
insertInt("Length", this->dataSize());
|
||||||
setState(kCompressed_State);
|
setState(kCompressed_State);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -613,7 +611,7 @@ bool SkPDFImage::populate(SkPDFCatalog* catalog) {
|
|||||||
if (!fStreamValid) {
|
if (!fStreamValid) {
|
||||||
SkAutoTUnref<SkStream> stream(
|
SkAutoTUnref<SkStream> stream(
|
||||||
extract_image_data(fBitmap, fSrcRect, fIsAlpha, NULL));
|
extract_image_data(fBitmap, fSrcRect, fIsAlpha, NULL));
|
||||||
setData(stream);
|
this->setData(stream);
|
||||||
fStreamValid = true;
|
fStreamValid = true;
|
||||||
}
|
}
|
||||||
return INHERITED::populate(catalog);
|
return INHERITED::populate(catalog);
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "SkData.h"
|
||||||
#include "SkPDFCatalog.h"
|
#include "SkPDFCatalog.h"
|
||||||
#include "SkPDFDevice.h"
|
#include "SkPDFDevice.h"
|
||||||
#include "SkPDFPage.h"
|
#include "SkPDFPage.h"
|
||||||
#include "SkPDFResourceDict.h"
|
#include "SkPDFResourceDict.h"
|
||||||
#include "SkStream.h"
|
|
||||||
|
|
||||||
SkPDFPage::SkPDFPage(SkPDFDevice* content)
|
SkPDFPage::SkPDFPage(SkPDFDevice* content)
|
||||||
: SkPDFDict("Page"),
|
: SkPDFDict("Page"),
|
||||||
@ -36,7 +36,7 @@ void SkPDFPage::finalizePage(SkPDFCatalog* catalog, bool firstPage,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SkAutoTUnref<SkStream> content(fDevice->content());
|
SkAutoTUnref<SkData> content(fDevice->copyContentToData());
|
||||||
fContentStream.reset(new SkPDFStream(content.get()));
|
fContentStream.reset(new SkPDFStream(content.get()));
|
||||||
insert("Contents", new SkPDFObjRef(fContentStream.get()))->unref();
|
insert("Contents", new SkPDFObjRef(fContentStream.get()))->unref();
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "SkPDFCatalog.h"
|
#include "SkPDFCatalog.h"
|
||||||
#include "SkPDFStream.h"
|
#include "SkPDFStream.h"
|
||||||
#include "SkStream.h"
|
#include "SkStream.h"
|
||||||
|
#include "SkStreamHelpers.h" // CopyStreamToData
|
||||||
|
|
||||||
static bool skip_compression(SkPDFCatalog* catalog) {
|
static bool skip_compression(SkPDFCatalog* catalog) {
|
||||||
return SkToBool(catalog->getDocumentFlags() &
|
return SkToBool(catalog->getDocumentFlags() &
|
||||||
@ -19,17 +20,17 @@ static bool skip_compression(SkPDFCatalog* catalog) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SkPDFStream::SkPDFStream(SkStream* stream) : fState(kUnused_State) {
|
SkPDFStream::SkPDFStream(SkStream* stream) : fState(kUnused_State) {
|
||||||
setData(stream);
|
this->setData(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkPDFStream::SkPDFStream(SkData* data) : fState(kUnused_State) {
|
SkPDFStream::SkPDFStream(SkData* data) : fState(kUnused_State) {
|
||||||
setData(data);
|
this->setData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkPDFStream::SkPDFStream(const SkPDFStream& pdfStream)
|
SkPDFStream::SkPDFStream(const SkPDFStream& pdfStream)
|
||||||
: SkPDFDict(),
|
: SkPDFDict(),
|
||||||
fState(kUnused_State) {
|
fState(kUnused_State) {
|
||||||
setData(pdfStream.fData.get());
|
this->setData(pdfStream.fData.get());
|
||||||
bool removeLength = true;
|
bool removeLength = true;
|
||||||
// Don't uncompress an already compressed stream, but we could.
|
// Don't uncompress an already compressed stream, but we could.
|
||||||
if (pdfStream.fState == kCompressed_State) {
|
if (pdfStream.fState == kCompressed_State) {
|
||||||
@ -55,14 +56,16 @@ void SkPDFStream::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
|
|||||||
if (indirect) {
|
if (indirect) {
|
||||||
return emitIndirectObject(stream, catalog);
|
return emitIndirectObject(stream, catalog);
|
||||||
}
|
}
|
||||||
|
SkAutoMutexAcquire lock(fMutex); // multiple threads could be calling emit
|
||||||
if (!this->populate(catalog)) {
|
if (!this->populate(catalog)) {
|
||||||
return fSubstitute->emitObject(stream, catalog, indirect);
|
return fSubstitute->emitObject(stream, catalog, indirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->INHERITED::emitObject(stream, catalog, false);
|
this->INHERITED::emitObject(stream, catalog, false);
|
||||||
stream->writeText(" stream\n");
|
stream->writeText(" stream\n");
|
||||||
stream->writeStream(fData.get(), fData->getLength());
|
if (fData.get()) {
|
||||||
fData->rewind();
|
stream->write(fData->data(), fData->size());
|
||||||
|
}
|
||||||
stream->writeText("\nendstream");
|
stream->writeText("\nendstream");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,30 +73,34 @@ size_t SkPDFStream::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
|
|||||||
if (indirect) {
|
if (indirect) {
|
||||||
return getIndirectOutputSize(catalog);
|
return getIndirectOutputSize(catalog);
|
||||||
}
|
}
|
||||||
|
SkAutoMutexAcquire lock(fMutex); // multiple threads could be calling emit
|
||||||
if (!this->populate(catalog)) {
|
if (!this->populate(catalog)) {
|
||||||
return fSubstitute->getOutputSize(catalog, indirect);
|
return fSubstitute->getOutputSize(catalog, indirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this->INHERITED::getOutputSize(catalog, false) +
|
return this->INHERITED::getOutputSize(catalog, false) +
|
||||||
strlen(" stream\n\nendstream") + fData->getLength();
|
strlen(" stream\n\nendstream") + this->dataSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
SkPDFStream::SkPDFStream() : fState(kUnused_State) {}
|
SkPDFStream::SkPDFStream() : fState(kUnused_State) {}
|
||||||
|
|
||||||
void SkPDFStream::setData(SkData* data) {
|
void SkPDFStream::setData(SkData* data) {
|
||||||
SkMemoryStream* stream = new SkMemoryStream;
|
fData.reset(SkSafeRef(data));
|
||||||
stream->setData(data);
|
|
||||||
fData.reset(stream); // Transfer ownership.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkPDFStream::setData(SkStream* stream) {
|
void SkPDFStream::setData(SkStream* stream) {
|
||||||
// Code assumes that the stream starts at the beginning and is rewindable.
|
// Code assumes that the stream starts at the beginning and is rewindable.
|
||||||
if (stream) {
|
if (stream) {
|
||||||
SkASSERT(stream->getPosition() == 0);
|
SkASSERT(stream->getPosition() == 0);
|
||||||
|
fData.reset(CopyStreamToData(stream));
|
||||||
SkASSERT(stream->rewind());
|
SkASSERT(stream->rewind());
|
||||||
|
} else {
|
||||||
|
fData.reset(NULL);
|
||||||
}
|
}
|
||||||
fData.reset(stream);
|
}
|
||||||
SkSafeRef(stream);
|
|
||||||
|
size_t SkPDFStream::dataSize() const {
|
||||||
|
return fData.get() ? fData->size() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkPDFStream::populate(SkPDFCatalog* catalog) {
|
bool SkPDFStream::populate(SkPDFCatalog* catalog) {
|
||||||
@ -102,17 +109,15 @@ bool SkPDFStream::populate(SkPDFCatalog* catalog) {
|
|||||||
SkDynamicMemoryWStream compressedData;
|
SkDynamicMemoryWStream compressedData;
|
||||||
|
|
||||||
SkAssertResult(SkFlate::Deflate(fData.get(), &compressedData));
|
SkAssertResult(SkFlate::Deflate(fData.get(), &compressedData));
|
||||||
if (compressedData.getOffset() < fData->getLength()) {
|
if (compressedData.getOffset() < this->dataSize()) {
|
||||||
SkMemoryStream* stream = new SkMemoryStream;
|
fData.reset(compressedData.copyToData());
|
||||||
stream->setData(compressedData.copyToData())->unref();
|
|
||||||
fData.reset(stream); // Transfer ownership.
|
|
||||||
insertName("Filter", "FlateDecode");
|
insertName("Filter", "FlateDecode");
|
||||||
}
|
}
|
||||||
fState = kCompressed_State;
|
fState = kCompressed_State;
|
||||||
} else {
|
} else {
|
||||||
fState = kNoCompression_State;
|
fState = kNoCompression_State;
|
||||||
}
|
}
|
||||||
insertInt("Length", fData->getLength());
|
insertInt("Length", this->dataSize());
|
||||||
} else if (fState == kNoCompression_State && !skip_compression(catalog) &&
|
} else if (fState == kNoCompression_State && !skip_compression(catalog) &&
|
||||||
SkFlate::HaveFlate()) {
|
SkFlate::HaveFlate()) {
|
||||||
if (!fSubstitute.get()) {
|
if (!fSubstitute.get()) {
|
||||||
|
@ -41,7 +41,8 @@ public:
|
|||||||
explicit SkPDFStream(const SkPDFStream& pdfStream);
|
explicit SkPDFStream(const SkPDFStream& pdfStream);
|
||||||
virtual ~SkPDFStream();
|
virtual ~SkPDFStream();
|
||||||
|
|
||||||
// The SkPDFObject interface.
|
// The SkPDFObject interface. These two methods use a mutex to
|
||||||
|
// allow multiple threads to call at the same time.
|
||||||
virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
|
virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
|
||||||
bool indirect);
|
bool indirect);
|
||||||
virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
|
virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
|
||||||
@ -67,22 +68,22 @@ protected:
|
|||||||
fSubstitute.reset(stream);
|
fSubstitute.reset(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkPDFStream* getSubstitute() {
|
SkPDFStream* getSubstitute() const {
|
||||||
return fSubstitute.get();
|
return fSubstitute.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setData(SkData* data);
|
void setData(SkData* data);
|
||||||
void setData(SkStream* stream);
|
void setData(SkStream* stream);
|
||||||
|
|
||||||
SkStream* getData() {
|
size_t dataSize() const;
|
||||||
return fData.get();
|
|
||||||
}
|
SkData* getData() const { return fData.get(); }
|
||||||
|
|
||||||
void setState(State state) {
|
void setState(State state) {
|
||||||
fState = state;
|
fState = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
State getState() {
|
State getState() const {
|
||||||
return fState;
|
return fState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,8 +91,10 @@ private:
|
|||||||
// Indicates what form (or if) the stream has been requested.
|
// Indicates what form (or if) the stream has been requested.
|
||||||
State fState;
|
State fState;
|
||||||
|
|
||||||
// TODO(vandebo): Use SkData (after removing deprecated constructor).
|
// Mutex guards fState, fData, and fSubstitute in public interface.
|
||||||
SkAutoTUnref<SkStream> fData;
|
SkMutex fMutex;
|
||||||
|
|
||||||
|
SkAutoTUnref<SkData> fData;
|
||||||
SkAutoTUnref<SkPDFStream> fSubstitute;
|
SkAutoTUnref<SkPDFStream> fSubstitute;
|
||||||
|
|
||||||
typedef SkPDFDict INHERITED;
|
typedef SkPDFDict INHERITED;
|
||||||
|
Loading…
Reference in New Issue
Block a user