[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
This commit is contained in:
vandebo@chromium.org 2011-02-28 19:52:18 +00:00
parent 58b28fb749
commit 0129410fbe
3 changed files with 35 additions and 58 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;