Category Archives: Sample Application

SWFTools (pdf2swf) to properly work with Flex

19
Filed under Experiments, Flex, Flex 3, Flex Tutorials, Labs, Open Source Stuffs, Sample Application

It’s hype, there’s no word to describe how to involve and open-source command-line tool to transcode from pdf to swf file and get it right work with Flex.
So, I googled a lot yesterday and today morning, and didn’t find any relevance information on this field. I just saw a collection of developers getting problem to put it to work. For sure it’s a little hard work to put it in right to work.
The problem took me attention because we got a job from a start-up company that does document of any type and convert into a swf. Of course that you should put more effort to accomplish bunch things like Scribd does.
To help theses unlucky devs out there follow the steps of this tutorial bellow and 20% of your problem will solve, bet if solves 100% isn’t?

Get Start

  • Download the last version of SWFTools and put in the root of your HD access mine was (C:\swftools)
  • Grab some pdf you want to convert into swf and start transcode.
  • Open up your Prompt command and goes to the path where you put your SWFTools

To run the pdf to swf converter you just type :

C:\SWFTools\pdf2swf originalfile.pdf -o newfile.swf

This is automatically converts your pdf into something easy format like swf and ready to Flash Player.

The pdf2swf has many options see them bellow:

  • −h, −−help Print short help message and exit
  • −V, −−version Print version info and exit
  • −o, −−output file.swf will Go into a seperate file.
  • −p, −−pages range Ex:3-5,10-12
  • −P, −−password password Use password for deciphering the pdf.
  • −v, −−verbose Be verbose. Use more than one -v for greater effect.
  • −z, −−zlib The resulting SWF will not be playable in browsers with Flash Plugins 5 and below!
  • −i, −−ignore SWF files a little bit smaller, but it may also cause the images in the pdf to look funny.
  • −j, −−jpegquality quality Set quality of embedded jpeg pictures to quality. 0 is worst (small), 100 is best (big). (default:85)
  • −s, −−set param=value Set a SWF encoder specific parameter. See pdf2swf -s help for more information.
  • −w, −−samewindow When clicked on, the page they point to will be opened in the window the SWF is displayed.
  • −t, −−stop The resulting SWF file will not turn pages automatically.
  • −T, −−flashversion num Set Flash Version in the SWF header to num.
  • −F, −−fontdir directory Add directory to the font search path.
  • −b, −−defaultviewer Therefore the swf file will be “browseable”, i.e. display some buttons for turning pages.
    The viewer swf to be used is determined by a symlink named “default_viewer.swf” in
    the swftools data directory.
  • −l, −−defaultloader The loader swf to be used is determined by a symlink named “default_loader.swf” in
    the swftools data directory.
  • −B, −−viewer filename See http://www.quiss.org/swftools/pdf2swf_usage.html for information on how to create your own viewers.
  • −L, −−preloader filename filename is an arbitrary swf animation.
  • −q, −−quiet Suppress normal messages. Use -qq to suppress warnings, also.
  • −S, −−shapes Don’t use SWF Fonts, but store everything as shape.
  • −f, −−fonts Store full fonts in SWF. (Don’t reduce to used characters).
  • −G, −−flatten This usually makes the file faster to render and also usually smaller, but will increase
    conversion time.
  • −I, −−info Don’t do actual conversion, just display a list of all pages in the PDF.
  • −Q, −−maxtime n Abort conversion after n seconds. Only available on Unix.

Converting in the right way

The creators of SWFTools claim that you can export in AVM2, but in fact the Flash Player only recognize the header in the swf, not the document structure, which for Flex DOM is fundamental to understand.

Ok, How I convert mine with options?

I used ANT to do stuff things for conventions since I don’t want to re-type always I have a new PDF to convert in house. But simplifying it worked for me this command line argument.

C:\SWFTOOLS>pdf2swf -z -t sourceFile.pdf -o OutputFile.swf

That’s right, you have your swf file converted and running, What was done? I insert a stop action in each frame because this cause the swf to play each frame. Also I compacted the file using gzip to decrease the size, same as Scribd does.

Flex side

Create a new Flex project, name it as you wish. After that you might be think it’s simple we can load it using SWFLoader, but you will have problems to control and Flex will understand that this file is just as asset not as a component. To work with that, you have various options like, Loader, ByteLoader, ModuleLoader and BulkLoader. To load into Flex and given you a certain to control it.

My solution was simple, as I known that pdf2swf just give me swf in head with 8 version, I can manage a instance and place where I wish. That was easy, but what about Flex to control from Flash 5,6,7,8, both have their own way of render and work. To accomplished that I googled a little, because I knew it that some one should have fight this problem before and for lucky I found this class that kick ass problem. See class bellow:

