• category: swing folder: W3CLengthUnits title: JEditorPaneのHTMLレンダリングでw3c準拠の長さ単位を使用する tags: [JEditorPane, Html, StyleSheet, CSS] author: aterai pubdate: 2020-10-12T03:21:41+09:00 description: JEditorPaneのHTMLレンダリングでフォントサイズなどに指定された絶対単位をw3c準拠の長さで表示します。 image: https://drive.google.com/uc?id=1j_CUQjXi2KjzpbM-AlCQME1ZInedQArw

概要

JEditorPaneHTMLレンダリングでフォントサイズなどに指定された絶対単位をw3c準拠の長さで表示します。

サンプルコード

JEditorPane editor = new JEditorPane("text/html", "");

HTMLEditorKit htmlEditorKit = (HTMLEditorKit) editor.getEditorKit();
StyleSheet styles = htmlEditorKit.getStyleSheet();
styles.addRule(".number {font-size: 14}");
styles.addRule(".pt {font-size: 14pt}");
styles.addRule(".em {font-size: 1.2em}");
styles.addRule(".percentage {font-size: 120%}");

String html = "<html><h3>h3 {font-size: medium}</h3>"
    + "<h3 class='number'>h3 {font-size: 14}</h3>"
    + "<h3 class='pt'>h3 {font-size: 14pt}</h3>"
    + "<h3 class='em'>h3 {font-size: 1.2em}</h3>"
    + "<h3 class='percentage'>h3 {font-size: 120%}</h3>";
editor.setText(html);

JCheckBox check = new JCheckBox("JEditorPane.W3C_LENGTH_UNITS");
check.addActionListener(e -> editor.putClientProperty(
    JEditorPane.W3C_LENGTH_UNITS, ((JCheckBox) e.getSource()).isSelected()));
View in GitHub: Java, Kotlin

解説

  • JEditorPane.W3C_LENGTH_UNITS: false
    • デフォルト
  • JEditorPane.W3C_LENGTH_UNITS: true
    • w3c準拠の長さ単位を使用する
    • CSS.LengthUnitクラスで以下のようにマッピングされているため、例えばポイントでfont-sizeが指定されている場合、JEditorPane.W3C_LENGTH_UNITStrueに設定すると一般的なWindows環境では96/72倍文字サイズが拡大する
    • 単位指定なしや相対単位の場合は変化しない
    • このサンプルのh3要素で相対単位のem%指定のfont-sizeが変化するのは親のbody要素の14ptを継承しているため
    • 以下のコードでは高DPIで文字サイズが大きくなりすぎるので8231286: HTML font size too large with high-DPI scaling and W3C_UNIT_LENGTHS by prsadhuk · Pull Request #1628 · openjdk/jdkで修正される模様
@see javax/swing/text/html/CSS.java
static class LengthUnit implements Serializable {
  static Hashtable<String, Float> lengthMapping = new Hashtable<String, Float>(6);
  static Hashtable<String, Float> w3cLengthMapping = new Hashtable<String, Float>(6);
  static {
    lengthMapping.put("pt", Float.valueOf(1f));
    // Not sure about 1.3, determined by experiementation.
    lengthMapping.put("px", Float.valueOf(1.3f));
    lengthMapping.put("mm", Float.valueOf(2.83464f));
    lengthMapping.put("cm", Float.valueOf(28.3464f));
    lengthMapping.put("pc", Float.valueOf(12f));
    lengthMapping.put("in", Float.valueOf(72f));
    int res = 72;
    try {
      res = Toolkit.getDefaultToolkit().getScreenResolution();
    } catch (HeadlessException e) {
    }
    // mapping according to the CSS2 spec
    w3cLengthMapping.put("pt", Float.valueOf(res / 72f));
    w3cLengthMapping.put("px", Float.valueOf(1f));
    w3cLengthMapping.put("mm", Float.valueOf(res / 25.4f));
    w3cLengthMapping.put("cm", Float.valueOf(res / 2.54f));
    w3cLengthMapping.put("pc", Float.valueOf(res / 6f));
    w3cLengthMapping.put("in", Float.valueOf((float) res));
  }
  // ...
}

参考リンク

コメント