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 com.sun.javafx.css.converters; 27 28 import com.sun.javafx.util.Utils; 29 import com.sun.javafx.css.Size; 30 import com.sun.javafx.css.StyleConverterImpl; 31 import javafx.css.CssMetaData; 32 import javafx.css.ParsedValue; 33 import javafx.css.StyleConverter; 34 import javafx.css.Styleable; 35 import javafx.scene.text.Font; 36 import javafx.scene.text.FontPosture; 37 import javafx.scene.text.FontWeight; 38 39 import java.util.Locale; 40 import java.util.Map; 41 import java.util.Map.Entry; 42 43 public final class FontConverter extends StyleConverterImpl<ParsedValue[], Font> { 44 45 // lazy, thread-safe instatiation 46 private static class Holder { 47 static final FontConverter INSTANCE = new FontConverter(); 48 } 49 50 public static StyleConverter<ParsedValue[], Font> getInstance() { 51 return Holder.INSTANCE; 52 } 53 54 private FontConverter() { 55 super(); 56 } 57 58 @Override 59 public Font convert(ParsedValue<ParsedValue[], Font> value, Font font) { 60 ParsedValue[] values = value.getValue(); 61 Font aFont = (font != null) ? font : Font.getDefault(); 62 String family = (values[0] != null) ? Utils.stripQuotes((String) values[0].convert(aFont)) : aFont.getFamily(); 63 // if font size is given in terms of percent, then we have to call 64 // pixels directly in order to pass the multiplier. 65 double fsize = aFont.getSize(); 66 if (values[1] != null) { 67 ParsedValue<?, ?> pv = (ParsedValue<?, ?>) values[1].getValue(); 68 Size size = (Size) pv.convert(aFont); 69 fsize = size.pixels(aFont.getSize(), aFont); 70 } 71 FontWeight weight = (values[2] != null) ? (FontWeight) values[2].convert(aFont) : FontWeight.NORMAL; 72 FontPosture style = (values[3] != null) ? (FontPosture) values[3].convert(aFont) : FontPosture.REGULAR; 73 Font f = Font.font(family, weight, style, fsize); 74 return f; 75 } 76 77 @Override 78 public Font convert(Map<CssMetaData<? extends Styleable, ?>, Object> convertedValues) { 79 Font font = Font.getDefault(); 80 double size = font.getSize(); 81 String family = font.getFamily(); 82 FontWeight weight = FontWeight.NORMAL; 83 FontPosture style = FontPosture.REGULAR; 84 85 for (Entry<CssMetaData<? extends Styleable, ?>, Object> entry : convertedValues.entrySet()) { 86 87 Object value = entry.getValue(); 88 if (value == null) { 89 continue; 90 } 91 final String prop = entry.getKey().getProperty(); 92 if (prop.endsWith("font-size")) { 93 size = ((Number) value).doubleValue(); 94 } else if (prop.endsWith("font-family")) { 95 family = Utils.stripQuotes((String) value); 96 } else if (prop.endsWith("font-weight")) { 97 weight = (FontWeight) value; 98 } else if (prop.endsWith("font-style")) { 99 style = (FontPosture) value; 100 } 101 } 102 final Font f = Font.font(family, weight, style, size); 103 return f; 104 } 105 106 @Override 107 public String toString() { 108 return "FontConverter"; 109 } 110 111 public static final class FontStyleConverter extends StyleConverterImpl<String, FontPosture> { 112 113 // lazy, thread-safe instatiation 114 private static class Holder { 115 static final FontStyleConverter INSTANCE = new FontStyleConverter(); 116 } 117 118 public static FontStyleConverter getInstance() { 119 return Holder.INSTANCE; 120 } 121 122 private FontStyleConverter() { 123 super(); 124 } 125 126 @Override 127 public FontPosture convert(ParsedValue<String, FontPosture> value, Font font) { 128 129 // Testing for RT-31022 exposed a ClassCastException where value 130 // wraps a String (e.g., "ITALIC", not a FontUnits.Style). 131 final Object val = value.getValue(); 132 133 FontPosture style = null; 134 135 if (val instanceof String) { 136 try { 137 String sval = ((String)val).toUpperCase(Locale.ROOT); 138 style = Enum.valueOf(FontPosture.class, sval); 139 } catch (IllegalArgumentException iae) { 140 style = FontPosture.REGULAR; 141 } catch (NullPointerException npe) { 142 style = FontPosture.REGULAR; 143 } 144 145 } else if (val instanceof FontPosture) { 146 style = (FontPosture)val; 147 } 148 return style; 149 } 150 151 @Override 152 public String toString() { 153 return "FontConverter.StyleConverter"; 154 } 155 } 156 157 public static final class FontWeightConverter extends StyleConverterImpl<String, FontWeight> { 158 159 // lazy, thread-safe instatiation 160 private static class Holder { 161 static final FontWeightConverter INSTANCE = new FontWeightConverter(); 162 } 163 164 public static FontWeightConverter getInstance() { 165 return Holder.INSTANCE; 166 } 167 168 private FontWeightConverter() { 169 super(); 170 } 171 172 @Override 173 public FontWeight convert(ParsedValue<String, FontWeight> value, Font font) { 174 175 // Testing for RT-31022 exposed a ClassCastException where value 176 // wraps a String (e.g., "ITALIC", not a FontUnits.Style). 177 final Object val = value.getValue(); 178 179 FontWeight weight = null; 180 181 if (val instanceof String) { 182 try { 183 String sval = ((String)val).toUpperCase(Locale.ROOT); 184 weight = Enum.valueOf(FontWeight.class, sval); 185 } catch (IllegalArgumentException iae) { 186 weight = FontWeight.NORMAL; 187 } catch (NullPointerException npe) { 188 weight = FontWeight.NORMAL; 189 } 190 191 } else if (val instanceof FontWeight) { 192 weight = (FontWeight)val; 193 } 194 195 return weight; 196 } 197 198 @Override 199 public String toString() { 200 return "FontConverter.WeightConverter"; 201 } 202 } 203 204 public static final class FontSizeConverter extends StyleConverterImpl<ParsedValue<?, Size>, Number> { 205 206 // lazy, thread-safe instatiation 207 private static class Holder { 208 static final FontSizeConverter INSTANCE = new FontSizeConverter(); 209 } 210 211 public static FontSizeConverter getInstance() { 212 return Holder.INSTANCE; 213 } 214 215 private FontSizeConverter() { 216 super(); 217 } 218 219 @Override 220 public Number convert(ParsedValue<ParsedValue<?, Size>, Number> value, Font font) { 221 final ParsedValue<?, Size> size = value.getValue(); 222 return size.convert(font).pixels(font.getSize(), font); 223 } 224 225 @Override 226 public String toString() { 227 return "FontConverter.FontSizeConverter"; 228 } 229 } 230 231 }