package
{
	import flash.display.Loader;
	import flash.net.URLRequest;
	import flash.net.URLStream;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.Event;
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	import flash.errors.EOFError; 

	public class ForcibleLoader
	{
		public function ForcibleLoader(loader:Loader)
		{
			this.loader = loader;
			_stream = new URLStream();
			_stream.addEventListener(Event.COMPLETE, completeHandler);
			_stream.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			_stream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
		}
		private var _loader:Loader;
		public var _stream:URLStream;
		public function get loader():Loader
		{
			return _loader;
		}
		public function set loader(value:Loader):void
		{
			_loader = value;
		}
		public function load(request:URLRequest):void
		{
			_stream.load(request);
		}
		private function completeHandler(event:Event):void
		{
			var inputBytes:ByteArray = new ByteArray();
			_stream.readBytes(inputBytes);
			_stream.close();
			inputBytes.endian = Endian.LITTLE_ENDIAN;
			if (isCompressed(inputBytes)) {
				uncompress(inputBytes);
			}
			var version:uint = uint(inputBytes[3]);
			if (version <= 10) {
				if (version == 8 || version == 9 || version == 10){
					flagSWF9Bit(inputBytes);
				}
				else if (version <= 7) {
					insertFileAttributesTag(inputBytes);
				}
				updateVersion(inputBytes, 9);
			}
			loader.loadBytes(inputBytes);
		}
		private function isCompressed(bytes:ByteArray):Boolean
		{
			return bytes[0] == 0x43;
		}
		private function uncompress(bytes:ByteArray):void
		{
			var cBytes:ByteArray = new ByteArray();
			cBytes.writeBytes(bytes, 8);
			bytes.length = 8;
			bytes.position = 8;
			cBytes.uncompress();
			bytes.writeBytes(cBytes);
			bytes[0] = 0x46;
			cBytes.length = 0;
		}
		private function getBodyPosition(bytes:ByteArray):uint
		{
			var result:uint = 0;
			result += 3; // FWS/CWS
			result += 1; // version(byte)
			result += 4; // length(32bit-uint)
			var rectNBits:uint = bytes[result] >>> 3;
			result += (5 + rectNBits * 4) / 8; // stage(rect)
			result += 2;
			result += 1; // frameRate(byte)
			result += 2; // totalFrames(16bit-uint)
			return result;
		}
		private function findFileAttributesPosition(offset:uint, bytes:ByteArray):uint
		{
			bytes.position = offset;
			try {
				for (;;) {
					var byte:uint = bytes.readShort();
					var tag:uint = byte >>> 6;
					if (tag == 69) {
						return bytes.position - 2;
					}
					var length:uint = byte & 0x3f;
					if (length == 0x3f) {
						length = bytes.readInt();
					}
					bytes.position += length;
				}
			}
			catch (e:EOFError) {
			}
			return NaN;
		}
		private function flagSWF9Bit(bytes:ByteArray):void
		{
			var pos:uint = findFileAttributesPosition(getBodyPosition(bytes), bytes);
			if (!isNaN(pos)) {
				bytes[pos + 2] |= 0x08;
			}
		}
		private function insertFileAttributesTag(bytes:ByteArray):void
		{
			var pos:uint = getBodyPosition(bytes);
			var afterBytes:ByteArray = new ByteArray();
			afterBytes.writeBytes(bytes, pos);
			bytes.length = pos;
			bytes.position = pos;
			bytes.writeByte(0x44);
			bytes.writeByte(0x11);
			bytes.writeByte(0x08);
			bytes.writeByte(0x00);
			bytes.writeByte(0x00);
			bytes.writeByte(0x00);
			bytes.writeBytes(afterBytes);
			afterBytes.length = 0;
		}
		private function updateVersion(bytes:ByteArray, version:uint):void
		{
			bytes[3] = version;
		}
		private function ioErrorHandler(event:IOErrorEvent):void
		{
			loader.contentLoaderInfo.dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR));
		}
		private function securityErrorHandler(event:SecurityErrorEvent):void
		{
			loader.contentLoaderInfo.dispatchEvent(new SecurityErrorEvent(SecurityErrorEvent.SECURITY_ERROR));
		}
	}
}

With this face off, you can handle quickly in Flex, I’ve built an application example. And for your own risk you can implement, share more functionalities, more controls, anyaway, you’re free for it.

Here’s the Main application.





		[Event(name="PDFComplete",type="flash.events.Event")]


	
		
	
	
			
			
			
				
			
			

