2009-05-28 15 views
10

Próbuję wyświetlić listę wszystkich czcionek o stałej szerokości dostępnych na komputerze użytkownika. Mogę uzyskać wszystkie rodziny czcionek w Swing przez:Sprawdzanie, czy czcionka jest w języku Java w stałej szerokości.

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

Czy istnieje sposób, aby dowiedzieć się, które z nich są w równych odstępach?

Z góry dziękuję.

Odpowiedz

3

Porównać narysowane długości kilku znaków (m, i, 1,. Powinno być dobrym zestawem).

Dla czcionek o stałej szerokości będą równe, dla czcionek o zmiennej szerokości nie będą.

+0

Możesz dodać przykładowy kod? – Jonik

+0

+1 za praktyczne i proste podejście; Używam i i m. –

1

Zgodnie z this response, Java nie wie zbyt wiele o podstawowych elementach czcionek, więc należy wykonać pewne porównania wymiarów czcionki.

4

Można użyć metody getWidths() klasy FontMetrics. Zgodnie z JavaDoc:

Pobiera szerokość pierwszych 256 znaków w czcionce. Przesunięcie to odległość od najbardziej wysuniętego na lewo punktu do najbardziej prawego punktu linii bazowej postaci. Zwróć uwagę, że przesunięcie ciągu znaków niekoniecznie jest sumą zaliczek jego znaków.

Można użyć metody klasy FontMetricscharWidth(char). Na przykład:

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(); 
+0

Dzięki za rozszerzenie przykładowego kodu - nie było oczywiste, jak uzyskać FontMetrics dla danej czcionki. Nadal, z jakiegoś powodu, nie znajduje to żadnych czcionek o stałej szerokości na moim komputerze (OS X) ... – Jonik

+0

Przetestowałem jedną czcionkę, która jest znana jako monospaced (java.awt.Font [rodzina = Andale Mono, name = Andale Mono , style = plain, size = 12]). Dla tej czcionki getWidths() zwraca liczby takie jak: 7 0 4 4 4 4 4 4 0 7 7 4 7 7 4 ...: -/ – Jonik

+0

Wypróbuj zaktualizowany kod –

1

Prawdopodobnie nie dotyczy przypadku, ale jeśli po prostu chcesz ustawić czcionkę do stałej szerokości czcionki, użyj logiczną nazwę czcionki:

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

To będzie zagwarantowane monospaced czcionka w twoim systemie.

4

prostszy sposób, który nie wymaga dokonywania BufferedImage dostać Graphics obiekt itp .:

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); 
     } 
    } 
Powiązane problemy