Added more accurate font height utility methods. Moved font utility
methods into FontUtil class.
This commit is contained in:
parent
61f4f5a4de
commit
01e5eab0ca
279
src/dorkbox/util/FontUtil.java
Normal file
279
src/dorkbox/util/FontUtil.java
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright 2014 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.util;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* Java Font utilities
|
||||
*/
|
||||
public
|
||||
class FontUtil {
|
||||
/** Default location where all the fonts are stored */
|
||||
@Property
|
||||
public static String FONTS_LOCATION = "resources/fonts";
|
||||
|
||||
|
||||
/** All of the fonts in the {@link #FONTS_LOCATION} will be loaded by the Font manager */
|
||||
public static
|
||||
void loadAllFonts() {
|
||||
boolean isJava6 = OS.javaVersion == 6;
|
||||
|
||||
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
Enumeration<URL> fonts = LocationResolver.getResources(FONTS_LOCATION);
|
||||
|
||||
if (fonts.hasMoreElements()) {
|
||||
// skip the FIRST one, since we always know that the first one is the directory we asked for
|
||||
fonts.nextElement();
|
||||
|
||||
while (fonts.hasMoreElements()) {
|
||||
URL url = fonts.nextElement();
|
||||
InputStream is = null;
|
||||
|
||||
//noinspection TryWithIdenticalCatches
|
||||
try {
|
||||
String path = url.toURI()
|
||||
.getPath();
|
||||
|
||||
// only support TTF fonts (java6) and OTF fonts (7+).
|
||||
if (path.endsWith(".ttf") || (!isJava6 && path.endsWith(".otf"))) {
|
||||
is = url.openStream();
|
||||
|
||||
Font newFont = Font.createFont(Font.TRUETYPE_FONT, is);
|
||||
// fonts that ALREADY exist are not re-registered
|
||||
ge.registerFont(newFont);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
} catch (FontFormatException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets (or creates) a Font based on a specific system property. Remember: the FontManager caches system/loaded fonts, so we don't need
|
||||
* to ALSO cache them as well. see: https://stackoverflow.com/questions/6102602/java-awt-is-font-a-lightweight-object
|
||||
* <p>
|
||||
* Also remember that if requesting a BOLD hint for a font, the system will look for a font that is BOLD. If none are found, it
|
||||
* will then apply transforms to the specified font to create a font that is bold. Specifying a bold name AND a bold hint will not
|
||||
* "double bold" the font
|
||||
* <p></p>
|
||||
* For example:
|
||||
* <p>
|
||||
*
|
||||
* Font titleTextFont = SwingUtil.parseFont("Source Code Pro Bold 16");
|
||||
*
|
||||
* @param fontInfo This is the font "name style size", as a string. For example "Source Code Pro Bold BOLD 16"
|
||||
*
|
||||
* @return the specified font
|
||||
*/
|
||||
public static
|
||||
Font parseFont(final String fontInfo) {
|
||||
try {
|
||||
final int sizeIndex = fontInfo.lastIndexOf(" ");
|
||||
|
||||
String size = fontInfo.substring(sizeIndex + 1);
|
||||
|
||||
// hint is at most 6 (ITALIC) before sizeIndex - we can use this to our benefit.
|
||||
int styleIndex = fontInfo.indexOf(" ", sizeIndex - 7);
|
||||
String styleString = fontInfo.substring(styleIndex + 1, sizeIndex);
|
||||
int style = Font.PLAIN;
|
||||
|
||||
if (styleString.equalsIgnoreCase("bold")) {
|
||||
style = Font.BOLD;
|
||||
}
|
||||
else if (styleString.equalsIgnoreCase("italic")) {
|
||||
style = Font.ITALIC;
|
||||
}
|
||||
|
||||
String fontName = fontInfo.substring(0, styleIndex);
|
||||
|
||||
// this can be WRONG, in which case it will just error out
|
||||
//noinspection MagicConstant
|
||||
return new Font(fontName, style, Integer.parseInt(size));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to load font info from '" + fontInfo + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the correct font (in GENERAL) for a specified pixel height.
|
||||
*
|
||||
* @param font the font we are checking
|
||||
* @param height the height in pixels we want to get as close as possible to
|
||||
*
|
||||
* @return the font (derived from the specified font) that is as close as possible to the requested height. If our font-size is less
|
||||
* than the height, then the approach is from the low size (so the returned font will always fit inside the box)
|
||||
*/
|
||||
public static
|
||||
Font getFontForSpecificHeight(final Font font, final int height) {
|
||||
int size = font.getSize();
|
||||
Boolean lastAction = null;
|
||||
BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = image.createGraphics();
|
||||
|
||||
while (true) {
|
||||
Font fontCheck = new Font(font.getName(), Font.PLAIN, size);
|
||||
|
||||
FontMetrics metrics = g.getFontMetrics(fontCheck);
|
||||
Rectangle2D rect = metrics.getStringBounds("`Tj|┃", g); // `Tj|┃ are glyphs that are at the top/bottom of the fontset (usually)
|
||||
double testHeight = rect.getHeight();
|
||||
|
||||
if (testHeight < height && lastAction != Boolean.FALSE) {
|
||||
size++;
|
||||
lastAction = Boolean.TRUE;
|
||||
} else if (testHeight > height && lastAction != Boolean.TRUE) {
|
||||
size--;
|
||||
lastAction = Boolean.FALSE;
|
||||
} else {
|
||||
// either we are the exact size, or we are ONE font size to big/small (depending on what our initial guess was)
|
||||
g.dispose();
|
||||
return fontCheck;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the specified font height for a specific string
|
||||
*
|
||||
* @param font the font to use
|
||||
* @param string the string to get the size of
|
||||
*
|
||||
* @return the height of the string
|
||||
*/
|
||||
public static
|
||||
int getFontHeight(final Font font, final String string) {
|
||||
BufferedImage image = new BufferedImage(1, 1, 1);
|
||||
Graphics2D g = image.createGraphics();
|
||||
FontRenderContext frc = g.getFontRenderContext();
|
||||
GlyphVector gv = font.createGlyphVector(frc, string);
|
||||
int height = gv.getPixelBounds(null, 0, 0).height;
|
||||
g.dispose();
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum font height used by alpha-numeric characters ONLY
|
||||
*/
|
||||
public static
|
||||
int getAlphaNumbericFontHeight(final Font font) {
|
||||
// Because font metrics is based on a graphics context, we need to create a small, temporary image to determine the width and height
|
||||
BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = image.createGraphics();
|
||||
|
||||
FontMetrics metrics = g.getFontMetrics(font);
|
||||
int height = metrics.getAscent() + metrics.getDescent();
|
||||
g.dispose();
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum font height used by of ALL characters.
|
||||
*/
|
||||
public static
|
||||
int getFontHeight(final Font font) {
|
||||
// Because font metrics is based on a graphics context, we need to create a small, temporary image to determine the width and height
|
||||
BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = image.createGraphics();
|
||||
|
||||
FontMetrics metrics = g.getFontMetrics(font);
|
||||
int height = metrics.getMaxAscent() + metrics.getMaxDescent();
|
||||
|
||||
g.dispose();
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the specified text (with a font) and as an image
|
||||
*
|
||||
* @param font the specified font to render the image
|
||||
* @return a BufferedImage of the specified text, font, and color
|
||||
*/
|
||||
public static
|
||||
BufferedImage getFontAsImage(final Font font, String text, Color foregroundColor) {
|
||||
// Because font metrics is based on a graphics context, we need to create a small, temporary image to determine the width and height
|
||||
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = img.createGraphics();
|
||||
g2d.setFont(font);
|
||||
|
||||
FontMetrics fm = g2d.getFontMetrics();
|
||||
int width = fm.stringWidth(text);
|
||||
int height = fm.getHeight();
|
||||
g2d.dispose();
|
||||
|
||||
// make it square
|
||||
if (width > height) {
|
||||
height = width;
|
||||
} else {
|
||||
width = height;
|
||||
}
|
||||
|
||||
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
g2d = img.createGraphics();
|
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
|
||||
|
||||
g2d.setFont(font);
|
||||
fm = g2d.getFontMetrics();
|
||||
|
||||
g2d.setColor(foregroundColor);
|
||||
|
||||
// width/4 centers the text in the image
|
||||
g2d.drawString(text, width/4.0f, fm.getAscent());
|
||||
g2d.dispose();
|
||||
|
||||
return img;
|
||||
}
|
||||
}
|
@ -15,38 +15,27 @@
|
||||
*/
|
||||
package dorkbox.util;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Image;
|
||||
import java.awt.MouseInfo;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.HierarchyEvent;
|
||||
import java.awt.event.HierarchyListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.swing.AbstractButton;
|
||||
@ -57,19 +46,11 @@ import javax.swing.UIManager;
|
||||
|
||||
public
|
||||
class SwingUtil {
|
||||
|
||||
/** Default location where all the fonts are stored */
|
||||
@Property
|
||||
public static String FONTS_LOCATION = "resources/fonts";
|
||||
|
||||
static {
|
||||
/*
|
||||
* hack workaround for starting the Toolkit thread before any Timer stuff
|
||||
* javax.swing.Timer uses the Event Dispatch Thread, which is not
|
||||
* created until the Toolkit thread starts up. Using the Swing
|
||||
* Timer before starting this stuff starts up may get unexpected
|
||||
* results (such as taking a long time before the first timer
|
||||
* event).
|
||||
* hack workaround for starting the Toolkit thread before any Timer stuff javax.swing.Timer uses the Event Dispatch Thread, which is not
|
||||
* created until the Toolkit thread starts up. Using the Swing Timer before starting this stuff starts up may get unexpected
|
||||
* results (such as taking a long time before the first timer event).
|
||||
*/
|
||||
Toolkit.getDefaultToolkit();
|
||||
}
|
||||
@ -173,100 +154,6 @@ class SwingUtil {
|
||||
new Exception("Could not load " + lookAndFeel + ", it was not available.").printStackTrace();
|
||||
}
|
||||
|
||||
/** All of the fonts in the {@link #FONTS_LOCATION} will be loaded by the Font manager */
|
||||
public static
|
||||
void loadAllFonts() {
|
||||
boolean isJava6 = OS.javaVersion == 6;
|
||||
|
||||
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
Enumeration<URL> fonts = LocationResolver.getResources(FONTS_LOCATION);
|
||||
|
||||
if (fonts.hasMoreElements()) {
|
||||
// skip the FIRST one, since we always know that the first one is the directory we asked for
|
||||
fonts.nextElement();
|
||||
|
||||
while (fonts.hasMoreElements()) {
|
||||
URL url = fonts.nextElement();
|
||||
InputStream is = null;
|
||||
|
||||
//noinspection TryWithIdenticalCatches
|
||||
try {
|
||||
String path = url.toURI()
|
||||
.getPath();
|
||||
|
||||
// only support TTF fonts (java6) and OTF fonts (7+).
|
||||
if (path.endsWith(".ttf") || (!isJava6 && path.endsWith(".otf"))) {
|
||||
is = url.openStream();
|
||||
|
||||
Font newFont = Font.createFont(Font.TRUETYPE_FONT, is);
|
||||
// fonts that ALREADY exist are not re-registered
|
||||
ge.registerFont(newFont);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
} catch (FontFormatException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets (or creates) a Font based on a specific system property. Remember: the FontManager caches system/loaded fonts, so we don't need
|
||||
* to ALSO cache them as well. see: https://stackoverflow.com/questions/6102602/java-awt-is-font-a-lightweight-object
|
||||
* <p>
|
||||
* Also remember that if requesting a BOLD hint for a font, the system will look for a font that is BOLD. If none are found, it
|
||||
* will then apply transforms to the specified font to create a font that is bold. Specifying a bold name AND a bold hint will not
|
||||
* "double bold" the font
|
||||
* <p></p>
|
||||
* For example:
|
||||
* <p>
|
||||
*
|
||||
* Font titleTextFont = SwingUtil.parseFont("Source Code Pro Bold 16");
|
||||
*
|
||||
* @param fontInfo This is the font "name style size", as a string. For example "Source Code Pro Bold BOLD 16"
|
||||
*
|
||||
* @return the specified font
|
||||
*/
|
||||
public static
|
||||
Font parseFont(final String fontInfo) {
|
||||
try {
|
||||
final int sizeIndex = fontInfo.lastIndexOf(" ");
|
||||
|
||||
String size = fontInfo.substring(sizeIndex + 1);
|
||||
|
||||
// hint is at most 6 (ITALIC) before sizeIndex - we can use this to our benefit.
|
||||
int styleIndex = fontInfo.indexOf(" ", sizeIndex - 7);
|
||||
String styleString = fontInfo.substring(styleIndex + 1, sizeIndex);
|
||||
int style = Font.PLAIN;
|
||||
|
||||
if (styleString.equalsIgnoreCase("bold")) {
|
||||
style = Font.BOLD;
|
||||
}
|
||||
else if (styleString.equalsIgnoreCase("italic")) {
|
||||
style = Font.ITALIC;
|
||||
}
|
||||
|
||||
String fontName = fontInfo.substring(0, styleIndex);
|
||||
|
||||
// this can be WRONG, in which case it will just error out
|
||||
//noinspection MagicConstant
|
||||
return new Font(fontName, style, Integer.parseInt(size));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to load font info from '" + fontInfo + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
/** used when setting various icon components in the GUI to "nothing", since null doesn't work */
|
||||
public static final Image BLANK_ICON = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB_PRE);
|
||||
|
||||
@ -318,113 +205,6 @@ class SwingUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the correct font (in GENERAL) for a specified pixel height.
|
||||
*
|
||||
* @param font the font we are checking
|
||||
* @param height the height in pixels we want to get as close as possible to
|
||||
*
|
||||
* @return the font (derived from the specified font) that is as close as possible to the requested height. If our font-size is less
|
||||
* than the height, then the approach is from the low size (so the returned font will always fit inside the box)
|
||||
*/
|
||||
public static
|
||||
Font getFontForSpecificHeight(final Font font, final int height) {
|
||||
int size = font.getSize();
|
||||
Boolean lastAction = null;
|
||||
BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = image.createGraphics();
|
||||
|
||||
while (true) {
|
||||
Font fontCheck = new Font(font.getName(), Font.PLAIN, size);
|
||||
|
||||
FontMetrics metrics = g.getFontMetrics(fontCheck);
|
||||
Rectangle2D rect = metrics.getStringBounds("`Tj|┃", g); // `Tj|┃ are glyphs that are at the top/bottom of the fontset (usually)
|
||||
double testHeight = rect.getHeight();
|
||||
|
||||
if (testHeight < height && lastAction != Boolean.FALSE) {
|
||||
size++;
|
||||
lastAction = Boolean.TRUE;
|
||||
} else if (testHeight > height && lastAction != Boolean.TRUE) {
|
||||
size--;
|
||||
lastAction = Boolean.FALSE;
|
||||
} else {
|
||||
// either we are the exact size, or we are ONE font size to big/small (depending on what our initial guess was)
|
||||
g.dispose();
|
||||
return fontCheck;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the specified font height
|
||||
* @param font
|
||||
* @return
|
||||
*/
|
||||
public static
|
||||
int getFontHeight(final Font font) {
|
||||
// Because font metrics is based on a graphics context, we need to create a small, temporary image to determine the width and height
|
||||
BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = image.createGraphics();
|
||||
|
||||
FontMetrics metrics = g.getFontMetrics(font);
|
||||
Rectangle2D rect = metrics.getStringBounds("`Tj|┃", g); // `Tj|┃ are glyphs that are at the top/bottom of the fontset (usually)
|
||||
int testHeight = (int) rect.getHeight();
|
||||
|
||||
g.dispose();
|
||||
|
||||
return testHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the specified text (with a font) and as an image
|
||||
*
|
||||
* @param font the specified font to render the image
|
||||
* @return a BufferedImage of the specified text, font, and color
|
||||
*/
|
||||
public static
|
||||
BufferedImage getFontAsImage(final Font font, String text, Color foregroundColor) {
|
||||
// Because font metrics is based on a graphics context, we need to create a small, temporary image to determine the width and height
|
||||
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = img.createGraphics();
|
||||
g2d.setFont(font);
|
||||
|
||||
FontMetrics fm = g2d.getFontMetrics();
|
||||
int width = fm.stringWidth(text);
|
||||
int height = fm.getHeight();
|
||||
g2d.dispose();
|
||||
|
||||
// make it square
|
||||
if (width > height) {
|
||||
height = width;
|
||||
} else {
|
||||
width = height;
|
||||
}
|
||||
|
||||
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
g2d = img.createGraphics();
|
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
|
||||
|
||||
g2d.setFont(font);
|
||||
fm = g2d.getFontMetrics();
|
||||
|
||||
g2d.setColor(foregroundColor);
|
||||
|
||||
// width/4 centers the text in the image
|
||||
g2d.drawString(text, width/4.0f, fm.getAscent());
|
||||
g2d.dispose();
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the largest icon/image for a button (or other JComponent that has .setIcon(image) method) without affecting the size of the
|
||||
* button. An image that is any larger will require that the button increases it's height or width.
|
||||
|
Loading…
Reference in New Issue
Block a user