1 /* 2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javafx.css.converter; 27 28 import com.sun.javafx.util.Utils; 29 import javafx.css.Size; 30 import javafx.css.CssMetaData; 31 import javafx.css.ParsedValue; 32 import javafx.css.StyleConverter; 33 import javafx.css.Styleable; 34 import javafx.scene.text.Font; 35 import javafx.scene.text.FontPosture; 36 import javafx.scene.text.FontWeight; 37 38 import java.util.Locale; 39 import java.util.Map; 40 import java.util.Map.Entry; 41 42 /** 43 * @since 9 44 */ 45 public final class FontConverter extends StyleConverter<ParsedValue[], Font> { 46 47 // lazy, thread-safe instatiation 48 private static class Holder { 49 static final FontConverter INSTANCE = new FontConverter(); 50 } 51 52 public static StyleConverter<ParsedValue[], Font> getInstance() { 53 return Holder.INSTANCE; 54 } 55 56 private FontConverter() { 57 super(); 58 } 59 60 @Override 61 public Font convert(ParsedValue<ParsedValue[], Font> value, Font font) { 62 ParsedValue[] values = value.getValue(); 63 Font aFont = (font != null) ? font : Font.getDefault(); 64 String family = (values[0] != null) ? Utils.stripQuotes((String) values[0].convert(aFont)) : aFont.getFamily(); 65 // if font size is given in terms of percent, then we have to call 66 // pixels directly in order to pass the multiplier. 67 double fsize = aFont.getSize(); 68 if (values[1] != null) { 69 ParsedValue<?, ?> pv = (ParsedValue<?, ?>) values[1].getValue(); 70 Size size = (Size) pv.convert(aFont); 71 fsize = size.pixels(aFont.getSize(), aFont); 72 } 73 FontWeight weight = (values[2] != null) ? (FontWeight) values[2].convert(aFont) : FontWeight.NORMAL; 74 FontPosture style = (values[3] != null) ? (FontPosture) values[3].convert(aFont) : FontPosture.REGULAR; 75 Font f = Font.font(family, weight, style, fsize); 76 return f; 77 } 78 79 @Override 80 public Font convert(Map<CssMetaData<? extends Styleable, ?>, Object> convertedValues) { 81 Font font = Font.getDefault(); 82 double size = font.getSize(); 83 String family = font.getFamily(); 84 FontWeight weight = FontWeight.NORMAL; 85 FontPosture style = FontPosture.REGULAR; 86 87 for (Entry<CssMetaData<? extends Styleable, ?>, Object> entry : convertedValues.entrySet()) { 88 89 Object value = entry.getValue(); 90 if (value == null) { 91 continue; 92 } 93 final String prop = entry.getKey().getProperty(); 94 if (prop.endsWith("font-size")) { 95 size = ((Number) value).doubleValue(); 96 } else if (prop.endsWith("font-family")) { 97 family = Utils.stripQuotes((String) value); 98 } else if (prop.endsWith("font-weight")) { 99 weight = (FontWeight) value; 100 } else if (prop.endsWith("font-style")) { 101 style = (FontPosture) value; 102 } 103 } 104 final Font f = Font.font(family, weight, style, size); 105 return f; 106 } 107 108 @Override 109 public String toString() { 110 return "FontConverter"; 111 } 112 113 public static final class FontStyleConverter extends StyleConverter<String, FontPosture> { 114 115 // lazy, thread-safe instatiation 116 private static class Holder { 117 static final FontStyleConverter INSTANCE = new FontStyleConverter(); 118 } 119 120 public static FontStyleConverter getInstance() { 121 return Holder.INSTANCE; 122 } 123 124 private FontStyleConverter() { 125 super(); 126 } 127 128 @Override 129 public FontPosture convert(ParsedValue<String, FontPosture> value, Font font) { 130 131 // Testing for RT-31022 exposed a ClassCastException where value 132 // wraps a String (e.g., "ITALIC", not a FontUnits.Style). 133 final Object val = value.getValue(); 134 135 FontPosture style = null; 136 137 if (val instanceof String) { 138 try { 139 String sval = ((String)val).toUpperCase(Locale.ROOT); 140 style = Enum.valueOf(FontPosture.class, sval); 141 } catch (IllegalArgumentException iae) { 142 style = FontPosture.REGULAR; 143 } catch (NullPointerException npe) { 144 style = FontPosture.REGULAR; 145 } 146 147 } else if (val instanceof FontPosture) { 148 style = (FontPosture)val; 149 } 150 return style; 151 } 152 153 @Override 154 public String toString() { 155 return "FontConverter.StyleConverter"; 156 } 157 } 158 159 public static final class FontWeightConverter extends StyleConverter<String, FontWeight> { 160 161 // lazy, thread-safe instatiation 162 private static class Holder { 163 static final FontWeightConverter INSTANCE = new FontWeightConverter(); 164 } 165 166 public static FontWeightConverter getInstance() { 167 return Holder.INSTANCE; 168 } 169 170 private FontWeightConverter() { 171 super(); 172 } 173 174 @Override 175 public FontWeight convert(ParsedValue<String, FontWeight> value, Font font) { 176 177 // Testing for RT-31022 exposed a ClassCastException where value 178 // wraps a String (e.g., "ITALIC", not a FontUnits.Style). 179 final Object val = value.getValue(); 180 181 FontWeight weight = null; 182 183 if (val instanceof String) { 184 try { 185 String sval = ((String)val).toUpperCase(Locale.ROOT); 186 weight = Enum.valueOf(FontWeight.class, sval); 187 } catch (IllegalArgumentException iae) { 188 weight = FontWeight.NORMAL; 189 } catch (NullPointerException npe) { 190 weight = FontWeight.NORMAL; 191 } 192 193 } else if (val instanceof FontWeight) { 194 weight = (FontWeight)val; 195 } 196 197 return weight; 198 } 199 200 @Override 201 public String toString() { 202 return "FontConverter.WeightConverter"; 203 } 204 } 205 206 public static final class FontSizeConverter extends StyleConverter<ParsedValue<?, Size>, Number> { 207 208 // lazy, thread-safe instatiation 209 private static class Holder { 210 static final FontSizeConverter INSTANCE = new FontSizeConverter(); 211 } 212 213 public static FontSizeConverter getInstance() { 214 return Holder.INSTANCE; 215 } 216 217 private FontSizeConverter() { 218 super(); 219 } 220 221 @Override 222 public Number convert(ParsedValue<ParsedValue<?, Size>, Number> value, Font font) { 223 final ParsedValue<?, Size> size = value.getValue(); 224 return size.convert(font).pixels(font.getSize(), font); 225 } 226 227 @Override 228 public String toString() { 229 return "FontConverter.FontSizeConverter"; 230 } 231 } 232 233 }