From d4137a890fff8e09c87427d6a5fef91e25ba13b1 Mon Sep 17 00:00:00 2001 From: Alexander Schulz-Rosengarten <als@informatik.uni-kiel.de> Date: Sat, 1 May 2021 11:02:24 +0200 Subject: [PATCH] Improved font size handling for offscreen rendering. Also adjusted svg renderer to use pixel sizes in offscreen mode. --- .../freehep/SemanticSVGGraphics2D.java | 41 ++++++++++++++++++- .../src/de/cau/cs/kieler/klighd/Klighd.java | 27 +++++++++++- .../klighd/microlayout/PlacementUtil.java | 12 ++++-- 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/plugins/de.cau.cs.kieler.klighd.piccolo.freehep/src/de/cau/cs/kieler/klighd/piccolo/freehep/SemanticSVGGraphics2D.java b/plugins/de.cau.cs.kieler.klighd.piccolo.freehep/src/de/cau/cs/kieler/klighd/piccolo/freehep/SemanticSVGGraphics2D.java index fbf4ee87b..ef98416a6 100644 --- a/plugins/de.cau.cs.kieler.klighd.piccolo.freehep/src/de/cau/cs/kieler/klighd/piccolo/freehep/SemanticSVGGraphics2D.java +++ b/plugins/de.cau.cs.kieler.klighd.piccolo.freehep/src/de/cau/cs/kieler/klighd/piccolo/freehep/SemanticSVGGraphics2D.java @@ -961,6 +961,43 @@ private String getTextsString(String text, Properties style, String indentation) y += lineHeight; } + } else if (Klighd.simulateSwtFontSizeInAwt()) { + // If simulation of SWT font sizes in AWT is active we can use px size and set text length + + final int fontSize = getFont().getSize(); + final float y = fontSize * pointToPxFactor; + final Double nextLength = this.nextTextLength; + this.nextTextLength = null; + + // if we have a multi-line text and a configured nextTextLength + // we need to recalculate the designated textLength per line + // otherwise we can stick to the given 'nextTextLength' value + boolean noTextLengthPerLineCalcRequired = nextLength == null || isSingleLine; + final FontData fontData = noTextLengthPerLineCalcRequired ? null : getFontData(getFont()); + + for (final String line : lines) { + content.append("\n" + indentation); + content.append("<text x=\"0\" y=\"").append(y).append("\""); + + final Double nextLineLength = noTextLengthPerLineCalcRequired ? nextLength : + // need to box the result here as the type of the ternary operation would be 'double' otherwise + // yielding NPEs if 'nextLength' is 'null' + Double.valueOf(PlacementUtil.estimateTextSize(fontData, line).getWidth()); + + // text length + content.append(textLength(nextLineLength)); + // semantic data + content.append(isSingleLine ? " " + // style + + style(style) + // semantic data + + attributes(false) : "" + ); + content.append(textLineAttributes(line, i++)); + content.append(">"); + content.append(line); + content.append("</text>"); + } } else { // without a display just use the pt size as line height for multiline text @@ -1098,10 +1135,10 @@ private Properties getFontProperties(Font font) { * A font's size is specified in 'pt' which is a relative size where a height of 72pt * corresponds to 1 inch. When a font is rendered on a screen however, these pts are converted * to pixels and sizes of nodes and boxes are determined correspondingly. We thus use a px size - * if we are able to determine the device with wich the font was rendered (i.e. the device). + * if we are able to determine the device with which the font was rendered (i.e. the device). */ Float size = (Float) attributes.get(TextAttribute.SIZE); - if (display != null) { + if (display != null || Klighd.simulateSwtFontSizeInAwt()) { result.put("font-size", fixedPrecision(size.floatValue() * pointToPxFactor) + "px"); } else { result.put("font-size", fixedPrecision(size.floatValue()) + "pt"); diff --git a/plugins/de.cau.cs.kieler.klighd/src/de/cau/cs/kieler/klighd/Klighd.java b/plugins/de.cau.cs.kieler.klighd/src/de/cau/cs/kieler/klighd/Klighd.java index 71f303e1a..702fc4691 100644 --- a/plugins/de.cau.cs.kieler.klighd/src/de/cau/cs/kieler/klighd/Klighd.java +++ b/plugins/de.cau.cs.kieler.klighd/src/de/cau/cs/kieler/klighd/Klighd.java @@ -46,6 +46,7 @@ public class Klighd { private static IKlighdStatusManager statusManager; private static boolean suppressDisplayScaleCompensationWhileHandlingText = false; + private static boolean simulateSwtFontSizeInAwt = true; static { boolean isLinux = false; @@ -128,7 +129,31 @@ public static boolean isSuppressDisplayScaleCompensationWhileHandlingText() { * <code>true</code> if compensation shall be suppressed, <code>false</code> reverts * to the default. */ - public static void setSuppressDisplayScaleCompensationWhileHandlingText(boolean suppress) { + public static void setSuppressDisplayScaleCompensationWhileHandlingText(final boolean suppress) { suppressDisplayScaleCompensationWhileHandlingText = suppress; } + + /** + * Returns the (global) setting on adjusting the font size estimation of AWT to match SWT sizes + * more closely. This also enables using px instead of pt when rendering SVGs. + * + * @return <code>true</code> if simulation is active and fonts will be scaled (default), + * <code>false</code> otherwise. + */ + public static boolean simulateSwtFontSizeInAwt() { + return simulateSwtFontSizeInAwt; + } + + /** + * Changes the (global) setting on adjusting adjusting the font size estimation of AWT to match SWT sizes + * more closely. This also enables using px instead of pt when rendering SVGs. + * This setting will only affect non-UI applications, but may be switched off if default AWT font sizes and values + * in pt are preferred. + * + * @param simulate + * <code>true</code> if font sizes should be adjusted, <code>false</code> to deactivate this behavior. + */ + public static void setSimulateSwtFontSizeInAwt(final boolean simulate) { + simulateSwtFontSizeInAwt = simulate; + } } diff --git a/plugins/de.cau.cs.kieler.klighd/src/de/cau/cs/kieler/klighd/microlayout/PlacementUtil.java b/plugins/de.cau.cs.kieler.klighd/src/de/cau/cs/kieler/klighd/microlayout/PlacementUtil.java index 3e41b3f15..5b5fdc883 100644 --- a/plugins/de.cau.cs.kieler.klighd/src/de/cau/cs/kieler/klighd/microlayout/PlacementUtil.java +++ b/plugins/de.cau.cs.kieler.klighd/src/de/cau/cs/kieler/klighd/microlayout/PlacementUtil.java @@ -245,7 +245,7 @@ public C getC() { // CHECKSTYLEON Visibility private static final KRenderingPackage KRENDERING_PACKAGE = KRenderingPackage.eINSTANCE; - + private static final float PT_TO_PX_FACTOR = KlighdConstants.DEFAULT_DISPLAY_DPI / 72f; /** * Evaluates a position inside given parent bounds. @@ -934,10 +934,11 @@ public static Bounds estimateTextSize(final KText kText) { public static Bounds estimateTextSize(final KText kText, final String text) { final Bounds testSize = getTestingTextSize(kText); - if (testSize != null) + if (testSize != null) { return testSize; - else + } else { return estimateTextSize(fontDataFor(kText, null), text); + } } /** @@ -1092,6 +1093,11 @@ private static Bounds estimateTextSizeAWT(final FontData fontData, final String textBounds = new Bounds(fm.getStringBounds(text, fmg)); } + if (Klighd.simulateSwtFontSizeInAwt()) { + textBounds.width *= PT_TO_PX_FACTOR; + textBounds.height *= PT_TO_PX_FACTOR; + } + return textBounds; }