Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 59d99d1068201fe6739f1c36e8e8afbd37695b35 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
/*******************************************************************************
 * Copyright (c) 2008, 2014 Angelo Zerr and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
 *     IBM Corporation
 *     Remy Chi Jian Suen <remy.suen@gmail.com>
 *******************************************************************************/
package org.eclipse.e4.ui.css.swt.helpers;

import static org.eclipse.e4.ui.css.swt.helpers.ThemeElementDefinitionHelper.normalizeId;

import org.eclipse.e4.ui.css.core.css2.CSS2FontHelper;
import org.eclipse.e4.ui.css.core.css2.CSS2FontPropertiesHelpers;
import org.eclipse.e4.ui.css.core.css2.CSS2PrimitiveValueImpl;
import org.eclipse.e4.ui.css.core.dom.properties.css2.CSS2FontProperties;
import org.eclipse.e4.ui.css.core.dom.properties.css2.CSS2FontPropertiesImpl;
import org.eclipse.e4.ui.css.core.engine.CSSElementContext;
import org.eclipse.e4.ui.internal.css.swt.CSSActivator;
import org.eclipse.e4.ui.internal.css.swt.definition.IColorAndFontProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Widget;
import org.w3c.dom.css.CSSPrimitiveValue;
import org.w3c.dom.css.CSSValue;

/**
 * CSS SWT Font Helper to :
 * <ul>
 * <li>get CSS2FontProperties from Font of SWT Control.</li>
 * <li>get Font of SWT Control from CSS2FontProperties.</li>
 * </ul>
 */
public class CSSSWTFontHelper {
	public static final String FONT_DEFINITION_MARKER = "#";

	private static final String DEFAULT_FONT = "defaultFont";

	/**
	 * Get CSS2FontProperties from Control stored into Data of Control. If
	 * CSS2FontProperties doesn't exist, create it from Font of Control and
	 * store it into Data of Control.
	 *
	 * @param control
	 * @return
	 */
	public static CSS2FontProperties getCSS2FontProperties(Widget widget,
			Font font, CSSElementContext context) {
		// Search into Data of Control if CSS2FontProperties exist.
		CSS2FontProperties fontProperties = CSS2FontPropertiesHelpers
				.getCSS2FontProperties(context);
		if (fontProperties == null) {
			// CSS2FontProperties doesn't exist, create it
			fontProperties = getCSS2FontProperties(font);
			// store into ClientProperty the CSS2FontProperties
			CSS2FontPropertiesHelpers.setCSS2FontProperties(fontProperties,
					context);
		}
		return fontProperties;
	}

	/**
	 * Get CSS2FontProperties from the widget. If CSS2FontProperties doesn't
	 * exist, create it from the widget's font, if it has one, and then store it
	 * in the widget's data if applicable.
	 *
	 * @param widget
	 *            the widget to retrieve CSS2 font properties from
	 * @return the font properties of the specified widget, or <code>null</code>
	 *         if none
	 */
	public static CSS2FontProperties getCSS2FontProperties(Widget widget,
			CSSElementContext context) {
		return getCSS2FontProperties(getFont(widget), context);
	}

	public static CSS2FontProperties getCSS2FontProperties(Font font,
			CSSElementContext context) {
		// Search into Data of Control if CSS2FontProperties exist.
		CSS2FontProperties fontProperties = CSS2FontPropertiesHelpers
				.getCSS2FontProperties(context);
		if (fontProperties == null && font != null) {
			// CSS2FontProperties doesn't exist, create it
			fontProperties = getCSS2FontProperties(font);
			// store into ClientProperty the CSS2FontProperties
			CSS2FontPropertiesHelpers.setCSS2FontProperties(fontProperties,
					context);
		}
		return fontProperties;
	}

	/**
	 * Build CSS2FontProperties from SWT Font.
	 *
	 * @param font
	 * @return
	 */
	public static CSS2FontProperties getCSS2FontProperties(Font font) {
		// Create CSS Font Properties
		CSS2FontProperties fontProperties = new CSS2FontPropertiesImpl();
		if (font != null) {
			FontData fontData = getFirstFontData(font);
			// Update font-family
			String fontFamily = getFontFamily(font);
			fontProperties.setFamily(new CSS2PrimitiveValueImpl(fontFamily));
			// Update font-size
			int fontSize = fontData.getHeight();
			fontProperties.setSize(new CSS2PrimitiveValueImpl(fontSize));
			// Update font-weight
			String fontWeight = getFontWeight(font);
			fontProperties.setWeight((new CSS2PrimitiveValueImpl(fontWeight)));
			// Update font-style
			String fontStyle = getFontStyle(font);
			fontProperties.setStyle((new CSS2PrimitiveValueImpl(fontStyle)));
		}
		return fontProperties;
	}

	/**
	 * Get CSS2FontProperties from Font of JComponent and store
	 * CSS2FontProperties instance into ClientProperty of JComponent.
	 *
	 * @param component
	 * @return
	 */
	public static Font getFont(CSS2FontProperties fontProperties,
			Control control) {
		FontData oldFontData = getFirstFontData(control.getFont());
		return getFont(fontProperties, oldFontData, control.getDisplay());
	}

	public static Font getFont(CSS2FontProperties fontProperties,
			FontData oldFontData, Display display) {
		FontData newFontData = getFontData(fontProperties, oldFontData);
		return new Font(display, newFontData);
	}

	/**
	 * Return FontData from {@link CSS2FontProperties}.
	 *
	 * @param fontProperties
	 * @param control
	 * @return
	 */
	public static FontData getFontData(CSS2FontProperties fontProperties,
			FontData oldFontData) {
		FontData newFontData = new FontData();

		// Family
		CSSPrimitiveValue cssFontFamily = fontProperties.getFamily();
		FontData[] fontDataByDefinition = new FontData[0];
		boolean fontDefinitionAsFamily = hasFontDefinitionAsFamily(fontProperties);

		if (fontDefinitionAsFamily) {
			fontDataByDefinition = findFontDataByDefinition(cssFontFamily);
			if (fontDataByDefinition.length > 0) {
				newFontData.setName(fontDataByDefinition[0].getName());
			}
		} else if (cssFontFamily != null) {
			newFontData.setName(cssFontFamily.getStringValue());
		}

		boolean fontFamilySet = newFontData.getName() != null && newFontData.getName().trim().length() > 0;
		if (!fontFamilySet && oldFontData != null) {
			newFontData.setName(oldFontData.getName());
		}

		// Style
		int style = getSWTStyle(fontProperties, oldFontData);
		if (fontDefinitionAsFamily && fontDataByDefinition.length > 0 && style == SWT.NORMAL) {
			newFontData.setStyle(fontDataByDefinition[0].getStyle());
		} else {
			newFontData.setStyle(style);
		}

		// Height
		CSSPrimitiveValue cssFontSize = fontProperties.getSize();
		boolean fontHeightSet = false;

		if (cssFontSize == null || cssFontSize.getCssText() == null) {
			if (fontDefinitionAsFamily && fontDataByDefinition.length > 0) {
				newFontData.setHeight(fontDataByDefinition[0].getHeight());
				fontHeightSet = true;
			}
		} else if (cssFontSize != null) {
			newFontData.setHeight((int) (cssFontSize).getFloatValue(CSSPrimitiveValue.CSS_PT));
			fontHeightSet = true;
		}
		if (!fontHeightSet && oldFontData != null) {
			newFontData.setHeight(oldFontData.getHeight());
		}

		return newFontData;
	}

	public static boolean hasFontDefinitionAsFamily(CSSValue value) {
		if (value instanceof CSS2FontProperties) {
			CSS2FontProperties props = (CSS2FontProperties) value;
			return props.getFamily() != null
					&& props.getFamily().getStringValue()
					.startsWith(FONT_DEFINITION_MARKER);
		}
		return false;
	}

