5742c.diff
new/src/com/goldencode/cache/LFUAgingCache.java 2022-05-30 12:23:29 +0000 | ||
---|---|---|
2 | 2 |
** Module : LFUAgingCache.java |
3 | 3 |
** Abstract : LFU cache implementation which adjusts element importance by age of last access |
4 | 4 |
** |
5 |
** Copyright (c) 2014-2021, Golden Code Development Corporation.
|
|
5 |
** Copyright (c) 2014-2022, Golden Code Development Corporation.
|
|
6 | 6 |
** |
7 | 7 |
** -#- -I- --Date-- --------------------------------------Description---------------------------------------- |
8 | 8 |
** 001 ECF 20140922 Created initial version. |
... | ... | |
11 | 11 |
** 004 ECF 20190327 Refactored to include more implementation-specific logic, allowing parent |
12 | 12 |
** class to be more generic. |
13 | 13 |
** 005 ECF 20210519 Refactoring to adjust for changes in the class hierarchy. |
14 |
** TJD 20220527 Support for text-metrics cache controlled by server |
|
14 | 15 |
*/ |
15 | 16 |
/* |
16 | 17 |
** This program is free software: you can redistribute it and/or modify |
... | ... | |
132 | 133 |
} |
133 | 134 |
|
134 | 135 |
/** |
136 |
* Retrieve the Most Frequently Used items out of cache. |
|
137 |
* Order of result is unimportant. |
|
138 |
* |
|
139 |
* @param maxEntries - maximum number of entries to return |
|
140 |
* @return Most Frequently Used items out of cache |
|
141 |
*/ |
|
142 |
|
|
143 |
public Map<K, V> getMFUEntries(int maxEntries) |
|
144 |
{ |
|
145 |
Map<K, V> result = new HashMap<K, V>(); |
|
146 | ||
147 |
// reverse order to get MFU elements |
|
148 |
Iterator<Entry<K, V>> mfuElementsIterator = sorted.descendingIterator(); |
|
149 |
while (mfuElementsIterator.hasNext()) |
|
150 |
{ |
|
151 |
if (--maxEntries < 0) |
|
152 |
{ |
|
153 |
break; |
|
154 |
} |
|
155 |
Entry<K, V> entry = mfuElementsIterator.next(); |
|
156 |
result.put(entry.getKey(), entry.getValue()); |
|
157 |
} |
|
158 |
return result; |
|
159 |
} |
|
160 |
|
|
161 |
/** |
|
135 | 162 |
* Get the number of elements which will be expired from the cache each time it becomes full, |
136 | 163 |
* and capacity is required for a new element. |
137 | 164 |
* |
new/src/com/goldencode/p2j/main/WebClientBuilder.java 2022-05-30 12:23:29 +0000 | ||
---|---|---|
25 | 25 |
** SBI 20211003 Added http configuration settings for the web client. |
26 | 26 |
** EVL 20211222 Added implementation to pass options to client driver from server via socket. |
27 | 27 |
** EVL 20220105 Improvements for Windows specific options passing via socket for web client. |
28 |
** TJD 20220527 Support for text-metrics cache controlled by server |
|
28 | 29 |
*/ |
29 | 30 |
/* |
30 | 31 |
** This program is free software: you can redistribute it and/or modify |
... | ... | |
282 | 283 |
cmd.add("client:web:maxHttpIdleTimeout=" + options.get("maxHttpIdleTimeout")); |
283 | 284 |
cmd.add("client:web:maxResponseHeaderSize=" + options.get("maxResponseHeaderSize")); |
284 | 285 |
cmd.add("client:web:maxRequestHeaderSize=" + options.get("maxRequestHeaderSize")); |
286 |
cmd.add("client:text-metrics:cache-size=" + options.get("clientTextMetricsCacheSize")); |
|
285 | 287 |
|
286 | 288 |
// Sets the web client embedded mode |
287 | 289 |
cmd.add("client:web:embedded=" + options.get("embedded")); |
new/src/com/goldencode/p2j/main/WebClientBuilderOptions.java 2022-05-30 12:23:29 +0000 | ||
---|---|---|
2 | 2 |
** Module : WebClientBuilderOptions.java |
3 | 3 |
** Abstract : store web client parameters read from the directory |
4 | 4 |
** |
5 |
** Copyright (c) 2014-2021, Golden Code Development Corporation.
|
|
5 |
** Copyright (c) 2014-2022, Golden Code Development Corporation.
|
|
6 | 6 |
** |
7 | 7 |
** -#- -I- --Date-- ---------------------------------Description---------------------------------- |
8 | 8 |
** 001 CA 20140206 First version, extracted from ClientBuilderOptions. |
... | ... | |
28 | 28 |
** CA 20210924 Replaced 'sticked' with 'fixed' name, for web client taskbar style. |
29 | 29 |
** SBI 20210926 Removed code that updates jvm arguments for new client. |
30 | 30 |
** SBI 20211003 Added http configuration settings for the web client. |
31 |
** TJD 20220527 Support for text-metrics cache controlled by server |
|
31 | 32 |
*/ |
32 | 33 |
/* |
33 | 34 |
** This program is free software: you can redistribute it and/or modify |
... | ... | |
88 | 89 | |
89 | 90 |
import com.goldencode.p2j.cfg.*; |
90 | 91 |
import com.goldencode.p2j.net.*; |
92 |
import com.goldencode.p2j.ui.*; |
|
91 | 93 |
import com.goldencode.p2j.ui.client.chui.driver.*; |
92 | 94 |
import com.goldencode.p2j.web.*; |
93 | 95 |
// must be explicit to avoid abmiguity with Java |
... | ... | |
291 | 293 |
// Read if the drawing batches are cached |
292 | 294 |
boolean graphicsCached = cbo.getNode(DIRECTORY_NODE_ID, "graphicsCached", false); |
293 | 295 |
|
296 |
// Get client font metrics cache size from configuration |
|
297 |
int clientTextMetricsCacheSize = cbo.getNode(FontTable.FONT_METRICS_NODE_ID, "client-cache-size", 0); |
|
298 |
|
|
294 | 299 |
String taskBarStyle = cbo.getNode(DIRECTORY_NODE_ID, "taskBarStyle", "fixed").trim(); |
295 | 300 |
options.put("taskBarStyle", taskBarStyle); |
296 | 301 |
|
... | ... | |
320 | 325 |
options.put("pingPongInterval", String.valueOf(pingPongInterval)); |
321 | 326 |
options.put("maxLostPings", String.valueOf(maxLostPings)); |
322 | 327 |
options.put("delayBetweenPingTries", String.valueOf(delayBetweenPingTries)); |
328 |
options.put("clientTextMetricsCacheSize", String.valueOf(clientTextMetricsCacheSize)); |
|
323 | 329 | |
324 | 330 |
// sets true or false if the web client embedded mode is on or off respectively |
325 | 331 |
options.put("embedded", embedded ? "true" : "false"); |
new/src/com/goldencode/p2j/ui/FontTable.java 2022-05-30 14:15:46 +0000 | ||
---|---|---|
60 | 60 |
** 034 EVL 20220110 Adding support for symbolic font flag. |
61 | 61 |
** 035 AL2 20220425 Parse and use the web text scale font specification. |
62 | 62 |
** 036 AL2 20220430 Changed default value for webScale. |
63 |
** 037 TJD 20220525 Support for text-metrics cache controlled by server |
|
63 | 64 |
*/ |
64 | 65 | |
65 | 66 |
/* |
... | ... | |
120 | 121 |
import java.io.*; |
121 | 122 |
import java.net.*; |
122 | 123 |
import java.util.*; |
124 |
import java.util.concurrent.locks.*; |
|
123 | 125 |
import java.util.logging.*; |
124 | 126 |
import javax.xml.parsers.*; |
125 | 127 |
import org.w3c.dom.*; |
... | ... | |
207 | 209 |
/** The fallback font, in case the default fonts are not specified. */ |
208 | 210 |
private static final String FALLBACK_DEFAULT_FONT = "System, size 10"; |
209 | 211 |
|
212 |
/** The name of the node containing the font metrics management configuration */ |
|
213 |
public static final String FONT_METRICS_NODE_ID = "font-metrics"; |
|
214 | ||
210 | 215 |
/** A map containing the legacy font metrics. */ |
211 | 216 |
private static Map<String, LegacyFontMetrics> legacyFontMetrics = new HashMap<>(); |
212 | 217 |
|
... | ... | |
215 | 220 |
|
216 | 221 |
/** A map containing legacy text/font keys and legacy font width and height dimensions */ |
217 | 222 |
private static Map<String, int[]> sharedLegacyTextDimensions = new HashMap<>(); |
223 | ||
224 |
/** Runtime cache for legacy text/font keys and legacy font width and height dimensions |
|
225 |
* Cache entries are metrics of legacy font stored as int[2] |
|
226 |
* Invalid entries are stored as int[0], so client dont need to query server for these |
|
227 |
*/ |
|
228 |
private static LFUAgingCache<String, int[]> sharedLegacyTextMetricsCache = new LFUAgingCache<>(100000); |
|
229 | ||
230 |
/** Size of a runtime cache for legacy text/font keys and legacy font width and height dimensions */ |
|
231 |
private static int sharedLegacyTextMetricsCacheSize = 0; |
|
218 | 232 |
|
233 |
/** Lock for synchronizing parallel operations on sharedLegacyTextMetricsCache variables */ |
|
234 |
private static Lock sharedLegacyTextMetricsLock = new ReentrantLock(); |
|
235 | ||
219 | 236 |
/** A set containing the name of the fixed fonts. */ |
220 | 237 |
private static Set<String> fixedFonts = new TreeSet<>(); |
221 | 238 |
|
... | ... | |
1263 | 1280 |
*/ |
1264 | 1281 |
static int[] getLegacyTextMetrics(String text, String key) |
1265 | 1282 |
{ |
1266 |
LegacyTextMetrics ltm = legacyTextMetrics.get(text); |
|
1267 |
if (ltm == null) |
|
1268 |
{ |
|
1269 |
if (LOG.isLoggable(Level.FINE)) |
|
1270 |
{ |
|
1271 |
LOG.fine("Text [" + text+ "] has no legacy metrics with font [" + key + "]."); |
|
1272 |
} |
|
1273 | ||
1274 |
return null; |
|
1275 |
} |
|
1276 |
|
|
1277 |
LegacyFontMetrics lfm = ltm.legacyMetrics.get(key); |
|
1278 |
if (lfm == null) |
|
1279 |
{ |
|
1280 |
if (LOG.isLoggable(Level.FINE)) |
|
1281 |
{ |
|
1282 |
LOG.fine("Text [" + text+ "] has no legacy metrics with font [" + key + "]."); |
|
1283 |
} |
|
1284 | ||
1285 |
return null; |
|
1286 |
} |
|
1287 |
|
|
1288 |
return new int[] { lfm.width, lfm.height }; |
|
1283 |
String cacheKey = buildTextMetricsKey(key, text); |
|
1284 |
|
|
1285 |
int[] textMetrics = null; |
|
1286 |
|
|
1287 |
// map based operations are fast, so lock is only at beginning |
|
1288 |
sharedLegacyTextMetricsLock.lock(); |
|
1289 |
try |
|
1290 |
{ |
|
1291 |
textMetrics = sharedLegacyTextMetricsCache.get(cacheKey); |
|
1292 |
if (textMetrics != null) |
|
1293 |
{ |
|
1294 |
return textMetrics; |
|
1295 |
} |
|
1296 |
|
|
1297 |
LegacyTextMetrics ltm = legacyTextMetrics.get(text); |
|
1298 |
if (ltm == null) |
|
1299 |
{ |
|
1300 |
if (LOG.isLoggable(Level.FINE)) |
|
1301 |
{ |
|
1302 |
LOG.fine("Text [" + text + "] has no legacy metrics with font [" + key + "]."); |
|
1303 |
} |
|
1304 |
// Store invalid metrics value, so client knows it should not query server for this |
|
1305 |
sharedLegacyTextMetricsCache.putIfAbsent(cacheKey, new int[0]); |
|
1306 |
return null; |
|
1307 |
} |
|
1308 |
|
|
1309 |
LegacyFontMetrics lfm = ltm.legacyMetrics.get(key); |
|
1310 |
if (lfm == null) |
|
1311 |
{ |
|
1312 |
if (LOG.isLoggable(Level.FINE)) |
|
1313 |
{ |
|
1314 |
LOG.fine("Text [" + text + "] has no legacy metrics with font [" + key + "]."); |
|
1315 |
} |
|
1316 |
// Store invalid metrics value, so client knows it should not query server for this |
|
1317 |
sharedLegacyTextMetricsCache.putIfAbsent(cacheKey, new int[0]); |
|
1318 |
return null; |
|
1319 |
} |
|
1320 |
|
|
1321 |
textMetrics = new int[] {lfm.width, lfm.height }; |
|
1322 |
|
|
1323 |
sharedLegacyTextMetricsCache.putIfAbsent(cacheKey, textMetrics); |
|
1324 |
} |
|
1325 |
finally |
|
1326 |
{ |
|
1327 |
sharedLegacyTextMetricsLock.unlock(); |
|
1328 |
} |
|
1329 |
return textMetrics; |
|
1330 |
} |
|
1331 |
|
|
1332 |
/** |
|
1333 |
* buildTextMetricsKey - a helper method to unify TextMetrics keys creation |
|
1334 |
* @param key - font key |
|
1335 |
* @param text - text |
|
1336 |
* @return textMetrics key |
|
1337 |
*/ |
|
1338 |
private static String buildTextMetricsKey(String key, String text) |
|
1339 |
{ |
|
1340 |
return key + "#" + text; |
|
1289 | 1341 |
} |
1290 | 1342 |
|
1291 | 1343 |
/** |
... | ... | |
1297 | 1349 |
*/ |
1298 | 1350 |
static Map<String, int[]> readLegacyTextMetrics() |
1299 | 1351 |
{ |
1300 |
return sharedLegacyTextDimensions; |
|
1352 |
int currentServerCacheSize = Utils.getDirectoryNodeInt(null, |
|
1353 |
FONT_METRICS_NODE_ID + |
|
1354 |
"/" + |
|
1355 |
"server-cache-size", |
|
1356 |
-1, |
|
1357 |
false); |
|
1358 |
|
|
1359 |
Map<String, int[]> trimmedTextDimensions = sharedLegacyTextDimensions; |
|
1360 |
|
|
1361 |
// return full legacy metrics if server cache size is undefined or set to -1 |
|
1362 |
if (currentServerCacheSize == -1) |
|
1363 |
{ |
|
1364 |
return sharedLegacyTextDimensions; |
|
1365 |
} |
|
1366 |
else |
|
1367 |
{ |
|
1368 |
int clientCacheSize = Utils.getDirectoryNodeInt(null, |
|
1369 |
FONT_METRICS_NODE_ID + |
|
1370 |
"/" + |
|
1371 |
"client-cache-size", |
|
1372 |
100, |
|
1373 |
false); |
|
1374 |
|
|
1375 |
sharedLegacyTextMetricsLock.lock(); |
|
1376 |
try |
|
1377 |
{ |
|
1378 |
// reinitialize cache only if cache size configuration has changed in runtime |
|
1379 |
if (currentServerCacheSize != sharedLegacyTextMetricsCacheSize || |
|
1380 |
sharedLegacyTextMetricsCache == null) |
|
1381 |
{ |
|
1382 |
sharedLegacyTextMetricsCache = new LFUAgingCache<>(currentServerCacheSize); |
|
1383 |
sharedLegacyTextMetricsCacheSize = currentServerCacheSize; |
|
1384 |
} |
|
1385 |
// send to client the most frequently used elements |
|
1386 |
trimmedTextDimensions = sharedLegacyTextMetricsCache.getMFUEntries(clientCacheSize); |
|
1387 |
} |
|
1388 |
finally |
|
1389 |
{ |
|
1390 |
sharedLegacyTextMetricsLock.unlock(); |
|
1391 |
} |
|
1392 |
|
|
1393 |
} |
|
1394 |
|
|
1395 |
// send configured cache size to client |
|
1396 |
return trimmedTextDimensions; |
|
1301 | 1397 |
} |
1302 | 1398 |
|
1303 | 1399 |
/** |
... | ... | |
1573 | 1669 |
{ |
1574 | 1670 |
String fontKey = fontEntry.getKey(); |
1575 | 1671 |
LegacyFontMetrics fontMx = fontEntry.getValue(); |
1576 |
String textKey = fontKey + "#" + text;
|
|
1672 |
String textKey = buildTextMetricsKey(fontKey, text);
|
|
1577 | 1673 |
|
1578 | 1674 |
dimensions.put(textKey, new int[] { fontMx.width, fontMx.height }); |
1579 | 1675 |
} |
new/src/com/goldencode/p2j/ui/chui/ThinClient.java 2022-05-30 14:21:04 +0000 | ||
---|---|---|
2811 | 2811 |
** EVL 20220516 The call to moveToTop(boolean) should be now called with explicit cast. This |
2812 | 2812 |
** is Frame class specific method. |
2813 | 2813 |
** AL2 20220524 Replaced getTempDirectory with readHtmlBrowserWhitelist. |
2814 |
** TJD 20220527 Support for text-metrics cache controlled by server |
|
2814 | 2815 |
*/ |
2815 | 2816 | |
2816 | 2817 |
/* |
... | ... | |
3683 | 3684 |
// negotiate the UI theme (before requesting fonts and colors from server) |
3684 | 3685 |
ThemeManager.init(tc.server, cfg.getString("client", "driver", "theme", null)); |
3685 | 3686 |
|
3687 |
// read cache size from configuration |
|
3688 |
// 0 means - use the same size server sends to client |
|
3689 |
String textMetricsCacheSize = cfg.getString("client", "text-metrics", "cache-size", "0"); |
|
3690 |
int requestedTextMetricsCacheSize = 0; |
|
3691 |
if (textMetricsCacheSize != null) |
|
3692 |
{ |
|
3693 |
try |
|
3694 |
{ |
|
3695 |
requestedTextMetricsCacheSize = Integer.valueOf(textMetricsCacheSize); |
|
3696 |
} |
|
3697 |
catch (NumberFormatException e) |
|
3698 |
{ |
|
3699 |
} |
|
3700 |
} |
|
3701 | ||
3702 |
|
|
3686 | 3703 |
// initialize the font manager |
3687 |
FontManager.init(tc.server); |
|
3704 |
FontManager.init(tc.server, requestedTextMetricsCacheSize);
|
|
3688 | 3705 |
|
3689 | 3706 |
// initialize the client side widget ID worker |
3690 | 3707 |
WidgetIdHelper.initWorker(new ClientIdHelper()); |
new/src/com/goldencode/p2j/ui/client/FontManager.java 2022-05-30 14:14:20 +0000 | ||
---|---|---|
2 | 2 |
** Module : FontManager.java |
3 | 3 |
** Abstract : client-side font management class |
4 | 4 |
** |
5 |
** Copyright (c) 2011-2020, Golden Code Development Corporation.
|
|
5 |
** Copyright (c) 2011-2022, Golden Code Development Corporation.
|
|
6 | 6 |
** |
7 | 7 |
** -#- -I- --Date-- ---------------------------------Description---------------------------------- |
8 | 8 |
** 001 SIY 20111115 Created initial version |
... | ... | |
55 | 55 |
** 035 HC 20200416 Extended direct font control to allow to use system font names. |
56 | 56 |
** 036 AL2 20220425 Added web text scale to font key generation. |
57 | 57 |
** Onyl web scaled fonts are checked to be locally installed. |
58 |
** 037 TJD 20220525 Support for text-metrics cache controlled by server |
|
58 | 59 |
*/ |
59 | 60 | |
60 | 61 |
/* |
... | ... | |
115 | 116 |
import java.util.*; |
116 | 117 |
import java.util.logging.*; |
117 | 118 | |
119 |
import com.goldencode.cache.*; |
|
118 | 120 |
import com.goldencode.p2j.security.*; |
119 | 121 |
import com.goldencode.p2j.ui.*; |
120 | 122 |
import com.goldencode.p2j.ui.chui.*; |
... | ... | |
1053 | 1055 |
* @param server |
1054 | 1056 |
* The server exports. |
1055 | 1057 |
*/ |
1056 |
public static void init(ServerExports server) |
|
1058 |
public static void init(ServerExports server, int textMetricsCacheSize)
|
|
1057 | 1059 |
{ |
1058 | 1060 |
// do not use locate() here |
1059 | 1061 |
WorkArea wa = local.get(); |
1060 | 1062 |
|
1061 |
wa.initialize(server); |
|
1063 |
wa.initialize(server, textMetricsCacheSize);
|
|
1062 | 1064 |
} |
1063 | 1065 | |
1064 | 1066 |
/** |
... | ... | |
1207 | 1209 |
WorkArea wa = locate(); |
1208 | 1210 |
String tkey = getTextKey(fontKey, text); |
1209 | 1211 |
int[] metrics = new int[] { width, height }; |
1210 |
wa.textMetrics.put(tkey, metrics); |
|
1212 |
wa.textMetricsCache.put(tkey, metrics);
|
|
1211 | 1213 |
} |
1212 | 1214 | |
1213 | 1215 |
/** |
... | ... | |
1286 | 1288 | |
1287 | 1289 |
/** |
1288 | 1290 |
* Get the metrics for the specified text and font from the |
1289 |
* {@link WorkArea#textMetrics cache}.
|
|
1291 |
* {@link WorkArea#textMetricsCache cache} or {@link WorkArea#textMetrics metrics}.
|
|
1290 | 1292 |
* <p> |
1291 | 1293 |
* If not present, ask the server-side for the metrics. |
1292 | 1294 |
* |
... | ... | |
1312 | 1314 | |
1313 | 1315 |
/** |
1314 | 1316 |
* Get the metrics for the specified text and font from the |
1315 |
* {@link WorkArea#textMetrics cache}.
|
|
1317 |
* {@link WorkArea#textMetricsCache cache} or {@link WorkArea#textMetrics metrics}.
|
|
1316 | 1318 |
* <p> |
1317 | 1319 |
* If not present, ask the server-side for the metrics. |
1318 | 1320 |
* |
... | ... | |
1337 | 1339 |
|
1338 | 1340 |
/** |
1339 | 1341 |
* Get the metrics for the specified text and font from the |
1340 |
* {@link WorkArea#textMetrics cache}.
|
|
1342 |
* {@link WorkArea#textMetricsCache cache} or {@link WorkArea#textMetrics metrics}.
|
|
1341 | 1343 |
* <p> |
1342 | 1344 |
* If not present, ask the server-side for the metrics. |
1343 | 1345 |
* |
... | ... | |
1358 | 1360 |
ScreenDriver<?> driver) |
1359 | 1361 |
{ |
1360 | 1362 |
WorkArea wa = locate(); |
1361 |
String tkey = getTextKey(key, text); |
|
1362 |
int[] metrics = wa.textMetrics.get(tkey); |
|
1363 |
|
|
1364 |
if (metrics != null) |
|
1363 |
String cacheKey = getTextKey(key, text); |
|
1364 |
int[] metrics = null; |
|
1365 |
|
|
1366 |
synchronized (wa.textMetricsCache) |
|
1367 |
{ |
|
1368 |
metrics = wa.textMetricsCache.get(cacheKey); |
|
1369 |
} |
|
1370 |
|
|
1371 |
// metrics.length is 0 for server miss entries |
|
1372 |
if (metrics != null && metrics.length > 0) |
|
1365 | 1373 |
{ |
1366 | 1374 |
// found from cache, fast exit |
1367 | 1375 |
return metrics; |
1368 | 1376 |
} |
1369 | ||
1370 |
// check server-side |
|
1371 |
metrics = wa.server.getLegacyTextMetrics(text, key); |
|
1372 | 1377 |
|
1378 |
// check legacy text metrics initialized from server, it never has metrics.length == 0 |
|
1379 |
if (wa.textMetrics != null) |
|
1380 |
{ |
|
1381 |
metrics = wa.textMetrics.get(cacheKey); |
|
1382 |
} |
|
1383 |
// check server-side only if not in cache and not in text metrics from server |
|
1373 | 1384 |
if (metrics == null) |
1374 | 1385 |
{ |
1386 |
metrics = wa.server.getLegacyTextMetrics(text, key); |
|
1387 |
} |
|
1388 |
|
|
1389 |
if (metrics == null || metrics.length == 0) |
|
1390 |
{ |
|
1375 | 1391 |
// let the driver measure the string |
1376 | 1392 |
FontDetails<?> fd = wa.fontCache.get(key); |
1377 | 1393 |
|
... | ... | |
1396 | 1412 |
} |
1397 | 1413 |
} |
1398 | 1414 |
|
1399 |
// cache it |
|
1400 |
wa.textMetrics.put(tkey, metrics); |
|
1401 |
|
|
1415 |
// put result into cache |
|
1416 |
synchronized (wa.textMetricsCache) |
|
1417 |
{ |
|
1418 |
wa.textMetricsCache.put(cacheKey, metrics); |
|
1419 |
} |
|
1402 | 1420 |
return metrics; |
1403 | 1421 |
} |
1404 | 1422 | |
... | ... | |
1454 | 1472 |
/** Access to the client's environment. May be <code>null</code> if not on a Windows OS. */ |
1455 | 1473 |
private EnvironmentDaemon ed; |
1456 | 1474 |
|
1457 |
/** A cache of text metrics. 0-index is the width, 1-index is the height. */ |
|
1458 |
private final Map<String, int[]> textMetrics = new HashMap<String, int[]>(); |
|
1475 |
/** A full text metrics from server. Only used if client cache metrics is not configured*/ |
|
1476 |
private Map<String, int[]> textMetrics = null; |
|
1477 | ||
1478 |
/** A cache of text metrics. 0-index is the width, 1-index is the height. |
|
1479 |
* Default size will help in case server will not send anything at startup |
|
1480 |
*/ |
|
1481 |
private LRUCache<String, int[]> textMetricsCache = new LRUCache<String, int[]>(10000); |
|
1459 | 1482 |
|
1460 | 1483 |
/** Flag to track if the work area has been initialized. */ |
1461 | 1484 |
private boolean initialized = false; |
... | ... | |
1477 | 1500 |
* Initialize this work area. |
1478 | 1501 |
* |
1479 | 1502 |
* @param server |
1503 |
* @param configured TextMetrics cache size |
|
1480 | 1504 |
* The server exports. |
1481 | 1505 |
*/ |
1482 |
public void initialize(ServerExports server) |
|
1506 |
public void initialize(ServerExports server, int textMetricsCacheSize)
|
|
1483 | 1507 |
{ |
1484 | 1508 |
initialized = true; |
1485 | 1509 |
if (OutputManager.getDriver().isChui()) |
... | ... | |
1497 | 1521 |
fontCache.clear(); |
1498 | 1522 |
windowFontTables.clear(); |
1499 | 1523 |
envFontTables.clear(); |
1500 |
textMetrics.clear(); |
|
1501 | 1524 |
|
1502 | 1525 |
// initialize only in GUI mode |
1503 | 1526 |
this.server = server; |
... | ... | |
1523 | 1546 |
|
1524 | 1547 |
// pre-populate the legacy text metrics for all the fonts in the font-table |
1525 | 1548 |
Map<String, int[]> legacyTextMetrics = server.readLegacyTextMetrics(); |
1526 |
textMetrics.putAll(legacyTextMetrics); |
|
1527 | ||
1549 |
|
|
1550 |
// initialized if client cache size is not defined by configuration option client-cache-size |
|
1551 |
if (textMetricsCacheSize == 0) |
|
1552 |
{ |
|
1553 |
// if server sends a very small set of items set it to a minimal value |
|
1554 |
if (legacyTextMetrics == null || legacyTextMetrics.size() < 10000) |
|
1555 |
{ |
|
1556 |
textMetricsCache = new LRUCache<String, int[]>(10000); |
|
1557 |
} |
|
1558 |
else |
|
1559 |
{ |
|
1560 |
// if client cache is not defined in config use size of data from server |
|
1561 |
textMetrics = legacyTextMetrics; |
|
1562 |
} |
|
1563 |
} |
|
1564 |
else |
|
1565 |
{ |
|
1566 |
// if client cache size is defined in config - use it |
|
1567 |
textMetricsCache = new LRUCache<String, int[]>(textMetricsCacheSize); |
|
1568 |
} |
|
1569 |
|
|
1570 |
// copy text metrics received from server into local cache |
|
1571 |
// only if client cache size is defined |
|
1572 |
if (legacyTextMetrics != null && textMetrics == null) |
|
1573 |
{ |
|
1574 |
for (String key:legacyTextMetrics.keySet()) |
|
1575 |
{ |
|
1576 |
textMetricsCache.put(key, legacyTextMetrics.get(key)); |
|
1577 |
} |
|
1578 |
} |
|
1579 |
|
|
1528 | 1580 |
// the rest of the fonts are installing here |
1529 | 1581 |
driver.releaseWindow(); |
1530 | 1582 |