Проверка того, является ли шрифт моноширинным в Java - PullRequest
12 голосов
/ 28 мая 2009

Я пытаюсь перечислить все моноширинные шрифты, доступные на компьютере пользователя. Я могу получить все семейства шрифтов в Swing через:

String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment()
                                    .getAvailableFontFamilyNames();

Есть ли способ выяснить, какие из них моноширинные?

Заранее спасибо.

Ответы [ 5 ]

6 голосов
/ 20 июня 2013

Более простой метод, который не требует создания BufferedImage для получения объекта Graphics и т. Д.:

    Font fonts[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
    List<Font> monoFonts1 = new ArrayList<>();

    FontRenderContext frc = new FontRenderContext(null, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT, RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT);
    for (Font font : fonts) {
        Rectangle2D iBounds = font.getStringBounds("i", frc);
        Rectangle2D mBounds = font.getStringBounds("m", frc);
        if (iBounds.getWidth() == mBounds.getWidth()) {
            monoFonts1.add(font);
        }
    }
4 голосов
/ 28 мая 2009

Вы можете использовать метод getWidths () класса FontMetrics . Согласно JavaDoc:

Получает ширину продвижения первых 256 символов в шрифте. Прогресс - это расстояние от крайней левой точки до крайней правой точки базовой линии персонажа. Обратите внимание, что продвижение строки не обязательно является суммой достижений ее символов.

Вы можете использовать метод charWidth(char) класса FontMetrics . Например:

Set<String> monospaceFontFamilyNames = new HashSet<String>();

GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontFamilyNames = graphicsEnvironment.getAvailableFontFamilyNames();

BufferedImage bufferedImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics graphics = bufferedImage.createGraphics();

for (String fontFamilyName : fontFamilyNames) {
    boolean isMonospaced = true;

    int fontStyle = Font.PLAIN;
    int fontSize = 12;
    Font font = new Font(fontFamilyName, fontStyle, fontSize);
    FontMetrics fontMetrics = graphics.getFontMetrics(font);

    int firstCharacterWidth = 0;
    boolean hasFirstCharacterWidth = false;
    for (int codePoint = 0; codePoint < 128; codePoint++) { 
        if (Character.isValidCodePoint(codePoint) && (Character.isLetter(codePoint) || Character.isDigit(codePoint))) {
            char character = (char) codePoint;
            int characterWidth = fontMetrics.charWidth(character);
            if (hasFirstCharacterWidth) {
                if (characterWidth != firstCharacterWidth) {
                    isMonospaced = false;
                    break;
                }
            } else {
                firstCharacterWidth = characterWidth;
                hasFirstCharacterWidth = true;
            }
        }
    }

    if (isMonospaced) {
        monospaceFontFamilyNames.add(fontFamilyName);
    }
}

graphics.dispose();
3 голосов
/ 28 мая 2009

Сравните нарисованные длины нескольких символов (m, i, 1,. Должен быть хорошим набором).

Для моноширинных шрифтов они все будут равны, для шрифтов переменной ширины они не будут.

1 голос
/ 28 мая 2009

Возможно, не подходит для вашего случая, но если вы просто хотите установить шрифт для моноширинного шрифта, используйте логическое имя шрифта:

Font mono = new Font("Monospaced", Font.PLAIN, 12);

Это будет гарантированный моноширинный шрифт в вашей системе.

1 голос
/ 28 мая 2009

Согласно этому ответу , Java не знает слишком много о базовых деталях шрифта, поэтому вам придется сделать некоторые сравнения размеров шрифта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...