Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8051892

Font.equals doesn't consider version

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • tbd
    • 7u65, 8, 9
    • client-libs
    • 2d
    • x86_64
    • linux_ubuntu

      FULL PRODUCT VERSION :
      Applicable to all Java versions

      ADDITIONAL OS VERSION INFORMATION :
      Applicable to all OSes

      A DESCRIPTION OF THE PROBLEM :
      Load two fonts from the ttf files such that the two fonts have same PS name but different PS versions.

      Call java.awt.Font.equals() on one object with the other as the arguement and see that the returned value is true.

      This causes several bugs elsewhere. For example, if one font had been loaded earlier. Then the second font is used to run the following:

      FontRenderContext frc = graphics2d.getFontRenderContext();
      GlyphVector gv = font2.layoutGlyphVector(frc, text, 0, text_length, flag);
      graphics2d.drawGlyphVector(gv, x, y);

      This ends up using cache built from the font1 and hence results in unpredictable erros depending on the difference in the two font versions.

      In one case, I noticed that "bcd" was rendered as "cde". When font2 was loaded first and then font1 was used to render "bcd" the output was "abc". For some other chars, like "!" in one case, the result was ArrayIndexOutOfBoundsException or a non printable char depending again on which font was used for the cache.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      You can get two such fonts from:
      https://android.googlesource.com/platform/frameworks/base/+/6a0ef07e1fff9c09542b5df1db762b3935e10898/data/fonts/Roboto-Regular.ttf

      and

      https://android.googlesource.com/platform/frameworks/base/+/e68d87e0920133cb8799bc89abb8d1206c3d7750/data/fonts/Roboto-Regular.ttf

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Fonts loaded from different ttf files that have different PS versions are not equal.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package com.javabug;

      import java.awt.Font;
      import java.awt.Graphics;
      import java.awt.Graphics2D;
      import java.awt.font.FontRenderContext;
      import java.awt.font.GlyphVector;
      import java.io.File;

      import javax.swing.JFrame;
      import javax.swing.JPanel;
      import javax.swing.WindowConstants;

      /**
       * Created by deepanshu on 7/23/14.
       */
      public class Main extends JPanel {

          @Override
          public void paint(Graphics g) {
              Graphics2D g2 = (Graphics2D) g;
              g2.clearRect(0, 0, 1000, 1000);
              Font font1, font2;
              File firstFontPath = new File("file path for first font");
              File secondFontPath = new File("file path for second font");
              boolean loadFont1First = true;
              try {
                  if (loadFont1First) {
                      font1 = Font.createFont(Font.TRUETYPE_FONT, firstFontPath);
                      font2 = Font.createFont(Font.TRUETYPE_FONT, secondFontPath);
                  } else {
                      font1 = Font.createFont(Font.TRUETYPE_FONT, secondFontPath);
                      font2 = Font.createFont(Font.TRUETYPE_FONT, firstFontPath);
                  }
              } catch (Exception e) {
                  e.printStackTrace();
                  return;
              }
              font1 = font1.deriveFont(15f);
              font2 = font2.deriveFont(15f);
              FontRenderContext frc = g2.getFontRenderContext();
              char[] text = "text".toCharArray();
              
              // Draw with first font.
              GlyphVector gv = font1.layoutGlyphVector(frc, text, 0, text.length,
                      Font.LAYOUT_NO_LIMIT_CONTEXT | Font.LAYOUT_NO_START_CONTEXT);
              g2.drawGlyphVector(gv, 20, 20);
              
              // Draw with second font.
              gv = font2.layoutGlyphVector(frc, text, 0, text.length, Font.LAYOUT_NO_LIMIT_CONTEXT |
                      Font.LAYOUT_NO_START_CONTEXT);
              g2.drawGlyphVector(gv, 20, 100);
          }

          public static void main(String[] args) {
              JFrame f = new JFrame();
              Main main = new Main();
              main.setBounds(0, 0, 500, 500);
              f.getContentPane().add(main);
              f.setSize(300, 200);
              f.setVisible(true);
              f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      None. I'm editing the font files to change the font names encoded in them and include the version number.

            prr Philip Race
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            11 Start watching this issue

              Created:
              Updated:
              Resolved: