| /******************************************************************************* |
| * Copyright (c) 2008, 2013 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 = "#"; |
| |
| /** |
| * 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; |
| } |
| } |
| } |