2012-02-28 21 views
7

Tôi đang sử dụng g.drawString(str, x, y) để vẽ một chuỗi với đối tượng Graphics2Dg. Phông chữ hiện tại của g không bao gồm tất cả các ký tự của str (Tôi có nghĩa là ký tự Trung Quốc trong đó). Trên Mac OS X, phông chữ dự phòng dường như được sử dụng tự động, nhưng không phải trên Windows, nơi các đường viền hình vuông màu đen xuất hiện thay vì các ký tự mong muốn.Làm cách nào để chỉ định phông chữ dự phòng trong Java2D/Graphics2D

  • Tại sao hành vi khác nhau tùy thuộc vào nền tảng?
  • Làm cách nào để chỉ định phông chữ dự phòng (hoặc một số phông chữ dự phòng) trong trường hợp thiếu ký tự?

(Ví dụ, một trong những phông chữ đẹp there.)

Cập nhật/More Info

Vì vậy, font ban đầu mà không hỗ trợ tất cả các ký tự không phải là một trong những của JVM logical fonts, nhưng là một phông chữ đi kèm đi kèm với ứng dụng của tôi và thu được với Font.createFont(). Vì vậy, việc thêm phông chữ vào thư mục lib/fonts/fallback của JRE không hoạt động ở đây.

Trả lời

5

Chúng tôi có thể gán chuỗi để chuyển phông chữ trên biểu tượng "xấu" và sử dụng Graphics2D.drawString(AttributedCharacterIterator iterator, int x, int y) để hiển thị kết quả. Advantage: tính năng này sẽ hoạt động với bất kỳ phông chữ nào. Hạn chế: không có một số loại bộ nhớ đệm của các đối tượng trung gian này sẽ hoạt động chậm hơn và bẩn hơn.

Vì vậy, tôi đề nghị sử dụng AttributedString với thuộc tính phông chữ chính trên toàn bộ chuỗi:

AttributedString astr = new AttributedString(text); 
astr.addAttribute(TextAttribute.FONT, mainFont, 0, textLength); 

và với font chữ dự phòng trên các bộ phận cụ thể:

astr.addAttribute(TextAttribute.FONT, fallbackFont, fallbackBegin, fallbackEnd); 

Các render chính nó:

g2d.drawString(astr.getIterator(), 20, 30); 

Kết quả (Physical "Segoe Print" làm phông chữ chính, hợp lý "Serif" là dự phòng):

enter image description here

Toàn bộ coi-to-be-SSCCE mã:

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.font.TextAttribute; 
import java.text.AttributedString; 

import javax.swing.JComponent; 
import javax.swing.JFrame; 

public class FontTest extends JFrame { 

    public FontTest() { 
     setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     getContentPane().setLayout(new BorderLayout()); 
     getContentPane().add(new TestStringComponent()); 
     pack(); 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new FontTest().setVisible(true); 
      } 
     }); 
    } 
} 

class TestStringComponent extends JComponent { 

    protected void paintComponent(Graphics g) { 
     Graphics2D g2d = (Graphics2D) g; 
     g.setColor(getBackground()); 
     g.fillRect(0, 0, getWidth(), getHeight()); 

     g.setColor(getForeground()); 

     Font mainFont = new Font("Segoe Print", Font.PLAIN, 25); 
     Font fallbackFont = new Font("Serif", Font.PLAIN, 25); 

     String s = "Test 漢鼎繁古印 Test 漢鼎繁古印 Test"; 

     g2d.drawString(createFallbackString(s, mainFont, fallbackFont).getIterator(), 20, 30); 
    } 

    public Dimension getPreferredSize() { 
     return new Dimension(500, 40); 
    } 

    private AttributedString createFallbackString(String text, Font mainFont, Font fallbackFont) { 
     AttributedString result = new AttributedString(text); 

     int textLength = text.length(); 
     result.addAttribute(TextAttribute.FONT, mainFont, 0, textLength); 

     boolean fallback = false; 
     int fallbackBegin = 0; 
     for (int i = 0; i < text.length(); i++) { 
      boolean curFallback = !mainFont.canDisplay(text.charAt(i)); 
      if (curFallback != fallback) { 
       fallback = curFallback; 
       if (fallback) { 
        fallbackBegin = i; 
       } else { 
        result.addAttribute(TextAttribute.FONT, fallbackFont, fallbackBegin, i); 
       } 
      } 
     } 
     return result; 
    } 
} 
+0

Tôi xin lỗi, nó cũng không làm việc whith sửa đổi của 'fontconfig.properties'. Cách thông thường là thêm tệp phông chữ tùy chỉnh vào chuỗi dự phòng. Các dòng cần thiết là: 'filename.Yourfont = YOURFONT.TTF' và' allfonts.yourfont = Yourfont'; sau đó thêm 'yourfont' vào danh sách' sequence.fallback'. Tôi đã lên kế hoạch mở rộng câu trả lời với các chi tiết, nhưng thật không may, nó chỉ hoạt động với các phông chữ * logic * chuẩn. Có lẽ một số fontconfig-ma thuật cần thiết, nhưng nó là ra khỏi kỹ năng và kinh nghiệm của tôi. Tôi xin lỗi vì câu trả lời vô ích. – Mersenne

+0

Tôi đã xóa giải pháp sai. Ít nhất, workaround hiện nó là mục đích. – Mersenne

+0

Tuyệt vời, cảm ơn sự giúp đỡ tuyệt vời của bạn! –

Các vấn đề liên quan