Skip to content

Commit 765d73f

Browse files
committed
[win32] Cache font height to prevent inconsistency
This commit adapts a limitation of handling fonts in the win32 implementation. When a font is initialized with FontData the height in points of it and the desired target zoom will be used to calculate the font height in pixels. When the FontData of an existing font is retrieved the Logfont data from the OS together with the font zoom are used to recalculate the original font height. As the conversion to pixels involved rounding, the reversed calculation will result in a different value than was used on creation time. With monitor-specific scaling a font for a different zoom will be calculated on the basis of the FontData of an existing base font. This can lead to font heights in pixels that differ from the "correct" value. To solve this limitation each font handle and its original font height in points are cached in a static Map to recreate the original value when Font::getFontData is called.
1 parent b85d9d2 commit 765d73f

File tree

2 files changed

+16
-17
lines changed

2 files changed

+16
-17
lines changed

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Font.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
package org.eclipse.swt.graphics;
1515

1616

17+
import java.util.*;
18+
1719
import org.eclipse.swt.*;
1820
import org.eclipse.swt.internal.*;
1921
import org.eclipse.swt.internal.win32.*;
@@ -55,6 +57,9 @@ public final class Font extends Resource {
5557
* (Warning: This field is platform dependent)
5658
*/
5759
int zoom;
60+
61+
private static Map<Long, Float> fontHeightCache = new HashMap<>();
62+
5863
/**
5964
* Prevents uninitialized instances from being created outside the package.
6065
*/
@@ -176,6 +181,7 @@ public Font(Device device, String name, int height, int style) {
176181
@Override
177182
void destroy() {
178183
OS.DeleteObject(handle);
184+
fontHeightCache.remove(handle);
179185
handle = 0;
180186
}
181187

@@ -213,7 +219,13 @@ public FontData[] getFontData() {
213219
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
214220
LOGFONT logFont = new LOGFONT ();
215221
OS.GetObject(handle, LOGFONT.sizeof, logFont);
216-
float heightInPoints = device.computePoints(logFont, handle, zoom);
222+
223+
float heightInPoints;
224+
if (fontHeightCache.containsKey(handle)) {
225+
heightInPoints = fontHeightCache.get(handle);
226+
} else {
227+
heightInPoints = device.computePoints(logFont, handle, zoom);
228+
}
217229
return new FontData[] {FontData.win32_new(logFont, heightInPoints)};
218230
}
219231

@@ -240,6 +252,7 @@ void init (FontData fd) {
240252
handle = OS.CreateFontIndirect(logFont);
241253
logFont.lfHeight = lfHeight;
242254
if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
255+
fontHeightCache.put(handle, fd.height);
243256
}
244257

245258
/**

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ScalingSWTFontRegistry.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ private Font getScaledFont(int targetZoom) {
5353

5454
private Font scaleFont(int zoom) {
5555
FontData fontData = baseFont.getFontData()[0];
56-
int baseZoom = computeZoom(fontData);
57-
fontData.data.lfHeight = Math.round(1.0f * fontData.data.lfHeight * zoom / baseZoom);
5856
Font scaledFont = Font.win32_new(device, fontData, zoom);
5957
addScaledFont(zoom, scaledFont);
6058
return scaledFont;
@@ -134,9 +132,8 @@ public Font getFont(FontData fontData, int zoom) {
134132
if (fontKeyMap.containsKey(fontData)) {
135133
container = fontKeyMap.get(fontData);
136134
} else {
137-
int calculatedZoom = computeZoom(fontData);
138-
Font newFont = Font.win32_new(device, fontData, calculatedZoom);
139-
container = new ScaledFontContainer(newFont, calculatedZoom);
135+
Font newFont = Font.win32_new(device, fontData, zoom);
136+
container = new ScaledFontContainer(newFont, zoom);
140137
fontHandleMap.put(newFont.handle, container);
141138
fontKeyMap.put(fontData, container);
142139
}
@@ -167,15 +164,4 @@ private Font getOrCreateFont(ScaledFontContainer container, int zoom) {
167164
}
168165
return scaledFont;
169166
}
170-
171-
private int computeZoom(FontData fontData) {
172-
int pixelHeight = fontData.data.lfHeight;
173-
float currentPointHeight = fontData.height;
174-
if (pixelHeight == 0 || Math.abs(currentPointHeight) < 0.001) {
175-
// if there is no font yet available, we use a defined zoom
176-
return 100;
177-
}
178-
float pointHeightOn100 = -(pixelHeight / 96f * 72f);
179-
return Math.round(100.0f * pointHeightOn100 / currentPointHeight);
180-
}
181167
}

0 commit comments

Comments
 (0)