JDK-7175487 : Cannot customize font configuration on Linux
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 7
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: generic
  • Submitted: 2012-06-08
  • Updated: 2016-08-11
  • Resolved: 2016-07-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b131Fixed
Related Reports
Relates :  
Description
SYNOPSIS
--------
Cannot customise font configuration with Java 7 on Linux

OPERATING SYSTEM
----------------
Linux

FULL JDK VERSION
----------------
Java 7 onwards

PROBLEM DESCRIPTION
-------------------
We are unable to customize logical fonts with Java 7 on Linux.

With Java 6 we are able to customize the fontconfig.properties file, but with Java 7 we are not able to customize the fontconfig.properties files, as per the following documentation:

--------
Support for Linux and Solaris 11 fonts

Historically, the logical fonts for the JDK were statically specified in a fontconfig.properties file. However, on the various implementations of Linux, there is no consistency in the presence of fonts. So, without custom files, Asian (CJK) text, etc, would not be rendered. In JDK 7, on Linux, and for Solaris 11, in the absence of a customized fontconfig.properties file for the OS version, the default behavior is to use the system libfontconfig to select fonts to use for the logical fonts. In this case, the logical fonts will reflect the fonts used by the Gnome/KDE desktop applications which use the same platform library. For more information, see Fontconfig on freedesktop.org.
--------
http://docs.oracle.com/javase/7/docs/webnotes/adoptionGuide/index.html#swing

This documentation states that for operating systems which do no have a customized fontconfig.properties file, logical fonts will be defined by libfontconfig. However, if we make changes to the OS font configuration those changes are not picked up by the JDK.

TESTCASE
--------
import java.awt.*;

public class TestFonts extends Canvas {
    public static void main (String args[]) {
        TestFonts tf = new TestFonts();
        tf.doit();
    }

    public TestFonts() {
    }

    public void doit() {
        Font font = new Font("Monospaced", Font.PLAIN, 12);
        FontMetrics fm = getFontMetrics(font);
        int[] widths = fm.getWidths();
        int charWidth = widths[65]; // Y8741 use 'A' char for width calculation
        int charHeight = fm.getHeight();
        int charDescent = fm.getDescent();
        System.out.println("family="+font.getFamily()+",name="+font.getFontName());              
        System.out.println("charWidth ="+charWidth+" charHeight="+charHeight+" charDescent="+charDescent);
    }
}

REPRODUCTION INSTRUCTIONS
-------------------------
The following tests assume that your Linux installation has the font "Courier New" located at /usr/share/fonts/courier/cour.ttf.

Test 1: Confirm customized fontconfig.properties does not work in Java 7
========================================================================

1. Run class TestFonts, expected output: (exact output may vary)

   # /jre/bin/java TestFonts
   family=Monospaced,name=Monospaced.plain
   charWidth =7 charHeight=15 charDescent=3

2. Backup and remove /jre/lib/fontconfig.*

3. Create the file:

   /jre/lib/fontconfig.<OS version>.properties
   
   with the contents below. We were running on SUSE 11, so I created the
   file "fontconfig.SuSE.11.properties".

   --------
   version 1

   monospaced.plain.latin-1=-monotype-courier new-medium-r-normal--*-%d-*-*-m-*-iso8859-1

   sequence.allfonts=latin-1

   awtfontpath.latin-1=/usr/share/fonts/courier/cour.ttf
   --------

4. Run class TestFonts and note that the value of charWidth, charHeight,
   charDescent is the same as step 1 => fontconfig.properties does not
   change the phyiscal font of "Monospaced"

EXPECTED:
   # /jre/bin/java TestFonts
   family=Monospaced,name=Monospaced.plain
   charWidth =7 charHeight=14 charDescent=4

ACTUAL:
   # /jre/bin/java TestFonts
   family=Monospaced,name=Monospaced.plain
   charWidth =7 charHeight=15 charDescent=3


Test 2: Confirm libfontconfig changes are not picked up by Java 7, in the absence of a customized fontconfig.properties file
===================================================================================


1. Run class TestFonts, expected output: (exact output may vary)

   # /jre/bin/java TestFonts
   family=Monospaced,name=Monospaced.plain
   charWidth =7 charHeight=15 charDescent=3

2. Create ~/.fonts.conf with the following contents:

   --------
   <?xml version="1.0"?>
   <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
   <fontconfig>
           <alias binding="strong">
                   <family>Monospaced</family>
                   <prefer>
                           <family>Courier New</family>
                   </prefer>
           </alias>
   </fontconfig>
   --------

3. Run fc-match to verify libfontconfig should select "Courier New" for
   monospace

   # fc-match monospace
   cour.ttf: "Courier New" "Normal"

4. Run class TestFonts and note that the value of charWidth, charHeight,
   charDescent is the same as step 1 => OS libfontconfig settings do not
   change the phyiscal font of "Monospaced"

EXPECTED:
   # /jre/bin/java TestFonts
   family=Monospaced,name=Monospaced.plain
   charWidth =7 charHeight=14 charDescent=4

ACTUAL:
   # /jre/bin/java TestFonts
   family=Monospaced,name=Monospaced.plain
   charWidth =7 charHeight=15 charDescent=3

Comments
This works for me on Ubuntu 13.04 at least in so far as a correctly named fontconfig.Ubuntu.13.04.properties is located and parsed on Ubuntu13.04 .. I don't know what "OpenSuSE" reports as distro but the fontconfig file should match what is in /etc/lsb-release. Also if it has an /etc/SuSE-release file then we will assume "SuSE" as the string to look for as such then we have no code that tries to recognise that, we look for "SuSE" However the file, once found, must also have valid content and mappings to files for the fonts. That requires care to get right. We have a "smoke test" function that does some validation but I think it might be worth just deleting that test. It says its testing slot 0 of a particular composite but it is more random than that. Also listing the file name is preferred but not mandatory. If someone creates a file for the distro then they may be running up against that failing the file before they have worked out the kinks. Also I notice the bug has this :- awtfontpath.latin-1=/usr/share/fonts/courier/cour.ttf The value is supposed to be a directory, not a file. See http://docs.oracle.com/javase/1.5.0/docs/guide/intl/fontconfig.html#unix
20-07-2016

Tried to understand and reproduce the issue on Ubuntu. The code sample (given in the bug-description) does not respond to the changes done in fontconfig.properties file located under jdk/lib, instead it responds to the changes done in the autogenerated font-config file under $HOME/.java/fonts. It seems like the auto-generated font-config under $HOME/.java/fonts has precedence over the fontconfig properties in jdk/lib
07-07-2016

- this is an issue reported against 7(7u), - there are now affected version 9 filed for this issue - 7u issues are transferred to Sustaining Nevertheless if someone have a report against 9 - please reopen and add affectedVersion 9 or 7u specific escalations might be reopen to Sustaining
10-08-2014

- this is an issue reported against 7(7u), - there are now affected version 9 filed for this issue - 7u issues are transferred to Sustaining Nevertheless if someone have a report against 9 - please reopen and add affectedVersion 9 or 7u specific escalations might be reopen to Sustaining
10-08-2014

as P3 needs to be fixed or deferred
27-05-2014

EVALUATION This is a duplicate of 6951776. The same fix is required in JDK 7 and 8 to support fontconfig customization.
14-06-2012