1 goog.provide('FlappSWFShapeRecords');
2 goog.require('FlappSWFFillStyles');
4 goog.scope(function() {
9 FlappSWFShapeRecords = function(ibit) {
13 FlappSWFShapeRecords.loadAndMarkEdgeLoop = function(code, ibit, fillStyles, lineStyles, numFillBits, numLineBits) {
14 var shapes = FlappSWFShapeRecords.load(code, ibit, fillStyles, lineStyles, numFillBits, numLineBits);
15 var edges = FlappSWFShapeRecords.convertEdges(shapes);
16 shapes = null ; // for GC
17 FlappSWFShapeRecords.markFillEdgeLoop(edges.fillEdges);
21 FlappSWFShapeRecords.load = function(code, ibit, fillStyles, lineStyles, numFillBits, numLineBits) {
22 var shapeRecords = []; // [[fillstyle0, fillstyle1, linestyle, edgetypes, [edges]], [], ...]
23 var fillStyleBaseIndex = 0;
24 var lineStyleBaseIndex = 0;
25 var fillStyle0 = 0, fillStyle1 = 0, lineStyle = 0;
26 var currentX = 0, currentY = 0;
28 var edgeTypeArray = [];
29 var edges = [currentX, currentY];
31 while (first6bits = ibit.ub(6)) {
32 if (first6bits & 0x20) { // Edge (1XXXXX)
33 var numBits = first6bits & 0x0F;
34 if (first6bits & 0x10) { // Straight Edge (11XXXX)
35 var deltaX = 0, deltaY = 0;
36 var generalLine = ibit.b();
37 if (generalLine) { // Straight Edge
38 deltaX = ibit.sb(numBits + 2);
39 deltaY = ibit.sb(numBits + 2);
40 } else { // Straight Edge
41 var vertLine = ibit.b();
42 if (vertLine) { // Straight Edge
43 deltaY = ibit.sb(numBits + 2);
45 deltaX = ibit.sb(numBits + 2);
48 var x = currentX + deltaX;
49 var y = currentY + deltaY;
50 edgeTypeArray.push('S');
54 } else { // Curved Edge (10XXXX)
55 var controlDeltaX = ibit.sb(numBits + 2);
56 var controlDeltaY = ibit.sb(numBits + 2);
57 var anchorDeltaX = ibit.sb(numBits + 2);
58 var anchorDeltaY = ibit.sb(numBits + 2);
59 var controlX = currentX + controlDeltaX;
60 var controlY = currentY + controlDeltaY;
61 var anchorX = controlX + anchorDeltaX;
62 var anchorY = controlY + anchorDeltaY;
63 edgeTypeArray.push('C');
64 edges.push(controlX, controlY,
69 } else if (first6bits) { // Change (0XXXXX != 000000)
70 if (edgeTypeArray.length > 1) {
72 {fillStyle0:fillStyle0, fillStyle1:fillStyle1, lineStyle:lineStyle,
73 edgeTypes:edgeTypeArray.join(''),edges:edges}
76 if (first6bits & 0x10) { // StateNewStyles
77 fillStyleBaseIndex = fillStyles.length;
78 lineStyleBaseIndex = lineStyles.length;
79 var appendFillStyles = FlappSWFFillStyles.load(code, ibit);
80 var appendLineStyles = FlappSWFLineStyles.load(code, ibit);
81 var extendFillStyles = [];
82 var extendLineStyles = [];
83 for (var i = 0, l = fillStyles.length ; i < l ; i++) {
84 extendFillStyles.push(fillStyles[i]);
86 for (var i = 0, l = appendFillStyles.length ; i < l ; i++) {
87 extendFillStyles.push(appendFillStyles[i]);
89 for (var i = 0, l = lineStyles.length ; i < l ; i++) {
90 extendLineStyles.push(lineStyles[i]);
92 for (var i = 0, l = appendLineStyles.length ; i < l ; i++) {
93 extendLineStyles.push(appendLineStyles[i]);
95 fillStyles = extendFillStyles;
96 lineStyles = extendFillStyles;
98 var numBits = ibit.ui8();
99 numFillBits = numBits >> 4;
100 numLineBits = numBits & 0x0f;
101 fillStyleBaseIndex = fillStyles.length;
102 lineStyleBaseIndex = lineStyles.length;
104 if (first6bits & 1) { // StateMoveTo
105 var moveBits = ibit.ub(5);
106 currentX = ibit.sb(moveBits); // MoveDeltaX(?)
107 currentY = ibit.sb(moveBits); // MoveDeltaY(?)
109 if (first6bits & 2) { // StateFillStyle0
110 fillStyle0 = ibit.ub(numFillBits);
112 fillStyle0 += fillStyleBaseIndex;
115 if (first6bits & 4) { // StateFillStyle1
116 fillStyle1 = ibit.ub(numFillBits);
118 fillStyle1 += fillStyleBaseIndex;
121 if (first6bits & 8) { // StateLineStyle
122 lineStyle = ibit.ub(numLineBits);
124 lineStyle += lineStyleBaseIndex;
128 edges = [currentX, currentY];
131 if (edgeTypeArray.length > 1) {
133 {fillStyle0:fillStyle0, fillStyle1:fillStyle1, lineStyle:lineStyle,
134 edgeTypes:edgeTypeArray.join(''), edges:edges}
140 FlappSWFShapeRecords.convertEdges = function(shapeRecords) {
142 var fillEdges = {}; // fillStyle => []
143 var lineEdges = {}; // lineStyle => []
144 for (i = 0, l = shapeRecords.length ; i < l ; i++) {
145 var record = shapeRecords[i];
146 var i2, l2 = record.edges.length;
147 var fillStyle0 = record.fillStyle0;
148 var fillStyle1 = record.fillStyle1;
149 var lineStyle = record.lineStyle;
150 var edgeTypes = record.edgeTypes;
151 var edges = record.edges;
154 edgesArray = new Int32Array(l2);
155 for (i2 = 0 ; i2 < l2 ; i2++) {
156 edgesArray[i2] = edges[i2];
158 if (! (fillStyle0 in fillEdges)) {
159 fillEdges[fillStyle0] = [];
161 fillEdges[fillStyle0].push({types:edgeTypes,
163 prev:null, next:null});
166 var rl2 = l2; // reverse l2
167 edgesArray = new Int32Array(l2);
168 for (i2 = 0 ; i2 < l2 ; i2++) {
169 edgesArray[i2] = edges[--rl2];
171 if (! (fillStyle1 in fillEdges)) {
172 fillEdges[fillStyle1] = [];
174 fillEdges[fillStyle1].push({types:edgeTypes.split('').reverse().join(''),
176 prev:null, next:null});
179 edgesArray = new Int32Array(l2);
180 for (i2 = 0 ; i2 < l2 ; i2++) {
181 edgesArray[i2] = edges[i2];
183 if (! (lineStyle in fillEdges)) {
184 fillEdges[lineStyle] = [];
186 lineEdges[lineStyle].push({types:edgeTypes,
190 return {fillEdges:fillEdges, lineEdges:lineEdges};
193 FlappSWFShapeRecords.markFillEdgeLoop = function(fillEdges) {
194 var style, edgesInfoList;
195 var i, l, i2, edgesInfo, edges;
196 for (style in fillEdges) {
197 edgesInfoList = fillEdges[style];
198 for (i = 0, l = edgesInfoList.length ; i < l ; i++) {
199 edgesInfo = edgesInfoList[i];
200 edges = edgesInfo.edges;
201 var edgesLastX = edges[edges.length - 2];
202 var edgesLastY = edges[edges.length - 1];
203 for (i2 = 0; i2 < l ; i2++) {
204 if (edgesInfo.prev !== null) {
207 var targetEdge = edgesInfoList[i2].edges;
208 if ((edgesLastX === edges[0]) &&
209 (edgesLastY === edges[1])){
211 edgesInfoList[i2].prev = i;
216 console.warn("edges link not found");