You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by de...@apache.org on 2005/09/25 21:53:33 UTC
svn commit: r291468 [3/19] - in /xmlgraphics/batik/trunk: ./
samples/tests/resources/wmf/ sources/org/apache/batik/ext/awt/geom/
sources/org/apache/batik/svggen/ sources/org/apache/batik/transcoder/
sources/org/apache/batik/transcoder/wmf/ sources/org/...
Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/transcoder/wmf/tosvg/WMFRecordStore.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/transcoder/wmf/tosvg/WMFRecordStore.java?rev=291468&r1=291467&r2=291468&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/transcoder/wmf/tosvg/WMFRecordStore.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/transcoder/wmf/tosvg/WMFRecordStore.java Sun Sep 25 12:51:54 2005
@@ -30,9 +30,10 @@
* @author <a href="mailto:luano@asd.ie">Luan O'Carroll</a>
* @version $Id$
*/
-public class WMFRecordStore implements WMFConstants{
+public class WMFRecordStore extends AbstractWMFReader {
- public WMFRecordStore(){
+ public WMFRecordStore() {
+ super();
reset();
}
@@ -45,90 +46,37 @@
vpY = 0;
vpW = 1000;
vpH = 1000;
- numObjects = 0;
+ scaleX = 1;
+ scaleY = 1;
+ inch = 0;
records = new Vector( 20, 20 );
- objectVector = new Vector();
- }
-
- private short readShort( DataInputStream is ) throws IOException{
- byte js[] = new byte[ 2 ];
- is.read( js );
- int iTemp = ((0xff) & js[ 1 ] ) << 8;
- short i = (short)(0xffff & iTemp);
- i |= ((0xff) & js[ 0 ] );
- return i;
- }
-
- private int readInt( DataInputStream is ) throws IOException {
- byte js[] = new byte[ 4 ];
- is.read( js );
- int i = ((0xff) & js[ 3 ] ) << 24;
- i |= ((0xff) & js[ 2 ] ) << 16;
- i |= ((0xff) & js[ 1 ] ) << 8;
- i |= ((0xff) & js[ 0 ] );
- return i;
}
/**
* Reads the WMF file from the specified Stream.
*/
- public boolean read( DataInputStream is ) throws IOException{
- reset();
-
- setReading( true );
- int dwIsAldus = readInt( is );
- if ( dwIsAldus == WMFConstants.META_ALDUS_APM ) {
- // Read the aldus placeable header.
- /* int key = dwIsAldus; */
- /* short hmf = */ readShort( is );
- /* short left = */ readShort( is );
- /* short top = */ readShort( is );
- /* short right = */ readShort( is );
- /* short bottom = */ readShort( is );
- /* short inch = */ readShort( is );
- /* int reserved = */ readInt ( is );
- /* short checksum = */ readShort( is );
- }
- else {
- System.out.println( "Unable to read file, it is not a Aldus Placable Metafile" );
- setReading( false );
- return false;
- }
-
- /* int mtType = */ readShort( is );
- /* int mtHeaderSize = */ readShort( is );
- /* int mtVersion = */ readShort( is );
- /* int mtSize = */ readInt ( is );
- int mtNoObjects = readShort( is );
- /* int mtMaxRecord = */ readInt ( is );
- /* int mtNoParameters = */ readShort( is );
-
+ protected boolean readRecords( DataInputStream is ) throws IOException {
short functionId = 1;
int recSize = 0;
+ short recData;
numRecords = 0;
- numObjects = mtNoObjects;
- objectVector.ensureCapacity( numObjects );
- for ( int i = 0; i < numObjects; i++ ) {
- objectVector.addElement( new GdiObject( i, false ));
- }
-
- while ( functionId > 0 ) {
+ while ( functionId > 0) {
recSize = readInt( is );
// Subtract size in 16-bit words of recSize and functionId;
recSize -= 3;
functionId = readShort( is );
if ( functionId <= 0 )
- break;
+ break;
MetaRecord mr = new MetaRecord();
switch ( functionId ) {
case WMFConstants.META_DRAWTEXT:
{
for ( int i = 0; i < recSize; i++ )
- readShort( is );
+ recData = readShort( is );
numRecords--;
}
break;
@@ -137,23 +85,50 @@
{
int yVal = readShort( is );
int xVal = readShort( is );
- int lenText = readInt( is );
- int len = 2*(recSize-4);
+ int lenText = readShort( is );
+ int flag = readShort( is );
+ int read = 4; // used to track the actual size really read
+ boolean clipped = false;
+ int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+ int len;
+ // determination of clipping property
+ if ((flag & WMFConstants.ETO_CLIPPED) != 0) {
+ x1 = readShort( is );
+ y1 = readShort( is );
+ x2 = readShort( is );
+ y2 = readShort( is );
+ read += 4;
+ clipped = true;
+ }
byte bstr[] = new byte[ lenText ];
- //is.read( bstr );
int i = 0;
- for ( ; i < lenText; i++ )
+ for ( ; i < lenText; i++ ) {
bstr[ i ] = is.readByte();
- for ( ; i < len; i++ )
- is.readByte();
-
- String str = new String( bstr );
- mr = new StringRecord( str );
+ }
+ read += (lenText + 1)/2;
+ /* must do this because WMF strings always have an even number of bytes, even
+ * if there is an odd number of characters
+ */
+ if (lenText % 2 != 0) is.readByte();
+ // if the record was not completely read, finish reading
+ if (read < recSize) for (int j = read; j < recSize; j++) readShort( is );
+
+ /* get the StringRecord, having decoded the String, using the current
+ * charset (which was given by the last META_CREATEFONTINDIRECT)
+ */
+ mr = new MetaRecord.ByteRecord(bstr);
mr.numPoints = recSize;
mr.functionId = functionId;
mr.AddElement( new Integer( xVal ));
mr.AddElement( new Integer( yVal ));
+ mr.AddElement( new Integer( flag ));
+ if (clipped) {
+ mr.AddElement( new Integer( x1 ));
+ mr.AddElement( new Integer( y1 ));
+ mr.AddElement( new Integer( x2 ));
+ mr.AddElement( new Integer( y2 ));
+ }
records.addElement( mr );
}
break;
@@ -161,15 +136,27 @@
case WMFConstants.META_TEXTOUT:
{
int len = readShort( is );
+ int read = 1; // used to track the actual size really read
byte bstr[] = new byte[ len ];
- //is.read( bstr );
- for ( int i = 0; i < len; i++ )
+ for ( int i = 0; i < len; i++ ) {
bstr[ i ] = is.readByte();
+ }
+ /* must do this because WMF strings always have an even number of bytes, even
+ * if there is an odd number of characters
+ */
+ if (len % 2 != 0) is.readByte();
+ read += (len + 1) / 2;
+
int yVal = readShort( is );
int xVal = readShort( is );
-
- String str = new String( bstr );
- mr = new StringRecord( str );
+ read += 2;
+ // if the record was not completely read, finish reading
+ if (read < recSize) for (int j = read; j < recSize; j++) readShort( is );
+
+ /* get the StringRecord, having decoded the String, using the current
+ * charset (which was givben by the last META_CREATEFONTINDIRECT)
+ */
+ mr = new MetaRecord.ByteRecord(bstr);
mr.numPoints = recSize;
mr.functionId = functionId;
@@ -183,58 +170,110 @@
case WMFConstants.META_CREATEFONTINDIRECT:
{
int lfHeight = readShort( is );
- /* int lfWidth = */ readShort( is );
- /* int lfEscapement = */ readShort( is );
- /* int lfOrientation = */ readShort( is );
+ int lfWidth = readShort( is );
+ int lfEscapement = readShort( is );
+ int lfOrientation = readShort( is );
int lfWeight = readShort( is );
int lfItalic = is.readByte();
- /* int lfUnderline = */ is.readByte();
- /* int lfStrikeOut = */ is.readByte();
- /* int lfCharSet = */ is.readByte();
- /* int lfOutPrecision = */ is.readByte();
- /* int lfClipPrecision = */ is.readByte();
- /* int lfQuality = */ is.readByte();
- /* int lfPitchAndFamily = */ is.readByte();
-
- int len = (2*(recSize-9));//13));
+ int lfUnderline = is.readByte();
+ int lfStrikeOut = is.readByte();
+ int lfCharSet = is.readByte() & 0x00ff;
+ //System.out.println("lfCharSet: "+(lfCharSet & 0x00ff));
+ int lfOutPrecision = is.readByte();
+ int lfClipPrecision = is.readByte();
+ int lfQuality = is.readByte();
+ int lfPitchAndFamily = is.readByte();
+
+ // don't need to read the end of the record,
+ // because it will always be completely used
+ int len = (2*(recSize-9));
byte lfFaceName[] = new byte[ len ];
- for ( int i = 0; i < len; i++ )
- lfFaceName[ i ] = is.readByte();
-
+ byte ch;
+ for ( int i = 0; i < len; i++ ) lfFaceName[ i ] = is.readByte();
String str = new String( lfFaceName );
- mr = new StringRecord( str );
+ mr = new MetaRecord.StringRecord( str );
mr.numPoints = recSize;
mr.functionId = functionId;
mr.AddElement( new Integer( lfHeight ));
mr.AddElement( new Integer( lfItalic ));
mr.AddElement( new Integer( lfWeight ));
+ mr.AddElement( new Integer( lfCharSet));
+ mr.AddElement( new Integer( lfUnderline));
+ mr.AddElement( new Integer( lfStrikeOut));
+ mr.AddElement( new Integer( lfOrientation));
+ // escapement is the orientation of the text in tenth of degrees
+ mr.AddElement( new Integer( lfEscapement));
records.addElement( mr );
}
break;
+
+ case WMFConstants.META_SETMAPMODE: {
+ mr.numPoints = recSize;
+ mr.functionId = functionId;
+ int mode = readShort( is );
+ mr.AddElement( new Integer( mode));
+ records.addElement( mr );
+ }
+ break;
+
+ case WMFConstants.META_SETVIEWPORTORG:
+ case WMFConstants.META_SETVIEWPORTEXT:
case WMFConstants.META_SETWINDOWORG:
- case WMFConstants.META_SETWINDOWEXT:
- {
+ case WMFConstants.META_SETWINDOWEXT: {
mr.numPoints = recSize;
mr.functionId = functionId;
- int i0 = readShort( is );
- int i1 = readShort( is );
- mr.AddElement( new Integer( i1 ));
- mr.AddElement( new Integer( i0 ));
+ int height = readShort( is );
+ int width = readShort( is );
+ mr.AddElement( new Integer( width ));
+ mr.AddElement( new Integer( height ));
records.addElement( mr );
- if ( functionId == WMFConstants.META_SETWINDOWEXT ) {
- vpW = i0;
- vpH = i1;
+ if (_bext && functionId == WMFConstants.META_SETWINDOWEXT) {
+ vpW = width;
+ vpH = height;
+ _bext = false;
}
}
break;
+
+ case WMFConstants.META_OFFSETVIEWPORTORG:
+ case WMFConstants.META_OFFSETWINDOWORG: {
+ mr.numPoints = recSize;
+ mr.functionId = functionId;
+
+ int y = readShort( is );
+ int x = readShort( is );
+ mr.AddElement( new Integer( x ));
+ mr.AddElement( new Integer( y ));
+ records.addElement( mr );
+ }
+ break;
+
+ case WMFConstants.META_SCALEVIEWPORTEXT:
+ case WMFConstants.META_SCALEWINDOWEXT: {
+ mr.numPoints = recSize;
+ mr.functionId = functionId;
+ int ydenom = readShort( is );
+ int ynum = readShort( is );
+ int xdenom= readShort( is );
+ int xnum = readShort( is );
+ mr.AddElement( new Integer( xdenom ));
+ mr.AddElement( new Integer( ydenom ));
+ mr.AddElement( new Integer( xnum ));
+ mr.AddElement( new Integer( ynum ));
+ records.addElement( mr );
+ scaleX = scaleX * (float)xdenom / (float)xnum;
+ scaleY = scaleY * (float)ydenom / (float)ynum;
+ }
+ break;
+
case WMFConstants.META_CREATEBRUSHINDIRECT:
{
mr.numPoints = recSize;
@@ -247,7 +286,7 @@
int red = colorref & 0xff;
int green = ( colorref & 0xff00 ) >> 8;
int blue = ( colorref & 0xff0000 ) >> 16;
- // int flags = ( colorref & 0x3000000 ) >> 24;
+ int flags = ( colorref & 0x3000000 ) >> 24;
mr.AddElement( new Integer( red ));
mr.AddElement( new Integer( green ));
mr.AddElement( new Integer( blue ));
@@ -258,7 +297,7 @@
records.addElement( mr );
}
break;
-
+
case WMFConstants.META_CREATEPENINDIRECT:
{
mr.numPoints = recSize;
@@ -268,14 +307,22 @@
Integer style = new Integer( readShort( is ));
mr.AddElement( style );
- int width = readShort( is );
- int colorref = readInt ( is );
- /* int height = */ readShort( is );
+ int width = readInt( is );
+ int colorref = readInt( is );
+
+ /**
+ * sometimes records generated by PPT have a
+ * recSize of 6 and not 5 => in this case only we have
+ * to read a last short element
+ **/
+ //int height = readShort( is );
+ if (recSize == 6) readShort(is);
- int red = colorref & 0xff;
+ int red = colorref & 0xff;
int green = ( colorref & 0xff00 ) >> 8;
- int blue = ( colorref & 0xff0000 ) >> 16;
- // int flags = ( colorref & 0x3000000 ) >> 24;
+ int blue = ( colorref & 0xff0000 ) >> 16;
+ int flags = ( colorref & 0x3000000 ) >> 24;
+
mr.AddElement( new Integer( red ));
mr.AddElement( new Integer( green ));
mr.AddElement( new Integer( blue ));
@@ -285,8 +332,20 @@
records.addElement( mr );
}
- break;
+ break;
+ case WMFConstants.META_SETTEXTALIGN:
+ {
+ mr.numPoints = recSize;
+ mr.functionId = functionId;
+ int align = readShort( is );
+ // need to do this, because sometimes there is more than one short
+ if (recSize > 1) for (int i = 1; i < recSize; i++) readShort( is );
+ mr.AddElement( new Integer( align ));
+ records.addElement( mr );
+ }
+ break;
+
case WMFConstants.META_SETTEXTCOLOR:
case WMFConstants.META_SETBKCOLOR:
{
@@ -297,7 +356,7 @@
int red = colorref & 0xff;
int green = ( colorref & 0xff00 ) >> 8;
int blue = ( colorref & 0xff0000 ) >> 16;
- // int flags = ( colorref & 0x3000000 ) >> 24;
+ int flags = ( colorref & 0x3000000 ) >> 24;
mr.AddElement( new Integer( red ));
mr.AddElement( new Integer( green ));
mr.AddElement( new Integer( blue ));
@@ -311,24 +370,37 @@
mr.numPoints = recSize;
mr.functionId = functionId;
- int i0 = readShort( is );
- int i1 = readShort( is );
- mr.AddElement( new Integer( i1 ));
- mr.AddElement( new Integer( i0 ));
+ int y = readShort( is );
+ int x = readShort( is );
+ mr.AddElement( new Integer( x ));
+ mr.AddElement( new Integer( y ));
records.addElement( mr );
}
break;
+
+ case WMFConstants.META_SETPOLYFILLMODE :
+ {
+ mr.numPoints = recSize;
+ mr.functionId = functionId;
+ int mode = readShort( is );
+ // need to do this, because sometimes there is more than one short
+ if (recSize > 1) for (int i = 1; i < recSize; i++) readShort( is );
+ mr.AddElement( new Integer( mode ));
+ records.addElement( mr );
+ }
+ break;
+
case WMFConstants.META_POLYPOLYGON:
{
mr.numPoints = recSize;
mr.functionId = functionId;
- int count = readShort( is );
+ int count = readShort( is ); // number of polygons
int pts[] = new int[ count ];
int ptCount = 0;
for ( int i = 0; i < count; i++ ) {
- pts[ i ] = readShort( is );
+ pts[ i ] = readShort( is ); // nomber of points for the polygon
ptCount += pts[ i ];
}
mr.AddElement( new Integer( count ));
@@ -336,16 +408,18 @@
for ( int i = 0; i < count; i++ )
mr.AddElement( new Integer( pts[ i ] ));
+ int offset = count+1;
for ( int i = 0; i < count; i++ ) {
for ( int j = 0; j < pts[ i ]; j++ ) {
- mr.AddElement( new Integer( readShort( is )));
- mr.AddElement( new Integer( readShort( is )));
+ mr.AddElement( new Integer( readShort( is ))); // x position of the polygon
+ mr.AddElement( new Integer( readShort( is ))); // y position of the polygon
}
}
records.addElement( mr );
}
break;
+ case WMFConstants.META_POLYLINE:
case WMFConstants.META_POLYGON:
{
mr.numPoints = recSize;
@@ -360,7 +434,7 @@
records.addElement( mr );
}
break;
-
+
case WMFConstants.META_ELLIPSE:
case WMFConstants.META_INTERSECTCLIPRECT:
case WMFConstants.META_RECTANGLE:
@@ -368,35 +442,49 @@
mr.numPoints = recSize;
mr.functionId = functionId;
- int i0 = readShort( is );
- int i1 = readShort( is );
- int i2 = readShort( is );
- int i3 = readShort( is );
- mr.AddElement( new Integer( i3 ));
- mr.AddElement( new Integer( i2 ));
- mr.AddElement( new Integer( i1 ));
- mr.AddElement( new Integer( i0 ));
+ int bottom = readShort( is );
+ int right = readShort( is );
+ int top = readShort( is );
+ int left = readShort( is );
+ mr.AddElement( new Integer( left ));
+ mr.AddElement( new Integer( top ));
+ mr.AddElement( new Integer( right ));
+ mr.AddElement( new Integer( bottom ));
records.addElement( mr );
}
break;
- case WMFConstants.META_ROUNDRECT:
- {
+ case WMFConstants.META_CREATEREGION: {
+ mr.numPoints = recSize;
+ mr.functionId = functionId;
+ int left = readShort( is );
+ int top = readShort( is );
+ int right = readShort( is );
+ int bottom = readShort( is );
+ mr.AddElement( new Integer( left ));
+ mr.AddElement( new Integer( top ));
+ mr.AddElement( new Integer( right ));
+ mr.AddElement( new Integer( bottom ));
+ records.addElement( mr );
+ }
+ break;
+
+ case WMFConstants.META_ROUNDRECT: {
mr.numPoints = recSize;
mr.functionId = functionId;
- int i0 = readShort( is );
- int i1 = readShort( is );
- int i2 = readShort( is );
- int i3 = readShort( is );
- int i4 = readShort( is );
- int i5 = readShort( is );
- mr.AddElement( new Integer( i5 ));
- mr.AddElement( new Integer( i4 ));
- mr.AddElement( new Integer( i3 ));
- mr.AddElement( new Integer( i2 ));
- mr.AddElement( new Integer( i1 ));
- mr.AddElement( new Integer( i0 ));
+ int el_height = readShort( is );
+ int el_width = readShort( is );
+ int bottom = readShort( is );
+ int right = readShort( is );
+ int top = readShort( is );
+ int left = readShort( is );
+ mr.AddElement( new Integer( left ));
+ mr.AddElement( new Integer( top ));
+ mr.AddElement( new Integer( right ));
+ mr.AddElement( new Integer( bottom ));
+ mr.AddElement( new Integer( el_width ));
+ mr.AddElement( new Integer( el_height ));
records.addElement( mr );
}
break;
@@ -407,26 +495,123 @@
mr.numPoints = recSize;
mr.functionId = functionId;
- int i0 = readShort( is );
- int i1 = readShort( is );
- int i2 = readShort( is );
- int i3 = readShort( is );
- int i4 = readShort( is );
- int i5 = readShort( is );
- int i6 = readShort( is );
- int i7 = readShort( is );
- mr.AddElement( new Integer( i7 ));
- mr.AddElement( new Integer( i6 ));
- mr.AddElement( new Integer( i5 ));
- mr.AddElement( new Integer( i4 ));
- mr.AddElement( new Integer( i3 ));
- mr.AddElement( new Integer( i2 ));
- mr.AddElement( new Integer( i1 ));
- mr.AddElement( new Integer( i0 ));
+ int yend = readShort( is );
+ int xend = readShort( is );
+ int ystart = readShort( is );
+ int xstart = readShort( is );
+ int bottom = readShort( is );
+ int right = readShort( is );
+ int top = readShort( is );
+ int left = readShort( is );
+ mr.AddElement( new Integer( left ));
+ mr.AddElement( new Integer( top ));
+ mr.AddElement( new Integer( right ));
+ mr.AddElement( new Integer( bottom ));
+ mr.AddElement( new Integer( xstart ));
+ mr.AddElement( new Integer( ystart ));
+ mr.AddElement( new Integer( xend ));
+ mr.AddElement( new Integer( yend ));
records.addElement( mr );
}
break;
+ // META_PATBLT added
+ case WMFConstants.META_PATBLT :
+ {
+ mr.numPoints = recSize;
+ mr.functionId = functionId;
+
+ int rop = readInt( is );
+ int height = readShort( is );
+ int width = readShort( is );
+ int left = readShort( is );
+ int top = readShort( is );
+
+ mr.AddElement( new Integer( rop ));
+ mr.AddElement( new Integer( height ));
+ mr.AddElement( new Integer( width ));
+ mr.AddElement( new Integer( top ));
+ mr.AddElement( new Integer( left ));
+
+ records.addElement( mr );
+ }
+ break;
+
+ case WMFConstants.META_SETBKMODE:
+ {
+ mr.numPoints = recSize;
+ mr.functionId = functionId;
+
+ int mode = readShort( is );
+ mr.AddElement( new Integer( mode ));
+ //if (recSize > 1) readShort( is );
+ if (recSize > 1) for (int i = 1; i < recSize; i++) readShort( is );
+ records.addElement( mr );
+ }
+ break;
+
+ // UPDATED : META_SETROP2 added
+ case WMFConstants.META_SETROP2:
+ {
+ mr.numPoints = recSize;
+ mr.functionId = functionId;
+
+ // rop should always be a short, but it is sometimes an int...
+ int rop;
+ if (recSize == 1) rop = readShort( is );
+ else rop = readInt( is );
+
+ mr.AddElement( new Integer( rop ));
+ records.addElement( mr );
+ }
+ break;
+ // UPDATED : META_DIBSTRETCHBLT added
+ case WMFConstants.META_DIBSTRETCHBLT:
+ {
+ int mode = is.readInt() & 0xff;
+ int heightSrc = readShort( is );
+ int widthSrc = readShort( is );
+ int sy = readShort( is );
+ int sx = readShort( is );
+ int heightDst = readShort( is );
+ int widthDst = readShort( is );
+ int dy = readShort( is );
+ int dx = readShort( is );
+
+ int len = 2*recSize - 20;
+ byte bitmap[] = new byte[len];
+ for (int i = 0; i < len; i++) bitmap[i] = is.readByte();
+
+ mr = new MetaRecord.ByteRecord(bitmap);
+ mr.numPoints = recSize;
+ mr.functionId = functionId;
+ mr.AddElement( new Integer( mode ));
+ mr.AddElement( new Integer( heightSrc ));
+ mr.AddElement( new Integer( widthSrc ));
+ mr.AddElement( new Integer( sy ));
+ mr.AddElement( new Integer( sx ));
+ mr.AddElement( new Integer( heightDst ));
+ mr.AddElement( new Integer( widthDst ));
+ mr.AddElement( new Integer( dy ));
+ mr.AddElement( new Integer( dx ));
+ records.addElement( mr );
+ }
+ break;
+ // UPDATED : META_CREATEPATTERNBRUSH added
+ case WMFConstants.META_DIBCREATEPATTERNBRUSH:
+ {
+ int type = is.readInt() & 0xff;
+ int len = 2*recSize - 4;
+ byte bitmap[] = new byte[len];
+ for (int i = 0; i < len; i++) bitmap[i] = is.readByte();
+
+ mr = new MetaRecord.ByteRecord(bitmap);
+ mr.numPoints = recSize;
+ mr.functionId = functionId;
+ mr.AddElement(new Integer( type ));
+ records.addElement( mr );
+ }
+ break;
default:
mr.numPoints = recSize;
mr.functionId = functionId;
@@ -446,51 +631,6 @@
return true;
}
- public void addObject( int type, Object obj ){
- int startIdx = 0;
- // if ( type == Wmf.PEN ) {
- // startIdx = 2;
- // }
- for ( int i = startIdx; i < numObjects; i++ ) {
- GdiObject gdi = (GdiObject)objectVector.elementAt( i );
- if ( gdi.used == false ) {
- gdi.Setup( type, obj );
- lastObjectIdx = i;
- break;
- }
- }
- }
-
- synchronized void setReading( boolean state ){
- bReading = state;
- }
-
- synchronized boolean isReading(){
- return bReading;
- }
-
- /**
- * Adds a GdiObject to the internal handle table.
- * Wmf files specify the index as given in EMF records such as
- * EMRCREATEPENINDIRECT whereas WMF files always use 0.
- *
- * This function should not normally be called by an application.
- */
- public void addObjectAt( int type, Object obj, int idx ) {
- if (( idx == 0 ) || ( idx > numObjects )) {
- addObject( type, obj );
- return;
- }
- lastObjectIdx = idx;
- for ( int i = 0; i < numObjects; i++ ) {
- GdiObject gdi = (GdiObject)objectVector.elementAt( i );
- if ( i == idx ) {
- gdi.Setup( type, obj );
- break;
- }
- }
- }
-
/**
* Returns the current URL
*/
@@ -506,13 +646,6 @@
}
/**
- * Returns a GdiObject from the handle table
- */
- public GdiObject getObject( int idx ) {
- return (GdiObject)objectVector.elementAt( idx );
- }
-
- /**
* Returns a meta record.
*/
public MetaRecord getRecord( int idx ) {
@@ -527,77 +660,39 @@
}
/**
- * Returns the number of GdiObjects in the handle table
- */
- public int getNumObjects() {
- return numObjects;
- }
-
- /**
* Returns the viewport x origin
*/
- public int getVpX() {
+ public float getVpX() {
return vpX;
}
/**
* Returns the viewport y origin
*/
- public int getVpY() {
+ public float getVpY() {
return vpY;
}
/**
- * Returns the viewport width
- */
- public int getVpW() {
- return vpW;
- }
-
- /**
- * Returns the viewport height
- */
- public int getVpH() {
- return vpH;
- }
-
- /**
* Sets the viewport x origin
*/
- public void setVpX( int newValue ) {
+ public void setVpX(float newValue ) {
vpX = newValue;
}
/**
* Sets the viewport y origin
*/
- public void setVpY( int newValue ) {
+ public void setVpY(float newValue ) {
vpY = newValue;
}
- /**
- * Sets the viewport width
- */
- public void setVpW( int newValue ) {
- vpW = newValue;
- }
-
- /**
- * Sets the viewport height
- */
- public void setVpH( int newValue ) {
- vpH = newValue;
- }
-
-
transient private URL url;
transient protected int numRecords;
- transient protected int numObjects;
- transient public int lastObjectIdx;
- transient protected int vpX, vpY, vpW, vpH;
+ transient protected float vpX, vpY;
transient protected Vector records;
- transient protected Vector objectVector;
transient protected boolean bReading = false;
+ transient private boolean _bext = true;
}
Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/transcoder/wmf/tosvg/WMFTranscoder.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/transcoder/wmf/tosvg/WMFTranscoder.java?rev=291468&r1=291467&r2=291468&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/transcoder/wmf/tosvg/WMFTranscoder.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/transcoder/wmf/tosvg/WMFTranscoder.java Sun Sep 25 12:51:54 2005
@@ -15,9 +15,12 @@
limitations under the License.
*/
+
package org.apache.batik.transcoder.wmf.tosvg;
import java.awt.Dimension;
+import java.awt.BasicStroke;
+import java.awt.geom.Rectangle2D;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
@@ -31,8 +34,10 @@
import java.net.URL;
import java.net.URLConnection;
+import org.w3c.dom.svg.SVGDocument;
+import org.apache.batik.transcoder.TranscodingHints;
+import org.apache.batik.transcoder.keys.*;
import org.apache.batik.dom.svg.SVGDOMImplementation;
-import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.transcoder.AbstractTranscoder;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
@@ -42,34 +47,63 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.XMLFilter;
+import org.apache.batik.svggen.SVGGraphics2D;
+import org.apache.batik.util.SVGConstants;
+import org.apache.batik.transcoder.ToSVGAbstractTranscoder;
+import org.w3c.dom.Node;
+import org.w3c.dom.DocumentFragment;
-/**
- * This class implements the <tt>Transcoder</tt> interface and
- * can convert a WMF input document into an SVG document.
+/** This class implements the <tt>Transcoder</tt> interface and
+ * can convert a WMF input document into an SVG document.
+ * <p>This class is copied from
+ * batik org.apache.batik.transcoder.wmf.tosvg.WMFTranscoder class.</p>
+ * <p>It can use <tt>TranscoderInput</tt> that are either a URI
+ * or a <tt>InputStream</tt> or a <tt>Reader</tt>. The
+ * <tt>XMLReader</tt> and <tt>Document</tt> <tt>TranscoderInput</tt>
+ * types are not supported.</p>
*
- * It can use <tt>TranscoderInput</tt> that are either a URI
- * or a <tt>InputStream</tt> or a <tt>Reader</tt>. The
- * <tt>XMLReader</tt> and <tt>Document</tt> <tt>TranscoderInput</tt>
- * types are not supported.
+ * <p>This transcoder can use <tt>TranscoderOutputs</tt> that are
+ * of any type except the <tt>XMLFilter</tt> type.</p>
*
- * This transcoder can use <tt>TranscoderOutputs</tt> that are
- * of any type except the <tt>XMLFilter</tt> type.
+ * <p>Corrected bugs from the original class:</p>
+ * <ul>
+ * <li> Manage images size</li>
+ * </ul>
+ * <p>Exemple of use :</p>
+ * <pre>
+ * WMFTranscoder transcoder = new WMFTranscoder();
+ * try {
+ * TranscoderInput wmf = new TranscoderInput(wmffile.toURL().toString());
+ * TranscoderOutput svg = new TranscoderOutput(new FileOutputStream(svgFile));
+ * transcoder.transcode(wmf, svg);
+ * } catch (MalformedURLException e){
+ * throw new TranscoderException(e);
+ * } catch (IOException e){
+ * throw new TranscoderException(e);
+ * }
+ * </pre>
+ * <p>Several transcoding hints are available for this transcoder :</p>
+ * <ul>
+ * <li>KEY_INPUT_WIDTH, KEY_INPUT_HEIGHT, KEY_XOFFSET, KEY_YOFFSET : this Integer values allows to
+ * set the portion of the image to transcode, defined by the width, height, and offset
+ * of this portion in Metafile units.
+ * </ul>
+ * <pre>
+ * transcoder.addTranscodingHint(FromWMFTranscoder.KEY_INPUT_WIDTH, new Integer(input_width));
+ * </pre>
+ * </li>
+ * <li>KEY_WIDTH, KEY_HEIGHT : this Float values allows to force the width and height of the output:
+ * </ul>
+ * <pre>
+ * transcoder.addTranscodingHint(FromWMFTranscoder.KEY_WIDTH, new Float(width));
+ * </pre>
+ * </li>
+ * </ul>
*
- * @version $Id$
- * @author <a href="mailto:luano@asd.ie">Luan O'Carroll</a>
*/
-public class WMFTranscoder extends AbstractTranscoder
- implements SVGConstants{
-
- /**
- * Error codes for the WMFTranscoder
- */
- public static final int WMF_TRANSCODER_ERROR_BASE = 0xff00;
- public static final int ERROR_NULL_INPUT = WMF_TRANSCODER_ERROR_BASE + 0;
- public static final int ERROR_INCOMPATIBLE_INPUT_TYPE = WMF_TRANSCODER_ERROR_BASE + 1;
- public static final int ERROR_INCOMPATIBLE_OUTPUT_TYPE = WMF_TRANSCODER_ERROR_BASE + 2;
-
+public class WMFTranscoder extends ToSVGAbstractTranscoder {
+
/**
* Default constructor
*/
@@ -93,136 +127,117 @@
// Build a RecordStore from the input
//
WMFRecordStore currentStore = new WMFRecordStore();
- try{
+ try {
currentStore.read(is);
- }catch(IOException e){
+ } catch (IOException e){
handler.fatalError(new TranscoderException(e));
return;
}
- //
+ // determines the width and height of output image
+ float wmfwidth; // width in pixels
+ float wmfheight; // height in pixels
+ float conv = 1f; // conversion factor
+
+ if (hints.containsKey(KEY_INPUT_WIDTH)) {
+ wmfwidth = ((Integer)hints.get(KEY_INPUT_WIDTH)).intValue();
+ wmfheight = ((Integer)hints.get(KEY_INPUT_HEIGHT)).intValue();
+ } else {
+ wmfwidth = currentStore.getWidthPixels();
+ wmfheight = currentStore.getHeightPixels();
+ }
+ float width = wmfwidth;
+ float height = wmfheight;
+
+ // change the output width and height if required
+ if (hints.containsKey(KEY_WIDTH)) {
+ width = ((Float)hints.get(KEY_WIDTH)).floatValue();
+ conv = width / wmfwidth;
+ height = height * width / wmfwidth;
+ }
+
+ // determine the offset values
+ int xOffset = 0;
+ int yOffset = 0;
+ if (hints.containsKey(KEY_XOFFSET)) {
+ xOffset = ((Integer)hints.get(KEY_XOFFSET)).intValue();
+ }
+ if (hints.containsKey(KEY_YOFFSET)) {
+ yOffset = ((Integer)hints.get(KEY_YOFFSET)).intValue();
+ }
+
+ // Set the size and viewBox on the output document
+ float sizeFactor = currentStore.getUnitsToPixels() * conv;
+
+ int vpX = (int)(currentStore.getVpX() * sizeFactor);
+ int vpY = (int)(currentStore.getVpY() * sizeFactor);
+
+ int vpW;
+ int vpH;
+ // if we took only a part of the image, we use its dimension for computing
+ if (hints.containsKey(KEY_INPUT_WIDTH)) {
+ vpW = (int)(((Integer)hints.get(KEY_INPUT_WIDTH)).intValue() * conv);
+ vpH = (int)(((Integer)hints.get(KEY_INPUT_HEIGHT)).intValue() * conv);
+ // else we took the whole image dimension
+ } else {
+ vpW = (int)(currentStore.getWidthUnits() * sizeFactor);
+ vpH = (int)(currentStore.getHeightUnits() * sizeFactor);
+ }
+
// Build a painter for the RecordStore
- //
- WMFPainter painter = new WMFPainter(currentStore);
+ WMFPainter painter = new WMFPainter(currentStore, xOffset, yOffset, conv);
- //
// Use SVGGraphics2D to generate SVG content
- //
- DOMImplementation domImpl
- = SVGDOMImplementation.getDOMImplementation();
-
- Document doc = domImpl.createDocument(SVG_NAMESPACE_URI,
- SVG_SVG_TAG, null);
-
- SVGGraphics2D svgGenerator = new SVGGraphics2D(doc);
+ Document doc = this.createDocument(output);
+ svgGenerator = new SVGGraphics2D(doc);
+
+ /** set precision
+ ** otherwise Ellipses aren't working (for example) (because of Decimal format
+ * modifications ins SVGGenerator Context
+ */
+ svgGenerator.getGeneratorContext().setPrecision(4);
painter.paint(svgGenerator);
-
- //
- // Set the size and viewBox on the output document
- //
- int vpX = currentStore.getVpX();
- int vpY = currentStore.getVpY();
- int vpW = currentStore.getVpW();
- int vpH = currentStore.getVpH();
+
svgGenerator.setSVGCanvasSize(new Dimension(vpW, vpH));
Element svgRoot = svgGenerator.getRoot();
+
svgRoot.setAttributeNS(null, SVG_VIEW_BOX_ATTRIBUTE,
"" + vpX + " " + vpY + " " +
vpW + " " + vpH );
-
- //
+
// Now, write the SVG content to the output
- //
writeSVGToOutput(svgGenerator, svgRoot, output);
}
/**
- * Writes the SVG content held by the svgGenerator to the
- * <tt>TranscoderOutput</tt>.
- */
- private void writeSVGToOutput(SVGGraphics2D svgGenerator,
- Element svgRoot,
- TranscoderOutput output)
- throws TranscoderException {
- // XMLFilter
- XMLFilter xmlFilter = output.getXMLFilter();
- if(xmlFilter != null){
- handler.fatalError(new TranscoderException("" + ERROR_INCOMPATIBLE_OUTPUT_TYPE));
- }
-
- // <!> FIX ME: SHOULD HANDLE DOCUMENT INPUT
- Document doc = output.getDocument();
- if(doc != null){
- handler.fatalError(new TranscoderException("" + ERROR_INCOMPATIBLE_OUTPUT_TYPE));
- }
-
- try{
- // Output stream
- OutputStream os = output.getOutputStream();
- if( os != null ){
- svgGenerator.stream(svgRoot, new OutputStreamWriter(os));
- return;
- }
-
- // Writer
- Writer wr = output.getWriter();
- if( wr != null ){
- svgGenerator.stream(svgRoot, wr);
- return;
- }
-
- // URI
- String uri = output.getURI();
- if( uri != null ){
- try{
- URL url = new URL(uri);
- URLConnection urlCnx = url.openConnection();
- os = urlCnx.getOutputStream();
- svgGenerator.stream(svgRoot, new OutputStreamWriter(os));
- return;
- }catch(MalformedURLException e){
- handler.fatalError(new TranscoderException(e));
- }catch(IOException e){
- handler.fatalError(new TranscoderException(e));
- }
- }
- }catch(IOException e){
- throw new TranscoderException(e);
- }
-
- throw new TranscoderException("" + ERROR_INCOMPATIBLE_OUTPUT_TYPE);
-
- }
-
- /**
* Checks that the input is one of URI or an <tt>InputStream</tt>
* returns it as a DataInputStream
*/
private DataInputStream getCompatibleInput(TranscoderInput input)
throws TranscoderException {
// Cannot deal with null input
- if(input == null){
+ if (input == null){
handler.fatalError(new TranscoderException("" + ERROR_NULL_INPUT));
}
// Can deal with InputStream
InputStream in = input.getInputStream();
- if(in != null){
+ if (in != null){
return new DataInputStream(new BufferedInputStream(in));
}
// Can deal with URI
String uri = input.getURI();
- if(uri != null){
+ if (uri != null){
try{
URL url = new URL(uri);
in = url.openStream();
return new DataInputStream(new BufferedInputStream(in));
- }catch(MalformedURLException e){
+ } catch (MalformedURLException e){
handler.fatalError(new TranscoderException(e));
- }catch(IOException e){
+ } catch (IOException e){
handler.fatalError(new TranscoderException(e));
}
}
@@ -231,11 +246,6 @@
return null;
}
- public static final String USAGE = "The WMFTranscoder converts a WMF document into an SVG document. \n" +
- "This simple application generates SVG documents that have the same name, but a where the .wmf extension \n" +
- "is replaced with .svg. To run the application, type the following at the command line: \n" +
- "java org.apache.batik.transcoder.wmf.tosvg.WMFTranscoder fileName [fileName]+";
-
public static final String WMF_EXTENSION = ".wmf";
public static final String SVG_EXTENSION = ".svg";
@@ -244,7 +254,7 @@
*/
public static void main(String args[]) throws TranscoderException {
if(args.length < 1){
- System.err.println(USAGE);
+ System.out.println("Usage : WMFTranscoder.main <file 1> ... <file n>");
System.exit(1);
}
@@ -261,7 +271,7 @@
String outputFileName = fileName.substring(0, fileName.toLowerCase().indexOf(WMF_EXTENSION)) + SVG_EXTENSION;
File inputFile = new File(fileName);
File outputFile = new File(outputFileName);
- try{
+ try {
TranscoderInput input = new TranscoderInput(inputFile.toURL().toString());
TranscoderOutput output = new TranscoderOutput(new FileOutputStream(outputFile));
transcoder.transcode(input, output);
Modified: xmlgraphics/batik/trunk/test-references/org/apache/batik/svggen/ATransform.svg
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/test-references/org/apache/batik/svggen/ATransform.svg?rev=291468&r1=291467&r2=291468&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/test-references/org/apache/batik/svggen/ATransform.svg (original)
+++ xmlgraphics/batik/trunk/test-references/org/apache/batik/svggen/ATransform.svg Sun Sep 25 12:51:54 2005
@@ -1,28 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>
-<svg fill-opacity="1" xmlns:xlink="http://www.w3.org/1999/xlink" color-interpolation="auto" color-rendering="auto" text-rendering="auto" stroke="black" stroke-linecap="square" width="300" stroke-miterlimit="10" stroke-opacity="1" shape-rendering="auto" fill="black" stroke-dasharray="none" font-weight="normal" stroke-width="1" height="400" xmlns="http://www.w3.org/2000/svg" font-family="'Arial'" font-style="normal" stroke-linejoin="miter" font-size="12" image-rendering="auto" stroke-dashoffset="0">
- <!--Generated by the Batik Graphics2D SVG Generator-->
- <defs id="genericDefs" />
- <g>
- <g text-rendering="optimizeLegibility" transform="translate(0,30)">
- <text xml:space="preserve" x="10" y="12" stroke="none">Default transform</text>
- <rect width="50" x="10" height="30" y="20" stroke="none" />
- <text xml:space="preserve" x="10" y="12" transform="translate(0,90)" stroke="none">Translate applied</text>
- <rect x="10" y="20" transform="translate(0,90)" width="50" height="30" stroke="none" />
- <text xml:space="preserve" x="10" y="12" transform="translate(35,215) rotate(90) translate(-35,-35)" stroke="none">Rotate about center</text>
- <rect x="10" y="20" transform="translate(35,215) rotate(90) translate(-35,-35)" width="50" height="30" stroke="none" />
- </g>
- <g text-rendering="optimizeLegibility" transform="matrix(1,0,0,1,0,30) translate(150,0)">
- <text xml:space="preserve" x="10" y="12" stroke="none">Scale (sx=2, sy=1)</text>
- <rect x="10" y="20" transform="scale(2,1)" width="50" height="30" stroke="none" />
- </g>
- <g text-rendering="optimizeLegibility" transform="matrix(1,0,0,1,0,30) translate(150,90)">
- <text xml:space="preserve" x="10" y="12" stroke="none">Shear</text>
- <rect x="10" y="20" transform="matrix(1,1,0.2,1,0,0)" width="50" height="30" stroke="none" />
- </g>
- <g fill="rgb(0,0,0)" text-rendering="optimizeLegibility" fill-opacity="0.501960813999" stroke-opacity="0.501960813999" stroke="rgb(0,0,0)">
- <rect width="56" x="164" height="80" y="150" stroke="none" />
- </g>
- </g>
-</svg>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN'
+ 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>
+<svg fill-opacity="1" xmlns:xlink="http://www.w3.org/1999/xlink" color-interpolation="auto" color-rendering="auto" text-rendering="auto" stroke="black" stroke-linecap="square" width="300" stroke-miterlimit="10" stroke-opacity="1" shape-rendering="auto" fill="black" stroke-dasharray="none" font-weight="normal" stroke-width="1" height="400" xmlns="http://www.w3.org/2000/svg" font-family="'Arial'" font-style="normal" stroke-linejoin="miter" font-size="12" image-rendering="auto" stroke-dashoffset="0"
+><!--Generated by the Batik Graphics2D SVG Generator--><defs id="genericDefs"
+ /><g
+ ><g text-rendering="optimizeLegibility" transform="translate(0,30)"
+ ><text xml:space="preserve" x="10" y="12" stroke="none"
+ >Default transform</text
+ ><rect width="50" x="10" height="30" y="20" stroke="none"
+ /><text xml:space="preserve" x="10" y="12" transform="translate(0,90)" stroke="none"
+ >Translate applied</text
+ ><rect x="10" y="20" transform="translate(0,90)" width="50" height="30" stroke="none"
+ /><text xml:space="preserve" x="10" y="12" transform="translate(35,215) rotate(90) translate(-35,-35)" stroke="none"
+ >Rotate about center</text
+ ><rect x="10" y="20" transform="translate(35,215) rotate(90) translate(-35,-35)" width="50" height="30" stroke="none"
+ /></g
+ ><g text-rendering="optimizeLegibility" transform="matrix(1,0,0,1,0,30) translate(150,0)"
+ ><text xml:space="preserve" x="10" y="12" stroke="none"
+ >Scale (sx=2, sy=1)</text
+ ><rect x="10" y="20" transform="scale(2,1)" width="50" height="30" stroke="none"
+ /></g
+ ><g text-rendering="optimizeLegibility" transform="matrix(1,0,0,1,0,30) translate(150,90)"
+ ><text xml:space="preserve" x="10" y="12" stroke="none"
+ >Shear</text
+ ><rect x="10" y="20" transform="matrix(1,1,0.2,1,0,0)" width="50" height="30" stroke="none"
+ /></g
+ ><g fill="rgb(0,0,0)" text-rendering="optimizeLegibility" fill-opacity="0.501960813999" stroke-opacity="0.501960813999" stroke="rgb(0,0,0)"
+ ><rect width="56" x="164" height="80" y="150" stroke="none"
+ /></g
+ ></g
+></svg
+>