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