X-Git-Url: http://git.nikiroo.be/?p=jvcard.git;a=blobdiff_plain;f=src%2Fcom%2Fgooglecode%2Flanterna%2Fterminal%2Fswing%2FAWTTerminalFontConfiguration.java;fp=src%2Fcom%2Fgooglecode%2Flanterna%2Fterminal%2Fswing%2FAWTTerminalFontConfiguration.java;h=0000000000000000000000000000000000000000;hp=ba3b0ea7c8934d9792a3547a867f682f53b7bcd3;hb=f06c81000632cfb5f525ca458f719338f55f9f66;hpb=a73a906356c971b080c36368e71a15d87e8b8d31 diff --git a/src/com/googlecode/lanterna/terminal/swing/AWTTerminalFontConfiguration.java b/src/com/googlecode/lanterna/terminal/swing/AWTTerminalFontConfiguration.java deleted file mode 100644 index ba3b0ea..0000000 --- a/src/com/googlecode/lanterna/terminal/swing/AWTTerminalFontConfiguration.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * This file is part of lanterna (http://code.google.com/p/lanterna/). - * - * lanterna is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * Copyright (C) 2010-2015 Martin - */ -package com.googlecode.lanterna.terminal.swing; - -import com.googlecode.lanterna.Symbols; -import com.googlecode.lanterna.TextCharacter; - -import java.awt.*; -import java.awt.font.FontRenderContext; -import java.awt.geom.Rectangle2D; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.*; -import java.util.List; - -/** - * This class encapsulates the font information used by an {@link AWTTerminal}. By customizing this class, you can - * choose which fonts are going to be used by an {@link AWTTerminal} component and some other related settings. - * @author martin - */ -public class AWTTerminalFontConfiguration { - - /** - * Controls how the SGR bold will take effect when enabled on a character. Mainly this is controlling if the - * character should be rendered with a bold font or not. The reason for this is that some characters, notably the - * lines and double-lines in defined in Symbol, usually doesn't look very good with bold font when you try to - * construct a GUI. - */ - public enum BoldMode { - /** - * All characters with SGR Bold enabled will be rendered using a bold font - */ - EVERYTHING, - /** - * All characters with SGR Bold enabled, except for the characters defined as constants in Symbols class, will - * be rendered using a bold font - */ - EVERYTHING_BUT_SYMBOLS, - /** - * Bold font will not be used for characters with SGR bold enabled - */ - NOTHING, - ; - } - - private static final Set MONOSPACE_CHECK_OVERRIDE = Collections.unmodifiableSet(new HashSet(Arrays.asList( - "VL Gothic Regular", - "NanumGothic", - "WenQuanYi Zen Hei Mono", - "WenQuanYi Zen Hei", - "AR PL UMing TW", - "AR PL UMing HK", - "AR PL UMing CN" - ))); - - private static List getDefaultWindowsFonts() { - return Collections.unmodifiableList(Arrays.asList( - new Font("Courier New", Font.PLAIN, 14), //Monospaced can look pretty bad on Windows, so let's override it - new Font("Monospaced", Font.PLAIN, 14))); - } - - private static List getDefaultLinuxFonts() { - return Collections.unmodifiableList(Arrays.asList( - new Font("DejaVu Sans Mono", Font.PLAIN, 14), - new Font("Monospaced", Font.PLAIN, 14), - //Below, these should be redundant (Monospaced is supposed to catch-all) - // but Java 6 seems to have issues with finding monospaced fonts sometimes - new Font("Ubuntu Mono", Font.PLAIN, 14), - new Font("FreeMono", Font.PLAIN, 14), - new Font("Liberation Mono", Font.PLAIN, 14), - new Font("VL Gothic Regular", Font.PLAIN, 14), - new Font("NanumGothic", Font.PLAIN, 14), - new Font("WenQuanYi Zen Hei Mono", Font.PLAIN, 14), - new Font("WenQuanYi Zen Hei", Font.PLAIN, 14), - new Font("AR PL UMing TW", Font.PLAIN, 14), - new Font("AR PL UMing HK", Font.PLAIN, 14), - new Font("AR PL UMing CN", Font.PLAIN, 14))); - } - - private static List getDefaultFonts() { - return Collections.unmodifiableList(Collections.singletonList( - new Font("Monospaced", Font.PLAIN, 14))); - } - - protected static Font[] selectDefaultFont() { - String osName = System.getProperty("os.name", "").toLowerCase(); - if(osName.contains("win")) { - List windowsFonts = getDefaultWindowsFonts(); - return windowsFonts.toArray(new Font[windowsFonts.size()]); - } - else if(osName.contains("linux")) { - List linuxFonts = getDefaultLinuxFonts(); - return linuxFonts.toArray(new Font[linuxFonts.size()]); - } - else { - List defaultFonts = getDefaultFonts(); - return defaultFonts.toArray(new Font[defaultFonts.size()]); - } - } - - /** - * This is the default font settings that will be used if you don't specify anything - */ - public static AWTTerminalFontConfiguration getDefault() { - return newInstance(filterMonospaced(selectDefaultFont())); - } - - /** - * Given an array of fonts, returns another array with only the ones that are monospaced. The fonts in the result - * will have the same order as in which they came in. A font is considered monospaced if the width of 'i' and 'W' is - * the same. - * @param fonts Fonts to filter monospaced fonts from - * @return Array with the fonts from the input parameter that were monospaced - */ - public static Font[] filterMonospaced(Font... fonts) { - List result = new ArrayList(fonts.length); - for(Font font: fonts) { - if (isFontMonospaced(font)) { - result.add(font); - } - } - return result.toArray(new Font[result.size()]); - } - - /** - * Creates a new font configuration from a list of fonts in order of priority. This works by having the terminal - * attempt to draw each character with the fonts in the order they are specified in and stop once we find a font - * that can actually draw the character. For ASCII characters, it's very likely that the first font will always be - * used. - * @param fontsInOrderOfPriority Fonts to use when drawing text, in order of priority - * @return Font configuration built from the font list - */ - @SuppressWarnings("WeakerAccess") - public static AWTTerminalFontConfiguration newInstance(Font... fontsInOrderOfPriority) { - return new AWTTerminalFontConfiguration(true, BoldMode.EVERYTHING_BUT_SYMBOLS, fontsInOrderOfPriority); - } - - private final List fontPriority; - private final int fontWidth; - private final int fontHeight; - private final boolean useAntiAliasing; - private final BoldMode boldMode; - - @SuppressWarnings("WeakerAccess") - protected AWTTerminalFontConfiguration(boolean useAntiAliasing, BoldMode boldMode, Font... fontsInOrderOfPriority) { - if(fontsInOrderOfPriority == null || fontsInOrderOfPriority.length == 0) { - throw new IllegalArgumentException("Must pass in a valid list of fonts to SwingTerminalFontConfiguration"); - } - this.useAntiAliasing = useAntiAliasing; - this.boldMode = boldMode; - this.fontPriority = new ArrayList(Arrays.asList(fontsInOrderOfPriority)); - this.fontWidth = getFontWidth(fontPriority.get(0)); - this.fontHeight = getFontHeight(fontPriority.get(0)); - - //Make sure all the fonts are monospace - for(Font font: fontPriority) { - if(!isFontMonospaced(font)) { - throw new IllegalArgumentException("Font " + font + " isn't monospaced!"); - } - } - - //Make sure all lower-priority fonts are less or equal in width and height, shrink if necessary - for(int i = 1; i < fontPriority.size(); i++) { - Font font = fontPriority.get(i); - while(getFontWidth(font) > fontWidth || getFontHeight(font) > fontHeight) { - float newSize = font.getSize2D() - 0.5f; - if(newSize < 0.01) { - throw new IllegalStateException("Unable to shrink font " + (i+1) + " to fit the size of highest priority font " + fontPriority.get(0)); - } - font = font.deriveFont(newSize); - fontPriority.set(i, font); - } - } - } - - Font getFontForCharacter(TextCharacter character) { - Font normalFont = getFontForCharacter(character.getCharacter()); - if(boldMode == BoldMode.EVERYTHING || (boldMode == BoldMode.EVERYTHING_BUT_SYMBOLS && isNotASymbol(character.getCharacter()))) { - if(character.isBold()) { - normalFont = normalFont.deriveFont(Font.BOLD); - } - } - return normalFont; - } - - private Font getFontForCharacter(char c) { - for(Font font: fontPriority) { - if(font.canDisplay(c)) { - return font; - } - } - //No available font here, what to do...? - return fontPriority.get(0); - } - - int getFontWidth() { - return fontWidth; - } - - int getFontHeight() { - return fontHeight; - } - - boolean isAntiAliased() { - return useAntiAliasing; - } - - private static boolean isFontMonospaced(Font font) { - if(MONOSPACE_CHECK_OVERRIDE.contains(font.getName())) { - return true; - } - FontRenderContext frc = new FontRenderContext( - null, - RenderingHints.VALUE_TEXT_ANTIALIAS_OFF, - RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT); - Rectangle2D iBounds = font.getStringBounds("i", frc); - Rectangle2D mBounds = font.getStringBounds("W", frc); - return iBounds.getWidth() == mBounds.getWidth(); - } - - private int getFontWidth(Font font) { - return (int)font.getStringBounds("W", getFontRenderContext()).getWidth(); - } - - private int getFontHeight(Font font) { - return (int)font.getStringBounds("W", getFontRenderContext()).getHeight(); - } - - private FontRenderContext getFontRenderContext() { - return new FontRenderContext( - null, - useAntiAliasing ? - RenderingHints.VALUE_TEXT_ANTIALIAS_ON : RenderingHints.VALUE_TEXT_ANTIALIAS_OFF, - RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT); - } - - - private static final Set SYMBOLS_CACHE = new HashSet(); - static { - for(Field field: Symbols.class.getFields()) { - if(field.getType() == char.class && - (field.getModifiers() & Modifier.FINAL) != 0 && - (field.getModifiers() & Modifier.STATIC) != 0) { - try { - SYMBOLS_CACHE.add(field.getChar(null)); - } - catch(IllegalArgumentException ignore) { - //Should never happen! - } - catch(IllegalAccessException ignore) { - //Should never happen! - } - } - } - } - - private boolean isNotASymbol(char character) { - return !SYMBOLS_CACHE.contains(character); - } -}