[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:
parent
58b28fb749
commit
0129410fbe
@ -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
|
||||
|
@ -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;
|
||||
if (paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding) {
|
||||
numGlyphs = paint.textToGlyphs(text, len, NULL);
|
||||
glyphIDs = (uint16_t*)sk_malloc_flags(numGlyphs * 2,
|
||||
// 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);
|
||||
glyphStorage.set(glyphIDs);
|
||||
SkAutoFree autoFreeGlyphIDs(glyphIDs);
|
||||
if (paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding) {
|
||||
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,
|
||||
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;
|
||||
|
@ -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;
|
||||
return numGlyphs;
|
||||
}
|
||||
|
||||
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 i;
|
||||
}
|
||||
glyphIDs[i] -= (fFirstGlyphID - 1);
|
||||
}
|
||||
|
||||
return numGlyphs;
|
||||
|
Loading…
Reference in New Issue
Block a user