001: /*
002: * @(#)Jmf.java 2.00 28/4/1999
003: *
004: * Copyright (c) 1997-9 Axiom Software Development Ltd..
005: * All Rights Reserved.
006: *
007: * Permission to use, copy, modify, and distribute this
008: * software and its documentation for NON-COMMERCIAL purposes
009: * and without fee is hereby granted provided that this
010: * copyright notice appears in all copies. Please refer to
011: * the file "copyright.html" for further important copyright
012: * and licensing information.
013: *
014: * ASD MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
015: * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED,
016: * INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
017: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
018: * NON-INFRINGEMENT. ASD SHALL NOT BE LIABLE FOR ANY DAMAGES
019: * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
020: * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
021: * $Revision: 1.12 $
022: */
023: package net.xoetrope.xui.wmf;
024:
025: import java.io.DataInputStream;
026: import java.io.IOException;
027:
028: /**
029: * Reads a WMF file, including an Aldus Placable Metafile Header.
030: * @author Luan O'Carroll
031: * @version 2.00
032: */
033: public class WmfRecordStore extends RecordStore {
034:
035: public WmfRecordStore() {
036: }
037:
038: private short readShort(DataInputStream is) throws IOException {
039: byte js[] = new byte[2];
040: is.read(js);
041: int iTemp = ((0xff) & js[1]) << 8;
042: short i = (short) (0xffff & iTemp);
043: i |= ((0xff) & js[0]);
044: return i;
045: }
046:
047: private int readInt(DataInputStream is) throws IOException {
048: byte js[] = new byte[4];
049: is.read(js);
050: int i = ((0xff) & js[3]) << 24;
051: i |= ((0xff) & js[2]) << 16;
052: i |= ((0xff) & js[1]) << 8;
053: i |= ((0xff) & js[0]);
054: return i;
055: }
056:
057: /**
058: * Reads the WMF file from the specified Stream.
059: */
060: public boolean read(DataInputStream is) throws IOException {
061: reset();
062:
063: setReading(true);
064: int dwIsAldus = readInt(is);
065: if (dwIsAldus == 0x9ac6cdd7) {
066: // Read the aldus placeable header.
067: int key = dwIsAldus;
068: short hmf = readShort(is);
069: short left = readShort(is);
070: short top = readShort(is);
071: short right = readShort(is);
072: short bottom = readShort(is);
073: short inch = readShort(is);
074: int reserved = readInt(is);
075: short checksum = readShort(is);
076: } else {
077: System.out
078: .println("Unable to read file, it is not a Aldus Placable Metafile");
079: setReading(false);
080: return false;
081: }
082:
083: int mtType = readShort(is);
084: int mtHeaderSize = readShort(is);
085: int mtVersion = readShort(is);
086: int mtSize = readInt(is);
087: int mtNoObjects = readShort(is);
088: int mtMaxRecord = readInt(is);
089: int mtNoParameters = readShort(is);
090:
091: short functionId = 1;
092: int recSize = 0;
093: short recData;
094:
095: numRecords = 0;
096:
097: numObjects = mtNoObjects;
098: objectVector.ensureCapacity(numObjects);
099: for (int i = 0; i < numObjects; i++) {
100: objectVector.addElement(new GdiObject(i, false));
101: }
102:
103: while (functionId > 0) {
104: recSize = readInt(is);
105: // Subtract size in 16-bit words of recSize and functionId;
106: recSize -= 3;
107: functionId = readShort(is);
108: if (functionId <= 0)
109: break;
110:
111: MetaRecord mr = new MetaRecord();
112: switch (functionId) {
113: case 0x062F: // DrawText
114: {
115: for (int i = 0; i < recSize; i++)
116: recData = readShort(is);
117: numRecords--;
118: }
119: break;
120:
121: case 0x0a32: // ExtTextOut
122: {
123: int yVal = readShort(is);
124: int xVal = readShort(is);
125: int lenText = readInt(is);
126: int len = 2 * (recSize - 4);
127: byte bstr[] = new byte[lenText];
128: //is.read( bstr );
129: int i = 0;
130: for (; i < lenText; i++)
131: bstr[i] = is.readByte();
132: for (; i < len; i++)
133: is.readByte();
134:
135: String str = new String(bstr);
136: mr = new StringRecord(str);
137: mr.numPoints = recSize;
138: mr.functionId = functionId;
139:
140: mr.AddElement(new Integer(xVal));
141: mr.AddElement(new Integer(yVal));
142: records.addElement(mr);
143: }
144: break;
145:
146: case 0x0521: // TextOut
147: {
148: int len = readShort(is);
149: byte bstr[] = new byte[len];
150: //is.read( bstr );
151: for (int i = 0; i < len; i++)
152: bstr[i] = is.readByte();
153: int yVal = readShort(is);
154: int xVal = readShort(is);
155:
156: String str = new String(bstr);
157: mr = new StringRecord(str);
158: mr.numPoints = recSize;
159: mr.functionId = functionId;
160:
161: mr.AddElement(new Integer(xVal));
162: mr.AddElement(new Integer(yVal));
163: records.addElement(mr);
164: }
165: break;
166:
167: case 0x02FB: // CreateFontIndirect
168: {
169: int lfHeight = readShort(is);
170: int lfWidth = readShort(is);
171: int lfEscapement = readShort(is);
172: int lfOrientation = readShort(is);
173: int lfWeight = readShort(is);
174:
175: int lfItalic = is.readByte();
176: int lfUnderline = is.readByte();
177: int lfStrikeOut = is.readByte();
178: int lfCharSet = is.readByte();
179: int lfOutPrecision = is.readByte();
180: int lfClipPrecision = is.readByte();
181: int lfQuality = is.readByte();
182: int lfPitchAndFamily = is.readByte();
183:
184: int len = (2 * (recSize - 9));//13));
185: byte lfFaceName[] = new byte[len];
186: byte ch;
187: for (int i = 0; i < len; i++)
188: lfFaceName[i] = is.readByte();
189:
190: String str = new String(lfFaceName);
191:
192: mr = new StringRecord(str);
193: mr.numPoints = recSize;
194: mr.functionId = functionId;
195:
196: mr.AddElement(new Integer(lfHeight));
197: mr.AddElement(new Integer(lfItalic));
198: mr.AddElement(new Integer(lfWeight));
199: records.addElement(mr);
200: }
201: break;
202:
203: case 0x020B: //EMR_SETWINDOWORGEX
204: case 0x020C: //EMR_SETWINDOWORGEX
205: {
206: mr.numPoints = recSize;
207: mr.functionId = functionId;
208:
209: int i0 = readShort(is);
210: int i1 = readShort(is);
211: mr.AddElement(new Integer(i1));
212: mr.AddElement(new Integer(i0));
213: records.addElement(mr);
214: }
215: break;
216:
217: case 0x02FC: // CreateBrushIndirect
218: {
219: mr.numPoints = recSize;
220: mr.functionId = functionId;
221:
222: // The style
223: mr.AddElement(new Integer(readShort(is)));
224:
225: int colorref = readInt(is);
226: int red = colorref & 0xff;
227: int green = (colorref & 0xff00) >> 8;
228: int blue = (colorref & 0xff0000) >> 16;
229: int flags = (colorref & 0x3000000) >> 24;
230: mr.AddElement(new Integer(red));
231: mr.AddElement(new Integer(green));
232: mr.AddElement(new Integer(blue));
233:
234: // The hatch style
235: mr.AddElement(new Integer(readShort(is)));
236:
237: records.addElement(mr);
238: }
239: break;
240:
241: case 0x02FA: // CreatePenIndirect:
242: {
243: mr.numPoints = recSize;
244: mr.functionId = functionId;
245:
246: // The style
247: Integer style = new Integer(readShort(is));
248: mr.AddElement(style);
249:
250: int width = readShort(is);
251: int colorref = readInt(is);
252: int height = readShort(is);
253:
254: int red = colorref & 0xff;
255: int green = (colorref & 0xff00) >> 8;
256: int blue = (colorref & 0xff0000) >> 16;
257: int flags = (colorref & 0x3000000) >> 24;
258: mr.AddElement(new Integer(red));
259: mr.AddElement(new Integer(green));
260: mr.AddElement(new Integer(blue));
261:
262: // The pen width
263: mr.AddElement(new Integer(width));
264:
265: for (int j = 0; j < recSize - 5; j++)
266: mr.AddElement(new Integer(readShort(is)));
267:
268: records.addElement(mr);
269: }
270: break;
271:
272: case 0x0209: // SetTextColor
273: case 0x0201: //"SETBKCOLOR",
274: {
275: mr.numPoints = recSize;
276: mr.functionId = functionId;
277:
278: int colorref = readInt(is);
279: int red = colorref & 0xff;
280: int green = (colorref & 0xff00) >> 8;
281: int blue = (colorref & 0xff0000) >> 16;
282: int flags = (colorref & 0x3000000) >> 24;
283: mr.AddElement(new Integer(red));
284: mr.AddElement(new Integer(green));
285: mr.AddElement(new Integer(blue));
286: records.addElement(mr);
287: }
288: break;
289:
290: case 0x0213: //"LINETO",
291: case 0x0214: //"MOVETO",
292: {
293: mr.numPoints = recSize;
294: mr.functionId = functionId;
295:
296: int i0 = readShort(is);
297: int i1 = readShort(is);
298: mr.AddElement(new Integer(i1));
299: mr.AddElement(new Integer(i0));
300: records.addElement(mr);
301: }
302: break;
303:
304: case 0x0538: //"POLYPOLYGON", 0x0538,
305: {
306: mr.numPoints = recSize;
307: mr.functionId = functionId;
308:
309: int count = readShort(is);
310: int pts[] = new int[count];
311: int ptCount = 0;
312: for (int i = 0; i < count; i++) {
313: pts[i] = readShort(is);
314: ptCount += pts[i];
315: }
316: mr.AddElement(new Integer(count));
317:
318: for (int i = 0; i < count; i++)
319: mr.AddElement(new Integer(pts[i]));
320:
321: int offset = count + 1;
322: for (int i = 0; i < count; i++) {
323: for (int j = 0; j < pts[i]; j++) {
324: mr.AddElement(new Integer(readShort(is)));
325: mr.AddElement(new Integer(readShort(is)));
326: }
327: }
328: records.addElement(mr);
329: }
330: break;
331:
332: case 0x0324: //"POLYGON", 0x0324,
333: {
334: mr.numPoints = recSize;
335: mr.functionId = functionId;
336:
337: int count = readShort(is);
338: mr.AddElement(new Integer(count));
339: for (int i = 0; i < count; i++) {
340: mr.AddElement(new Integer(readShort(is)));
341: mr.AddElement(new Integer(readShort(is)));
342: }
343: records.addElement(mr);
344: }
345: break;
346:
347: case 0x0418: //"ELLIPSE",
348: case 0x0416: //"INTERSECTCLIPRECT",
349: case 0x041B: //"RECTANGLE",
350: {
351: mr.numPoints = recSize;
352: mr.functionId = functionId;
353:
354: int i0 = readShort(is);
355: int i1 = readShort(is);
356: int i2 = readShort(is);
357: int i3 = readShort(is);
358: mr.AddElement(new Integer(i3));
359: mr.AddElement(new Integer(i2));
360: mr.AddElement(new Integer(i1));
361: mr.AddElement(new Integer(i0));
362: records.addElement(mr);
363: }
364: break;
365:
366: case 0x061C: //"ROUNDRECT",
367: {
368: mr.numPoints = recSize;
369: mr.functionId = functionId;
370:
371: int i0 = readShort(is);
372: int i1 = readShort(is);
373: int i2 = readShort(is);
374: int i3 = readShort(is);
375: int i4 = readShort(is);
376: int i5 = readShort(is);
377: mr.AddElement(new Integer(i5));
378: mr.AddElement(new Integer(i4));
379: mr.AddElement(new Integer(i3));
380: mr.AddElement(new Integer(i2));
381: mr.AddElement(new Integer(i1));
382: mr.AddElement(new Integer(i0));
383: records.addElement(mr);
384: }
385: break;
386:
387: case 0x0817: //"ARC",
388: case 0x081A: //"PIE",
389: {
390: mr.numPoints = recSize;
391: mr.functionId = functionId;
392:
393: int i0 = readShort(is);
394: int i1 = readShort(is);
395: int i2 = readShort(is);
396: int i3 = readShort(is);
397: int i4 = readShort(is);
398: int i5 = readShort(is);
399: int i6 = readShort(is);
400: int i7 = readShort(is);
401: mr.AddElement(new Integer(i7));
402: mr.AddElement(new Integer(i6));
403: mr.AddElement(new Integer(i5));
404: mr.AddElement(new Integer(i4));
405: mr.AddElement(new Integer(i3));
406: mr.AddElement(new Integer(i2));
407: mr.AddElement(new Integer(i1));
408: mr.AddElement(new Integer(i0));
409: records.addElement(mr);
410: }
411: break;
412:
413: default:
414: mr.numPoints = recSize;
415: mr.functionId = functionId;
416:
417: for (int j = 0; j < recSize; j++)
418: mr.AddElement(new Integer(readShort(is)));
419:
420: records.addElement(mr);
421: break;
422:
423: }
424:
425: numRecords++;
426: }
427:
428: setReading(false);
429: return true;
430: }
431:
432: public int addObject(int type, Object obj) {
433: int startIdx = 0;
434: //if ( type == Jmf.PEN ) {
435: // startIdx = 2;
436: //}
437: for (int i = startIdx; i < numObjects; i++) {
438: GdiObject gdi = (GdiObject) objectVector.elementAt(i);
439: if (gdi.used == false) {
440: gdi.Setup(type, obj);
441: lastObjectIdx = i;
442: return i;
443: }
444: }
445: return -1;
446: }
447:
448: }
|