| Index: src/pdf/SkPDFFont.cpp
|
| diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
|
| index 014b328030c4e0baa0eacff09150fe510f583264..aa4b4b5534c084815c5a786a69e7385897be3ed4 100644
|
| --- a/src/pdf/SkPDFFont.cpp
|
| +++ b/src/pdf/SkPDFFont.cpp
|
| @@ -150,8 +150,8 @@ int8_t hexToBin(uint8_t c) {
|
| return -1;
|
| }
|
|
|
| -SkStream* handleType1Stream(SkStream* srcStream, size_t* headerLen,
|
| - size_t* dataLen, size_t* trailerLen) {
|
| +static SkData* handle_type1_stream(SkStream* srcStream, size_t* headerLen,
|
| + size_t* dataLen, size_t* trailerLen) {
|
| // 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
|
| // 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);
|
|
|
| if (parsePFB(src, srcLen, headerLen, dataLen, trailerLen)) {
|
| - SkMemoryStream* result =
|
| - new SkMemoryStream(*headerLen + *dataLen + *trailerLen);
|
| - memcpy((char*)result->getAtPos(), src + 6, *headerLen);
|
| - result->seek(*headerLen);
|
| - memcpy((char*)result->getAtPos(), src + 6 + *headerLen + 6, *dataLen);
|
| - result->seek(*headerLen + *dataLen);
|
| - memcpy((char*)result->getAtPos(), src + 6 + *headerLen + 6 + *dataLen,
|
| - *trailerLen);
|
| - result->rewind();
|
| - return result;
|
| + static const int kPFBSectionHeaderLength = 6;
|
| + const size_t length = *headerLen + *dataLen + *trailerLen;
|
| + SkASSERT(length > 0);
|
| + SkASSERT(length + (2 * kPFBSectionHeaderLength) <= srcLen);
|
| +
|
| + SkAutoTMalloc<uint8_t> buffer(length);
|
| +
|
| + const uint8_t* const srcHeader = src + kPFBSectionHeaderLength;
|
| + // There is a six-byte section header before header and data
|
| + // (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.
|
| size_t hexDataLen;
|
| if (parsePFA((const char*)src, srcLen, headerLen, &hexDataLen, dataLen,
|
| trailerLen)) {
|
| - SkMemoryStream* result =
|
| - new SkMemoryStream(*headerLen + *dataLen + *trailerLen);
|
| - memcpy((char*)result->getAtPos(), src, *headerLen);
|
| - result->seek(*headerLen);
|
| + const size_t length = *headerLen + *dataLen + *trailerLen;
|
| + SkASSERT(length > 0);
|
| + SkAutoTMalloc<uint8_t> buffer(length);
|
| +
|
| + memcpy(buffer.get(), src, *headerLen);
|
| + uint8_t* const resultData = &(buffer[*headerLen]);
|
|
|
| const uint8_t* hexData = src + *headerLen;
|
| const uint8_t* trailer = hexData + hexDataLen;
|
| @@ -236,21 +253,19 @@ SkStream* handleType1Stream(SkStream* srcStream, size_t* headerLen,
|
| } else {
|
| dataByte |= curNibble;
|
| highNibble = true;
|
| - ((char *)result->getAtPos())[outputOffset++] = dataByte;
|
| + resultData[outputOffset++] = dataByte;
|
| }
|
| }
|
| if (!highNibble) {
|
| - ((char *)result->getAtPos())[outputOffset++] = dataByte;
|
| + resultData[outputOffset++] = dataByte;
|
| }
|
| SkASSERT(outputOffset == *dataLen);
|
| - result->seek(*headerLen + outputOffset);
|
|
|
| - memcpy((char *)result->getAtPos(), src + *headerLen + hexDataLen,
|
| - *trailerLen);
|
| - result->rewind();
|
| - return result;
|
| - }
|
| + uint8_t* const resultTrailer = &(buffer[*headerLen + outputOffset]);
|
| + memcpy(resultTrailer, src + *headerLen + hexDataLen, *trailerLen);
|
|
|
| + return SkData::NewFromMalloc(buffer.detach(), length);
|
| + }
|
| return NULL;
|
| }
|
|
|
| @@ -556,9 +571,8 @@ static SkPDFStream* generate_tounicode_cmap(
|
| append_cmap_sections(glyphToUnicode, subset, &cmap, multiByteGlyphs,
|
| firstGlyphID, lastGlyphID);
|
| append_cmap_footer(&cmap);
|
| - SkAutoTUnref<SkMemoryStream> cmapStream(new SkMemoryStream());
|
| - cmapStream->setData(cmap.copyToData())->unref();
|
| - return new SkPDFStream(cmapStream.get());
|
| + SkAutoTUnref<SkData> cmapData(cmap.copyToData());
|
| + return new SkPDFStream(cmapData.get());
|
| }
|
|
|
| #if defined (SK_SFNTLY_SUBSETTER)
|
| @@ -574,6 +588,7 @@ static size_t get_subset_font_stream(const char* fontName,
|
| SkPDFStream** fontStream) {
|
| int ttcIndex;
|
| SkAutoTUnref<SkStream> fontData(typeface->openStream(&ttcIndex));
|
| + SkASSERT(fontData.get());
|
|
|
| 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 trailer SK_INIT_TO_AVOID_WARNING;
|
| SkAutoTUnref<SkStream> rawFontData(typeface()->openStream(&ttcIndex));
|
| - SkStream* fontData = handleType1Stream(rawFontData.get(), &header, &data,
|
| + SkData* fontData = handle_type1_stream(rawFontData.get(), &header, &data,
|
| &trailer);
|
| if (fontData == NULL) {
|
| return false;
|
|
|