	private static FontData[] findFontDataByDefinition(CSSPrimitiveValue cssFontFamily) {
		IColorAndFontProvider provider = CSSActivator.getDefault().getColorAndFontProvider();
		FontData[] result = new FontData[0];
		if (provider != null) {
			FontData[] fontData = provider.getFont(normalizeId(cssFontFamily.getStringValue().substring(1)));
			if (fontData != null) {
				result = fontData;
			}
		}
		return result;
	}

	/**
	 * Return SWT style Font from {@link CSS2FontProperties}.
	 *
	 * @param fontProperties
	 * @param control
	 * @return
	 */
	public static int getSWTStyle(CSS2FontProperties fontProperties,
			FontData fontData) {
		if (fontData == null) {
			return SWT.NONE;
		}

		int fontStyle = fontData.getStyle();
		// CSS2 font-style
		CSSPrimitiveValue cssFontStyle = fontProperties.getStyle();
		if (cssFontStyle != null) {
			String style = cssFontStyle.getStringValue();
			if ("italic".equals(style)) {
				fontStyle = fontStyle | SWT.ITALIC;
			} else {
				if (fontStyle == (fontStyle | SWT.ITALIC)) {
					fontStyle = fontStyle ^ SWT.ITALIC;
				}
			}
		}
		// CSS font-weight
		CSSPrimitiveValue cssFontWeight = fontProperties.getWeight();
		if (cssFontWeight != null) {
			String weight = cssFontWeight.getStringValue();
			if ("bold".equals(weight.toLowerCase())) {
				fontStyle = fontStyle | SWT.BOLD;
			} else {
				if (fontStyle == (fontStyle | SWT.BOLD)) {
					fontStyle = fontStyle ^ SWT.BOLD;
				}
			}
		}
		return fontStyle;
	}

	/**
	 * Return CSS Value font-family from the widget's font, if it has a font
	 *
	 * @param widget
	 * @return
	 */
	public static String getFontFamily(Widget widget) {
		return getFontFamily(getFont(widget));
	}

	/**
	 * Return CSS Value font-family from SWT Font
	 *
	 * @param font
	 * @return
	 */
	public static String getFontFamily(Font font) {
		FontData fontData = getFirstFontData(font);
		return getFontFamily(fontData);
	}

	public static String getFontFamily(FontData fontData) {
		if (fontData != null) {
			String family = fontData.getName();
			return CSS2FontHelper.getFontFamily(family);
		}
		return null;
	}

	/**
	 * Return CSS Value font-size the widget's font, if it has a font
	 *
	 * @param widget
	 * @return
	 */
	public static String getFontSize(Widget widget) {
		return getFontSize(getFont(widget));
	}

	/**
	 * Return CSS Value font-size from SWT Font
	 *
	 * @param font
	 * @return
	 */
	public static String getFontSize(Font font) {
		FontData fontData = getFirstFontData(font);
		return getFontSize(fontData);
	}

	public static String getFontSize(FontData fontData) {
		if (fontData != null) {
			return CSS2FontHelper.getFontSize(fontData.getHeight());
		}
		return null;
	}

	/**
	 * Return CSS Value font-style from the widget's font, if it has a font
	 *
	 * @param widget
	 * @return
	 */
	public static String getFontStyle(Widget widget) {
		return getFontStyle(getFont(widget));
	}

	/**
	 * Return CSS Value font-style from SWT Font
	 *
	 * @param font
	 * @return
	 */
	public static String getFontStyle(Font font) {
		FontData fontData = getFirstFontData(font);
		return getFontStyle(fontData);
	}

	public static String getFontStyle(FontData fontData) {
		boolean isItalic = false;
		if (fontData != null) {
			isItalic = isItalic(fontData);
		}
		return CSS2FontHelper.getFontStyle(isItalic);
	}

