Merge "ImageGenerator: Handle special characters in xml files" am: 697003dbce am: f2099b7872
am: 2a0f71627e

Change-Id: I27f54dd877eab5be5ea8170e2923cf8de7fe97a4
diff --git a/tools/image_generator/ImageGenerator.java b/tools/image_generator/ImageGenerator.java
index 19d187d..50a4984 100644
--- a/tools/image_generator/ImageGenerator.java
+++ b/tools/image_generator/ImageGenerator.java
@@ -92,7 +92,7 @@
 
     // Some localized font cannot draw the word "Android" and some PUNCTUATIONS; we need to fall
     // back to use our default latin font instead.
-    private static final char[] PUNCTUATIONS = {',', ';', '.', '!' };
+    private static final char[] PUNCTUATIONS = {',', ';', '.', '!', '?'};
 
     private static final String ANDROID_STRING = "Android";
 
@@ -214,8 +214,9 @@
                             index + ANDROID_STRING.length());
                 }
 
-                // Adds the attribute to use default font to draw the PUNCTUATIONS ", . !"
+                // Adds the attribute to use default font to draw the PUNCTUATIONS ", . ; ! ?"
                 for (char punctuation : PUNCTUATIONS) {
+                    // TODO (xunchang) handle the RTL language that has different directions for '?'
                     if (text.indexOf(punctuation) != -1 && !textFont.canDisplay(punctuation)) {
                         int index = 0;
                         while ((index = text.indexOf(punctuation, index)) != -1) {
@@ -229,6 +230,11 @@
 
             mWrappedLines.add(new LineInfo(attributedText, width));
         }
+
+        /** Merges two WrappedTextInfo. */
+        public void addLines(WrappedTextInfo other) {
+            mWrappedLines.addAll(other.mWrappedLines);
+        }
     }
 
     /** Initailizes the fields of the image image. */
@@ -393,15 +399,7 @@
                 "Can not find the font file " + fontName + " for language " + language);
     }
 
-    /**
-     * Wraps the text with a maximum of mImageWidth pixels per line.
-     *
-     * @param text the string representation of text to wrap
-     * @param metrics the metrics of the Font used to draw the text; it gives the width in pixels of
-     *     the text given its string representation
-     * @return a WrappedTextInfo class with the width of each AttributedString smaller than
-     *     mImageWidth pixels
-     */
+    /** Wraps the text with a maximum of mImageWidth pixels per line. */
     private WrappedTextInfo wrapText(String text, FontMetrics metrics) {
         WrappedTextInfo info = new WrappedTextInfo();
 
@@ -437,6 +435,29 @@
     }
 
     /**
+     * Handles the special characters of the raw text embedded in the xml file; and wraps the text
+     * with a maximum of mImageWidth pixels per line.
+     *
+     * @param text the string representation of text to wrap
+     * @param metrics the metrics of the Font used to draw the text; it gives the width in pixels of
+     *     the text given its string representation
+     * @return a WrappedTextInfo class with the width of each AttributedString smaller than
+     *     mImageWidth pixels
+     */
+    private WrappedTextInfo processAndWrapText(String text, FontMetrics metrics) {
+        // Apostrophe is escaped in the xml file.
+        String processed = text.replace("\\'", "'");
+        // The separator "\n\n" indicates a new line in the text.
+        String[] lines = processed.split("\\\\n\\\\n");
+        WrappedTextInfo result = new WrappedTextInfo();
+        for (String line : lines) {
+            result.addLines(wrapText(line, metrics));
+        }
+
+        return result;
+    }
+
+    /**
      * Encodes the information of the text image for |locale|. According to minui/resources.cpp, the
      * width, height and locale of the image is decoded as: int w = (row[1] << 8) | row[0]; int h =
      * (row[3] << 8) | row[2]; __unused int len = row[4]; char* loc =
@@ -477,7 +498,7 @@
             throws IOException, FontFormatException {
         Graphics2D graphics = createGraphics(locale);
         FontMetrics fontMetrics = graphics.getFontMetrics();
-        WrappedTextInfo wrappedTextInfo = wrapText(text, fontMetrics);
+        WrappedTextInfo wrappedTextInfo = processAndWrapText(text, fontMetrics);
 
         int textWidth = 0;
         for (WrappedTextInfo.LineInfo lineInfo : wrappedTextInfo.mWrappedLines) {
@@ -512,7 +533,7 @@
 
         Graphics2D graphics = createGraphics(locale);
         FontMetrics fontMetrics = graphics.getFontMetrics();
-        WrappedTextInfo wrappedTextInfo = wrapText(text, fontMetrics);
+        WrappedTextInfo wrappedTextInfo = processAndWrapText(text, fontMetrics);
 
         // Marks the start y offset for the text image of current locale; and reserves one line to
         // encode the image metadata.