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