# HG changeset patch # User prr # Date 1445444485 25200 # Node ID 4a358314de0cc3a7e1540b548fd7c0aa45bd2a1e # Parent 35ac6c6f6b6ae98678cfdda9ce058fbb0f03a143 8132890: Text overlapping on dot matrix printers. Reviewed-by: jgodinez, serb diff -r 35ac6c6f6b6a -r 4a358314de0c jdk/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java Wed Oct 21 18:58:19 2015 +0300 +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java Wed Oct 21 09:21:25 2015 -0700 @@ -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 -r 35ac6c6f6b6a -r 4a358314de0c jdk/test/java/awt/print/PrinterJob/PrintTextTest.java --- a/jdk/test/java/awt/print/PrinterJob/PrintTextTest.java Wed Oct 21 18:58:19 2015 +0300 +++ b/jdk/test/java/awt/print/PrinterJob/PrintTextTest.java Wed Oct 21 09:21:25 2015 -0700 @@ -23,7 +23,7 @@ /** * @test - * @bug 6425068 7157659 + * @bug 6425068 7157659 8132890 * @summary Confirm that text prints where we expect to the length we expect. * @run main/manual=yesno PrintTextTest */ @@ -113,6 +113,32 @@ 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 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); name = "Page " + new Integer(page++); ptt = new PrintTextTest(name, font, null, false); @@ -121,6 +147,30 @@ book.append(ptt, portrait); 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")) { font = new Font("MS Gothic", Font.PLAIN, 12); name = "Page " + new Integer(page++);