Skip to content
This repository has been archived by the owner on May 15, 2022. It is now read-only.

Shape Export to Objective C

claus edited this page Jan 6, 2013 · 21 revisions

With as3swf you can automatically generate Objective-C source code (Core Graphics, Quartz) from SWF Shapes, to reuse those shapes in your iPhone projects. The as3swf Core Graphics shape exporter generates ready-to-use Objective-C class files (UIView subclasses).


Example

The following example is a simple AIR application that loads a SWF and exports all contained shapes to Objective-C source code. Source files are written to a folder “as3swf” on the Desktop, named “Shape{x}View.h” and “Shape{x}View.m” (where {x} is the internal shape id).

package 
{
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.filesystem.File;
  import flash.filesystem.FileMode;
  import flash.filesystem.FileStream;
  import flash.net.URLLoader;
  import flash.net.URLLoaderDataFormat;
  import flash.net.URLRequest;
  import flash.utils.ByteArray;
  
  import com.codeazur.as3swf.SWF;
  import com.codeazur.as3swf.tags.ITag;
  import com.codeazur.as3swf.tags.TagDefineShape;
  import com.codeazur.as3swf.exporters.CoreGraphicsShapeExporter;

  public class Test extends Sprite
  {
    public function Test()
    {
      var request:URLRequest = new URLRequest("any.swf");
      var loader:URLLoader = new URLLoader();
      loader.dataFormat = URLLoaderDataFormat.BINARY;
      loader.addEventListener(Event.COMPLETE, completeHandler);
      loader.load(request);
    }

    private function completeHandler(e:Event):void {
      var swf:SWF = new SWF(URLLoader(e.target).data as ByteArray);
      for (var i:uint = 0; i < swf.tags.length; i++) {
        var tag:ITag = swf.tags[i];
        if (tag is TagDefineShape) {
          var defineShape:TagDefineShape = tag as TagDefineShape;
          var docHandler:CoreGraphicsShapeExporter = 
            new CoreGraphicsShapeExporter(
              swf,
              "Shape" + defineShape.shapeId + "View",
              "as3swf",
              "Claus Wahlers",
              "côdeazur brasil"
            );
          defineShape.export(docHandler);
          writeSource(docHandler);
        }
      }
    }

    private function writeSource(doc:CoreGraphicsShapeExporter):void {
      var fileName:String = "as3swf" + File.separator + doc.className;
      var h:File = File.desktopDirectory.resolvePath(fileName + ".h");
      var m:File = File.desktopDirectory.resolvePath(fileName + ".m");
      var stream:FileStream = new FileStream();
      stream.open(h, FileMode.WRITE);
      stream.writeUTFBytes(doc.h);
      stream.close();
      stream.open(m, FileMode.WRITE);
      stream.writeUTFBytes(doc.m);
      stream.close();
    }
  }
}

The interesting part here is the completeHandler. The SWF is parsed by as3swf into an internal object model. The code then iterates over all tags, and, for each DefineShape tag, exports the respective shape and writes the resulting class files to the file system. While the tag’s export function executes, it calls back functions implemented in the document handler (see IShapeExporter and CoreGraphicsShapeExporter), which generate the Objective-C code.


A Simple Demo

Here’s a simple demo of a SWF whose shapes we export to Objective-C classes using the example code above:

This SWF contains only one shape:

