• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
renderTextImage(String text, int paddingPercentage, Options options)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