diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/image_generator/Android.bp | 1 | ||||
-rw-r--r-- | tools/image_generator/ImageGenerator.java | 86 |
2 files changed, 35 insertions, 52 deletions
diff --git a/tools/image_generator/Android.bp b/tools/image_generator/Android.bp index ce6e277bc..2afdd5a84 100644 --- a/tools/image_generator/Android.bp +++ b/tools/image_generator/Android.bp @@ -19,6 +19,7 @@ java_library_host { static_libs: [ "commons-cli-1.2", + "icu4j-host", ], srcs: [ diff --git a/tools/image_generator/ImageGenerator.java b/tools/image_generator/ImageGenerator.java index 9d882678a..50a498456 100644 --- a/tools/image_generator/ImageGenerator.java +++ b/tools/image_generator/ImageGenerator.java @@ -16,6 +16,8 @@ package com.android.recovery.tools; +import com.ibm.icu.text.BreakIterator; + import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.HelpFormatter; @@ -44,7 +46,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.StringTokenizer; import java.util.TreeMap; import java.util.logging.Level; import java.util.logging.Logger; @@ -91,7 +92,7 @@ public class ImageGenerator { // 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"; @@ -153,22 +154,6 @@ public class ImageGenerator { } }; - // Languages that breaks on arbitrary characters. - // TODO(xunchang) switch to icu library if possible. For example, for Thai and Khmer, there is - // no space between words; and word breaking is based on grammatical analysis and on word - // matching in dictionaries. - private static final Set<String> LOGOGRAM_LANGUAGE = - new HashSet<String>() { - { - add("ja"); // Japanese - add("km"); // Khmer - add("ko"); // Korean - add("lo"); // Lao - add("th"); // Thai - add("zh"); // Chinese - } - }; - /** Exception to indicate the failure to find the translated text strings. */ public static class LocalizedStringNotFoundException extends Exception { public LocalizedStringNotFoundException(String message) { @@ -229,8 +214,9 @@ public class ImageGenerator { 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) { @@ -244,6 +230,11 @@ public class ImageGenerator { 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. */ @@ -408,16 +399,20 @@ public class ImageGenerator { "Can not find the font file " + fontName + " for language " + language); } - /** Separates the text string by spaces and wraps it by words. */ - private WrappedTextInfo wrapTextByWords(String text, FontMetrics metrics) { + /** Wraps the text with a maximum of mImageWidth pixels per line. */ + private WrappedTextInfo wrapText(String text, FontMetrics metrics) { WrappedTextInfo info = new WrappedTextInfo(); - StringTokenizer st = new StringTokenizer(text, " \n"); + + BreakIterator lineBoundary = BreakIterator.getLineInstance(); + lineBoundary.setText(text); int lineWidth = 0; // Width of the processed words of the current line. + int start = lineBoundary.first(); StringBuilder line = new StringBuilder(); - while (st.hasMoreTokens()) { - String token = st.nextToken(); - int tokenWidth = metrics.stringWidth(token + " "); + for (int end = lineBoundary.next(); end != BreakIterator.DONE; + start = end, end = lineBoundary.next()) { + String token = text.substring(start, end); + int tokenWidth = metrics.stringWidth(token); // Handles the width mismatch of the word "Android" between different fonts. if (token.contains(ANDROID_STRING) && metrics.getFont().canDisplayUpTo(ANDROID_STRING) != -1) { @@ -430,7 +425,7 @@ public class ImageGenerator { line = new StringBuilder(); lineWidth = 0; } - line.append(token).append(" "); + line.append(token); lineWidth += tokenWidth; } @@ -439,27 +434,9 @@ public class ImageGenerator { return info; } - /** One character is a word for CJK. */ - private WrappedTextInfo wrapTextByCharacters(String text, FontMetrics metrics) { - WrappedTextInfo info = new WrappedTextInfo(); - // TODO (xunchang) handle the text wrapping with logogram language mixed with latin. - StringBuilder line = new StringBuilder(); - for (char token : text.toCharArray()) { - if (metrics.stringWidth(line + Character.toString(token)) > mImageWidth) { - info.addLine(line.toString(), metrics.stringWidth(line.toString()), - metrics.getFont(), null); - line = new StringBuilder(); - } - line.append(token); - } - info.addLine(line.toString(), metrics.stringWidth(line.toString()), metrics.getFont(), - null); - - return info; - } - /** - * Wraps the text with a maximum of mImageWidth pixels per line. + * 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 @@ -467,12 +444,17 @@ public class ImageGenerator { * @return a WrappedTextInfo class with the width of each AttributedString smaller than * mImageWidth pixels */ - private WrappedTextInfo wrapText(String text, FontMetrics metrics, String language) { - if (LOGOGRAM_LANGUAGE.contains(language)) { - return wrapTextByCharacters(text, metrics); + 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 wrapTextByWords(text, metrics); + return result; } /** @@ -516,7 +498,7 @@ public class ImageGenerator { throws IOException, FontFormatException { Graphics2D graphics = createGraphics(locale); FontMetrics fontMetrics = graphics.getFontMetrics(); - WrappedTextInfo wrappedTextInfo = wrapText(text, fontMetrics, locale.getLanguage()); + WrappedTextInfo wrappedTextInfo = processAndWrapText(text, fontMetrics); int textWidth = 0; for (WrappedTextInfo.LineInfo lineInfo : wrappedTextInfo.mWrappedLines) { @@ -551,7 +533,7 @@ public class ImageGenerator { Graphics2D graphics = createGraphics(locale); FontMetrics fontMetrics = graphics.getFontMetrics(); - WrappedTextInfo wrappedTextInfo = wrapText(text, fontMetrics, locale.getLanguage()); + 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. |