1 /*
   2  * Copyright (c) 2019, Red Hat, Inc.
   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  * @test
  26  * @bug 8218854
  27  * @requires jdk.version.major >= 8
  28  * @run main/othervm MaxAdvanceIsMax
  29  */
  30 
  31 import java.awt.Font;
  32 import java.awt.FontMetrics;
  33 import java.awt.Graphics2D;
  34 import java.awt.GraphicsEnvironment;
  35 import java.awt.RenderingHints;
  36 import java.awt.image.BufferedImage;
  37 
  38 public class MaxAdvanceIsMax {
  39 
  40     private static boolean debug = true;
  41 
  42     private static final class AntialiasHint {
  43         private Object aaHint;
  44         private String asString = "";
  45 
  46         AntialiasHint(Object aaHint) {
  47             if (aaHint.equals(
  48                     RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)) {
  49                 asString += "FT_LOAD_TARGET_MONO";
  50             } else if (aaHint.equals(
  51                     RenderingHints.VALUE_TEXT_ANTIALIAS_ON)) {
  52                 asString += "FT_LOAD_TARGET_NORMAL";
  53             } else if (aaHint.equals(
  54                     RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB)) {
  55                 asString += "FT_LOAD_TARGET_LCD";
  56             } else if (aaHint.equals(
  57                     RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB)) {
  58                 asString += "FT_LOAD_TARGET_LCD_V";
  59             }
  60             this.aaHint = aaHint;
  61         }
  62 
  63         public Object getHint() {
  64             return aaHint;
  65         }
  66 
  67         public String toString() {
  68             return asString;
  69         }
  70     }
  71 
  72     private static final AntialiasHint[] antialiasHints = {
  73             new AntialiasHint(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF),
  74             new AntialiasHint(RenderingHints.VALUE_TEXT_ANTIALIAS_ON),
  75             new AntialiasHint(RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB),
  76             new AntialiasHint(RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB)
  77     };
  78 
  79     private static final class StyleAndSize {
  80         int style;
  81         float size;
  82         public StyleAndSize(int style, float size) {
  83             this.style = style;
  84             this.size = size;
  85         }
  86     };
  87 
  88     private static final StyleAndSize[] stylesAndSizes = new StyleAndSize[] {
  89         new StyleAndSize(Font.BOLD | Font.ITALIC, 10)
  90     };
  91 
  92     public static void main(String[] args) throws Exception {
  93         GraphicsEnvironment e =
  94                 GraphicsEnvironment.getLocalGraphicsEnvironment();
  95         Font[] fonts = e.getAllFonts();
  96         BufferedImage bi = new BufferedImage(500, 500,
  97                 BufferedImage.TYPE_INT_RGB);
  98         for (AntialiasHint antialiasHint : antialiasHints) {
  99             for (Font f : fonts) {
 100                 for (StyleAndSize styleAndSize : stylesAndSizes) {
 101                     f = f.deriveFont(styleAndSize.style, styleAndSize.size);
 102                     Graphics2D g2d = bi.createGraphics();
 103                     g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
 104                             antialiasHint.getHint());
 105                     FontMetrics fm = g2d.getFontMetrics(f);
 106                     int[] width;
 107                     int maxWidth = -1;
 108                     int maxAdvance = fm.getMaxAdvance();
 109                     if (debug) {
 110                         System.out.println("Testing " + f + " in " +
 111                                 antialiasHint);
 112                         System.out.println("getMaxAdvance: " + maxAdvance);
 113                     }
 114                     if (maxAdvance != -1) {
 115                         String failureMessage = null;
 116                         width = fm.getWidths();
 117                         for (int j = 0; j < width.length; j++) {
 118                             if (width[j] > maxWidth) {
 119                                 maxWidth = width[j];
 120                             }
 121                             if (width[j] > maxAdvance) {
 122                                 failureMessage = "FAILED: getMaxAdvance is " +
 123                                                  "not max for font: " +
 124                                                  f.toString() +
 125                                                  " getMaxAdvance(): " +
 126                                                  maxAdvance +
 127                                                  " getWidths()[" + j + "]: " +
 128                                                  width[j];
 129                                 throw new Exception(failureMessage);
 130                             }
 131                         }
 132                     }
 133                     if (debug) {
 134                         System.out.println("Max char width: " + maxWidth);
 135                         System.out.println("PASSED");
 136                         System.out.println(".........................");
 137                     }
 138                 }
 139             }
 140         }
 141         System.out.println("TEST PASS - OK");
 142     }
 143 }