Subversion Repositories display

Rev

Rev 283 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (C) 2007 Steve Ratcliffe
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *
 * Author: Steve Ratcliffe
 * Create date: Dec 16, 2007
 */

package test.display;

import uk.me.parabola.imgfmt.app.ImgFileReader;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Print out the line sections.
 *
 * @author Steve Ratcliffe
 */

public class LineSectDisplayer extends TypSectionDisplayer {
        private final ImgFileReader reader;
        private final PrintStream outStream;

        private final List<Integer> offsets = new ArrayList<Integer>();

        public LineSectDisplayer(ImgFileReader reader, PrintStream outStream) {
                this.reader = reader;
                this.outStream = outStream;
        }

        public void print() {
                Displayer d = new Displayer(reader);
                d.setTitle("Line type styles");

                DisplayItem item = d.item();
                item.addText("A list of line types, and pointers to their styles");

                // Get the types first as they have the offsets into the styles
                // section that we will need later.
                reader.position(0x3d);
                long typestart = reader.getInt();
                int itemsize = reader.getChar();
                int size = reader.getInt();

                // Now get the styles start, as needed
                reader.position(0x1f);
                int stylestart = reader.getInt();

                d = printTypes(typestart, itemsize, size);
                d.print(outStream);

                reader.position(0x1f);
                stylestart = reader.getInt();

                size = reader.getInt();
                d = printStyles(stylestart, size);
                d.print(outStream);
        }

        /**
         * Some details obtained from the referenced document.
         *
         * @see <a href="http://pinns.co.uk/osm/typformat.html">TYP format, N Willink</a>
         */

        private Displayer printStyles(int start, int size) {
                Displayer d = new Displayer(reader);
                d.setTitle("Line styles");
                d.setSectStart(start);

                reader.position(start);

                // Actually print out the styles the best we can
                for (int i = 0; i < offsets.size(); i++) {
                        int off = start + offsets.get(i);
                        int end = start + ((i < offsets.size() - 1) ? offsets.get(i + 1) : size);
                        reader.position(off);

                        // The first two bytes appear to determine what comes next
                        //int flags = d.charValue("Flags %04x");
                        DisplayItem item = d.byteItem();
                        int val = item.getValue();
                        int type = val & 0x7;
                        int width = (val >> 3) & 0x1f;
                        item.addText("Type %x, width %d", type, width);

                        int flags = d.byteValue("Flags 0x%x");

                        boolean hasNight = (type & 1) != 0;

                        switch (type & ~1) {
                        case 0:
                                d.int3Value("Day #%06x");
                                d.int3Value("Day #%06x");
                                if (hasNight) {
                                        d.int3Value("Night #%06x");
                                        d.int3Value("Night #%06x");
                                }
                                break;
                        case 2:
                                d.int3Value("Day #%06x");
                                if (hasNight) {
                                        d.int3Value("Night #%06x");
                                        d.int3Value("Night #%06x");
                                }
                                break;
                        case 4:
                                d.int3Value("Day #%06x");
                                d.int3Value("Day #%06x");
                                if (hasNight) {
                                        d.int3Value("Night #%06x");
                                }
                                break;
                        case 6:
                                d.int3Value("Day #%06x");
                                if (hasNight) {
                                        d.int3Value("Night #%06x");
                                }
                                break;
                        }

                        d.rawValue(width * 4, "Pixmap data");
                       
                        if (width == 0) {
                                d.byteValue("Line width %d");
                                if ((type & ~1) != 6)
                                        d.byteValue("Border width %d");
                        }

                        if ((flags & 0x1) != 0)  // Has text
                printLabels(d);

                        if ((flags & 0x4) != 0)  // Font info
                printFontInfo(d);

                        // Now display everything that is left
                        d.rawValue((int) (end - reader.position()));
                        d.gap();
                }
                return d;
        }

    private Displayer printTypes(long typestart, int itemsize, int size) {
                Displayer d = new Displayer(reader);
                d.setTitle("Line types");

                reader.position(typestart);

                // These things really can and are different sizes.
                long end = typestart + size;
                for (long pos = typestart; pos < end; pos += itemsize) {
                        DisplayItem item = d.item();

                        int typ_id = reader.getChar();
                        item.setBytes((char) typ_id);
                        item.addText("type %x", (typ_id >> 5));

                        // Get the offset into the shape style section.
                        item = d.intItem(itemsize - 2);
                        int off = item.getValue();

                        item.addText("Style at offset %04x", off);
                        offsets.add(off);
                }

                return d;
        }
}