»
S
I
D
E
B
A
R
«
Finding SWC dependencies
Jul 24th, 2009 by Gaurav

The nightly builds for Flex SDK 4 now contain a new tool called swcdepends which can be used to analyze the dependencies between SWC files. This tool can be found under the bin folder of the SDK and the latest nightly builds for Flex SDK 4 is available at http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4

Types of Dependencies

There can be four types of dependencies between two action script classes.

  • expression – e
  • inheritance – i
  • namespace – n
  • signature – s

Using swcdepends

swcdepends can be used from command line like mxmlc or compc but it also introduces few new options.

If you run the swcdepends without any options then it will display the dependencies for the SWCs present in the Flex SDK. Starting with the ones which have the least dependencies on other SWCs.

But you can also use various options in swcdepends to filter or expand the data you are interested in. Some of them are:

-show-swcs
-show-swcs expects a list of SWCs for which you want to see the dependency info. For example if you run:
$ ./swcdepends -show-swcs framework.swc spark.swc

It will display:

sdk\frameworks\libs\framework.swc:
        sdk\frameworks\libs\player\10\playerglobal.swc
sdk\frameworks\libs\spark.swc:
        sdk\frameworks\libs\textLayout.swc
        sdk\frameworks\libs\framework.swc
        sdk\frameworks\libs\player\10\playerglobal.swc

Notice that it first lists the SWC for which the analysis is requested and then the dependencies are listed (dependencies are indented)

-show-external-classes
-show-external-classes=true will also display the names of classes which are found as dependencies. For example if you run:
$ ./swcdepends -show-swcs framework.swc -show-external-classes=true

It will show output like:

sdk\frameworks\libs\framework.swc:
        sdk\frameworks\libs\player\10\playerglobal.swc
                flash.utils:Dictionary
                flash.events:MouseEvent
                flash.text:TextFieldAutoSize
                flash.xml:XMLDocument
                Class
                Date
                flash.utils:Timer
                .....

-show-types
-show-types=true will also show the type of dependency next to the class. For example if you run:
$ ./swcdepends -show-swcs framework.swc -show-external-classes=true -show-types=true

It will show output like:

sdk\frameworks\libs\framework.swc:
        sdk\frameworks\libs\player\10\playerglobal.swc
                flash.utils:Dictionary  s e
                flash.events:MouseEvent i s e
                flash.text:TextFieldAutoSize    e
                flash.xml:XMLDocument   s e
                Class   e
                Date    s e
                flash.utils:Timer       s e
                .....

Also when -show-types=true is specified -show-external-classes=true is not required.

-types
-types expects the list the type that should be displayed, so this option can be used to filter the information based on types. The following command:
$ ./swcdepends -show-swcs framework.swc -show-types=true -types=i,s

will display:

sdk\frameworks\libs\framework.swc:
        sdk\frameworks\libs\player\10\playerglobal.swc
                flash.utils:Dictionary  s
                flash.events:MouseEvent i s
                flash.xml:XMLDocument   s
                flash.system:LoaderContext      s
                flash.geom:Point        s
                Date    s
                ....

So it will filter out the dependencies of type expression and namespace.

-minimize-dependency-set
-minimize-dependency-set is true by default and it narrows the results to filter out a SWC, if the scripts resolved in the SWC are subset of the scripts resolved in another dependent SWC

So if you run
$ ./swcdepends -show-swcs spark.swc

It doesn’t show you flex.swc, because flex.swc is a subset of framework.swc and everything if flex.swc is already present in framework.swc. But if you want you can always see more info using:

$ ./swcdepends -show-swcs spark.swc -minimize-dependency-set=false

Hopefully this tool will provide useful info regarding how SWCs are related to each other. If you run into any bugs, feel free to log them at http://bugs.adobe.com/flex

Creating smaller swfs (Part III)
Jul 16th, 2009 by Gaurav

Here is the part three..

The very fact that you are writing applications using Flex proves that you care about user interface. And one of the features of Flex that enables you to provide a better user experience is font embedding. There are many benefits of using embedded fonts but the most important one is that it provides consistency regarding how the application will appear across different client environments and you don’t need to make sure whether the font is pre-installed. But there can also be few disadvantages of using embedded fonts, like when you use embedded font it gets stitched into your SWF which results in increasing the overall size of the SWF.

So lets look at how you can reap the benefits of using embedded fonts while still avoiding the start up time cost due to a larger SWF. The trick for doing this is to use Modules (for embedding fonts) and avoid embedding the fonts in the main SWF. That way you can achieve smaller start up time and fetch the fonts when you need to use them.

