2009-05-28 34 views
10

Tôi đang thử liệt kê tất cả các phông chữ đơn cách sẵn có trên máy của người dùng hay không. Tôi có thể nhận được tất cả các họ phông chữ trong Swing qua:Kiểm tra xem Phông chữ có đơn cách nhau trong Java

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

Có cách nào để tìm ra chúng trong số này là đơn cách không?

Xin cảm ơn trước.

Trả lời

3

So sánh độ dài rút ra của nhiều ký tự (m, i, 1,. Nên là một tập hợp tốt).

Đối với phông chữ đơn cách, tất cả chúng đều bằng nhau, đối với phông chữ có chiều rộng thay đổi, chúng sẽ không như vậy.

+0

Bạn có thể thêm mã ví dụ? – Jonik

+0

+1 cho cách tiếp cận thực tế và đơn giản; Tôi sử dụng i và m. –

1

Theo this response, Java không biết nhiều về chi tiết phông chữ cơ bản, vì vậy bạn phải thực hiện một số so sánh kích thước phông chữ.

4

Bạn có thể sử dụng phương thức getWidths() của lớp FontMetrics. Theo JavaDoc:

Nhận độ rộng trước của 256 ký tự đầu tiên trong Phông chữ. Tạm ứng là khoảng cách từ điểm tận cùng bên trái đến điểm tận cùng bên phải trên đường cơ sở của nhân vật. Lưu ý rằng sự tiến bộ của một String không nhất thiết là tổng của các tiến bộ của các ký tự của nó.

Bạn có thể sử dụng phương thức charWidth(char) của lớp FontMetrics. Ví dụ:

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

Cảm ơn bạn đã mở rộng mã ví dụ của mình - không rõ ràng cách lấy FontMetrics cho một Font đã cho. Tuy nhiên, vì lý do nào đó, điều này không tìm thấy bất kỳ phông chữ đơn cách nào trên máy của tôi (OS X) ... – Jonik

+0

Tôi đã thử nghiệm với một phông chữ được biết là đơn cách (java.awt.Font [family = Andale Mono, name = Andale Mono , style = plain, size = 12]). Đối với font getWidths() trả về các số như: 7 0 4 4 4 4 4 4 0 7 7 4 7 7 4 ...: -/ – Jonik

+0

Hãy thử mã cập nhật –

1

Có lẽ không áp dụng cho trường hợp của bạn, nhưng nếu bạn chỉ đơn giản là muốn thiết lập các phông chữ để một font chữ đơn, sử dụng tên font logic:

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

Đây sẽ là một đảm bảo monospaced phông chữ trên hệ thống của bạn.

4

Một phương pháp đơn giản mà không yêu cầu thực hiện một BufferedImage để có được một đối tượng Graphics v.v .:

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); 
     } 
    } 
Các vấn đề liên quan