Merge
diff --git a/.hgtags b/.hgtags
index 6208cf2..a2ae0ba 100644
--- a/.hgtags
+++ b/.hgtags
@@ -501,6 +501,7 @@
ea7a705eab9e6495d08a92ff21e0370b68374c54 jdk8u66-b33
72ab45285f0e8293aa63e889bc75f0287b6e0436 jdk8u66-b34
e169a214f1f096af6b57169eeb0ba66ee5e9caa3 jdk8u66-b35
+430a8d04d8358206b682323f61405f951f43c773 jdk8u66-b36
9a2747ef337bdee71bc8225dea77eb403cca1179 jdk8u71-b00
e8b5e10a19d66a77d04f12d4677e6fec66f79651 jdk8u71-b01
25d689a73bc037e1710f95f6d4acf0671d22047d jdk8u71-b02
diff --git a/src/windows/classes/sun/awt/windows/WPathGraphics.java b/src/windows/classes/sun/awt/windows/WPathGraphics.java
index c3410a9..31d9c28 100644
--- a/src/windows/classes/sun/awt/windows/WPathGraphics.java
+++ b/src/windows/classes/sun/awt/windows/WPathGraphics.java
@@ -494,24 +494,48 @@
*/
float fontSize = font.getSize2D();
+ double devResX = wPrinterJob.getXRes();
+ double devResY = wPrinterJob.getYRes();
+
+ double fontDevScaleY = devResY / DEFAULT_USER_RES;
+
+ int orient = getPageFormat().getOrientation();
+ if (orient == PageFormat.LANDSCAPE ||
+ orient == PageFormat.REVERSE_LANDSCAPE)
+ {
+ double tmp = devResX;
+ devResX = devResY;
+ devResY = tmp;
+ }
+
+ double devScaleX = devResX / DEFAULT_USER_RES;
+ double devScaleY = devResY / DEFAULT_USER_RES;
+ fontTransform.scale(1.0/devScaleX, 1.0/devScaleY);
+
Point2D.Double pty = new Point2D.Double(0.0, 1.0);
fontTransform.deltaTransform(pty, pty);
double scaleFactorY = Math.sqrt(pty.x*pty.x+pty.y*pty.y);
- float scaledFontSizeY = (float)(fontSize * scaleFactorY);
+ float scaledFontSizeY = (float)(fontSize * scaleFactorY * fontDevScaleY);
Point2D.Double ptx = new Point2D.Double(1.0, 0.0);
fontTransform.deltaTransform(ptx, ptx);
double scaleFactorX = Math.sqrt(ptx.x*ptx.x+ptx.y*ptx.y);
- float scaledFontSizeX = (float)(fontSize * scaleFactorX);
float awScale = getAwScale(scaleFactorX, scaleFactorY);
int iangle = getAngle(ptx);
+ ptx = new Point2D.Double(1.0, 0.0);
+ deviceTransform.deltaTransform(ptx, ptx);
+ double advanceScaleX = Math.sqrt(ptx.x*ptx.x+ptx.y*ptx.y);
+ pty = new Point2D.Double(0.0, 1.0);
+ deviceTransform.deltaTransform(pty, pty);
+ double advanceScaleY = Math.sqrt(pty.x*pty.x+pty.y*pty.y);
+
Font2D font2D = FontUtilities.getFont2D(font);
if (font2D instanceof TrueTypeFont) {
textOut(str, font, (TrueTypeFont)font2D, frc,
scaledFontSizeY, iangle, awScale,
- deviceTransform, scaleFactorX,
+ advanceScaleX, advanceScaleY,
x, y, devpos.x, devpos.y, targetW);
} else if (font2D instanceof CompositeFont) {
/* Composite fonts are made up of multiple fonts and each
@@ -542,7 +566,7 @@
PhysicalFont slotFont = compFont.getSlotFont(slot);
textOut(substr, font, slotFont, frc,
scaledFontSizeY, iangle, awScale,
- deviceTransform, scaleFactorX,
+ advanceScaleX, advanceScaleY,
userx, usery, devx, devy, 0f);
Rectangle2D bds = font.getStringBounds(substr, frc);
float xAdvance = (float)bds.getWidth();
@@ -635,18 +659,42 @@
*/
float fontSize = font.getSize2D();
+ double devResX = wPrinterJob.getXRes();
+ double devResY = wPrinterJob.getYRes();
+
+ double fontDevScaleY = devResY / DEFAULT_USER_RES;
+
+ int orient = getPageFormat().getOrientation();
+ if (orient == PageFormat.LANDSCAPE ||
+ orient == PageFormat.REVERSE_LANDSCAPE)
+ {
+ double tmp = devResX;
+ devResX = devResY;
+ devResY = tmp;
+ }
+
+ double devScaleX = devResX / DEFAULT_USER_RES;
+ double devScaleY = devResY / DEFAULT_USER_RES;
+ fontTransform.scale(1.0/devScaleX, 1.0/devScaleY);
+
Point2D.Double pty = new Point2D.Double(0.0, 1.0);
fontTransform.deltaTransform(pty, pty);
double scaleFactorY = Math.sqrt(pty.x*pty.x+pty.y*pty.y);
- float scaledFontSizeY = (float)(fontSize * scaleFactorY);
+ float scaledFontSizeY = (float)(fontSize * scaleFactorY * fontDevScaleY);
- Point2D.Double pt = new Point2D.Double(1.0, 0.0);
- fontTransform.deltaTransform(pt, pt);
- double scaleFactorX = Math.sqrt(pt.x*pt.x+pt.y*pt.y);
- float scaledFontSizeX = (float)(fontSize * scaleFactorX);
+ Point2D.Double ptx = new Point2D.Double(1.0, 0.0);
+ fontTransform.deltaTransform(ptx, ptx);
+ double scaleFactorX = Math.sqrt(ptx.x*ptx.x+ptx.y*ptx.y);
float awScale = getAwScale(scaleFactorX, scaleFactorY);
- int iangle = getAngle(pt);
+ int iangle = getAngle(ptx);
+
+ ptx = new Point2D.Double(1.0, 0.0);
+ deviceTransform.deltaTransform(ptx, ptx);
+ double advanceScaleX = Math.sqrt(ptx.x*ptx.x+ptx.y*ptx.y);
+ pty = new Point2D.Double(0.0, 1.0);
+ deviceTransform.deltaTransform(pty, pty);
+ double advanceScaleY = Math.sqrt(pty.x*pty.x+pty.y*pty.y);
int numGlyphs = gv.getNumGlyphs();
int[] glyphCodes = gv.getGlyphCodes(0, numGlyphs, null);
@@ -705,8 +753,7 @@
* rotation element of the deviceTransform.
*/
AffineTransform advanceTransform =
- new AffineTransform(deviceTransform);
- advanceTransform.rotate(iangle*Math.PI/1800.0);
+ AffineTransform.getScaleInstance(advanceScaleX, advanceScaleY);
float[] glyphAdvPos = new float[glyphPos.length];
advanceTransform.transform(glyphPos, 0, //source
@@ -784,8 +831,7 @@
Font font, PhysicalFont font2D,
FontRenderContext frc,
float deviceSize, int rotation, float awScale,
- AffineTransform deviceTransform,
- double scaleFactorX,
+ double scaleFactorX, double scaleFactorY,
float userx, float usery,
float devx, float devy, float targetW) {
@@ -826,8 +872,7 @@
* See earlier comment in printGlyphVector() for details.
*/
AffineTransform advanceTransform =
- new AffineTransform(deviceTransform);
- advanceTransform.rotate(rotation*Math.PI/1800.0);
+ AffineTransform.getScaleInstance(scaleFactorX, scaleFactorY);
float[] glyphAdvPos = new float[glyphPos.length];
advanceTransform.transform(glyphPos, 0, //source
@@ -841,11 +886,11 @@
/* If 2D and GDI agree on the advance of the string we do not
* need to explicitly assign glyph positions.
* If we are to use the GDI advance, require it to agree with
- * JDK to a precision of <= 0.2% - ie 1 pixel in 500
+ * JDK to a precision of <= 1.0% - ie 1 pixel in 100
* discrepancy after rounding the 2D advance to the
* nearest pixel and is greater than one pixel in total.
- * ie strings < 500 pixels in length will be OK so long
- * as they differ by only 1 pixel even though that is > 0.02%
+ * ie strings < 100 pixels in length will be OK so long
+ * as they differ by only 1 pixel even though that is > 1%
* The bounds from 2D are in user space so need to
* be scaled to device space for comparison with GDI.
* scaleX is the scale from user space to device space needed for this.
@@ -863,7 +908,7 @@
if (ratio < 1) {
ratio = 1/ratio;
}
- return diff <= 1 || ratio < 1.002;
+ return diff <= 1 || ratio < 1.01;
}
return true;
}
diff --git a/test/java/awt/print/PrinterJob/PrintTextTest.html b/test/java/awt/print/PrinterJob/PrintTextTest.html
new file mode 100644
index 0000000..1ef0918
--- /dev/null
+++ b/test/java/awt/print/PrinterJob/PrintTextTest.html
@@ -0,0 +1,46 @@
+<!--
+ Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ or visit www.oracle.com if you need additional information or have any
+ questions.
+-->
+
+<html>
+<body>
+<applet code="PrintTextTest.class" width=400 height=100></applet>
+This tests that printed text renders similarly to on-screen,
+under a variety of APIs and graphics and font transforms
+Print to your preferred printer. Collect the output.
+Refer to the onscreen buttons to cycle through the on-screen
+content
+For each page, confirm that the printed content corresponds to
+the on-screen rendering for that *same* page.
+Some cases may look odd but its intentional. Verify
+it looks the same on screen and on the printer.
+Note that text does not scale linearly from screen to printer
+so some differences are normal and not a bug.
+The easiest way to spot real problems is to check that
+any underlines are the same length as the underlined text
+and that any rotations are the same in each case.
+Note that each on-screen page is printed in both portrait
+and landscape mode
+So for example, Page 1/Portrait, and Page 1/Landscape when
+rotated to view properly, should both match Page 1 on screen.;
+</body>
+</html>
diff --git a/test/java/awt/print/PrinterJob/PrintTextTest.java b/test/java/awt/print/PrinterJob/PrintTextTest.java
new file mode 100644
index 0000000..3ce4c72
--- /dev/null
+++ b/test/java/awt/print/PrinterJob/PrintTextTest.java
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/**
+ * @test
+ * @bug 6425068 7157659 8132890
+ * @summary Confirm that text prints where we expect to the length we expect.
+ * @run applet/manual=yesno PrintTextTest.html
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import java.text.*;
+import java.util.*;
+import java.awt.font.*;
+import java.awt.geom.*;
+import java.awt.print.*;
+import javax.swing.*;
+
+public class PrintTextTest extends JApplet {
+ public void start() {
+ StandalonePrintTextTest.main(null);
+ }
+}
+
+class StandalonePrintTextTest extends Component implements Printable {
+
+ static int preferredSize;
+ Font textFont;
+ AffineTransform gxTx;
+ String page;
+ boolean useFM;
+
+ public static void main(String args[]) {
+
+ PrinterJob pjob = PrinterJob.getPrinterJob();
+ PageFormat portrait = pjob.defaultPage();
+ portrait.setOrientation(PageFormat.PORTRAIT);
+ preferredSize = (int)portrait.getImageableWidth();
+
+ PageFormat landscape = pjob.defaultPage();
+ landscape.setOrientation(PageFormat.LANDSCAPE);
+
+ Book book = new Book();
+
+ JTabbedPane p = new JTabbedPane();
+
+ int page = 1;
+ Font font = new Font("Dialog", Font.PLAIN, 18);
+ String name = "Page " + new Integer(page++);
+ StandalonePrintTextTest ptt = new StandalonePrintTextTest(name, font, null, false);
+ p.add(name, ptt);
+ book.append(ptt, portrait);
+ book.append(ptt, landscape);
+
+ font = new Font("Dialog", Font.PLAIN, 18);
+ name = "Page " + new Integer(page++);
+ ptt = new StandalonePrintTextTest(name, font, null, true);
+ p.add(name, ptt);
+ book.append(ptt, portrait);
+ book.append(ptt, landscape);
+
+ font = new Font("Lucida Sans", Font.PLAIN, 18);
+ name = "Page " + new Integer(page++);
+ ptt = new StandalonePrintTextTest(name, font, null, false);
+ p.add(name, ptt);
+ book.append(ptt, portrait);
+ book.append(ptt, landscape);
+
+ font = new Font("Lucida Sans", Font.PLAIN, 18);
+ AffineTransform rotTx = AffineTransform.getRotateInstance(0.15);
+ rotTx.translate(60,0);
+ name = "Page " + new Integer(page++);
+ ptt = new StandalonePrintTextTest(name, font, rotTx, false);
+ p.add(name, ptt);
+ book.append(ptt, portrait);
+ book.append(ptt, landscape);
+
+ font = new Font("Dialog", Font.PLAIN, 18);
+ AffineTransform scaleTx = AffineTransform.getScaleInstance(1.25, 1.25);
+ name = "Page " + new Integer(page++);
+ ptt = new StandalonePrintTextTest(name, font, scaleTx, false);
+ p.add(name, ptt);
+ book.append(ptt, portrait);
+ book.append(ptt, landscape);
+
+ font = new Font("Dialog", Font.PLAIN, 18);
+ scaleTx = AffineTransform.getScaleInstance(-1.25, 1.25);
+ scaleTx.translate(-preferredSize/1.25, 0);
+ name = "Page " + new Integer(page++);
+ ptt = new StandalonePrintTextTest(name, font, scaleTx, false);
+ p.add(name, ptt);
+ book.append(ptt, portrait);
+ book.append(ptt, landscape);
+
+ font = new Font("Dialog", Font.PLAIN, 18);
+ scaleTx = AffineTransform.getScaleInstance(1.25, -1.25);
+ scaleTx.translate(0, -preferredSize/1.25);
+ name = "Page " + new Integer(page++);
+ ptt = new StandalonePrintTextTest(name, font, scaleTx, false);
+ p.add(name, ptt);
+ book.append(ptt, portrait);
+ book.append(ptt, landscape);
+
+ font = font.deriveFont(rotTx);
+ name = "Page " + new Integer(page++);
+ ptt = new StandalonePrintTextTest(name, font, null, false);
+ p.add(ptt, BorderLayout.CENTER);
+ p.add(name, ptt);
+ book.append(ptt, portrait);
+ book.append(ptt, landscape);
+
+ font = new Font("Monospaced", Font.PLAIN, 12);
+ name = "Page " + new Integer(page++);
+ ptt = new StandalonePrintTextTest(name, font, null, false);
+ p.add(ptt, BorderLayout.CENTER);
+ p.add(name, ptt);
+ book.append(ptt, portrait);
+ book.append(ptt, landscape);
+
+ Font xfont = font.deriveFont(AffineTransform.getScaleInstance(1.5, 1));
+ name = "Page " + new Integer(page++);
+ ptt = new StandalonePrintTextTest(name, xfont, null, false);
+ p.add(ptt, BorderLayout.CENTER);
+ p.add(name, ptt);
+ book.append(ptt, portrait);
+ book.append(ptt, landscape);
+
+ Font yfont = font.deriveFont(AffineTransform.getScaleInstance(1, 1.5));
+ name = "Page " + new Integer(page++);
+ ptt = new StandalonePrintTextTest(name, yfont, null, false);
+ p.add(ptt, BorderLayout.CENTER);
+ p.add(name, ptt);
+ book.append(ptt, portrait);
+ book.append(ptt, landscape);
+
+ if (System.getProperty("os.name").startsWith("Windows")) {
+ font = new Font("MS Gothic", Font.PLAIN, 12);
+ name = "Page " + new Integer(page++);
+ ptt = new PrintJAText(name, font, null, true);
+ p.add(ptt, BorderLayout.CENTER);
+ p.add(name, ptt);
+ book.append(ptt, portrait);
+ book.append(ptt, landscape);
+
+ font = new Font("MS Gothic", Font.PLAIN, 12);
+ name = "Page " + new Integer(page++);
+ rotTx = AffineTransform.getRotateInstance(0.15);
+ ptt = new PrintJAText(name, font, rotTx, true);
+ p.add(ptt, BorderLayout.CENTER);
+ p.add(name, ptt);
+ book.append(ptt, portrait);
+ book.append(ptt, landscape);
+ }
+
+ pjob.setPageable(book);
+
+ JFrame f = new JFrame();
+ f.add(BorderLayout.CENTER, p);
+ f.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {System.exit(0);}
+ });
+ f.pack();
+ f.show();
+
+ try {
+ if (pjob.printDialog()) {
+ pjob.print();
+ }
+ } catch (PrinterException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+
+ public StandalonePrintTextTest(String page, Font font, AffineTransform gxTx,
+ boolean fm) {
+ this.page = page;
+ textFont = font;
+ this.gxTx = gxTx;
+ this.useFM = fm;
+ setBackground(Color.white);
+ }
+
+ public static AttributedCharacterIterator getIterator(String s) {
+ return new AttributedString(s).getIterator();
+ }
+
+ static String orient(PageFormat pf) {
+ if (pf.getOrientation() == PageFormat.PORTRAIT) {
+ return "Portrait";
+ } else {
+ return "Landscape";
+ }
+ }
+
+ public int print(Graphics g, PageFormat pf, int pageIndex) {
+
+ Graphics2D g2d = (Graphics2D)g;
+ g2d.translate(pf.getImageableX(), pf.getImageableY());
+ g.drawString(page+" "+orient(pf),50,20);
+ g.translate(0, 25);
+ paint(g);
+ return PAGE_EXISTS;
+ }
+
+ public Dimension getMinimumSize() {
+ return getPreferredSize();
+ }
+
+ public Dimension getPreferredSize() {
+ return new Dimension(preferredSize, preferredSize);
+ }
+
+ public void paint(Graphics g) {
+
+ /* fill with white before any transformation is applied */
+ g.setColor(Color.white);
+ g.fillRect(0, 0, getSize().width, getSize().height);
+
+
+ Graphics2D g2d = (Graphics2D) g;
+ if (gxTx != null) {
+ g2d.transform(gxTx);
+ }
+ if (useFM) {
+ g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
+ RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ }
+
+ g.setFont(textFont);
+ FontMetrics fm = g.getFontMetrics();
+
+ String s;
+ int LS = 30;
+ int ix=10, iy=LS+10;
+ g.setColor(Color.black);
+
+ s = "drawString(String str, int x, int y)";
+ g.drawString(s, ix, iy);
+ if (!textFont.isTransformed()) {
+ g.drawLine(ix, iy+1, ix+fm.stringWidth(s), iy+1);
+ }
+
+ iy += LS;
+ s = "drawString(AttributedCharacterIterator iterator, int x, int y)";
+ g.drawString(getIterator(s), ix, iy);
+
+ iy += LS;
+ s = "\tdrawChars(\t\r\nchar[], int off, int len, int x, int y\t)";
+ g.drawChars(s.toCharArray(), 0, s.length(), ix, iy);
+ if (!textFont.isTransformed()) {
+ g.drawLine(ix, iy+1, ix+fm.stringWidth(s), iy+1);
+ }
+
+ iy += LS;
+ s = "drawBytes(byte[], int off, int len, int x, int y)";
+ byte data[] = new byte[s.length()];
+ for (int i = 0; i < data.length; i++) {
+ data[i] = (byte) s.charAt(i);
+ }
+ g.drawBytes(data, 0, data.length, ix, iy);
+
+ Font f = g2d.getFont();
+ FontRenderContext frc = g2d.getFontRenderContext();
+
+ iy += LS;
+ s = "drawString(String s, float x, float y)";
+ g2d.drawString(s, (float) ix, (float) iy);
+ if (!textFont.isTransformed()) {
+ g.drawLine(ix, iy+1, ix+fm.stringWidth(s), iy+1);
+ }
+
+ iy += LS;
+ s = "drawString(AttributedCharacterIterator iterator, "+
+ "float x, float y)";
+ g2d.drawString(getIterator(s), (float) ix, (float) iy);
+
+ iy += LS;
+ s = "drawGlyphVector(GlyphVector g, float x, float y)";
+ GlyphVector gv = f.createGlyphVector(frc, s);
+ g2d.drawGlyphVector(gv, ix, iy);
+ Point2D adv = gv.getGlyphPosition(gv.getNumGlyphs());
+ if (!textFont.isTransformed()) {
+ g.drawLine(ix, iy+1, ix+(int)adv.getX(), iy+1);
+ }
+
+ iy += LS;
+ s = "GlyphVector with position adjustments";
+
+ gv = f.createGlyphVector(frc, s);
+ int ng = gv.getNumGlyphs();
+ adv = gv.getGlyphPosition(ng);
+ for (int i=0; i<ng; i++) {
+ Point2D gp = gv.getGlyphPosition(i);
+ double gx = gp.getX();
+ double gy = gp.getY();
+ if (i % 2 == 0) {
+ gy+=5;
+ } else {
+ gy-=5;
+ }
+ gp.setLocation(gx, gy);
+ gv.setGlyphPosition(i, gp);
+ }
+ g2d.drawGlyphVector(gv, ix, iy);
+ if (!textFont.isTransformed()) {
+ g.drawLine(ix, iy+1, ix+(int)adv.getX(), iy+1);
+ }
+
+ iy +=LS;
+ s = "drawString: \u0924\u094d\u0930 \u0915\u0948\u0930\u0947 End.";
+ g.drawString(s, ix, iy);
+ if (!textFont.isTransformed()) {
+ g.drawLine(ix, iy+1, ix+fm.stringWidth(s), iy+1);
+ }
+
+ iy += LS;
+ s = "TextLayout 1: \u0924\u094d\u0930 \u0915\u0948\u0930\u0947 End.";
+ TextLayout tl = new TextLayout(s, new HashMap(), frc);
+ tl.draw(g2d, ix, iy);
+
+ iy += LS;
+ s = "TextLayout 2: \u0924\u094d\u0930 \u0915\u0948\u0930\u0947 End.";
+ tl = new TextLayout(s, f, frc);
+ tl.draw(g2d, ix, iy);
+ }
+}
+
+class PrintJAText extends StandalonePrintTextTest {
+
+
+ public PrintJAText(String page, Font font, AffineTransform gxTx,
+ boolean fm) {
+ super(page, font, gxTx, fm);
+ }
+
+ private static final String TEXT =
+ "\u3042\u3044\u3046\u3048\u304a\u30a4\u30ed\u30cf" +
+ "\u30cb\u30db\u30d8\u30c8\u4e00\u4e01\u4e02\u4e05\uff08";
+
+
+ public void paint(Graphics g) {
+
+ /* fill with white before any transformation is applied */
+ g.setColor(Color.white);
+ g.fillRect(0, 0, getSize().width, getSize().height);
+
+
+ Graphics2D g2d = (Graphics2D) g;
+ if (gxTx != null) {
+ g2d.transform(gxTx);
+ }
+ if (useFM) {
+ g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
+ RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ }
+
+ String text = TEXT + TEXT + TEXT;
+ g.setColor(Color.black);
+ int y = 20;
+ float origSize = 7f;
+ for (int i=0;i<11;i++) {
+ float size = origSize+(i*0.1f);
+ g2d.translate(0, size+6);
+ Font f = textFont.deriveFont(size);
+ g2d.setFont(f);
+ FontMetrics fontMetrics = g2d.getFontMetrics();
+ int stringWidth = fontMetrics.stringWidth(text);
+ g.drawLine(0, y+1, stringWidth, y+1);
+ g.drawString(text, 0, y);
+ y +=10;
+ }
+ }
+}