in batik-transcoder/src/main/java/org/apache/batik/transcoder/wmf/tosvg/WMFHeaderProperties.java [138:600]
protected boolean readRecords(DataInputStream is) throws IOException {
// effective reading of the rest of the file
short functionId = 1;
int recSize = 0;
int gdiIndex; // the last Object index
int brushObject = -1; // the last brush
int penObject = -1; // the last pen
int fontObject = -1; // the last font
GdiObject gdiObj;
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;
switch ( functionId ) {
case WMFConstants.META_SETMAPMODE: {
int mapmode = readShort( is );
// change isotropic if mode is anisotropic
if (mapmode == WMFConstants.MM_ANISOTROPIC) isotropic = false;
}
break;
case WMFConstants.META_SETWINDOWORG: {
vpY = readShort( is );
vpX = readShort( is );
}
break;
case WMFConstants.META_SETWINDOWEXT: {
vpH = readShort( is );
vpW = readShort( is );
if (! isotropic) scaleXY = (float)vpW / vpH;
vpW = (int)(vpW * scaleXY);
}
break;
case WMFConstants.META_CREATEPENINDIRECT:
{
int objIndex = 0;
int penStyle = readShort( is );
readInt( is ); // width
// color definition
int colorref = readInt( is );
int red = colorref & 0xff;
int green = ( colorref & 0xff00 ) >> 8;
int blue = ( colorref & 0xff0000 ) >> 16;
Color color = new Color( red, green, blue);
if (recSize == 6) readShort(is); // if size greater than 5
if ( penStyle == WMFConstants.META_PS_NULL ) {
objIndex = addObjectAt( NULL_PEN, color, objIndex );
} else {
objIndex = addObjectAt( PEN, color, objIndex );
}
}
break;
case WMFConstants.META_CREATEBRUSHINDIRECT:
{
int objIndex = 0;
int brushStyle = readShort( is );
// color definition
int colorref = readInt( is );
int red = colorref & 0xff;
int green = ( colorref & 0xff00 ) >> 8;
int blue = ( colorref & 0xff0000 ) >> 16;
Color color = new Color( red, green, blue);
readShort( is ); // hatch
if ( brushStyle == WMFConstants.META_PS_NULL ) {
objIndex = addObjectAt( NULL_BRUSH, color, objIndex);
} else
objIndex = addObjectAt(BRUSH, color, objIndex );
}
break;
case WMFConstants.META_SETTEXTALIGN:
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 );
currentHorizAlign = WMFUtilities.getHorizontalAlignment(align);
currentVertAlign = WMFUtilities.getVerticalAlignment(align);
break;
case WMFConstants.META_EXTTEXTOUT: {
int y = readShort( is );
int x = (int)(readShort( is ) * scaleXY);
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 = (int)(readShort( is ) * scaleXY);
y1 = readShort( is );
x2 = (int)(readShort( is ) * scaleXY);
y2 = readShort( is );
read += 4;
clipped = true;
}
byte[] bstr = new byte[ lenText ];
int i = 0;
for ( ; i < lenText; i++ ) {
bstr[ i ] = is.readByte();
}
String sr = WMFUtilities.decodeString(wf, bstr);
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 );
TextLayout layout = new TextLayout( sr, wf.font, fontCtx );
int lfWidth = (int)layout.getBounds().getWidth();
x = (int)layout.getBounds().getX();
int lfHeight =
(int)getVerticalAlignmentValue(layout, currentVertAlign);
resizeBounds(x, y);
resizeBounds(x+lfWidth, y+lfHeight);
firstEffectivePaint = false;
}
break;
case WMFConstants.META_DRAWTEXT:
case WMFConstants.META_TEXTOUT: {
int len = readShort( is );
int read = 1; // used to track the actual size really read
byte[] bstr = new byte[ len ];
for ( int i = 0; i < len; i++ ) {
bstr[ i ] = is.readByte();
}
String sr = WMFUtilities.decodeString(wf, bstr);
/* 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 y = readShort( is );
int x = (int)(readShort( is ) * scaleXY);
read += 2;
// if the record was not completely read, finish reading
if (read < recSize) for (int j = read; j < recSize; j++) readShort( is );
TextLayout layout = new TextLayout( sr, wf.font, fontCtx );
int lfWidth = (int)layout.getBounds().getWidth();
x = (int)layout.getBounds().getX();
int lfHeight =
(int)getVerticalAlignmentValue(layout, currentVertAlign);
resizeBounds(x, y);
resizeBounds(x+lfWidth, y+lfHeight);
}
break;
case WMFConstants.META_CREATEFONTINDIRECT: {
int lfHeight = readShort( is );
float size = (int)(scaleY * lfHeight);
int lfWidth = readShort( is );
int escape = readShort( is );
int orient = readShort( is );
int weight = readShort( is );
int italic = is.readByte();
int underline = is.readByte();
int strikeOut = is.readByte();
int charset = is.readByte() & 0x00ff;
int lfOutPrecision = is.readByte();
int lfClipPrecision = is.readByte();
int lfQuality = is.readByte();
int lfPitchAndFamily = is.readByte();
int style = italic > 0 ? Font.ITALIC : Font.PLAIN;
style |= (weight > 400) ? Font.BOLD : Font.PLAIN;
// 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 ];
byte ch;
for ( int i = 0; i < len; i++ ) lfFaceName[ i ] = is.readByte();
String face = new String( lfFaceName );
// FIXED : management of font names
int d = 0;
while ((d < face.length()) &&
((Character.isLetterOrDigit(face.charAt(d))) ||
(Character.isWhitespace(face.charAt(d))))) d++;
if (d > 0) face = face.substring(0,d);
else face = "System";
if ( size < 0 ) size = -size /* * -1.3 */;
int objIndex = 0;
Font f = new Font(face, style, (int)size);
f = f.deriveFont(size);
WMFFont wf = new WMFFont(f, charset, underline,
strikeOut, italic, weight, orient, escape);
objIndex = addObjectAt( FONT, wf , objIndex );
}
break;
case WMFConstants.META_CREATEREGION: {
int objIndex = 0;
for ( int j = 0; j < recSize; j++ ) readShort(is); // read all fields
objIndex = addObjectAt( PALETTE, INTEGER_0, 0 );
}
break;
case WMFConstants.META_CREATEPALETTE: {
int objIndex = 0;
for ( int j = 0; j < recSize; j++ ) readShort(is); // read all fields
objIndex = addObjectAt( OBJ_REGION, INTEGER_0, 0 );
}
break;
case WMFConstants.META_SELECTOBJECT:
gdiIndex = readShort(is);
if (( gdiIndex & 0x80000000 ) != 0 ) // Stock Object
break;
gdiObj = getObject( gdiIndex );
if ( !gdiObj.used )
break;
switch( gdiObj.type ) {
case PEN:
penObject = gdiIndex;
break;
case BRUSH:
brushObject = gdiIndex;
break;
case FONT: {
this.wf = ((WMFFont)gdiObj.obj);
fontObject = gdiIndex;
}
break;
case NULL_PEN:
penObject = -1;
break;
case NULL_BRUSH:
brushObject = -1;
break;
}
break;
case WMFConstants.META_DELETEOBJECT:
gdiIndex = readShort(is);
gdiObj = getObject( gdiIndex );
if ( gdiIndex == brushObject ) brushObject = -1;
else if ( gdiIndex == penObject ) penObject = -1;
else if ( gdiIndex == fontObject ) fontObject = -1;
gdiObj.clear();
break;
case WMFConstants.META_LINETO: {
int y = readShort( is );
int x = (int)(readShort( is ) * scaleXY);
if (penObject >= 0) {
resizeBounds(startX, startY);
resizeBounds(x, y);
firstEffectivePaint = false;
}
startX = x;
startY = y;
}
break;
case WMFConstants.META_MOVETO: {
startY = readShort( is );
startX = (int)(readShort( is ) * scaleXY);
}
break;
case WMFConstants.META_POLYPOLYGON: {
int count = readShort( is );
int[] pts = new int[ count ];
int ptCount = 0;
for ( int i = 0; i < count; i++ ) {
pts[ i ] = readShort( is );
ptCount += pts[ i ];
}
int offset = count+1;
for ( int i = 0; i < count; i++ ) {
for ( int j = 0; j < pts[ i ]; j++ ) {
// FIXED 115 : correction preliminary images dimensions
int x = (int)(readShort( is ) * scaleXY);
int y = readShort( is );
if ((brushObject >= 0) || (penObject >= 0)) resizeBounds(x, y);
}
}
firstEffectivePaint = false;
}
break;
case WMFConstants.META_POLYGON: {
int count = readShort( is );
float[] _xpts = new float[ count+1 ];
float[] _ypts = new float[ count+1 ];
for ( int i = 0; i < count; i++ ) {
_xpts[i] = readShort( is ) * scaleXY;
_ypts[i] = readShort( is );
}
_xpts[count] = _xpts[0];
_ypts[count] = _ypts[0];
Polygon2D pol = new Polygon2D(_xpts, _ypts, count);
paint(brushObject, penObject, pol);
}
break;
case WMFConstants.META_POLYLINE:
{
int count = readShort( is );
float[] _xpts = new float[ count ];
float[] _ypts = new float[ count ];
for ( int i = 0; i < count; i++ ) {
_xpts[i] = readShort( is ) * scaleXY;
_ypts[i] = readShort( is );
}
Polyline2D pol = new Polyline2D(_xpts, _ypts, count);
paintWithPen(penObject, pol);
}
break;
case WMFConstants.META_ELLIPSE:
case WMFConstants.META_INTERSECTCLIPRECT:
case WMFConstants.META_RECTANGLE: {
int bot = readShort( is );
int right = (int)(readShort( is ) * scaleXY);
int top = readShort( is );
int left = (int)(readShort( is ) * scaleXY);
Rectangle2D.Float rec = new Rectangle2D.Float(left, top, right-left, bot-top);
paint(brushObject, penObject, rec);
}
break;
case WMFConstants.META_ROUNDRECT: {
readShort( is );
readShort( is );
int bot = readShort( is );
int right = (int)(readShort( is ) * scaleXY);
int top = readShort( is );
int left = (int)(readShort( is ) * scaleXY);
Rectangle2D.Float rec = new Rectangle2D.Float(left, top, right-left, bot-top);
paint(brushObject, penObject, rec);
}
break;
case WMFConstants.META_ARC:
case WMFConstants.META_CHORD:
case WMFConstants.META_PIE: {
readShort( is );
readShort( is );
readShort( is );
readShort( is );
int bot = readShort( is );
int right = (int)(readShort( is ) * scaleXY);
int top = readShort( is );
int left = (int)(readShort( is ) * scaleXY);
Rectangle2D.Float rec = new Rectangle2D.Float(left, top, right-left, bot-top);
paint(brushObject, penObject, rec);
}
break;
case WMFConstants.META_PATBLT : {
readInt( is ); // rop
int height = readShort( is );
int width = (int)(readShort( is ) * scaleXY);
int left = (int)(readShort( is ) * scaleXY);
int top = readShort( is );
if (penObject >= 0) resizeBounds(left, top);
if (penObject >= 0) resizeBounds(left+width, top+height);
}
break;
// UPDATED : META_DIBSTRETCHBLT added
case WMFConstants.META_DIBSTRETCHBLT:
{
is.readInt(); // mode
readShort( is ); // heightSrc
readShort( is ); // widthSrc
readShort( is ); // sy
readShort( is ); // sx
float heightDst = readShort( is );
float widthDst = readShort( is ) * scaleXY;
float dy = readShort( is ) * getVpWFactor() * inch / PIXEL_PER_INCH;
float dx = readShort( is ) * getVpWFactor() * inch / PIXEL_PER_INCH * scaleXY;
widthDst = widthDst * getVpWFactor() * inch / PIXEL_PER_INCH;
heightDst = heightDst * getVpHFactor() * inch / PIXEL_PER_INCH;
resizeImageBounds((int)dx, (int)dy);
resizeImageBounds((int)(dx + widthDst), (int)(dy + heightDst));
int len = 2*recSize - 20;
for (int i = 0; i < len; i++) is.readByte();
}
break;
case WMFConstants.META_STRETCHDIB: {
is.readInt(); // mode
readShort( is ); // usage
readShort( is ); // heightSrc
readShort( is ); // widthSrc
readShort( is ); // sy
readShort( is ); // sx
float heightDst = readShort( is );
float widthDst = readShort( is ) * scaleXY;
float dy = readShort( is ) * getVpHFactor() * inch / PIXEL_PER_INCH;
float dx = readShort( is ) * getVpHFactor() * inch / PIXEL_PER_INCH * scaleXY;
widthDst = widthDst * getVpWFactor() * inch / PIXEL_PER_INCH;
heightDst = heightDst * getVpHFactor() * inch / PIXEL_PER_INCH;
resizeImageBounds((int)dx, (int)dy);
resizeImageBounds((int)(dx + widthDst), (int)(dy + heightDst));
int len = 2*recSize - 22;
byte[] bitmap = new byte[len];
for (int i = 0; i < len; i++) bitmap[i] = is.readByte();
}
break;
case WMFConstants.META_DIBBITBLT: {
is.readInt(); // mode
readShort( is ); //sy
readShort( is ); //sx
readShort( is ); // hdc
float height = readShort( is )
* (float)inch / PIXEL_PER_INCH * getVpHFactor();
float width = readShort( is )
* (float)inch / PIXEL_PER_INCH * getVpWFactor() * scaleXY;
float dy =
inch / PIXEL_PER_INCH * getVpHFactor() * readShort( is );
float dx =
inch / PIXEL_PER_INCH * getVpWFactor() * readShort( is ) * scaleXY;
resizeImageBounds((int)dx, (int)dy);
resizeImageBounds((int)(dx + width), (int)(dy + height));
}
break;
default:
for ( int j = 0; j < recSize; j++ )
readShort(is);
break;
}
}
// sets the width, height, etc of the image if the file does not have an APM (in this case it is retrieved
// from the viewport)
if (! isAldus) {
width = vpW;
height = vpH;
right = vpX;
left = vpX + vpW;
top = vpY;
bottom = vpY + vpH;
}
resetBounds();
return true;
}