[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
diff --git a/include/pdf/SkPDFFont.h b/include/pdf/SkPDFFont.h
index bfa620b..e2b5093 100644
--- a/include/pdf/SkPDFFont.h
+++ b/include/pdf/SkPDFFont.h
@@ -49,21 +49,15 @@
      */
     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 cf6a68e..d0f32ac 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -314,24 +314,21 @@
     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 @@
     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 @@
     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 d1c142f..c7bbeba 100644
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -329,30 +329,21 @@
     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;