1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24  
  25 /**
  26  * @test
  27  * @bug 6425068 7157659 8132890
  28  * @summary Confirm that text prints where we expect to the length we expect.
  29  * @run applet/manual=yesno PrintTextTest.html
  30  */
  31 
  32 import java.awt.*;
  33 import java.awt.event.*;
  34 import java.text.*;
  35 import java.util.*;
  36 import java.awt.font.*;
  37 import java.awt.geom.*;
  38 import java.awt.print.*;
  39 import javax.swing.*;
  40 
  41 public class PrintTextTest extends JApplet {
  42     public void start() {
  43         StandalonePrintTextTest.main(null);
  44     }
  45 }
  46 
  47 class StandalonePrintTextTest extends Component implements Printable {
  48 
  49     static int preferredSize;
  50     Font textFont;
  51     AffineTransform gxTx;
  52     String page;
  53     boolean useFM;
  54 
  55     public static void main(String args[]) {
  56 
  57         PrinterJob pjob = PrinterJob.getPrinterJob();
  58         PageFormat portrait = pjob.defaultPage();
  59         portrait.setOrientation(PageFormat.PORTRAIT);
  60         preferredSize = (int)portrait.getImageableWidth();
  61 
  62         PageFormat landscape = pjob.defaultPage();
  63         landscape.setOrientation(PageFormat.LANDSCAPE);
  64 
  65         Book book = new Book();
  66 
  67         JTabbedPane p = new JTabbedPane();
  68 
  69         int page = 1;
  70         Font font = new Font("Dialog", Font.PLAIN, 18);
  71         String name = "Page " + new Integer(page++);
  72         StandalonePrintTextTest ptt = new StandalonePrintTextTest(name, font, null, false);
  73         p.add(name, ptt);
  74         book.append(ptt, portrait);
  75         book.append(ptt, landscape);
  76 
  77         font = new Font("Dialog", Font.PLAIN, 18);
  78         name = "Page " + new Integer(page++);
  79         ptt = new StandalonePrintTextTest(name, font, null, true);
  80         p.add(name, ptt);
  81         book.append(ptt, portrait);
  82         book.append(ptt, landscape);
  83 
  84         font = new Font("Lucida Sans", Font.PLAIN, 18);
  85         name = "Page " + new Integer(page++);
  86         ptt = new StandalonePrintTextTest(name, font, null, false);
  87         p.add(name, ptt);
  88         book.append(ptt, portrait);
  89         book.append(ptt, landscape);
  90 
  91         font = new Font("Lucida Sans", Font.PLAIN, 18);
  92         AffineTransform rotTx = AffineTransform.getRotateInstance(0.15);
  93         rotTx.translate(60,0);
  94         name = "Page " + new Integer(page++);
  95         ptt = new StandalonePrintTextTest(name, font, rotTx, false);
  96         p.add(name, ptt);
  97         book.append(ptt, portrait);
  98         book.append(ptt, landscape);
  99 
 100         font = new Font("Dialog", Font.PLAIN, 18);
 101         AffineTransform scaleTx = AffineTransform.getScaleInstance(1.25, 1.25);
 102         name = "Page " + new Integer(page++);
 103         ptt = new StandalonePrintTextTest(name, font, scaleTx, false);
 104         p.add(name, ptt);
 105         book.append(ptt, portrait);
 106         book.append(ptt, landscape);
 107 
 108         font = new Font("Dialog", Font.PLAIN, 18);
 109         scaleTx = AffineTransform.getScaleInstance(-1.25, 1.25);
 110         scaleTx.translate(-preferredSize/1.25, 0);
 111         name = "Page " + new Integer(page++);
 112         ptt = new StandalonePrintTextTest(name, font, scaleTx, false);
 113         p.add(name, ptt);
 114         book.append(ptt, portrait);
 115         book.append(ptt, landscape);
 116 
 117         font = new Font("Dialog", Font.PLAIN, 18);
 118         scaleTx = AffineTransform.getScaleInstance(1.25, -1.25);
 119         scaleTx.translate(0, -preferredSize/1.25);
 120         name = "Page " + new Integer(page++);
 121         ptt = new StandalonePrintTextTest(name, font, scaleTx, false);
 122         p.add(name, ptt);
 123         book.append(ptt, portrait);
 124         book.append(ptt, landscape);
 125 
 126         font = font.deriveFont(rotTx);
 127         name = "Page " + new Integer(page++);
 128         ptt = new StandalonePrintTextTest(name, font, null, false);
 129         p.add(ptt, BorderLayout.CENTER);
 130         p.add(name, ptt);
 131         book.append(ptt, portrait);
 132         book.append(ptt, landscape);
 133 
 134         font = new Font("Monospaced", Font.PLAIN, 12);
 135         name = "Page " + new Integer(page++);
 136         ptt = new StandalonePrintTextTest(name, font, null, false);
 137         p.add(ptt, BorderLayout.CENTER);
 138         p.add(name, ptt);
 139         book.append(ptt, portrait);
 140         book.append(ptt, landscape);
 141 
 142         Font xfont = font.deriveFont(AffineTransform.getScaleInstance(1.5, 1));
 143         name = "Page " + new Integer(page++);
 144         ptt = new StandalonePrintTextTest(name, xfont, null, false);
 145         p.add(ptt, BorderLayout.CENTER);
 146         p.add(name, ptt);
 147         book.append(ptt, portrait);
 148         book.append(ptt, landscape);
 149 
 150         Font yfont = font.deriveFont(AffineTransform.getScaleInstance(1, 1.5));
 151         name = "Page " + new Integer(page++);
 152         ptt = new StandalonePrintTextTest(name, yfont, null, false);
 153         p.add(ptt, BorderLayout.CENTER);
 154         p.add(name, ptt);
 155         book.append(ptt, portrait);
 156         book.append(ptt, landscape);
 157 
 158         if (System.getProperty("os.name").startsWith("Windows")) {
 159             font = new Font("MS Gothic", Font.PLAIN, 12);
 160             name = "Page " + new Integer(page++);
 161             ptt = new PrintJAText(name, font, null, true);
 162             p.add(ptt, BorderLayout.CENTER);
 163             p.add(name, ptt);
 164             book.append(ptt, portrait);
 165             book.append(ptt, landscape);
 166 
 167             font = new Font("MS Gothic", Font.PLAIN, 12);
 168             name = "Page " + new Integer(page++);
 169             rotTx = AffineTransform.getRotateInstance(0.15);
 170             ptt = new PrintJAText(name, font, rotTx, true);
 171             p.add(ptt, BorderLayout.CENTER);
 172             p.add(name, ptt);
 173             book.append(ptt, portrait);
 174             book.append(ptt, landscape);
 175         }
 176 
 177         pjob.setPageable(book);
 178 
 179         JFrame f = new JFrame();
 180         f.add(BorderLayout.CENTER, p);
 181         f.addWindowListener(new WindowAdapter() {
 182             public void windowClosing(WindowEvent e) {System.exit(0);}
 183         });
 184         f.pack();
 185         f.show();
 186 
 187         try {
 188             if (pjob.printDialog()) {
 189                 pjob.print();
 190             }
 191         } catch (PrinterException e) {
 192             throw new RuntimeException(e.getMessage());
 193         }
 194     }
 195 
 196     public StandalonePrintTextTest(String page, Font font, AffineTransform gxTx,
 197                          boolean fm) {
 198         this.page = page;
 199         textFont = font;
 200         this.gxTx = gxTx;
 201         this.useFM = fm;
 202         setBackground(Color.white);
 203     }
 204 
 205     public static AttributedCharacterIterator getIterator(String s) {
 206         return new AttributedString(s).getIterator();
 207     }
 208 
 209     static String orient(PageFormat pf) {
 210         if (pf.getOrientation() == PageFormat.PORTRAIT) {
 211             return "Portrait";
 212         } else {
 213             return "Landscape";
 214         }
 215     }
 216 
 217     public int print(Graphics g, PageFormat pf, int pageIndex) {
 218 
 219         Graphics2D g2d = (Graphics2D)g;
 220         g2d.translate(pf.getImageableX(),  pf.getImageableY());
 221         g.drawString(page+" "+orient(pf),50,20);
 222         g.translate(0, 25);
 223         paint(g);
 224         return PAGE_EXISTS;
 225     }
 226 
 227     public Dimension getMinimumSize() {
 228         return getPreferredSize();
 229     }
 230 
 231     public Dimension getPreferredSize() {
 232         return new Dimension(preferredSize, preferredSize);
 233     }
 234 
 235     public void paint(Graphics g) {
 236 
 237         /* fill with white before any transformation is applied */
 238         g.setColor(Color.white);
 239         g.fillRect(0, 0, getSize().width, getSize().height);
 240 
 241 
 242         Graphics2D g2d = (Graphics2D) g;
 243         if (gxTx != null) {
 244             g2d.transform(gxTx);
 245         }
 246         if (useFM) {
 247             g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
 248                                  RenderingHints.VALUE_FRACTIONALMETRICS_ON);
 249         }
 250 
 251         g.setFont(textFont);
 252         FontMetrics fm = g.getFontMetrics();
 253 
 254         String s;
 255         int LS = 30;
 256         int ix=10, iy=LS+10;
 257         g.setColor(Color.black);
 258 
 259         s = "drawString(String str, int x, int y)";
 260         g.drawString(s, ix, iy);
 261         if (!textFont.isTransformed()) {
 262             g.drawLine(ix, iy+1, ix+fm.stringWidth(s), iy+1);
 263         }
 264 
 265         iy += LS;
 266         s = "drawString(AttributedCharacterIterator iterator, int x, int y)";
 267         g.drawString(getIterator(s), ix, iy);
 268 
 269         iy += LS;
 270         s = "\tdrawChars(\t\r\nchar[], int off, int len, int x, int y\t)";
 271         g.drawChars(s.toCharArray(), 0, s.length(), ix, iy);
 272         if (!textFont.isTransformed()) {
 273             g.drawLine(ix, iy+1, ix+fm.stringWidth(s), iy+1);
 274         }
 275 
 276         iy += LS;
 277         s = "drawBytes(byte[], int off, int len, int x, int y)";
 278         byte data[] = new byte[s.length()];
 279         for (int i = 0; i < data.length; i++) {
 280             data[i] = (byte) s.charAt(i);
 281         }
 282         g.drawBytes(data, 0, data.length, ix, iy);
 283 
 284         Font f = g2d.getFont();
 285         FontRenderContext frc = g2d.getFontRenderContext();
 286 
 287         iy += LS;
 288         s = "drawString(String s, float x, float y)";
 289         g2d.drawString(s, (float) ix, (float) iy);
 290         if (!textFont.isTransformed()) {
 291             g.drawLine(ix, iy+1, ix+fm.stringWidth(s), iy+1);
 292         }
 293 
 294         iy += LS;
 295         s = "drawString(AttributedCharacterIterator iterator, "+
 296             "float x, float y)";
 297         g2d.drawString(getIterator(s), (float) ix, (float) iy);
 298 
 299         iy += LS;
 300         s = "drawGlyphVector(GlyphVector g, float x, float y)";
 301         GlyphVector gv = f.createGlyphVector(frc, s);
 302         g2d.drawGlyphVector(gv, ix, iy);
 303         Point2D adv = gv.getGlyphPosition(gv.getNumGlyphs());
 304         if (!textFont.isTransformed()) {
 305             g.drawLine(ix, iy+1, ix+(int)adv.getX(), iy+1);
 306         }
 307 
 308         iy += LS;
 309         s = "GlyphVector with position adjustments";
 310 
 311         gv = f.createGlyphVector(frc, s);
 312         int ng = gv.getNumGlyphs();
 313         adv = gv.getGlyphPosition(ng);
 314         for (int i=0; i<ng; i++) {
 315             Point2D gp = gv.getGlyphPosition(i);
 316             double gx = gp.getX();
 317             double gy = gp.getY();
 318             if (i % 2 == 0) {
 319                 gy+=5;
 320             } else {
 321                 gy-=5;
 322             }
 323             gp.setLocation(gx, gy);
 324             gv.setGlyphPosition(i, gp);
 325         }
 326         g2d.drawGlyphVector(gv, ix, iy);
 327         if (!textFont.isTransformed()) {
 328             g.drawLine(ix, iy+1, ix+(int)adv.getX(), iy+1);
 329         }
 330 
 331         iy +=LS;
 332         s = "drawString: \u0924\u094d\u0930 \u0915\u0948\u0930\u0947 End.";
 333         g.drawString(s, ix, iy);
 334         if (!textFont.isTransformed()) {
 335             g.drawLine(ix, iy+1, ix+fm.stringWidth(s), iy+1);
 336         }
 337 
 338         iy += LS;
 339         s = "TextLayout 1: \u0924\u094d\u0930 \u0915\u0948\u0930\u0947 End.";
 340         TextLayout tl = new TextLayout(s, new HashMap(), frc);
 341         tl.draw(g2d,  ix, iy);
 342 
 343         iy += LS;
 344         s = "TextLayout 2: \u0924\u094d\u0930 \u0915\u0948\u0930\u0947 End.";
 345         tl = new TextLayout(s, f, frc);
 346         tl.draw(g2d,  ix, iy);
 347     }
 348 }
 349 
 350 class PrintJAText extends StandalonePrintTextTest {
 351 
 352 
 353     public PrintJAText(String page, Font font, AffineTransform gxTx,
 354                          boolean fm) {
 355         super(page, font, gxTx, fm);
 356     }
 357 
 358     private static final String TEXT =
 359         "\u3042\u3044\u3046\u3048\u304a\u30a4\u30ed\u30cf" +
 360         "\u30cb\u30db\u30d8\u30c8\u4e00\u4e01\u4e02\u4e05\uff08";
 361 
 362 
 363     public void paint(Graphics g) {
 364 
 365         /* fill with white before any transformation is applied */
 366         g.setColor(Color.white);
 367         g.fillRect(0, 0, getSize().width, getSize().height);
 368 
 369 
 370         Graphics2D g2d = (Graphics2D) g;
 371         if (gxTx != null) {
 372             g2d.transform(gxTx);
 373         }
 374         if (useFM) {
 375             g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
 376                                  RenderingHints.VALUE_FRACTIONALMETRICS_ON);
 377         }
 378 
 379         String text = TEXT + TEXT + TEXT;
 380         g.setColor(Color.black);
 381         int y = 20;
 382         float origSize = 7f;
 383         for (int i=0;i<11;i++) {
 384             float size = origSize+(i*0.1f);
 385             g2d.translate(0, size+6);
 386             Font f = textFont.deriveFont(size);
 387             g2d.setFont(f);
 388             FontMetrics fontMetrics = g2d.getFontMetrics();
 389             int stringWidth = fontMetrics.stringWidth(text);
 390             g.drawLine(0, y+1, stringWidth, y+1);
 391             g.drawString(text, 0, y);
 392             y +=10;
 393         }
 394     }
 395 }