001: /*
002: * $Id: LazyShape.java,v 1.2 2002/02/15 23:44:28 skavish Exp $
003: *
004: * ==========================================================================
005: *
006: * The JGenerator Software License, Version 1.0
007: *
008: * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
009: *
010: * Redistribution and use in source and binary forms, with or without
011: * modification, are permitted provided that the following conditions are met:
012: *
013: * 1. Redistributions of source code must retain the above copyright
014: * notice, this list of conditions and the following disclaimer.
015: *
016: * 2. Redistributions in binary form must reproduce the above copyright
017: * notice, this list of conditions and the following disclaimer in
018: * the documentation and/or other materials provided with the
019: * distribution.
020: *
021: * 3. The end-user documentation included with the redistribution, if
022: * any, must include the following acknowlegement:
023: * "This product includes software developed by Dmitry Skavish
024: * (skavish@usa.net, http://www.flashgap.com/)."
025: * Alternately, this acknowlegement may appear in the software itself,
026: * if and wherever such third-party acknowlegements normally appear.
027: *
028: * 4. The name "The JGenerator" must not be used to endorse or promote
029: * products derived from this software without prior written permission.
030: * For written permission, please contact skavish@usa.net.
031: *
032: * 5. Products derived from this software may not be called "The JGenerator"
033: * nor may "The JGenerator" appear in their names without prior written
034: * permission of Dmitry Skavish.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
040: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: *
049: */
050:
051: package org.openlaszlo.iv.flash.api.shape;
052:
053: import java.awt.geom.*;
054: import java.io.PrintStream;
055:
056: import org.openlaszlo.iv.flash.parser.*;
057: import org.openlaszlo.iv.flash.util.*;
058: import org.openlaszlo.iv.flash.api.*;
059:
060: public class LazyShape extends FlashDef {
061:
062: public static class BitmapRef {
063: public FlashDef bitmap;
064: public int offset;
065:
066: public BitmapRef(FlashDef bitmap, int offset) {
067: this .bitmap = bitmap;
068: this .offset = offset;
069: }
070: }
071:
072: protected IVVector bitmaps;
073: protected DataMarker data;
074: protected Rectangle2D bounds;
075: protected int tagCode;
076:
077: public LazyShape() {
078: }
079:
080: public int getTag() {
081: return tagCode;
082: }
083:
084: public static FlashDef parse(Parser p) {
085: FlashFile file = p.getFile();
086: if (file.isFullParsing()) {
087: Shape shape = Shape.parse(p);
088: return shape;
089: } else {
090: LazyShape shape = new LazyShape();
091: shape.tagCode = p.getTagCode();
092: shape.setID(p.getUWord());
093: shape.bounds = p.getRect();
094: // skip the data
095: shape.data = new DataMarker(p.getBuf(), p.getPos(), p
096: .getTagEndPos());
097: extractBitmaps(p, shape);
098: return shape;
099: }
100: }
101:
102: public void write(FlashOutput fob) {
103: fob.writeTag(tagCode, 2 + GeomHelper.getSize(bounds)
104: + data.length());
105: fob.writeDefID(this );
106: fob.write(bounds);
107: int pos = fob.getPos();
108: data.write(fob);
109: if (bitmaps != null) {
110: for (int i = 0; i < bitmaps.size(); i++) {
111: BitmapRef ref = (BitmapRef) bitmaps.elementAt(i);
112: int bitmapID;
113: if (ref.bitmap == null) { // 02/08/01 by sd
114: bitmapID = 0xffff;
115: } else {
116: bitmapID = fob.getDefID(ref.bitmap);
117: }
118: fob.writeWordAt(bitmapID, pos + ref.offset);
119: }
120: }
121: }
122:
123: private static void parseShapeStyle(Parser p, LazyShape shape,
124: boolean withAlpha, int pos) {
125: // Get the number of fills.
126: int nFills = p.getUByte();
127: if (nFills == 255) {
128: nFills = p.getUWord();
129: }
130:
131: // Get each of the fill style.
132: for (int i = 0; i < nFills; i++) {
133: int fillStyle = p.getUByte();
134: if ((fillStyle & 0x10) != 0) { // gradient
135: // Get the gradient matrix.
136: p.skipMatrix();
137: // Get the number of colors.
138: int nColors = p.getUByte();
139: // Get each of the colors.
140: for (int j = 0; j < nColors; j++) {
141: p.skip(1); // ratio
142: Color.skip(p, withAlpha);
143: }
144: } else if ((fillStyle & 0x40) != 0) { // bitmap
145: int id_pos = p.getPos() - pos;
146: int id = p.getUWord(); // id may be equal to 0xffff, I don't know what it means
147: FlashDef def = p.getDef(id);
148: shape.addBitmap(def, id_pos);
149: p.skipMatrix();
150: } else { // A solid color
151: Color.skip(p, withAlpha);
152: }
153: }
154:
155: int nLines = p.getUByte();
156: if (nLines == 255) {
157: nLines = p.getUWord();
158: }
159: // Get each of the line styles.
160: for (int i = 0; i < nLines; i++) {
161: p.skip(2); // width
162: Color.skip(p, withAlpha);
163: }
164:
165: }
166:
167: private static void extractBitmaps(Parser p, LazyShape shape) {
168: int pos = p.getPos();
169:
170: boolean withAlpha = shape.getTag() == Tag.DEFINESHAPE3;
171:
172: parseShapeStyle(p, shape, withAlpha, pos);
173:
174: int nBits = p.getUByte();
175: int nFillBits = (nBits & 0xf0) >> 4;
176: int nLineBits = nBits & 0x0f;
177: // parse shape records
178: p.initBits();
179: for (;;) {
180: if (p.getBool()) { // edge record
181: if (p.getBool()) { // stright edge
182: int nb = p.getBits(4) + 2;
183: if (p.getBool()) {
184: p.skipBits(nb + nb); // general line
185: } else {
186: p.skipBits(1 + nb); // horiz or vert line
187: }
188:
189: } else { // curved edge
190: int nb = p.getBits(4) + 2;
191: p.skipBits(nb * 4);
192: }
193: } else { // non-edge record
194: int flags = p.getBits(5);
195: if (flags == 0)
196: break; // end record
197: if ((flags & StyleChangeRecord.MOVETO) != 0) {
198: int nMoveBits = p.getBits(5);
199: p.skipBits(nMoveBits + nMoveBits);
200: }
201: if ((flags & StyleChangeRecord.FILLSTYLE0) != 0) {
202: p.skipBits(nFillBits);
203: }
204: if ((flags & StyleChangeRecord.FILLSTYLE1) != 0) {
205: p.skipBits(nFillBits);
206: }
207: if ((flags & StyleChangeRecord.LINESTYLE) != 0) {
208: p.skipBits(nLineBits);
209: }
210: if ((flags & StyleChangeRecord.NEW_STYLES) != 0) {
211: parseShapeStyle(p, shape, withAlpha, pos);
212: nBits = p.getUByte();
213: nFillBits = (nBits & 0xf0) >> 4;
214: nLineBits = nBits & 0x0f;
215: p.initBits();
216: }
217: if ((flags & 0x80) != 0) {
218: break;
219: }
220: }
221: }
222: }
223:
224: public void printContent(PrintStream out, String indent) {
225: out.println(indent + "LazyShape(" + Tag.tagNames[tagCode]
226: + "): id=" + getID() + ", name='" + getName() + "'");
227: out.println(indent + " " + bounds);
228: if (bitmaps != null) {
229: out.print(indent + " bitmaps used: ");
230: for (int i = 0; i < bitmaps.size(); i++) {
231: BitmapRef ref = (BitmapRef) bitmaps.elementAt(i);
232: out.print("id["
233: + i
234: + "]="
235: + (ref.bitmap != null ? ref.bitmap.getID()
236: : 0xffff) + " ");
237: }
238: out.println();
239: }
240: }
241:
242: public boolean isConstant() {
243: return true;
244: }
245:
246: public Rectangle2D getBounds() {
247: return bounds;
248: }
249:
250: public void collectDeps(DepsCollector dc) {
251: if (bitmaps != null) {
252: for (int i = 0; i < bitmaps.size(); i++) {
253: BitmapRef ref = (BitmapRef) bitmaps.elementAt(i);
254: if (ref.bitmap != null)
255: dc.addDep(ref.bitmap);
256: }
257: }
258: }
259:
260: public void addBitmap(FlashDef def, int offset) {
261: if (bitmaps == null)
262: bitmaps = new IVVector();
263: bitmaps.addElement(new BitmapRef(def, offset));
264: }
265:
266: protected FlashItem copyInto(FlashItem item, ScriptCopier copier) {
267: super .copyInto(item, copier);
268: ((LazyShape) item).data = (DataMarker) data.getCopy();
269: ((LazyShape) item).tagCode = tagCode;
270: ((LazyShape) item).bounds = (Rectangle2D) bounds.clone();
271: if (bitmaps != null) {
272: IVVector v = new IVVector(bitmaps.size());
273: for (int i = 0; i < bitmaps.size(); i++) {
274: BitmapRef ref = (BitmapRef) bitmaps.elementAt(i);
275: v.addElement(new BitmapRef(copier.copy(ref.bitmap),
276: ref.offset));
277: }
278: ((LazyShape) item).bitmaps = v;
279: }
280: return item;
281: }
282:
283: public FlashItem getCopy(ScriptCopier copier) {
284: return copyInto(new LazyShape(), copier);
285: }
286: }
|