1 18 package org.apache.batik.bridge; 19 20 import java.util.ArrayList ; 21 import java.util.Iterator ; 22 import java.util.LinkedList ; 23 import java.util.List ; 24 import java.util.Map ; 25 import java.util.StringTokenizer ; 26 27 import org.apache.batik.dom.svg.SVGOMDocument; 28 import org.apache.batik.gvt.font.GVTFontFamily; 29 import org.apache.batik.gvt.font.GVTFontFace; 30 import org.apache.batik.gvt.font.UnresolvedFontFamily; 31 import org.apache.batik.util.SVGConstants; 32 33 import org.apache.batik.css.engine.CSSEngine; 34 import org.apache.batik.css.engine.FontFaceRule; 35 36 import org.w3c.dom.Document ; 37 import org.w3c.dom.Element ; 38 import org.w3c.dom.NodeList ; 39 40 46 public abstract class SVGFontUtilities implements SVGConstants { 47 48 public static List getFontFaces(Document doc, 49 BridgeContext ctx) { 50 Map fontFamilyMap = ctx.getFontFamilyMap(); 53 List ret = (List )fontFamilyMap.get(doc); 54 if (ret != null) 55 return ret; 56 57 ret = new LinkedList (); 58 59 NodeList fontFaceElements = doc.getElementsByTagNameNS 60 (SVG_NAMESPACE_URI, SVG_FONT_FACE_TAG); 61 62 SVGFontFaceElementBridge fontFaceBridge; 63 fontFaceBridge = (SVGFontFaceElementBridge)ctx.getBridge 64 (SVG_NAMESPACE_URI, SVG_FONT_FACE_TAG); 65 66 for (int i = 0; i < fontFaceElements.getLength(); i++) { 67 Element fontFaceElement = (Element )fontFaceElements.item(i); 68 ret.add(fontFaceBridge.createFontFace 69 (ctx, fontFaceElement)); 70 } 71 72 CSSEngine engine = ((SVGOMDocument)doc).getCSSEngine(); 73 List sms = engine.getFontFaces(); 74 Iterator iter = sms.iterator(); 75 while (iter.hasNext()) { 76 FontFaceRule ffr = (FontFaceRule)iter.next(); 77 ret.add(CSSFontFace.createCSSFontFace(engine, ffr)); 78 } 79 return ret; 80 } 81 82 83 102 public static GVTFontFamily getFontFamily(Element textElement, 103 BridgeContext ctx, 104 String fontFamilyName, 105 String fontWeight, 106 String fontStyle) { 107 108 String fontKeyName = fontFamilyName.toLowerCase() + " " + 110 fontWeight + " " + fontStyle; 111 112 Map fontFamilyMap = ctx.getFontFamilyMap(); 115 GVTFontFamily fontFamily = 116 (GVTFontFamily)fontFamilyMap.get(fontKeyName); 117 if (fontFamily != null) { 118 return fontFamily; 119 } 120 121 Document doc = textElement.getOwnerDocument(); 123 124 List fontFaces = (List )fontFamilyMap.get(doc); 125 126 if (fontFaces == null) { 127 fontFaces = getFontFaces(doc, ctx); 128 fontFamilyMap.put(doc, fontFaces); 129 } 130 131 132 Iterator iter = fontFaces.iterator(); 133 List svgFontFamilies = new LinkedList (); 134 while (iter.hasNext()) { 135 FontFace fontFace = (FontFace)iter.next(); 136 137 if (!fontFace.hasFamilyName(fontFamilyName)) { 138 continue; 139 } 140 141 String fontFaceStyle = fontFace.getFontStyle(); 142 if (fontFaceStyle.equals(SVG_ALL_VALUE) || 143 fontFaceStyle.indexOf(fontStyle) != -1) { 144 GVTFontFamily ffam = fontFace.getFontFamily(ctx); 145 if (ffam != null) 146 svgFontFamilies.add(ffam); 147 } 148 } 149 150 if (svgFontFamilies.size() == 1) { 151 fontFamilyMap.put(fontKeyName, svgFontFamilies.get(0)); 153 return (GVTFontFamily)svgFontFamilies.get(0); 154 155 } else if (svgFontFamilies.size() > 1) { 156 String fontWeightNumber = getFontWeightNumberString(fontWeight); 158 159 List fontFamilyWeights = new ArrayList (svgFontFamilies.size()); 161 Iterator ffiter = svgFontFamilies.iterator(); 162 while(ffiter.hasNext()) { 163 GVTFontFace fontFace; 164 fontFace = ((GVTFontFamily)ffiter.next()).getFontFace(); 165 String fontFaceWeight = fontFace.getFontWeight(); 166 fontFaceWeight = getFontWeightNumberString(fontFaceWeight); 167 fontFamilyWeights.add(fontFaceWeight); 168 } 169 170 174 List newFontFamilyWeights = new ArrayList (fontFamilyWeights); 175 for (int i = 100; i <= 900; i+= 100) { 176 String weightString = String.valueOf(i); 177 boolean matched = false; 178 int minDifference = 1000; 179 int minDifferenceIndex = 0; 180 for (int j = 0; j < fontFamilyWeights.size(); j++) { 181 String fontFamilyWeight = (String )fontFamilyWeights.get(j); 182 if (fontFamilyWeight.indexOf(weightString) > -1) { 183 matched = true; 184 break; 185 } 186 StringTokenizer st = 187 new StringTokenizer (fontFamilyWeight, " ,"); 188 while (st.hasMoreTokens()) { 189 int weightNum = Integer.parseInt(st.nextToken()); 190 int difference = Math.abs(weightNum - i); 191 if (difference < minDifference) { 192 minDifference = difference; 193 minDifferenceIndex = j; 194 } 195 } 196 } 197 if (!matched) { 198 String newFontFamilyWeight = 199 newFontFamilyWeights.get(minDifferenceIndex) + 200 ", " + weightString; 201 newFontFamilyWeights.set(minDifferenceIndex, 202 newFontFamilyWeight); 203 } 204 } 205 206 207 for (int i = 0; i < svgFontFamilies.size(); i++) { 209 String fontFaceWeight = (String )newFontFamilyWeights.get(i); 210 if (fontFaceWeight.indexOf(fontWeightNumber) > -1) { 211 fontFamilyMap.put(fontKeyName, svgFontFamilies.get(i)); 212 return (GVTFontFamily)svgFontFamilies.get(i); 213 } 214 } 215 fontFamilyMap.put(fontKeyName, svgFontFamilies.get(0)); 217 return (GVTFontFamily) svgFontFamilies.get(0); 218 219 } else { 220 GVTFontFamily gvtFontFamily = 222 new UnresolvedFontFamily(fontFamilyName); 223 fontFamilyMap.put(fontKeyName, gvtFontFamily); 224 return gvtFontFamily; 225 } 226 } 227 228 237 protected static String getFontWeightNumberString(String fontWeight) { 238 if (fontWeight.equals(SVG_NORMAL_VALUE)) { 239 return SVG_400_VALUE; 240 } else if (fontWeight.equals(SVG_BOLD_VALUE)) { 241 return SVG_700_VALUE; 242 } else if (fontWeight.equals(SVG_ALL_VALUE)) { 243 return "100, 200, 300, 400, 500, 600, 700, 800, 900"; 244 } 245 return fontWeight; 246 } 247 } 248 | Popular Tags |