[SWF] Version: 10, FileLength: 1791, FileLengthCompressed: 1021, FrameSize: (320,203), FrameRate: 60, FrameCount: 1, Tags: 8
  Tags:
    [69:FileAttributes] AS3: true, HasMetadata: true, UseDirectBlit: false, UseGPU: false, UseNetwork: false
    [77:Metadata] 
    [09:SetBackgroundColor] Color: ffffffff
    [86:DefineSceneAndFrameLabelData] 
      Scenes:
        [0] Offset: 0, Name: Scene 1
    [22:DefineShape2] ID: 1, Bounds: (622,5776,620,3452)
      FillStyles:
        [1] [SWFFillStyle] Type: 0 (solid), Color: ff000000
      ShapeRecords:
        [SWFShapeRecordStyleChange] MoveTo: 2644,764, FillStyle0: 1
        [SWFShapeRecordCurvedEdge] ControlDelta: -288,-138, AnchorDelta: -324,0
        [SWFShapeRecordCurvedEdge] ControlDelta: -585,0, AnchorDelta: -411,414
        [SWFShapeRecordCurvedEdge] ControlDelta: -414,411, AnchorDelta: 0,585
        [SWFShapeRecordCurvedEdge] ControlDelta: 0,585, AnchorDelta: 414,414
        [SWFShapeRecordCurvedEdge] ControlDelta: 411,411, AnchorDelta: 585,0
        [SWFShapeRecordCurvedEdge] ControlDelta: 324,0, AnchorDelta: 288,-138
        [SWFShapeRecordCurvedEdge] ControlDelta: 279,-135, AnchorDelta: 198,-240
        [SWFShapeRecordCurvedEdge] ControlDelta: -192,-261, AnchorDelta: -66,-312
        [SWFShapeRecordCurvedEdge] ControlDelta: -99,252, AnchorDelta: -222,156
        [SWFShapeRecordCurvedEdge] ControlDelta: -231,159, AnchorDelta: -279,0
        [SWFShapeRecordCurvedEdge] ControlDelta: -369,0, AnchorDelta: -261,-261
        [SWFShapeRecordCurvedEdge] ControlDelta: -261,-261, AnchorDelta: 0,-369
        [SWFShapeRecordCurvedEdge] ControlDelta: 0,-369, AnchorDelta: 261,-261
        [SWFShapeRecordCurvedEdge] ControlDelta: 261,-261, AnchorDelta: 369,0
        [SWFShapeRecordCurvedEdge] ControlDelta: 279,0, AnchorDelta: 231,159
        [SWFShapeRecordCurvedEdge] ControlDelta: 222,156, AnchorDelta: 99,252
        [SWFShapeRecordCurvedEdge] ControlDelta: 66,-312, AnchorDelta: 192,-261
        [SWFShapeRecordCurvedEdge] ControlDelta: -198,-240, AnchorDelta: -279,-135
        [SWFShapeRecordStyleChange] MoveTo: 0,0, FillStyle0: 0, FillStyle1: 0, LineStyle: 0
          New FillStyles:
            [1] [SWFFillStyle] Type: 0 (solid), Color: ff86b9e1
        [SWFShapeRecordStyleChange] MoveTo: 2374,1694, FillStyle0: 1
        [SWFShapeRecordCurvedEdge] ControlDelta: 144,141, AnchorDelta: 0,201
        [SWFShapeRecordCurvedEdge] ControlDelta: 0,201, AnchorDelta: -144,141
        [SWFShapeRecordCurvedEdge] ControlDelta: -141,144, AnchorDelta: -201,0
        [SWFShapeRecordCurvedEdge] ControlDelta: -201,0, AnchorDelta: -141,-144
        [SWFShapeRecordCurvedEdge] ControlDelta: -144,-141, AnchorDelta: 0,-201
        [SWFShapeRecordCurvedEdge] ControlDelta: 0,-201, AnchorDelta: 144,-141
        [SWFShapeRecordCurvedEdge] ControlDelta: 141,-144, AnchorDelta: 201,0
        [SWFShapeRecordCurvedEdge] ControlDelta: 201,0, AnchorDelta: 141,144
        [SWFShapeRecordStyleChange] MoveTo: 2575,1493
        [SWFShapeRecordCurvedEdge] ControlDelta: -222,-225, AnchorDelta: -321,0
        [SWFShapeRecordCurvedEdge] ControlDelta: -321,0, AnchorDelta: -225,225
        [SWFShapeRecordCurvedEdge] ControlDelta: -225,225, AnchorDelta: 0,318
        [SWFShapeRecordCurvedEdge] ControlDelta: 0,318, AnchorDelta: 225,225
        [SWFShapeRecordCurvedEdge] ControlDelta: 225,225, AnchorDelta: 321,0
        [SWFShapeRecordCurvedEdge] ControlDelta: 321,0, AnchorDelta: 222,-225
        [SWFShapeRecordCurvedEdge] ControlDelta: 225,-222, AnchorDelta: 0,-321
        [SWFShapeRecordCurvedEdge] ControlDelta: 0,-318, AnchorDelta: -225,-225
        [SWFShapeRecordStyleChange] MoveTo: 0,0, FillStyle0: 0, FillStyle1: 0, LineStyle: 0
          New FillStyles:
            [1] [SWFFillStyle] Type: 0 (solid), Color: ff000000
        [SWFShapeRecordStyleChange] MoveTo: 5776,2030, FillStyle0: 1
        [SWFShapeRecordCurvedEdge] ControlDelta: -3,-582, AnchorDelta: -414,-414
        [SWFShapeRecordCurvedEdge] ControlDelta: -414,-414, AnchorDelta: -585,0
        [SWFShapeRecordCurvedEdge] ControlDelta: -588,0, AnchorDelta: -414,414
        [SWFShapeRecordCurvedEdge] ControlDelta: -414,414, AnchorDelta: 0,588
        [SWFShapeRecordCurvedEdge] ControlDelta: 0,585, AnchorDelta: 414,414
        [SWFShapeRecordCurvedEdge] ControlDelta: 411,414, AnchorDelta: 585,3
        [SWFShapeRecordStraightEdge] Horizontal: 783
        [SWFShapeRecordStraightEdge] Vertical: -522
        [SWFShapeRecordStraightEdge] Horizontal: -780
        [SWFShapeRecordCurvedEdge] ControlDelta: -369,-3, AnchorDelta: -261,-261
        [SWFShapeRecordCurvedEdge] ControlDelta: -261,-261, AnchorDelta: 0,-369
        [SWFShapeRecordCurvedEdge] ControlDelta: 0,-369, AnchorDelta: 264,-261
        [SWFShapeRecordCurvedEdge] ControlDelta: 261,-264, AnchorDelta: 369,0
        [SWFShapeRecordCurvedEdge] ControlDelta: 369,0, AnchorDelta: 261,261
        [SWFShapeRecordCurvedEdge] ControlDelta: 261,261, AnchorDelta: 3,369
        [SWFShapeRecordStraightEdge] General: -3,1419
        [SWFShapeRecordStraightEdge] Horizontal: 525
        [SWFShapeRecordStraightEdge] Vertical: -1422
        [SWFShapeRecordStyleChange] MoveTo: 0,0, FillStyle0: 0, FillStyle1: 0, LineStyle: 0
          New FillStyles:
            [1] [SWFFillStyle] Type: 0 (solid), Color: ff86b9e1
        [SWFShapeRecordStyleChange] MoveTo: 4360,1259, FillStyle0: 1
        [SWFShapeRecordCurvedEdge] ControlDelta: -321,0, AnchorDelta: -228,228
        [SWFShapeRecordCurvedEdge] ControlDelta: -228,228, AnchorDelta: 0,321
        [SWFShapeRecordCurvedEdge] ControlDelta: 0,321, AnchorDelta: 225,228
        [SWFShapeRecordCurvedEdge] ControlDelta: 228,228, AnchorDelta: 321,0
        [SWFShapeRecordStraightEdge] Horizontal: 780
        [SWFShapeRecordStraightEdge] Vertical: -780
        [SWFShapeRecordCurvedEdge] ControlDelta: 0,-321, AnchorDelta: -228,-228
        [SWFShapeRecordCurvedEdge] ControlDelta: -228,-225, AnchorDelta: -321,0
        [SWFShapeRecordStyleChange] MoveTo: 4852,2039
        [SWFShapeRecordStraightEdge] General: -3,12
        [SWFShapeRecordStraightEdge] Vertical: 477
        [SWFShapeRecordStraightEdge] Horizontal: -492
        [SWFShapeRecordCurvedEdge] ControlDelta: -204,-3, AnchorDelta: -141,-144
        [SWFShapeRecordCurvedEdge] ControlDelta: -144,-144, AnchorDelta: 0,-201
        [SWFShapeRecordCurvedEdge] ControlDelta: 0,-201, AnchorDelta: 144,-147
        [SWFShapeRecordCurvedEdge] ControlDelta: 147,-144, AnchorDelta: 201,0
        [SWFShapeRecordCurvedEdge] ControlDelta: 201,0, AnchorDelta: 144,144
        [SWFShapeRecordCurvedEdge] ControlDelta: 144,141, AnchorDelta: 3,204
        [SWFShapeRecordStraightEdge] Vertical: 6
        [SWFShapeRecordEnd]
    [26:PlaceObject2] Depth: 4, CharacterID: 1, Matrix: (1,1,0,0,0,0)
    [01:ShowFrame] 
    [00:End]

