1 /******************************************************************************* 2 * Copyright (c) 2004, 2015 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.jface.resource; 15 16 import org.eclipse.swt.graphics.Device; 17 import org.eclipse.swt.graphics.Font; 18 import org.eclipse.swt.graphics.FontData; 19 import org.eclipse.swt.widgets.Display; 20 21 /** 22 * Lightweight descriptor for a font. Creates the described font on demand. 23 * Subclasses can implement different ways of describing a font. These objects 24 * will be compared, so hashCode(...) and equals(...) must return something 25 * meaningful. 26 * 27 * @since 3.1 28 */ 29 public abstract class FontDescriptor extends DeviceResourceDescriptor { 30 31 /** 32 * Creates a FontDescriptor that describes an existing font. The resulting 33 * descriptor depends on the Font. Disposing the Font while the descriptor 34 * is still in use may throw a graphic disposed exception. 35 * 36 * @since 3.1 37 * 38 * @deprecated use {@link FontDescriptor#createFrom(Font)} 39 * 40 * @param font a font to describe 41 * @param originalDevice must be the same Device that was passed into 42 * the font's constructor when it was first created. 43 * @return a newly created FontDescriptor. 44 */ 45 @Deprecated createFrom(Font font, Device originalDevice)46 public static FontDescriptor createFrom(Font font, Device originalDevice) { 47 return new ArrayFontDescriptor(font); 48 } 49 50 /** 51 * Creates a FontDescriptor that describes an existing font. The resulting 52 * descriptor depends on the original Font, and disposing the original Font 53 * while the descriptor is still in use may cause SWT to throw a graphic 54 * disposed exception. 55 * 56 * @since 3.1 57 * 58 * @param font font to create 59 * @return a newly created FontDescriptor that describes the given font 60 */ createFrom(Font font)61 public static FontDescriptor createFrom(Font font) { 62 return new ArrayFontDescriptor(font); 63 } 64 65 /** 66 * Creates a new FontDescriptor given the an array of FontData that describes 67 * the font. 68 * 69 * @since 3.1 70 * 71 * @param data an array of FontData that describes the font (will be passed into 72 * the Font's constructor) 73 * @return a FontDescriptor that describes the given font 74 */ createFrom(FontData[] data)75 public static FontDescriptor createFrom(FontData[] data) { 76 return new ArrayFontDescriptor(data); 77 } 78 79 /** 80 * Creates a new FontDescriptor given the associated FontData 81 * 82 * @param data FontData describing the font to create 83 * @return a newly created FontDescriptor 84 */ createFrom(FontData data)85 public static FontDescriptor createFrom(FontData data) { 86 return new ArrayFontDescriptor(new FontData[]{data}); 87 } 88 89 /** 90 * Creates a new FontDescriptor given an OS-specific font name, height, and style. 91 * 92 * @see Font#Font(org.eclipse.swt.graphics.Device, java.lang.String, int, int) 93 * 94 * @param name os-specific font name 95 * @param height height (pixels) 96 * @param style a bitwise combination of NORMAL, BOLD, ITALIC 97 * @return a new FontDescriptor 98 */ createFrom(String name, int height, int style)99 public static FontDescriptor createFrom(String name, int height, int style) { 100 return createFrom(new FontData(name, height, style)); 101 } 102 103 /** 104 * Returns the set of FontData associated with this font. Modifying the elements 105 * in the returned array has no effect on the original FontDescriptor. 106 * 107 * @return the set of FontData associated with this font 108 * @since 3.3 109 */ getFontData()110 public FontData[] getFontData() { 111 Font tempFont = createFont(Display.getCurrent()); 112 FontData[] result = tempFont.getFontData(); 113 destroyFont(tempFont); 114 return result; 115 } 116 117 /** 118 * Returns an array of FontData containing copies of the FontData 119 * from the original. 120 * 121 * @param original array to copy 122 * @return a deep copy of the original array 123 * @since 3.3 124 */ copy(FontData[] original)125 public static FontData[] copy(FontData[] original) { 126 FontData[] result = new FontData[original.length]; 127 for (int i = 0; i < original.length; i++) { 128 FontData next = original[i]; 129 130 result[i] = copy(next); 131 } 132 133 return result; 134 } 135 136 /** 137 * Returns a copy of the original FontData 138 * 139 * @param next FontData to copy 140 * @return a copy of the given FontData 141 * @since 3.3 142 */ copy(FontData next)143 public static FontData copy(FontData next) { 144 FontData result = new FontData(next.getName(), next.getHeight(), next.getStyle()); 145 result.setLocale(next.getLocale()); 146 return result; 147 } 148 149 /** 150 * Returns a FontDescriptor that is equivalent to the receiver, but uses 151 * the given style bits. 152 * 153 * <p>Does not modify the receiver.</p> 154 * 155 * @param style a bitwise combination of SWT.NORMAL, SWT.ITALIC and SWT.BOLD 156 * @return a new FontDescriptor with the given style 157 * 158 * @since 3.3 159 */ setStyle(int style)160 public final FontDescriptor setStyle(int style) { 161 FontData[] data = getFontData(); 162 163 for (FontData next : data) { 164 next.setStyle(style); 165 } 166 167 // Optimization: avoid holding onto extra instances by returning the receiver if 168 // if it is exactly the same as the result 169 FontDescriptor result = new ArrayFontDescriptor(data); 170 if (result.equals(this)) { 171 return this; 172 } 173 174 return result; 175 } 176 177 /** 178 * <p>Returns a FontDescriptor that is equivalent to the receiver, but 179 * has the given style bits, in addition to any styles the receiver already has.</p> 180 * 181 * <p>Does not modify the receiver.</p> 182 * 183 * @param style a bitwise combination of SWT.NORMAL, SWT.ITALIC and SWT.BOLD 184 * @return a new FontDescriptor with the given additional style bits 185 * @since 3.3 186 */ withStyle(int style)187 public final FontDescriptor withStyle(int style) { 188 FontData[] data = getFontData(); 189 190 for (FontData next : data) { 191 next.setStyle(next.getStyle() | style); 192 } 193 194 // Optimization: avoid allocating extra instances by returning the receiver if 195 // if it is exactly the same as the result 196 FontDescriptor result = new ArrayFontDescriptor(data); 197 if (result.equals(this)) { 198 return this; 199 } 200 201 return result; 202 } 203 204 /** 205 * <p>Returns a new FontDescriptor that is equivalent to the receiver, but 206 * has the given height.</p> 207 * 208 * <p>Does not modify the receiver.</p> 209 * 210 * @param height a height, in points 211 * @return a new FontDescriptor with the height, in points 212 * @since 3.3 213 */ setHeight(int height)214 public final FontDescriptor setHeight(int height) { 215 FontData[] data = getFontData(); 216 217 for (FontData next : data) { 218 next.setHeight(height); 219 } 220 221 // Optimization: avoid holding onto extra instances by returning the receiver if 222 // if it is exactly the same as the result 223 FontDescriptor result = new ArrayFontDescriptor(data); 224 if (result.equals(this)) { 225 return this; 226 } 227 228 return result; 229 } 230 231 /** 232 * <p>Returns a FontDescriptor that is equivalent to the receiver, but whose height 233 * is larger by the given number of points.</p> 234 * 235 * <p>Does not modify the receiver.</p> 236 * 237 * @param heightDelta a change in height, in points. Negative values will return smaller 238 * fonts. 239 * @return a FontDescriptor whose height differs from the receiver by the given number 240 * of points. 241 * @since 3.3 242 */ increaseHeight(int heightDelta)243 public final FontDescriptor increaseHeight(int heightDelta) { 244 if (heightDelta == 0) { 245 return this; 246 } 247 FontData[] data = getFontData(); 248 249 for (FontData next : data) { 250 next.setHeight(next.getHeight() + heightDelta); 251 } 252 253 return new ArrayFontDescriptor(data); 254 } 255 256 /** 257 * Creates the Font described by this descriptor. 258 * 259 * @since 3.1 260 * 261 * @param device device on which to allocate the font 262 * @return a newly allocated Font (never null) 263 * @throws DeviceResourceException if unable to allocate the Font 264 */ createFont(Device device)265 public abstract Font createFont(Device device) throws DeviceResourceException; 266 267 /** 268 * Deallocates anything that was allocated by createFont, given a font 269 * that was allocated by an equal FontDescriptor. 270 * 271 * @since 3.1 272 * 273 * @param previouslyCreatedFont previously allocated font 274 */ destroyFont(Font previouslyCreatedFont)275 public abstract void destroyFont(Font previouslyCreatedFont); 276 277 @Override createResource(Device device)278 public final Object createResource(Device device) throws DeviceResourceException { 279 return createFont(device); 280 } 281 282 @Override destroyResource(Object previouslyCreatedObject)283 public final void destroyResource(Object previouslyCreatedObject) { 284 destroyFont((Font)previouslyCreatedObject); 285 } 286 } 287