Version 2.0.0: update sources
[jvcard.git] / src / com / googlecode / lanterna / terminal / swing / AWTTerminalFontConfiguration.java
diff --git a/src/com/googlecode/lanterna/terminal/swing/AWTTerminalFontConfiguration.java b/src/com/googlecode/lanterna/terminal/swing/AWTTerminalFontConfiguration.java
deleted file mode 100644 (file)
index ba3b0ea..0000000
+++ /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 <http://www.gnu.org/licenses/>.
- *
- * 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<String> MONOSPACE_CHECK_OVERRIDE = Collections.unmodifiableSet(new HashSet<String>(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<Font> 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<Font> 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<Font> 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<Font> windowsFonts = getDefaultWindowsFonts();
-            return windowsFonts.toArray(new Font[windowsFonts.size()]);
-        }
-        else if(osName.contains("linux")) {
-            List<Font> linuxFonts = getDefaultLinuxFonts();
-            return linuxFonts.toArray(new Font[linuxFonts.size()]);
-        }
-        else {
-            List<Font> 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<Font> result = new ArrayList<Font>(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<Font> 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<Font>(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<Character> SYMBOLS_CACHE = new HashSet<Character>();
-    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);
-    }
-}