	public static boolean isItalic(FontData fontData) {
		int fontStyle = fontData.getStyle();
		return ((fontStyle | SWT.ITALIC) == fontStyle);
	}

	/**
	 * Return CSS Value font-weight from the widget's font, if it has a font
	 *
	 * @param widget
	 * @return
	 */
	public static String getFontWeight(Widget widget) {
		return getFontWeight(getFont(widget));
	}

	/**
	 * Return CSS Value font-weight from Control Font
	 *
	 * @param font
	 * @return
	 */
	public static String getFontWeight(Font font) {
		FontData fontData = getFirstFontData(font);
		return getFontWeight(fontData);
	}

	public static String getFontWeight(FontData fontData) {
		boolean isBold = false;
		if (fontData != null) {
			isBold = isBold(fontData);
		}
		return CSS2FontHelper.getFontWeight(isBold);
	}

	public static boolean isBold(FontData fontData) {
		int fontStyle = fontData.getStyle();
		return ((fontStyle | SWT.BOLD) == fontStyle);
	}

	/**
	 * Return CSS Value font-family from Control Font
	 *
	 * @param control
	 * @return
	 */
	public static String getFontComposite(Control control) {
		return getFontComposite(control.getFont());
	}

	/**
	 * Return CSS Value font-family from SWT Font
	 *
	 * @param font
	 * @return
	 */
	public static String getFontComposite(Font font) {
		FontData fontData = getFirstFontData(font);
		return getFontComposite(fontData);
	}

	public static String getFontComposite(FontData fontData) {
		if (fontData != null) {
			StringBuffer composite = new StringBuffer();
			// font-family
			composite.append(getFontFamily(fontData));
			composite.append(" ");
			// font-size
			composite.append(getFontSize(fontData));
			composite.append(" ");
			// font-weight
			composite.append(getFontWeight(fontData));
			composite.append(" ");
			// font-style
			composite.append(getFontStyle(fontData));
			return composite.toString();
		}
		return null;
	}

	/**
	 * Return first FontData from Control Font.
	 *
	 * @param control
	 * @return
	 */
	public static FontData getFirstFontData(Control control) {
		Font font = control.getFont();
		if (font == null) {
			return null;
		}
		return getFirstFontData(font);
	}

	/**
	 *
	 * Return first FontData from SWT Font.
	 *
	 * @param font
	 * @return
	 */
	public static FontData getFirstFontData(Font font) {
		FontData[] fontDatas = font.getFontData();
		if (fontDatas == null || fontDatas.length < 1) {
			return null;
		}
		return fontDatas[0];
	}

	private static Font getFont(Widget widget) {
		if (widget instanceof CTabItem) {
			return ((CTabItem) widget).getFont();
		} else if (widget instanceof Control) {
			return ((Control) widget).getFont();
		} else {
			return null;
		}
	}

	public static void storeDefaultFont(Control control) {
		storeDefaultFont(control, control.getFont());
	}

	public static void storeDefaultFont(CTabItem item) {
		storeDefaultFont(item, item.getFont());
	}

	private static void storeDefaultFont(Widget widget, Font font) {
		if (widget.getData(DEFAULT_FONT) == null) {
			widget.setData(DEFAULT_FONT, font);
		}
	}

	public static void restoreDefaultFont(Control control) {
		Font defaultFont = (Font) control.getData(DEFAULT_FONT);
		if (defaultFont != null) {
			control.setFont(defaultFont.isDisposed() ? control.getDisplay()
					.getSystemFont() : defaultFont);
		}
	}

	public static void restoreDefaultFont(CTabItem item) {
		Font defaultFont = (Font) item.getData(DEFAULT_FONT);
		if (defaultFont != null) {
			item.setFont(defaultFont.isDisposed() ? item.getDisplay()
					.getSystemFont() : defaultFont);
		}
	}
}

Back to the top