From 0129410fbe4b88a0632fb7aa5185610b30e69852 Mon Sep 17 00:00:00 2001 From: "vandebo@chromium.org" Date: Mon, 28 Feb 2011 19:52:18 +0000 Subject: [PATCH] [PDF] Fix broken encoding conversion code for non-multibyte fonts. Review URL: http://codereview.appspot.com/4245044 git-svn-id: http://skia.googlecode.com/svn/trunk@863 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/pdf/SkPDFFont.h | 14 ++++--------- src/pdf/SkPDFDevice.cpp | 44 +++++++++++++++++------------------------ src/pdf/SkPDFFont.cpp | 35 ++++++++++++-------------------- 3 files changed, 35 insertions(+), 58 deletions(-) diff --git a/include/pdf/SkPDFFont.h b/include/pdf/SkPDFFont.h index bfa620b4cb..e2b5093d76 100644 --- a/include/pdf/SkPDFFont.h +++ b/include/pdf/SkPDFFont.h @@ -49,21 +49,15 @@ public: */ bool multiByteGlyphs(); - /** Convert the input glyph IDs into the font encoding. If the font has - * more glyphs than can be encoded (like a type 1 font with more than - * 255 glyphs) this method only converts up to the first out of range + /** Convert (in place) the input glyph IDs into the font encoding. If the + * font has more glyphs than can be encoded (like a type 1 font with more + * than 255 glyphs) this method only converts up to the first out of range * glyph ID. * @param glyphIDs The input text as glyph IDs. * @param numGlyphs The number of input glyphs. - * @param encodedValues The method writes its result to this parameter. - * multiByteGlyphs() reveals the output format. - * @param encodedLength The size of encodedValues (in bytes), which is - * overwritten with how much of encodedValues is - * used. * @return Returns the number of glyphs consumed. */ - size_t glyphsToPDFFontEncoding(const uint16_t* glyphIDs, size_t numGlyphs, - void* encodedValues, size_t* encodedLength); + size_t glyphsToPDFFontEncoding(uint16_t* glyphIDs, size_t numGlyphs); /** Get the font resource for the passed font ID and glyphID. The * reference count of the object is incremented and it is the caller's diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp index cf6a68e3d9..d0f32ac338 100644 --- a/src/pdf/SkPDFDevice.cpp +++ b/src/pdf/SkPDFDevice.cpp @@ -314,24 +314,21 @@ void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, SkPaint textPaint = calculateTextPaint(paint); updateGSFromPaint(textPaint, true); - // Make sure we have a glyph id encoding. - SkAutoFree glyphStorage; - uint16_t* glyphIDs; - size_t numGlyphs; + // We want the text in glyph id encoding and a writable buffer, so we end + // up making a copy either way. + size_t numGlyphs = paint.textToGlyphs(text, len, NULL); + uint16_t* glyphIDs = + (uint16_t*)sk_malloc_flags(numGlyphs * 2, + SK_MALLOC_TEMP | SK_MALLOC_THROW); + SkAutoFree autoFreeGlyphIDs(glyphIDs); if (paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding) { - numGlyphs = paint.textToGlyphs(text, len, NULL); - glyphIDs = (uint16_t*)sk_malloc_flags(numGlyphs * 2, - SK_MALLOC_TEMP | SK_MALLOC_THROW); - glyphStorage.set(glyphIDs); paint.textToGlyphs(text, len, glyphIDs); textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); } else { SkASSERT((len & 1) == 0); - numGlyphs = len / 2; - glyphIDs = (uint16_t*)text; + SkASSERT(len / 2 == numGlyphs); + memcpy(glyphIDs, text, len); } - SkAutoFree encodedStorage( - sk_malloc_flags(numGlyphs * 2, SK_MALLOC_TEMP | SK_MALLOC_THROW)); SkScalar width; SkScalar* widthPtr = NULL; @@ -346,16 +343,13 @@ void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, while (numGlyphs > consumedGlyphCount) { updateFont(textPaint, glyphIDs[consumedGlyphCount]); SkPDFFont* font = fGraphicStack[fGraphicStackIndex].fFont; - size_t encodedLength = numGlyphs * 2; - consumedGlyphCount += font->glyphsToPDFFontEncoding( - glyphIDs + consumedGlyphCount, numGlyphs - consumedGlyphCount, - encodedStorage.get(), &encodedLength); - if (font->multiByteGlyphs()) - encodedLength /= 2; - fContent.append( - SkPDFString::formatString((const uint16_t*)encodedStorage.get(), - encodedLength, - font->multiByteGlyphs())); + size_t availableGlyphs = + font->glyphsToPDFFontEncoding(glyphIDs + consumedGlyphCount, + numGlyphs - consumedGlyphCount); + fContent.append(SkPDFString::formatString(glyphIDs + consumedGlyphCount, + availableGlyphs, + font->multiByteGlyphs())); + consumedGlyphCount += availableGlyphs; fContent.append(" Tj\n"); } fContent.append("ET\n"); @@ -410,10 +404,8 @@ void SkPDFDevice::drawPosText(const SkDraw&, const void* text, size_t len, updateFont(textPaint, glyphIDs[0]); for (size_t i = 0; i < numGlyphs; i++) { SkPDFFont* font = fGraphicStack[fGraphicStackIndex].fFont; - uint16_t encodedValue; - size_t encodedLength = 2; - if (font->glyphsToPDFFontEncoding(glyphIDs + i, 1, &encodedValue, - &encodedLength) == 0) { + uint16_t encodedValue = glyphIDs[i]; + if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { updateFont(textPaint, glyphIDs[i]); i--; continue; diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp index d1c142fec9..c7bbebac3f 100644 --- a/src/pdf/SkPDFFont.cpp +++ b/src/pdf/SkPDFFont.cpp @@ -329,30 +329,21 @@ bool SkPDFFont::multiByteGlyphs() { return fMultiByteGlyphs; } -size_t SkPDFFont::glyphsToPDFFontEncoding(const uint16_t* glyphIDs, - size_t numGlyphs, void* encodedValues, - size_t* encodedLength) { - if (numGlyphs * 2 > *encodedLength) - numGlyphs = *encodedLength / 2; - - // A font with multibyte glyphs will support all glyph IDs in a single font, - // shortcut if we can. +size_t SkPDFFont::glyphsToPDFFontEncoding(uint16_t* glyphIDs, + size_t numGlyphs) { + // A font with multibyte glyphs will support all glyph IDs in a single font. if (fMultiByteGlyphs) { - *encodedLength = numGlyphs * 2; - memcpy(encodedValues, glyphIDs, *encodedLength); - } else { - char* output = (char*) encodedValues; - for (size_t i = 0; i < numGlyphs; i++) { - if (glyphIDs[i] == 0) { - output[i] = 0; - continue; - } - if (glyphIDs[i] < fFirstGlyphID || glyphIDs[i] > fLastGlyphID) { - numGlyphs = i; - break; - } - output[i] = glyphIDs[i] - fFirstGlyphID + 1; + return numGlyphs; + } + + for (size_t i = 0; i < numGlyphs; i++) { + if (glyphIDs[i] == 0) { + continue; } + if (glyphIDs[i] < fFirstGlyphID || glyphIDs[i] > fLastGlyphID) { + return i; + } + glyphIDs[i] -= (fFirstGlyphID - 1); } return numGlyphs;