You see, I didn’t used the SWFLoader of Flex, as explained before, I prefer to handle in diffrent way.
This application is simple, has some buggies (littles), but in general, just figure you out how to do such thing.

Missing things you could implement, TextSearch, Thumbnail generation from loaded swf to pages.

Download the FULL source code of this application here. Wanna see example of running, you have to download and it’s included. Because I didn’t put effort in secury sandbox levels in it.

Links of my researches:

#4 Flex Hack – Add charts to Datagrid without Data Visualization Framework

6
Filed under Flex, Flex 3, Flex Beyound basic, Flex Components, Flex Data Visualization Framework, Flex Hacks, Sample Application

By far Flex is great, you pick up an idea and after that becomes a solution. One of the things I really enjoy in Flex is playing with Charts. People here in Brazil always stay shocked with power of Charts and its simplicity to make.

Anyway, Bringing Charts in Flex are such power and looks your App really awesome. This hack today is regarding that thing, simplicity without the Data Visualization Framework aka(Flex Charts).

Also by meaning the real name for that is Gantt Chart like wikipedia says. Which a great colleague of field Andrew Trice dide a good example on how to handle that.[Update] Actually the Dusty explain on the comments that this hack is more micro chart(SparkLine chart) than Gantt Chart.

What is necessary to it?
– Flex 3.0.x SDK or Flex 2.0.x SDK
– Imagination

Anyway, here’s the result of what this hack can do:

How is it done?

Same as Andrew did, but a little simple, I explored the resources of Flex DisplayObject class has and UIComponent has, like draw easy.

Here’s the code for the Hack:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
	<mx:Script>
		<![CDATA[
			import mx.controls.Alert;
			import mx.collections.ArrayCollection;
 
			[Bindable]private var productCollection:ArrayCollection = new ArrayCollection();
			[Bindable]private var product:Object;
 
			private function addProduct():void {
				if(pName.text != '' && pPrice.text != '' && pSold.text != ''){
					product = new Object();
					product.Name = pName.text;
					product.Price = pPrice.text;
					product.Sold = pSold.text;
					productCollection.addItem(product);
				}else{
					Alert.show('Fill out all fields!','Error');
				}
			}
		]]>
	</mx:Script>
 
	<mx:DataGrid  dataProvider="{productCollection}" x="30" y="33" width="486" height="306">
		<mx:columns>
			<mx:DataGridColumn headerText="Product Name" dataField="Name"/>
			<mx:DataGridColumn headerText="Price" dataField="Price"/>
			<mx:DataGridColumn headerText="Sold Itens" dataField="Sold">
					<mx:itemRenderer>
						<mx:Component>
								<mx:HBox horizontalScrollPolicy="off" verticalScrollPolicy="off" width="100%" height="100%">
									<mx:HBox verticalScrollPolicy="off" horizontalScrollPolicy="off" backgroundColor="#a604e9"
										 width="{Number(data.Sold)*0.01}" height="100%"/>
									<mx:Label text="{String(Number(data.Sold)*0.01)}%"/>
								</mx:HBox>
						</mx:Component>
					</mx:itemRenderer>
			</mx:DataGridColumn>
		</mx:columns>
	</mx:DataGrid>
	<mx:Form defaultButton="{addProductBtn}" x="545" y="24">
		<mx:FormItem label="Product Name">
			<mx:TextInput id="pName"/>
		</mx:FormItem>
		<mx:FormItem label="Price">
			<mx:TextInput restrict="[0-9]" id="pPrice"/>
		</mx:FormItem>
		<mx:FormItem label="Sold Itens">
			<mx:TextInput id="pSold" restrict="[0-9]"/>
		</mx:FormItem>
	</mx:Form>
	<mx:Button id="addProductBtn" x="736" y="142" label="Add Product" click="addProduct()"/>
 
</mx:Application>

As you see you can reproduce any kind of hack like that, because the power of itemRender mechanism in Flex is very powerful for data representation. By at the end you see that is not a big deal doing that with your project, and the final result looks awesome.

Playing Effects Too

