8132890: Text overlapping on dot matrix printers

Reviewed-by: jgodinez, serb
This commit is contained in:
Phil Race 2015-10-21 09:21:25 -07:00
parent d9ebc2b4c2
commit 5c26723516
2 changed files with 116 additions and 21 deletions

View File

@ -494,24 +494,48 @@ final class WPathGraphics extends PathGraphics {
*/ */
float fontSize = font.getSize2D(); 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); Point2D.Double pty = new Point2D.Double(0.0, 1.0);
fontTransform.deltaTransform(pty, pty); fontTransform.deltaTransform(pty, pty);
double scaleFactorY = Math.sqrt(pty.x*pty.x+pty.y*pty.y); 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); Point2D.Double ptx = new Point2D.Double(1.0, 0.0);
fontTransform.deltaTransform(ptx, ptx); fontTransform.deltaTransform(ptx, ptx);
double scaleFactorX = Math.sqrt(ptx.x*ptx.x+ptx.y*ptx.y); double scaleFactorX = Math.sqrt(ptx.x*ptx.x+ptx.y*ptx.y);
float scaledFontSizeX = (float)(fontSize * scaleFactorX);
float awScale = getAwScale(scaleFactorX, scaleFactorY); float awScale = getAwScale(scaleFactorX, scaleFactorY);
int iangle = getAngle(ptx); 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); Font2D font2D = FontUtilities.getFont2D(font);
if (font2D instanceof TrueTypeFont) { if (font2D instanceof TrueTypeFont) {
textOut(str, font, (TrueTypeFont)font2D, frc, textOut(str, font, (TrueTypeFont)font2D, frc,
scaledFontSizeY, iangle, awScale, scaledFontSizeY, iangle, awScale,
deviceTransform, scaleFactorX, advanceScaleX, advanceScaleY,
x, y, devpos.x, devpos.y, targetW); x, y, devpos.x, devpos.y, targetW);
} else if (font2D instanceof CompositeFont) { } else if (font2D instanceof CompositeFont) {
/* Composite fonts are made up of multiple fonts and each /* Composite fonts are made up of multiple fonts and each
@ -542,7 +566,7 @@ final class WPathGraphics extends PathGraphics {
PhysicalFont slotFont = compFont.getSlotFont(slot); PhysicalFont slotFont = compFont.getSlotFont(slot);
textOut(substr, font, slotFont, frc, textOut(substr, font, slotFont, frc,
scaledFontSizeY, iangle, awScale, scaledFontSizeY, iangle, awScale,
deviceTransform, scaleFactorX, advanceScaleX, advanceScaleY,
userx, usery, devx, devy, 0f); userx, usery, devx, devy, 0f);
Rectangle2D bds = font.getStringBounds(substr, frc); Rectangle2D bds = font.getStringBounds(substr, frc);
float xAdvance = (float)bds.getWidth(); float xAdvance = (float)bds.getWidth();
@ -635,18 +659,42 @@ final class WPathGraphics extends PathGraphics {
*/ */
float fontSize = font.getSize2D(); 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); Point2D.Double pty = new Point2D.Double(0.0, 1.0);
fontTransform.deltaTransform(pty, pty); fontTransform.deltaTransform(pty, pty);
double scaleFactorY = Math.sqrt(pty.x*pty.x+pty.y*pty.y); 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); Point2D.Double ptx = new Point2D.Double(1.0, 0.0);
fontTransform.deltaTransform(pt, pt); fontTransform.deltaTransform(ptx, ptx);
double scaleFactorX = Math.sqrt(pt.x*pt.x+pt.y*pt.y); double scaleFactorX = Math.sqrt(ptx.x*ptx.x+ptx.y*ptx.y);
float scaledFontSizeX = (float)(fontSize * scaleFactorX);
float awScale = getAwScale(scaleFactorX, scaleFactorY); 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 numGlyphs = gv.getNumGlyphs();
int[] glyphCodes = gv.getGlyphCodes(0, numGlyphs, null); int[] glyphCodes = gv.getGlyphCodes(0, numGlyphs, null);
@ -705,8 +753,7 @@ final class WPathGraphics extends PathGraphics {
* rotation element of the deviceTransform. * rotation element of the deviceTransform.
*/ */
AffineTransform advanceTransform = AffineTransform advanceTransform =
new AffineTransform(deviceTransform); AffineTransform.getScaleInstance(advanceScaleX, advanceScaleY);
advanceTransform.rotate(iangle*Math.PI/1800.0);
float[] glyphAdvPos = new float[glyphPos.length]; float[] glyphAdvPos = new float[glyphPos.length];
advanceTransform.transform(glyphPos, 0, //source advanceTransform.transform(glyphPos, 0, //source
@ -784,8 +831,7 @@ final class WPathGraphics extends PathGraphics {
Font font, PhysicalFont font2D, Font font, PhysicalFont font2D,
FontRenderContext frc, FontRenderContext frc,
float deviceSize, int rotation, float awScale, float deviceSize, int rotation, float awScale,
AffineTransform deviceTransform, double scaleFactorX, double scaleFactorY,
double scaleFactorX,
float userx, float usery, float userx, float usery,
float devx, float devy, float targetW) { float devx, float devy, float targetW) {
@ -826,8 +872,7 @@ final class WPathGraphics extends PathGraphics {
* See earlier comment in printGlyphVector() for details. * See earlier comment in printGlyphVector() for details.
*/ */
AffineTransform advanceTransform = AffineTransform advanceTransform =
new AffineTransform(deviceTransform); AffineTransform.getScaleInstance(scaleFactorX, scaleFactorY);
advanceTransform.rotate(rotation*Math.PI/1800.0);
float[] glyphAdvPos = new float[glyphPos.length]; float[] glyphAdvPos = new float[glyphPos.length];
advanceTransform.transform(glyphPos, 0, //source advanceTransform.transform(glyphPos, 0, //source
@ -841,11 +886,11 @@ final class WPathGraphics extends PathGraphics {
/* If 2D and GDI agree on the advance of the string we do not /* If 2D and GDI agree on the advance of the string we do not
* need to explicitly assign glyph positions. * need to explicitly assign glyph positions.
* If we are to use the GDI advance, require it to agree with * 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 * discrepancy after rounding the 2D advance to the
* nearest pixel and is greater than one pixel in total. * nearest pixel and is greater than one pixel in total.
* ie strings < 500 pixels in length will be OK so long * ie strings < 100 pixels in length will be OK so long
* as they differ by only 1 pixel even though that is > 0.02% * as they differ by only 1 pixel even though that is > 1%
* The bounds from 2D are in user space so need to * The bounds from 2D are in user space so need to
* be scaled to device space for comparison with GDI. * be scaled to device space for comparison with GDI.
* scaleX is the scale from user space to device space needed for this. * scaleX is the scale from user space to device space needed for this.
@ -863,7 +908,7 @@ final class WPathGraphics extends PathGraphics {
if (ratio < 1) { if (ratio < 1) {
ratio = 1/ratio; ratio = 1/ratio;
} }
return diff <= 1 || ratio < 1.002; return diff <= 1 || ratio < 1.01;
} }
return true; return true;
} }

View File

@ -23,7 +23,7 @@
/** /**
* @test * @test
* @bug 6425068 7157659 * @bug 6425068 7157659 8132890
* @summary Confirm that text prints where we expect to the length we expect. * @summary Confirm that text prints where we expect to the length we expect.
* @run main/manual=yesno PrintTextTest * @run main/manual=yesno PrintTextTest
*/ */
@ -113,6 +113,32 @@ public class PrintTextTest extends Component implements Printable {
book.append(ptt, portrait); book.append(ptt, portrait);
book.append(ptt, landscape); 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 PrintTextTest(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 PrintTextTest(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 PrintTextTest(name, font, scaleTx, false);
p.add(name, ptt);
book.append(ptt, portrait);
book.append(ptt, landscape);
font = font.deriveFont(rotTx); font = font.deriveFont(rotTx);
name = "Page " + new Integer(page++); name = "Page " + new Integer(page++);
ptt = new PrintTextTest(name, font, null, false); ptt = new PrintTextTest(name, font, null, false);
@ -121,6 +147,30 @@ public class PrintTextTest extends Component implements Printable {
book.append(ptt, portrait); book.append(ptt, portrait);
book.append(ptt, landscape); book.append(ptt, landscape);
font = new Font("Monospaced", Font.PLAIN, 12);
name = "Page " + new Integer(page++);
ptt = new PrintTextTest(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 PrintTextTest(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 PrintTextTest(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")) { if (System.getProperty("os.name").startsWith("Windows")) {
font = new Font("MS Gothic", Font.PLAIN, 12); font = new Font("MS Gothic", Font.PLAIN, 12);
name = "Page " + new Integer(page++); name = "Page " + new Integer(page++);