Приложение Java на Mac OS X неправильно печатает шрифты
Недавно я обнаружил, что написанная мной программа печати значков, которая годами прекрасно работала на Windows, не печатает правильно на MAC OS X. Я использую шрифт Arial TrueType. Программа, кажется, отображает основной шрифт без надлежащего масштабирования. Я использую intellij и jdk1.7.0_15. Шрифт отображается правильно на экране, но не при печати на принтере или в формате PDF. Когда я перечисляю шрифты, которые доступны программе на консоли, используя GraphicsEnvironment.getAvailableFontFamilyNames, Arial указывается в качестве одного из них. Когда я загружаю шрифт непосредственно из файла шрифта, он работает правильно. Я гонялся за этим хвостом более суток, любые предложения будут оценены. Вот код, который демонстрирует мою проблему...
/**
* DisplayPage.java
*/
import java.awt.*;
import java.awt.print.*;
public class DisplayPage extends ApplicationFrame {
public static void main(String[] args) {
// Create app and display draw page
DisplayPage f = new DisplayPage();
f.setTitle("PaintingAndStroking v1.0");
f.setSize(850, 1100);
f.center();
f.setVisible(true);
// Generate print job to print page
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setPrintable(new PrintPage());
boolean doPrint = pj.printDialog();
if (doPrint) {
try {
pj.print();
} catch (PrinterException e) {
System.out.println(e);
}
}
}
/**
* This is called by the windows event processor
* @param g java.awt.Graphics context for display
*/
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
DrawPage.draw(g2d);
}
}
/**
* ApplicationFrame.java
*/
import java.awt.*;
import java.awt.event.*;
public class ApplicationFrame extends Frame {
public ApplicationFrame() { this("ApplicationFrame v1.0"); }
public ApplicationFrame(String title) {
super(title);
setSize(850, 1100);
center();
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
System.exit(0);
}
});
}
public void center() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = getSize();
int x = (screenSize.width - frameSize.width) / 2;
int y = (screenSize.height - frameSize.height) / 2;
setLocation(x, y);
}
}
/**
* PrintPage.java
*/
import java.awt.*;
import java.awt.print.*;
public class PrintPage
implements Printable {
public int print(Graphics g, PageFormat pf, int page)
throws PrinterException {
// We have only one page
if (page > 0) {
return NO_SUCH_PAGE;
}
// Create Graphics2D context
Graphics2D g2d = (Graphics2D)g;
// Draw page
DrawPage.draw(g2d);
// Verify page exists
return PAGE_EXISTS;
}
}
/**
* DrawPage.java
*/
import java.awt.*;
public class DrawPage {
static public void draw(Graphics2D g2d) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Font[] fonts = ge.getAllFonts();
String[] fontFamilies = ge.getAvailableFontFamilyNames();
for (int i=0; i<fontFamilies.length; i++) {
System.out.println(fontFamilies[i]);
}
double x = 15, y = 50, w = 70, h = 70;
GradientPaint gp = new GradientPaint(75, 75, Color.white,
95, 95, Color.gray, true);
// Fill with a gradient
g2d.setPaint(gp);
// Stroke with a solid color.
g2d.setPaint(Color.black);
g2d.setStroke(new BasicStroke(8));
// Stroke with a gradient.
g2d.setPaint(gp);
// Draw text string
String text = new String("This is a test...");
g2d.setPaint(Color.black);
g2d.setStroke(new BasicStroke(8));
Font font = new Font("Arial", Font.PLAIN, 36);
g2d.setFont(font);
g2d.drawString("This is a test of Arial 36", 50, 100);
font = new Font("Arial", Font.PLAIN, 72);
g2d.setFont(font);
g2d.drawString("This is a test of Arial 72", 50, 200);
}
}
3 ответа
Я написал сообщение в блоге об этом под названием " Печать сломана в Mac OS X с Java 7", которое включает в себя все, что я нашел, включая причину, отчеты об ошибках, а также наш обходной путь на данный момент. Короткая версия такова, что она выглядит как ошибка в Apple Mac OS или Java 7, и на момент написания статьи она все еще не исправлена.
Для этой проблемы есть обходной путь. Проблемы с рендерингом шрифта связаны с ошибкой в реализации Graphics.drawString().
Два подхода, чтобы избежать этого:
Вы можете заменить свои вызовы Graphics.drawString(...) на вызов, подобный этому
- Graphics.drawGlyphVector(Graphics.getFont(). CreateGlyphVector(Graphics.getFontRenderingContext(), String.toCharArray()))
Вы можете предоставить свою собственную реализацию Graphics2D, которая переопределяет методы drawString () и выполняет указанное выше преобразование и делегирует drawGlyphVector()
Использование drawGlyphVector() приведет к тому, что текст будет визуализироваться кодом AWT Java, а не рендерингом собственной ОС, поэтому могут быть некоторые визуальные артефакты и сниженная производительность. Но это намного лучше, чем нынешняя ситуация.
У меня была такая же проблема, как и у вас. Я понизил версию Java до 1.6 с 1.7, используя эти инструкции.
http://support.apple.com/kb/HT5559?viewlocale=en_US
Это не лучшее решение, но вы сможете решить свою проблему.