Here’s same example but now using Effects.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
	<mx:Script>
		<![CDATA[
			import mx.controls.Alert;
			import mx.collections.ArrayCollection;
			import mx.effects.easing.Elastic;
 
			[Bindable]private var productCollection:ArrayCollection = new ArrayCollection();
			[Bindable]private var product:Object;
 
			private function addProduct():void {
				if(pName.text != '' && pPrice.text != '' && pSold.text != ''){
					product = new Object();
					product.Name = pName.text;
					product.Price = pPrice.text;
					product.Sold = pSold.text;
					productCollection.addItem(product);
				}else{
					Alert.show('Fill out all fields!','Error');
				}
			}
		]]>
	</mx:Script>
 
	<mx:DataGrid  dataProvider="{productCollection}" x="30" y="33" width="486" height="306">
		<mx:columns>
			<mx:DataGridColumn headerText="Product Name" dataField="Name"/>
			<mx:DataGridColumn headerText="Price" dataField="Price"/>
			<mx:DataGridColumn headerText="Sold Itens" dataField="Sold">
					<mx:itemRenderer>
						<mx:Component>
								<mx:HBox horizontalScrollPolicy="off" verticalScrollPolicy="off" width="100%" height="100%">
									<mx:Resize duration="1500" target="{_grchart}" id="_eff" widthTo="{Number(data.Sold)*0.01}"/>
									<mx:Script>
										<![CDATA[
											import mx.effects.easing.Back;
										]]>
									</mx:Script>
									<mx:HBox  id="_grchart" creationComplete="_eff.play()" verticalScrollPolicy="off" horizontalScrollPolicy="off" backgroundColor="#a604e9"
										 width="0" height="100%"/>
									<mx:Label text="{String(int(data.Sold)*0.01)}%"/>
								</mx:HBox>
						</mx:Component>
					</mx:itemRenderer>
			</mx:DataGridColumn>
		</mx:columns>
	</mx:DataGrid>
	<mx:Form defaultButton="{addProductBtn}" x="545" y="24">
		<mx:FormItem label="Product Name">
			<mx:TextInput id="pName"/>
		</mx:FormItem>
		<mx:FormItem label="Price">
			<mx:TextInput restrict="[0-9]" id="pPrice"/>
		</mx:FormItem>
		<mx:FormItem label="Sold Itens">
			<mx:TextInput maxChars="4" id="pSold" restrict="[0-9]" width="162"/>
		</mx:FormItem>
	</mx:Form>
	<mx:Button id="addProductBtn" x="736" y="142" label="Add Product" click="addProduct()"/>
</mx:Application>

GoogleMap Flex Component

15
Filed under 3.0, Actionscript, Experiments, Flex, Flex Components, Google, Sample Application

After the release of greatest and awaited API for Flash Platform developers, I decided to facilitate the life of Flex Developers, Created just in some minutes a new component for Flex Developers who want to add more control or be very well organized.

I’ve created a new Component for Flex. here’s how to its works.

Copy and paste this code in your own Path.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
>>
package com.igorcosta
{
	import com.google.maps.LatLng;
	import com.google.maps.Map;
	import com.google.maps.MapEvent;
	import com.google.maps.MapType;
 
	import flash.events.Event;
	import flash.geom.Point;
 
	import mx.core.UIComponent;
	import mx.events.FlexEvent;
 
	public class GoogleFlexMap extends UIComponent
	{
 
		private var _Width:Number = 650;
		private var _Height:Number = 500;
		private var _mapa:Map;
		private var _key:String;		
		public function GoogleFlexMap()
		{
			super();
			super.addEventListener(FlexEvent.INITIALIZE,init);						
		}
		private function init(event:Event):void {
			 this.width = _Width;
			this.height = _Height;			
			// Ininitate the Map Object
			_mapa = new Map();
			_mapa.key =_key;
			_mapa.addEventListener(MapEvent.MAP_READY,createUIMap);
			_mapa.setSize( new Point (this.width, this.height))
			// add map to displaylist
			this.addChild(_mapa);
		}
		public function get key():String{
				return _key;
		}
		public function set key(value:String):void {
			_key = value;
		}
		private function createUIMap(event:Event):void {
			_mapa.setCenter( new LatLng(40.736072,-73.992062),14,MapType.HYBRID_MAP_TYPE);
		}	
	}
}

How to use?

Simple just do that in your main application

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:google="com.igorcosta.*"  xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
  	<google: GoogleFlexMap 
  		key="your_key_goes_here" 
  		width="100%" height="100%"/>
 
</mx:  Application>

Very important link before you start.

There’s a lot of to do to be more simple as possible, as soon as I get more time I will add more options to automate that.

My experience with writing a draw application

0
Filed under 3.0, Actionscript, Experiments, Flex 3, Labs, Open Source Stuffs, Sample Application

The Code zipped in this post is just an experiment I did last week while was on travel to visit a client and see how the draw API works with Flex UI guesture.

Not to be very polite source code with a huge enachment to do. I was providing my capabilities with drawing.

Use, modify and distribute with no costs or copyrights need.

 Download it here.