1//////////////////////////////////////////////////////////////////////////////// 2// 3// ADOBE SYSTEMS INCORPORATED 4// Copyright 2008 Adobe Systems Incorporated 5// All Rights Reserved. 6// 7// NOTICE: Adobe permits you to use, modify, and distribute this file 8// in accordance with the terms of the license agreement accompanying it. 9// 10//////////////////////////////////////////////////////////////////////////////// 11 12package spark.utils 13{ 14 15import flash.text.TextFormat; 16import flash.text.engine.ElementFormat; 17import flash.text.engine.FontDescription; 18import flash.text.engine.FontLookup; 19import flash.text.engine.TextBlock; 20import flash.text.engine.TextElement; 21import flash.text.engine.TextLine; 22 23import flashx.textLayout.compose.ISWFContext; 24 25import mx.core.IEmbeddedFontRegistry; 26import mx.core.IFlexModuleFactory; 27import mx.core.IUIComponent; 28import mx.core.Singleton; 29import mx.managers.ISystemManager; 30import mx.styles.IStyleClient; 31 32[ExcludeClass] 33 34/** 35 * @private 36 */ 37public class FTETextUtil 38{ 39 include "../core/Version.as"; 40 41 //-------------------------------------------------------------------------- 42 // 43 // Methods - Font Baseline 44 // 45 //-------------------------------------------------------------------------- 46 47 //-------------------------------------------------------------------------- 48 // 49 // Class properties 50 // 51 //-------------------------------------------------------------------------- 52 53 /** 54 * @private 55 * Used in getEmbeddedFontContext(). 56 */ 57 private static var staticTextFormat:TextFormat; 58 59 //---------------------------------- 60 // embeddedFontRegistry 61 //---------------------------------- 62 63 private static var noEmbeddedFonts:Boolean; 64 65 /** 66 * @private 67 * Storage for the _embeddedFontRegistry property. 68 * Note: This gets initialized on first access, 69 * not when this class is initialized, in order to ensure 70 * that the Singleton registry has already been initialized. 71 */ 72 private static var _embeddedFontRegistry:IEmbeddedFontRegistry; 73 74 /** 75 * @private 76 * A reference to the embedded font registry. 77 * Single registry in the system. 78 * Used to look up the moduleFactory of a font. 79 */ 80 private static function get embeddedFontRegistry():IEmbeddedFontRegistry 81 { 82 if (!_embeddedFontRegistry && !noEmbeddedFonts) 83 { 84 try 85 { 86 _embeddedFontRegistry = IEmbeddedFontRegistry( 87 Singleton.getInstance("mx.core::IEmbeddedFontRegistry")); 88 } 89 catch (e:Error) 90 { 91 noEmbeddedFonts = true; 92 } 93 } 94 95 return _embeddedFontRegistry; 96 } 97 98 //-------------------------------------------------------------------------- 99 // 100 // Class methods 101 // 102 //-------------------------------------------------------------------------- 103 104 /** 105 * Method to measure baseline position 106 * 107 * @param client The IStyleClient to use to calculate the baseline. 108 * @param height Height of client. Used only for degenerate cases. 109 * @param moduleFactory The default moduleFactory to use for the font. 110 */ 111 public static function calculateFontBaseline(client:IStyleClient, height:Number, moduleFactory:IFlexModuleFactory):Number 112 { 113 var fontDescription:FontDescription = new FontDescription(); 114 var embeddedFontContext:IFlexModuleFactory; 115 116 var s:String; 117 118 s = client.getStyle("cffHinting"); 119 if (s != null) 120 fontDescription.cffHinting = s; 121 122 s = client.getStyle("fontFamily"); 123 if (s != null) 124 fontDescription.fontName = s; 125 126 s = client.getStyle("fontLookup"); 127 if (s != null) 128 { 129 // FTE understands only "device" and "embeddedCFF" 130 // for fontLookup. But Flex allows this style to be 131 // set to "auto", in which case we automatically 132 // determine it based on whether the CSS styles 133 // specify an embedded font. 134 if (s == "auto") 135 { 136 embeddedFontContext = getEmbeddedFontContext(client, moduleFactory); 137 s = (embeddedFontContext) ? 138 FontLookup.EMBEDDED_CFF : 139 FontLookup.DEVICE; 140 } 141 fontDescription.fontLookup = s; 142 } 143 144 s = client.getStyle("fontStyle"); 145 if (s != null) 146 fontDescription.fontPosture = s; 147 148 s = client.getStyle("fontWeight"); 149 if (s != null) 150 fontDescription.fontWeight = s; 151 152 var elementFormat:ElementFormat = new ElementFormat(); 153 elementFormat.fontDescription = fontDescription; 154 elementFormat.fontSize = client.getStyle("fontSize"); 155 156 var textElement:TextElement = new TextElement(); 157 textElement.elementFormat = elementFormat; 158 textElement.text = "Wj"; 159 160 var textBlock:TextBlock = new TextBlock(); 161 textBlock.content = textElement; 162 163 var textLine:TextLine; 164 if (embeddedFontContext) 165 { 166 var swfContext:ISWFContext = ISWFContext(embeddedFontContext); 167 textLine = swfContext.callInContext( 168 textBlock.createTextLine, textBlock, 169 [ null, 1000]); 170 } 171 else 172 textLine = textBlock.createTextLine(null, 1000); 173 174 if (height < 2 + textLine.ascent + 2) 175 return int(height + (textLine.ascent - height) / 2); 176 177 return 2 + textLine.ascent; 178 } 179 180 /** 181 * @private 182 * Uses the component's CSS styles to determine the module factory 183 * that should creates its TextLines. 184 */ 185 private static function getEmbeddedFontContext(client:IStyleClient, moduleFactory:IFlexModuleFactory):IFlexModuleFactory 186 { 187 var fontContext:IFlexModuleFactory; 188 189 var fontLookup:String = client.getStyle("fontLookup"); 190 if (fontLookup != FontLookup.DEVICE) 191 { 192 var font:String = client.getStyle("fontFamily"); 193 var bold:Boolean = client.getStyle("fontWeight") == "bold"; 194 var italic:Boolean = client.getStyle("fontStyle") == "italic"; 195 196 var localLookup:ISystemManager; 197 if (moduleFactory != null && moduleFactory is ISystemManager) 198 localLookup = ISystemManager(moduleFactory); 199 else if (client is IUIComponent) 200 { 201 var uic:IUIComponent = IUIComponent(client); 202 if (uic.parent is IUIComponent) 203 localLookup = IUIComponent(uic.parent).systemManager; 204 } 205 206 fontContext = embeddedFontRegistry.getAssociatedModuleFactory( 207 font, bold, italic, client, moduleFactory, localLookup, true); 208 } 209 210 if (!fontContext && fontLookup == FontLookup.EMBEDDED_CFF) 211 { 212 // if we couldn't find the font and somebody insists it is 213 // embedded, try the default fontContext 214 fontContext = moduleFactory; 215 } 216 217 return fontContext; 218 } 219 220} 221 222} 223