Here is an example of an application that displays text using four different fonts:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
		layout="vertical" width="650" height="400"
		verticalAlign="middle" horizontalAlign="center" 
		creationComplete="creationCompleteHandler(event)">
	<mx:Script>
		<![CDATA[
			import mx.events.ModuleEvent;
			import mx.modules.ModuleManager;
			import mx.modules.IModuleInfo;
			import mx.events.FlexEvent;
			import mx.controls.Alert;
			import mx.validators.Validator;
			private var fontModuleInfo:IModuleInfo;
 
			protected function button_clickHandler(event:MouseEvent):void {
				if(currentState != 'LoggedIn') {
					var validators:Array = [];
					validators[0] = this.v0;
					validators[1] = this.v1;
 
					var inValid:Array = Validator.validateAll(validators);
					if(inValid.length ==0) {
						if(tiUserName.text == 'guest' 
							&& tiPassword.text =='guest') {
							currentState = 'LoggedIn';
						} else {
							Alert.show("Invalid username" +
								" or password."); 
						}
					}
				} else {
					currentState = '';
				}
			}
 
			protected function creationCompleteHandler(event:FlexEvent):void 
			{
				fontModuleInfo = ModuleManager.getModule("FontModule.swf");
				fontModuleInfo.addEventListener(ModuleEvent.READY,
					readyHandler);
				fontModuleInfo.load();
			}
 
			private function readyHandler(event:Event):void {
				fontModuleInfo.factory.create();
			}
 
		]]>
	</mx:Script>
 
	<mx:StringValidator source="{tiUserName}" property="text" id="v0"
						required="true" maxLength="10" 
						trigger="{loginButton}" triggerEvent="click" />
	<mx:StringValidator source="{tiPassword}" property="text" id="v1"
						required="true" maxLength="10" 
						trigger="{loginButton}" triggerEvent="click" />
 
	<mx:states>
		<mx:State name="LoggedIn">
			<mx:RemoveChild target="{loginPanel}"/>
			<mx:AddChild relativeTo="{loginButton}" position="before">
				<mx:Panel id="pnl" title="Labels with different fonts. 
						  Embedded fonts can be rotated." paddingTop="10" 
						  paddingBottom="10" paddingLeft="10" paddingRight="10">
					<mx:Label id="lblVerdana" 
						  styleName="myVerdanaDescriptor" rotation="1"  
						  text="The quick brown fox jumps over the lazy dog." />
					<mx:Label id="lblCandara" 
						  styleName="myCandaraDescriptor" rotation="1"
						  text="The quick brown fox jumps over the lazy dog." />
					<mx:Label id="lblVrinda" 
						  styleName="myVrindaDescriptor" rotation="1"
						  text="The quick brown fox jumps over the lazy dog." />
					<mx:Label id="lblMinion" 
						  styleName="myMinionDescriptor" rotation="1"
						  text="The quick brown fox jumps over the lazy dog." />
				</mx:Panel>
			</mx:AddChild>
			<mx:SetProperty target="{loginButton}" 
							name="label" value="Log Out"/>
		</mx:State>
	</mx:states>
 
	<mx:Panel id="loginPanel" 
			  title="Login"  borderAlpha="0.15"
			  horizontalScrollPolicy="off" verticalScrollPolicy="off">
 
		<mx:Form id="loginForm" >
			<mx:FormItem label="Username:">
				<mx:TextInput id="tiUserName" />
			</mx:FormItem>
			<mx:FormItem label="Password:">
				<mx:TextInput id="tiPassword" 
							  displayAsPassword="true" />
			</mx:FormItem>
		</mx:Form>
	</mx:Panel>
	<mx:Button label="Login" id="loginButton" 
			   click="button_clickHandler(event)"/>
</mx:Application>

And here is the module (FontModule.mxml) used to embed fonts:

<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml">
	<mx:Style>
		@font-face {
			src:url("verdana.TTF");
			fontFamily: myVerdana;
		}
 
		.myVerdanaDescriptor
		{
			fontFamily: myVerdana;
			color: red;
			fontSize: 24;
		}
 
		@font-face {
			src:url("MinionPro-Regular.otf");
			fontFamily: myMinion;
		}
 
		.myMinionDescriptor
		{
			fontFamily: myMinion;
			color: green;
			fontSize: 24;
		}
 
		@font-face {
			src:url("Vrinda.ttf");
			fontFamily: myVrinda;
		}
 
		.myVrindaDescriptor
		{
			fontFamily: myVrinda;
			color: red;
			fontSize: 24;
		}
 
		@font-face {
			src:url("CANDARA.TTF");
			fontFamily: myCandara;
		}
 
		.myCandaraDescriptor
		{
			fontFamily: myCandara;
			color: green;
			fontSize: 24;
		}
	</mx:Style>
</mx:Module>

Below is the running sample, to log in use “guest” as user name and password and click on the button.



The size benefits:

Configuration Swf size Comments
If fonts are embedded in main swf 607 KB  
If fonts are fonts embedded in module 267 KB The font Module is 354 KB
If fonts are fonts embedded in module and main app uses default SDK RSLs. (as is the case with the above example) 84 KB This app was compiled with Flex 4 beta build. With a more recent Flex 4 build there should be increased benefits for swf size reduction.

So we trimmed the SWF by 86% for this sample.

The above approach works if you don’t need embedded fonts right at the application start up. In the above example the font module is loaded after the main app is initialized, as we don’t need to show text using embedded fonts on the log in screen. This way the user experiences a reduced start up time and you can still use the fonts you like ;)

If you app uses multiple fonts and some of them are not required at the application start up, consider embedding fonts in a module.

»  Substance: WordPress   »  Style: Ahren Ahimsa