protected boolean readRecords()

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;
    }