1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.assetstudiolib; 18 19 import java.awt.Color; 20 import java.awt.Font; 21 import java.awt.Graphics2D; 22 import java.awt.RenderingHints; 23 import java.awt.font.FontRenderContext; 24 import java.awt.font.TextLayout; 25 import java.awt.geom.Rectangle2D; 26 import java.awt.image.BufferedImage; 27 28 /** 29 * A set of utility classes for rendering text to a {@link BufferedImage}, suitable for use as a 30 * source image to {@link GraphicGenerator} objects. 31 */ 32 public class TextRenderUtil { 33 /** 34 * Renders the given string with the provided {@link Options} to a 35 * {@link BufferedImage}. 36 * 37 * @param text The text to render. 38 * @param paddingPercentage If nonzero, a percentage of the width or height 39 * (whichever is smaller) to add as padding around the text 40 * @param options The optional parameters for rendering the text. 41 * @return An image, suitable for use as an input to a 42 * {@link GraphicGenerator}. 43 */ 44 public static BufferedImage renderTextImage(String text, int paddingPercentage, 45 Options options) { 46 if (options == null) { 47 options = new Options(); 48 } 49 50 BufferedImage tempImage = Util.newArgbBufferedImage(1, 1); 51 if (text == null || text.equals("")) { 52 return tempImage; 53 } 54 55 Graphics2D tempG = (Graphics2D) tempImage.getGraphics(); 56 57 Font font = options.font; 58 if (font == null) { 59 font = new Font(options.fontName, options.fontStyle, options.fontSize); 60 // Map<TextAttribute, Object> map = new Hashtable<TextAttribute, Object>(); 61 // map.put(TextAttribute.TRACKING, 0.3); 62 // font = font.deriveFont(map); 63 } 64 65 FontRenderContext frc = tempG.getFontRenderContext(); 66 67 TextLayout layout = new TextLayout(text, font, frc); 68 Rectangle2D bounds = layout.getBounds(); 69 70 // The padding is a percentage relative to the overall minimum of the width or height 71 if (paddingPercentage != 0) { 72 double minDimension = Math.min(bounds.getWidth(), bounds.getHeight()); 73 double delta = minDimension * paddingPercentage / 100; 74 bounds.setRect(bounds.getMinX() - delta, bounds.getMinY() - delta, 75 bounds.getWidth() + 2 * delta, bounds.getHeight() + 2 * delta); 76 } 77 78 BufferedImage image = Util.newArgbBufferedImage( 79 Math.max(1, (int) bounds.getWidth()), Math.max(1, (int) bounds.getHeight())); 80 Graphics2D g = (Graphics2D) image.getGraphics(); 81 g.setColor(new Color(options.foregroundColor, true)); 82 g.setFont(font); 83 84 g.setRenderingHint( 85 RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 86 g.setRenderingHint( 87 RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 88 89 g.drawString(text, (float) -bounds.getX(), (float) -bounds.getY()); 90 91 g.dispose(); 92 tempG.dispose(); 93 94 return image; 95 } 96 97 /** 98 * The parameters for text rendering. There are no required values so a <code>new 99 * Options()</code> object is considered valid. 100 */ 101 public static class Options { 102 // We use a large default font size to reduce the need to scale generated images up. 103 // TODO: Instead, a graphic generator should use a different source image for each density. 104 private static final int DEFAULT_FONT_SIZE = 512; 105 106 /** Foreground color to render text with, as an AARRGGBB packed integer */ 107 public int foregroundColor = 0xFFFFFFFF; 108 109 /** 110 * The optional {@link Font} to use. If null, a {@link Font} object will be generated using 111 * the other options. 112 */ 113 public Font font = null; 114 115 /** 116 * The optional font name. Defaults to {@link Font#SERIF}. 117 * 118 * @see Font#Font(String, int, int) 119 */ 120 public String fontName = Font.SERIF; 121 122 /** 123 * The optional font styling (bold and/or italic). Defaults to no styling. 124 * 125 * @see Font#Font(String, int, int) 126 */ 127 public int fontStyle = 0; 128 129 /** 130 * The optional font size, in points. Defaults to a very large font size, to prevent 131 * up-scaling rendered text. 132 * 133 * @see Font#Font(String, int, int) 134 */ 135 public int fontSize = DEFAULT_FONT_SIZE; 136 } 137 } 138