Exporting to Objective-C, as3swf generates the following source files:

//
//  Shape1View.h
//  Shape1View
//
//  Created by Claus Wahlers on Mon Sep 14 2009.
//  Copyright 2009 côdeazur brasil. All rights reserved.
//
 
#import <UIKit/UIKit.h>
 
@interface Shape1View : UIView {
}
 
- (void)drawFill0:(CGContextRef)ctx;
- (void)drawFill1:(CGContextRef)ctx;
- (void)drawFill2:(CGContextRef)ctx;
- (void)drawFill3:(CGContextRef)ctx;
 
@end
//
//  Shape1View.m
//  Shape1View
//
//  Created by Claus Wahlers on Mon Sep 14 2009.
//  Copyright 2009 côdeazur brasil. All rights reserved.
//
 
#import "Shape1View.h"
 
@implementation Shape1View
 
- (id)initWithFrame:(CGRect)frame {
	if (self = [super initWithFrame:frame]) {
		// Initialization code
	}
	return self;
}
 
- (void)drawRect:(CGRect)rect {
	CGContextRef ctx = UIGraphicsGetCurrentContext();
	[self drawFill0:ctx];
	[self drawFill1:ctx];
	[self drawFill2:ctx];
	[self drawFill3:ctx];
}
 
- (void)drawFill0:(CGContextRef)ctx {
	CGContextSaveGState(ctx);
 
	CGContextBeginPath(ctx);
	CGContextMoveToPoint(ctx, 132.2f, 38.2f);
	CGContextAddQuadCurveToPoint(ctx, 146.15f, 44.95f, 156.05f, 56.95f);
	CGContextAddQuadCurveToPoint(ctx, 146.45f, 70.0f, 143.15f, 85.6f);
	CGContextAddQuadCurveToPoint(ctx, 138.2f, 73.0f, 127.1f, 65.2f);
	CGContextAddQuadCurveToPoint(ctx, 115.55f, 57.25f, 101.6f, 57.25f);
	CGContextAddQuadCurveToPoint(ctx, 83.15f, 57.25f, 70.1f, 70.3f);
	CGContextAddQuadCurveToPoint(ctx, 57.05f, 83.35f, 57.05f, 101.8f);
	CGContextAddQuadCurveToPoint(ctx, 57.05f, 120.25f, 70.1f, 133.3f);
	CGContextAddQuadCurveToPoint(ctx, 83.15f, 146.35f, 101.6f, 146.35f);
	CGContextAddQuadCurveToPoint(ctx, 115.55f, 146.35f, 127.1f, 138.4f);
	CGContextAddQuadCurveToPoint(ctx, 138.2f, 130.6f, 143.15f, 118.0f);
	CGContextAddQuadCurveToPoint(ctx, 146.45f, 133.6f, 156.05f, 146.65f);
	CGContextAddQuadCurveToPoint(ctx, 146.15f, 158.65f, 132.2f, 165.4f);
	CGContextAddQuadCurveToPoint(ctx, 117.8f, 172.3f, 101.6f, 172.3f);
	CGContextAddQuadCurveToPoint(ctx, 72.35f, 172.3f, 51.8f, 151.75f);
	CGContextAddQuadCurveToPoint(ctx, 31.1f, 131.05f, 31.1f, 101.8f);
	CGContextAddQuadCurveToPoint(ctx, 31.1f, 72.55f, 51.8f, 52.0f);
	CGContextAddQuadCurveToPoint(ctx, 72.35f, 31.3f, 101.6f, 31.3f);
	CGContextAddQuadCurveToPoint(ctx, 117.8f, 31.3f, 132.2f, 38.2f);
	CGContextClosePath(ctx);
 
	CGFloat c[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
	CGContextSetFillColor(ctx, c);
	CGContextFillPath(ctx);
 
	CGContextRestoreGState(ctx);
}
 
- (void)drawFill1:(CGContextRef)ctx {
	CGContextSaveGState(ctx);
 
	CGContextBeginPath(ctx);
	CGContextMoveToPoint(ctx, 128.75f, 74.65f);
	CGContextAddQuadCurveToPoint(ctx, 140.0f, 85.9f, 140.0f, 101.8f);
	CGContextAddQuadCurveToPoint(ctx, 140.0f, 117.85f, 128.75f, 128.95f);
	CGContextAddQuadCurveToPoint(ctx, 117.65f, 140.2f, 101.6f, 140.2f);
	CGContextAddQuadCurveToPoint(ctx, 85.55f, 140.2f, 74.3f, 128.95f);
	CGContextAddQuadCurveToPoint(ctx, 63.05f, 117.7f, 63.05f, 101.8f);
	CGContextAddQuadCurveToPoint(ctx, 63.05f, 85.9f, 74.3f, 74.65f);
	CGContextAddQuadCurveToPoint(ctx, 85.55f, 63.4f, 101.6f, 63.4f);
	CGContextAddQuadCurveToPoint(ctx, 117.65f, 63.4f, 128.75f, 74.65f);
	CGContextMoveToPoint(ctx, 118.7f, 84.7f);
	CGContextAddQuadCurveToPoint(ctx, 111.65f, 77.5f, 101.6f, 77.5f);
	CGContextAddQuadCurveToPoint(ctx, 91.55f, 77.5f, 84.5f, 84.7f);
	CGContextAddQuadCurveToPoint(ctx, 77.3f, 91.75f, 77.3f, 101.8f);
	CGContextAddQuadCurveToPoint(ctx, 77.3f, 111.85f, 84.5f, 118.9f);
	CGContextAddQuadCurveToPoint(ctx, 91.55f, 126.1f, 101.6f, 126.1f);
	CGContextAddQuadCurveToPoint(ctx, 111.65f, 126.1f, 118.7f, 118.9f);
	CGContextAddQuadCurveToPoint(ctx, 125.9f, 111.85f, 125.9f, 101.8f);
	CGContextAddQuadCurveToPoint(ctx, 125.9f, 91.75f, 118.7f, 84.7f);
	CGContextClosePath(ctx);
 
	CGFloat c[4] = { 0.5254901960784314f, 0.7254901960784313f, 0.8823529411764706f, 1.0f };
	CGContextSetFillColor(ctx, c);
	CGContextFillPath(ctx);
 
	CGContextRestoreGState(ctx);
}
 
- (void)drawFill2:(CGContextRef)ctx {
	CGContextSaveGState(ctx);
 
	CGContextBeginPath(ctx);
	CGContextMoveToPoint(ctx, 288.8f, 101.5f);
	CGContextAddLineToPoint(ctx, 288.8f, 172.6f);
	CGContextAddLineToPoint(ctx, 262.55f, 172.6f);
	CGContextAddLineToPoint(ctx, 262.7f, 101.65f);
	CGContextAddQuadCurveToPoint(ctx, 262.55f, 83.2f, 249.5f, 70.15f);
	CGContextAddQuadCurveToPoint(ctx, 236.45f, 57.1f, 218.0f, 57.1f);
	CGContextAddQuadCurveToPoint(ctx, 199.55f, 57.1f, 186.5f, 70.3f);
	CGContextAddQuadCurveToPoint(ctx, 173.3f, 83.35f, 173.3f, 101.8f);
	CGContextAddQuadCurveToPoint(ctx, 173.3f, 120.25f, 186.35f, 133.3f);
	CGContextAddQuadCurveToPoint(ctx, 199.4f, 146.35f, 217.85f, 146.5f);
	CGContextAddLineToPoint(ctx, 256.85f, 146.5f);
	CGContextAddLineToPoint(ctx, 256.85f, 172.6f);
	CGContextAddLineToPoint(ctx, 217.7f, 172.6f);
	CGContextAddQuadCurveToPoint(ctx, 188.45f, 172.45f, 167.9f, 151.75f);
	CGContextAddQuadCurveToPoint(ctx, 147.2f, 131.05f, 147.2f, 101.8f);
	CGContextAddQuadCurveToPoint(ctx, 147.2f, 72.4f, 167.9f, 51.7f);
	CGContextAddQuadCurveToPoint(ctx, 188.6f, 31.0f, 218.0f, 31.0f);
	CGContextAddQuadCurveToPoint(ctx, 247.25f, 31.0f, 267.95f, 51.7f);
	CGContextAddQuadCurveToPoint(ctx, 288.65f, 72.4f, 288.8f, 101.5f);
	CGContextClosePath(ctx);
 
	CGFloat c[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
	CGContextSetFillColor(ctx, c);
	CGContextFillPath(ctx);
 
	CGContextRestoreGState(ctx);
}
 
- (void)drawFill3:(CGContextRef)ctx {
	CGContextSaveGState(ctx);
 
	CGContextBeginPath(ctx);
	CGContextMoveToPoint(ctx, 242.6f, 101.95f);
	CGContextAddLineToPoint(ctx, 242.6f, 101.65f);
	CGContextAddQuadCurveToPoint(ctx, 242.45f, 91.45f, 235.25f, 84.4f);
	CGContextAddQuadCurveToPoint(ctx, 228.05f, 77.2f, 218.0f, 77.2f);
	CGContextAddQuadCurveToPoint(ctx, 207.95f, 77.2f, 200.6f, 84.4f);
	CGContextAddQuadCurveToPoint(ctx, 193.4f, 91.75f, 193.4f, 101.8f);
	CGContextAddQuadCurveToPoint(ctx, 193.4f, 111.85f, 200.6f, 119.05f);
	CGContextAddQuadCurveToPoint(ctx, 207.65f, 126.25f, 217.85f, 126.4f);
	CGContextAddLineToPoint(ctx, 242.45f, 126.4f);
	CGContextAddLineToPoint(ctx, 242.45f, 102.55f);
	CGContextAddLineToPoint(ctx, 242.6f, 101.95f);
	CGContextMoveToPoint(ctx, 218.0f, 62.95f);
	CGContextAddQuadCurveToPoint(ctx, 234.05f, 62.95f, 245.45f, 74.2f);
	CGContextAddQuadCurveToPoint(ctx, 256.85f, 85.6f, 256.85f, 101.65f);
	CGContextAddLineToPoint(ctx, 256.85f, 140.65f);
	CGContextAddLineToPoint(ctx, 217.85f, 140.65f);
	CGContextAddQuadCurveToPoint(ctx, 201.8f, 140.65f, 190.4f, 129.25f);
	CGContextAddQuadCurveToPoint(ctx, 179.15f, 117.85f, 179.15f, 101.8f);
	CGContextAddQuadCurveToPoint(ctx, 179.15f, 85.75f, 190.55f, 74.35f);
	CGContextAddQuadCurveToPoint(ctx, 201.95f, 62.95f, 218.0f, 62.95f);
	CGContextClosePath(ctx);
 
	CGFloat c[4] = { 0.5254901960784314f, 0.7254901960784313f, 0.8823529411764706f, 1.0f };
	CGContextSetFillColor(ctx, c);
	CGContextFillPath(ctx);
 
	CGContextRestoreGState(ctx);
}
 
- (void)dealloc {
	[super dealloc];
}
 
@end

The final result, integrated in a simple iPhone project:

Clone this wiki locally