[comp.windows.interviews] Using graphics...

linton@marktwain.rad.sgi.com (Mark Linton) (06/28/91)

In article <26613@beta.gov>, larson@beta.lanl.gov (Theodore W. Larson) writes:
|> 
|>        
|>        Is there a problem with the graphics libraries,
|>        or am I doing something wrong?  I get include file
|>        errors to the effect of:
|> 
|> "/interviews/include/InterViews/2.6/InterViews/Graphic/base.h", line 150: error: two initializers for Graphic::transform() argument ?
|> "/interviews/include/InterViews/2.6/InterViews/Graphic/base.h", line 235: error:  Graphic::transform() cannot be redeclared in class declaration

The libgraphic include files are not set up to work with 3.0.  We can fix this, but ...

|>     when I compile the following code.  All I am trying to do is
|>     read a raster image from a file and display it to a window.
|>     If you know a better way to do this, please let me know.
|>     Also, has anyone had any success in getting a viewer to work
|>     with IV-3.0??
|>     If so, please mail me some sample source. It would be much
|>     appreciated. 

you should use the Image glyph class for rasters.  Below is a sample program
that puts an (SGI-format) image up in a window.  It also defines a ScaleToFit
class that scales its child by the ratio of its allocation to the child's desired allocation.

#include <InterViews/background.h>
#include <InterViews/image.h>
#include <InterViews/monoglyph.h>
#include <InterViews/raster.h>
#include <InterViews/transformer.h>
#include <InterViews/window.h>
#include <InterViews/world.h>
#include <stdio.h>
#include <stdlib.h>

#define iopen bad_iopen
#include <gl/image.h>
#undef iopen
extern "C" {

IMAGE* iopen(const char*, const char*, int, int, int, int, int);
void iclose(IMAGE*);
void getrow(IMAGE*, short*, unsigned int, unsigned int);

};

class ScaleToFit : public MonoGlyph {
public:
    ScaleToFit(Glyph*);

    virtual void request(Requisition&) const;
    virtual void allocate(Canvas*, const Allocation&, Extension&);
    virtual void draw(Canvas*, const Allocation&) const;
private:
    Allocation allocation_;
    Transformer matrix_;
};

ScaleToFit::ScaleToFit(Glyph* g) : MonoGlyph(g) { }

/*
 * Generate an allocation that matches the requistion natural size precisely.
 */

void ScaleToFit::request(Requisition& r) const {
    MonoGlyph::request(r);
    Requirement& rx = r.requirement(Dimension_X);
    Coord xsize = rx.natural();
    float xalign = rx.alignment();
    Allotment ax(xalign * xsize, xsize, xalign);
    allocation_.allot(Dimension_X, ax);

    Requirement& ry = r.requirement(Dimension_Y);
    Coord ysize = ry.natural();
    float yalign = ry.alignment();
    Allotment ay(yalign * ysize, ysize, yalign);
    allocation_.allot(Dimension_Y, ay);
}

void ScaleToFit::allocate(Canvas* c, const Allocation& a, Extension& ext) {
    matrix_ = Transformer();
    matrix_.scale(
	a.allotment(Dimension_X).span() /
	    allocation_.allotment(Dimension_X).span(),
	a.allotment(Dimension_Y).span() /
	    allocation_.allotment(Dimension_Y).span()
    );
    c->push_transform();
    c->transform(matrix_);
    MonoGlyph::allocate(c, allocation_, ext);
    c->pop_transform();
}

void ScaleToFit::draw(Canvas* c, const Allocation&) const {
    c->push_transform();
    c->transform(matrix_);
    MonoGlyph::draw(c, allocation_);
    c->pop_transform();
}

int main(int argc, char** argv) {
    World world("Ipaste", argc, argv);
    if (argc == 1) {
	fprintf(stderr, "Usage: %s <file>\n", argv[0]);
	exit(1);
    }

    IMAGE* img = iopen(argv[1], "r", 0, 0, 0, 0, 0);
    if (img == nil) {
	fprintf(stderr, "%s: open image %s failed\n", argv[0], argv[1]);
	exit(1);
    }
    Raster* rast = new Raster(img->xsize, img->ysize);
    short* red = new short[img->xsize];
    short* green = new short[img->xsize];
    short* blue = new short[img->xsize];
    for (unsigned int y = 0; y < img->ysize; y++) {
	getrow(img, red, y, 0);
	getrow(img, green, y, 1);
	getrow(img, blue, y, 2);
	for (unsigned int x = 0; x < img->xsize; x++) {
	    rast->poke(
		x, y, red[x] / 255.0, green[x] / 255.0, blue[x] / 255.0, 1.0
	    );
	}
    }
    delete[] red;
    delete[] green;
    delete[] blue;
    iclose(img);

    Window* w = new ApplicationWindow(
	new Background(
	    new ScaleToFit(new Image(rast)),
	    world.background()
	)
    );

    w->map();
    world.run();
}