443
edits
-
Changes
Created page with "GFXLIB_en == About this library (cited from web site) == GFX lib is a small C graphics library for the MSX computer. It is being developed and compiled with the Hitech-C comp..."
GFXLIB_en
== About this library (cited from web site) ==
GFX lib is a small C graphics library for the MSX computer. It is being developed and compiled with the Hitech-C compiler.
;Features (until now)
* VDP and VRAM access functions
* Line algorithms
* Vector math and 3D Graphics
* Sprite manipulation
* PSG manipulation (new!)
* Joystick input
* Many examples available as commented source code
* Miscelaneous utilities (defines, helpers...)
== Basic definitions and utilities(cited from defs.h) ==
;#define map_pixel(x,y) (map_block(x,y) + ((y) & 7))
:here is how it works:
// map the row start (by row I mean a block of 8 lines)
addr = (y & ~(7)) << 5; // this is the same as (y / 8) * 256
// then we aim for the column (column = block of 8 pixels)
addr += (x & ~(7)); // this is the same as (x / 8) * 8
// finally, aim for the remaining "sub-row" inside the row block
addr += (y & 7);
;<nowiki>#define map_subpixel(x) (128 >> ((x) & 7))</nowiki>
:maps the subpixel (bit) inside the vram byte
;<nowiki>#define LONG(v) ((long)(v))</nowiki>
===fixed point arithmetic===
;<nowiki>#define i2f(v) ((v) << 6)</nowiki>
:integer to fixed-point
;<nowiki>#define f2i(v) ((v) >> 6)</nowiki>
:fixed-point to integer
;<nowiki>#define mulfx(x,y) ((LONG(y) * LONG(x)) >> 6)</nowiki>
:fixed-point multiplication
;<nowiki>#define divfx(x,y) ((LONG(x) << 6) / LONG(y))</nowiki>
:fixed-point division
;<nowiki>#define sqrfx(x) ((LONG(x) * LONG(x)) >> 6)</nowiki>
:fixed-point square
;<nowiki>#define sqrtfx(x) (LONG(sqrt(x)) << 3)</nowiki>
:fixed-point square root
:formula: sqrt(N * 64) = sqrt(N) * sqrt(64) -> must compensate with 64/sqrt(64) = 8
;<nowiki>#define wgavgfx(x, y, w) (mulfx(i2f(1) - w, x) + mulfx(w, y))</nowiki>
:weighted average (w=0.0 -> x, w=0.5->average, w=1.0 ->y)
===malloc helpers===
;<nowiki>#define new(x) ((x*)malloc(sizeof(x)))</nowiki>
:allocates space for 1 element of type argument "x"
;<nowiki>#define newa(x, c) ((x*)malloc(sizeof(x) * c))</nowiki>
:allocates space for argument "c" elements of type argument "x"
== Main library functions(cited from gfx.h) ==
library functions / enums.
==== Video ====
VRAM and VDP related functions
;enum video_mode{}
:video modes
enum video_mode {
mode_0 = 0x6C,
mode_1 = 0x6F,
mode_2 = 0x72,
mode_3 = 0x75
};
;enum screen_map{}
:mangled screen sections (3 maps)
enum screen_map {
place_1 = 1,
place_2 = 2,
place_3 = 4,
place_all = 255
};
;<nowiki>#define MODE2_MAX (256 * 24)</nowiki>
:screen 2 section bytecount
;<nowiki>#define MODE2_ATTR (8192)</nowiki>
:screen 2 attributes section start address
;<nowiki>#define MODE2_WIDTH 256</nowiki>
:screen 2 width in pixels
;<nowiki>#define MODE2_HEIGHT 192</nowiki>
:screen 2 height in pixels
===VDP and VRAM functions===
;extern void set_mode(u_int mode);
:set screen mode
;extern void set_mangled_mode();
:set screen to mangled mode (screen 1 + 2)
;extern void set_color(u_char front, u_char back, u_char border);
:set screen color
;extern void fill(u_int addr, u_char value, u_int count);
:fill vram from argument "addr", with argument "value", for argument "count" bytes
;extern void vpoke(u_int addr, u_char value);
:set argument "value" at a given vram address argument "addr".
;extern u_char vpeek(u_int addr);
:get value from a given vram address argument "addr"
;extern void vmerge(u_int addr, u_char value);
:set argument "value" at a given vram address argument "addr", merging bits (OR) with the existing value
;extern void vwrite(void* source, u_int dest, u_int count);
:transfer \a count bytes from ram to vram
;extern void vread(u_int source, void* dest, u_int count);
:transfer argument count bytes from vram to ram
;extern void set_vdp(u_char reg, u_char value);
:set a vdp register with a \a value
;extern u_char get_vdp(u_char reg);
:get a vdp value from register \a reg
;extern void locate(u_char x, u_char y);
:move the screen cursor to a given position
===primitives (not many yet :))===
;extern void fill_v(u_int addr, u_char value, u_char count);
:vertical fill on vram starting at adress argument "addr", of a given argument "value", for argument "count" lines
;extern void pset(int x, int y);
:set point at the given position on vram
===mangled mode chars===
;void set_char_form(char c, void* form, u_char place);
:set char argument "c" shape, from argument "form", at the given screen map argument "place"
;void set_char_attr(char c, void *attr, u_char place);
:set char argument "c" attributes, from argument "attr", at the given screen map argument "place"
;void set_char_color(char c, u_char color, u_char place);
:set char argument "c" with argument "color", at the given screen map argument "place"
;void set_char(char c, void* form, void *attr, u_char color, u_char place);
:set char argument "c" shape, attributes and color, all in one
=== Sprites ===
;typedef struct {}sprite_t;
:sprite data
typedef struct {
u_char y; ///< Y position
u_char x; ///< X position
u_char handle; ///< internal vdp handle
u_char color; ///< sprite color
} sprite_t;
;enum sprite_mode{}
:sprite modes
enum sprite_mode {
sprite_default = 0,
sprite_scaled = 1,
sprite_large = 2
};
;extern void set_sprite_mode(u_char mode);
:set the sprite argument "mode"
;extern void *set_sprite(u_char, void*);
;extern void *put_sprite(u_char, int, int, u_char, u_char);
:this is not compiling... I suggest some #define's instead
;extern void set_sprite_8(u_char handle, void* data);
:set the sprite argument "handle", with the shape from "argument" data (small size)
;extern void set_sprite_16(u_char handle, void* data);
:set the sprite argument "handle", with the shape from argument "data" (big size)
;extern void put_sprite_8(u_char id, int x, int y, u_char handle, u_char color);
:put the sprite with argument "id" and shape from \a handle, into the given position with argument "color" (small size)
;extern void put_sprite_16(u_char id, int x, int y, u_char handle, u_char color);
:put the sprite with argument "id" and shape from argument "handle", into the given position with argument "color" (big size)
===surface===
<nowiki>FIXME: this is not usable right now</nowiki>
;typedef struct {}surface_t;
:represents a drawing surface
typedef struct {
int width;
int height;
int type;
union {
u_char* ram; ///< ram adress, for off-screen surfaces
u_int vram;
} data;
} surface_t;
enum surface_type {
surface_ram,
surface_vram
};
typedef struct {
int x, y;
int width, height;
} rect_t;
;extern void blit(surface_t *source, surface_t *dest, rect_t *from, rect_t *to);
;extern void blit_ram_vram(u_char* source, u_int dest, u_char w, u_char h, int sjmp, int djmp);
;extern void blit_fill_vram(u_int dest, u_char value, u_char w, u_char h, int djmp);
===Controllers===
enum stick_direction {
st_up = 1,
st_right = 2,
st_down = 4,
st_left = 8
};
;extern u_char st_dir[];
;extern u_char get_stick(u_char id);
:get state of joystick number argument "id"
;extern bool get_trigger(u_char id);
:get state of joystick button (trigger) number argument "id", true = pressed
=== Random ===
Fast and dirty pseudo-random number generator
;extern void seed_rnd(int seed);
:seed the pseudo-random number generator
;extern u_char get_rnd();
:get the next number from the pseudo-random number generator
=== PSG ===
PSG (sound generator) manipulation functions
;#define sound(reg, value) psg_set(reg, value)
:alias for setting psg registers (for the BASIC fans)
;#define psgT(hz) ((int)(111760.0 / (hz)))
:convert a given frequency into a suitable period for PSG
enum {
chanNone = 0, ///< no channel
chan0 = 1, ///< the first audio channel
chan1 = 2, ///< the second audio channel
chan2 = 4, ///< the third audio channel
chanAll = 7 ///< all audio channels
};
:volume envelopes, where U = up, D = down, H = high
enum {
envD = 0, ///< envelope, falling into silence
envU = 4, ///< envelope, raising to highest volume, then silenced
envDD = 8, ///< envelope, falling into silence multiple times
envDUD = 10, ///< envelope, first falling, and then triangle shaped
envDH = 11, ///< envelope, falling into silence, then abrupt high volume
envUU = 12, ///< envelope, raising until top multiple times
envUH = 13, ///< envelope, raising until top and then mantaining high volume
envUDUD = 14 ///< envelope, triangle shaped
};
;void psg_set(u_char reg, u_char value);
:set a psg register with a argument "value"
;u_char psg_get(u_char reg);
:get value from psg register
;void psg_init();
:initialize psg
;void psg_tone(u_char channel, int period);
:set a given tone for the channel (0-2)
;void psg_noise(u_char period);
:set the global noise period
;void psg_volume(u_char channel, u_char volume);
:set channel's volume
;void psg_envelope(u_char waveform, int period, u_char channels);
:set the volume envelope of number argument "waveform", with the given period, on a group of channels (ORed bits)
;void psg_channels(u_char tone_channels, u_char noise_channels);
:set noise or tone generation on a group of channels (ORed bits)
;u_char psg_tone_channels();
:get the group of channels currently generating tone (ORed bits)
;u_char psg_noise_channels();
:get the group of channels currently generating noise (ORed bits)
-------------------------------------
== Line drawing functions(cited from line.h) ==
LINE.H : line drawing functions (header)
;DITHER(I, Y) (dithpat[I][Y & 1])
:get a dithered pattern of intensity argument "I" on the screen line argument "Y"
;extern u_char dithpat[5][2];
;extern void surface_line(surface_t*, int x1, int y1, int x2, int y2);
:Draw a line on a surface
<ref>cf:ex11.c,ex5.c</ref>
;extern void line(int x1, int y1, int x2, int y2);
:Draw a line on video
<ref>cf:N/A</ref>
;extern void line_slow(int x1, int y1, int x2, int y2);
:Draw a line on video (slow)
<ref>cf:N/A</ref>
;extern void calculate_side(int x1, int y1, int x2, int y2, int low[], int high[]);
:Calculate a triangle side
<ref>cf:ex10.c</ref>
;extern void hline(int x1, int y1, int x2, u_char value);
:Draw horizontal line on video. Argument "value" can be a bit pattern. note: x1 <= x2
<ref>cf:ex10.c</ref>
extern void surface_hline(surface_t *s, int x1, int y1, int x2, u_char value);
:Draw horizontal line on surface. Argument "value" can be a bit pattern. note: x1 <= x2
<ref>cf:ex10.c</ref>
== Note1(cited from gfx.h) ==
This is a work-in-progress, meaning that most of this code is unstable
and it's subject to future changes. Also, most of it is very hackish,
not properly cleaned up nor tested.
== Note2(cited from readme) ==
Currently it is a work-in-progress (currently targeted at MSX 1.x series)
I decided to release this unfinished code anyway because:
* it works. well, the examples DO work ya know :)
* it might be useful to someone else (writing code, learning, ...)
* my lack of time isn't helping to move forward
SO... give it a try, look at the cool examples, send patches :)
Check the Changelog to see some of the most recent features.
Hope you enjoy it. Happy coding!
== Note from editors of WIKI ==
There's no single technical document or specification in this package but well commented in each source and header files. We pick up, edit and integrate these comments here as a reference.
Changed these issues.
* "\a" means "argument" in original comments so it is expanded to word "argument" for convenience here.
* Order of sentences are changed to make definition first and comments are second.
* Sample file names are added as far as possible.
/*=========================================================================
GFX - a small graphics library
Copyright (C) 2004 Rafael de Oliveira Jannone
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact the author:
by e-mail : rafael AT jannone DOT org
homepage : http://jannone.org/gfxlib
ICQ UIN : 10115284
See the License at http://www.gnu.org/copyleft/lesser.txt
=========================================================================*/
== About this library (cited from web site) ==
GFX lib is a small C graphics library for the MSX computer. It is being developed and compiled with the Hitech-C compiler.
;Features (until now)
* VDP and VRAM access functions
* Line algorithms
* Vector math and 3D Graphics
* Sprite manipulation
* PSG manipulation (new!)
* Joystick input
* Many examples available as commented source code
* Miscelaneous utilities (defines, helpers...)
== Basic definitions and utilities(cited from defs.h) ==
;#define map_pixel(x,y) (map_block(x,y) + ((y) & 7))
:here is how it works:
// map the row start (by row I mean a block of 8 lines)
addr = (y & ~(7)) << 5; // this is the same as (y / 8) * 256
// then we aim for the column (column = block of 8 pixels)
addr += (x & ~(7)); // this is the same as (x / 8) * 8
// finally, aim for the remaining "sub-row" inside the row block
addr += (y & 7);
;<nowiki>#define map_subpixel(x) (128 >> ((x) & 7))</nowiki>
:maps the subpixel (bit) inside the vram byte
;<nowiki>#define LONG(v) ((long)(v))</nowiki>
===fixed point arithmetic===
;<nowiki>#define i2f(v) ((v) << 6)</nowiki>
:integer to fixed-point
;<nowiki>#define f2i(v) ((v) >> 6)</nowiki>
:fixed-point to integer
;<nowiki>#define mulfx(x,y) ((LONG(y) * LONG(x)) >> 6)</nowiki>
:fixed-point multiplication
;<nowiki>#define divfx(x,y) ((LONG(x) << 6) / LONG(y))</nowiki>
:fixed-point division
;<nowiki>#define sqrfx(x) ((LONG(x) * LONG(x)) >> 6)</nowiki>
:fixed-point square
;<nowiki>#define sqrtfx(x) (LONG(sqrt(x)) << 3)</nowiki>
:fixed-point square root
:formula: sqrt(N * 64) = sqrt(N) * sqrt(64) -> must compensate with 64/sqrt(64) = 8
;<nowiki>#define wgavgfx(x, y, w) (mulfx(i2f(1) - w, x) + mulfx(w, y))</nowiki>
:weighted average (w=0.0 -> x, w=0.5->average, w=1.0 ->y)
===malloc helpers===
;<nowiki>#define new(x) ((x*)malloc(sizeof(x)))</nowiki>
:allocates space for 1 element of type argument "x"
;<nowiki>#define newa(x, c) ((x*)malloc(sizeof(x) * c))</nowiki>
:allocates space for argument "c" elements of type argument "x"
== Main library functions(cited from gfx.h) ==
library functions / enums.
==== Video ====
VRAM and VDP related functions
;enum video_mode{}
:video modes
enum video_mode {
mode_0 = 0x6C,
mode_1 = 0x6F,
mode_2 = 0x72,
mode_3 = 0x75
};
;enum screen_map{}
:mangled screen sections (3 maps)
enum screen_map {
place_1 = 1,
place_2 = 2,
place_3 = 4,
place_all = 255
};
;<nowiki>#define MODE2_MAX (256 * 24)</nowiki>
:screen 2 section bytecount
;<nowiki>#define MODE2_ATTR (8192)</nowiki>
:screen 2 attributes section start address
;<nowiki>#define MODE2_WIDTH 256</nowiki>
:screen 2 width in pixels
;<nowiki>#define MODE2_HEIGHT 192</nowiki>
:screen 2 height in pixels
===VDP and VRAM functions===
;extern void set_mode(u_int mode);
:set screen mode
;extern void set_mangled_mode();
:set screen to mangled mode (screen 1 + 2)
;extern void set_color(u_char front, u_char back, u_char border);
:set screen color
;extern void fill(u_int addr, u_char value, u_int count);
:fill vram from argument "addr", with argument "value", for argument "count" bytes
;extern void vpoke(u_int addr, u_char value);
:set argument "value" at a given vram address argument "addr".
;extern u_char vpeek(u_int addr);
:get value from a given vram address argument "addr"
;extern void vmerge(u_int addr, u_char value);
:set argument "value" at a given vram address argument "addr", merging bits (OR) with the existing value
;extern void vwrite(void* source, u_int dest, u_int count);
:transfer \a count bytes from ram to vram
;extern void vread(u_int source, void* dest, u_int count);
:transfer argument count bytes from vram to ram
;extern void set_vdp(u_char reg, u_char value);
:set a vdp register with a \a value
;extern u_char get_vdp(u_char reg);
:get a vdp value from register \a reg
;extern void locate(u_char x, u_char y);
:move the screen cursor to a given position
===primitives (not many yet :))===
;extern void fill_v(u_int addr, u_char value, u_char count);
:vertical fill on vram starting at adress argument "addr", of a given argument "value", for argument "count" lines
;extern void pset(int x, int y);
:set point at the given position on vram
===mangled mode chars===
;void set_char_form(char c, void* form, u_char place);
:set char argument "c" shape, from argument "form", at the given screen map argument "place"
;void set_char_attr(char c, void *attr, u_char place);
:set char argument "c" attributes, from argument "attr", at the given screen map argument "place"
;void set_char_color(char c, u_char color, u_char place);
:set char argument "c" with argument "color", at the given screen map argument "place"
;void set_char(char c, void* form, void *attr, u_char color, u_char place);
:set char argument "c" shape, attributes and color, all in one
=== Sprites ===
;typedef struct {}sprite_t;
:sprite data
typedef struct {
u_char y; ///< Y position
u_char x; ///< X position
u_char handle; ///< internal vdp handle
u_char color; ///< sprite color
} sprite_t;
;enum sprite_mode{}
:sprite modes
enum sprite_mode {
sprite_default = 0,
sprite_scaled = 1,
sprite_large = 2
};
;extern void set_sprite_mode(u_char mode);
:set the sprite argument "mode"
;extern void *set_sprite(u_char, void*);
;extern void *put_sprite(u_char, int, int, u_char, u_char);
:this is not compiling... I suggest some #define's instead
;extern void set_sprite_8(u_char handle, void* data);
:set the sprite argument "handle", with the shape from "argument" data (small size)
;extern void set_sprite_16(u_char handle, void* data);
:set the sprite argument "handle", with the shape from argument "data" (big size)
;extern void put_sprite_8(u_char id, int x, int y, u_char handle, u_char color);
:put the sprite with argument "id" and shape from \a handle, into the given position with argument "color" (small size)
;extern void put_sprite_16(u_char id, int x, int y, u_char handle, u_char color);
:put the sprite with argument "id" and shape from argument "handle", into the given position with argument "color" (big size)
===surface===
<nowiki>FIXME: this is not usable right now</nowiki>
;typedef struct {}surface_t;
:represents a drawing surface
typedef struct {
int width;
int height;
int type;
union {
u_char* ram; ///< ram adress, for off-screen surfaces
u_int vram;
} data;
} surface_t;
enum surface_type {
surface_ram,
surface_vram
};
typedef struct {
int x, y;
int width, height;
} rect_t;
;extern void blit(surface_t *source, surface_t *dest, rect_t *from, rect_t *to);
;extern void blit_ram_vram(u_char* source, u_int dest, u_char w, u_char h, int sjmp, int djmp);
;extern void blit_fill_vram(u_int dest, u_char value, u_char w, u_char h, int djmp);
===Controllers===
enum stick_direction {
st_up = 1,
st_right = 2,
st_down = 4,
st_left = 8
};
;extern u_char st_dir[];
;extern u_char get_stick(u_char id);
:get state of joystick number argument "id"
;extern bool get_trigger(u_char id);
:get state of joystick button (trigger) number argument "id", true = pressed
=== Random ===
Fast and dirty pseudo-random number generator
;extern void seed_rnd(int seed);
:seed the pseudo-random number generator
;extern u_char get_rnd();
:get the next number from the pseudo-random number generator
=== PSG ===
PSG (sound generator) manipulation functions
;#define sound(reg, value) psg_set(reg, value)
:alias for setting psg registers (for the BASIC fans)
;#define psgT(hz) ((int)(111760.0 / (hz)))
:convert a given frequency into a suitable period for PSG
enum {
chanNone = 0, ///< no channel
chan0 = 1, ///< the first audio channel
chan1 = 2, ///< the second audio channel
chan2 = 4, ///< the third audio channel
chanAll = 7 ///< all audio channels
};
:volume envelopes, where U = up, D = down, H = high
enum {
envD = 0, ///< envelope, falling into silence
envU = 4, ///< envelope, raising to highest volume, then silenced
envDD = 8, ///< envelope, falling into silence multiple times
envDUD = 10, ///< envelope, first falling, and then triangle shaped
envDH = 11, ///< envelope, falling into silence, then abrupt high volume
envUU = 12, ///< envelope, raising until top multiple times
envUH = 13, ///< envelope, raising until top and then mantaining high volume
envUDUD = 14 ///< envelope, triangle shaped
};
;void psg_set(u_char reg, u_char value);
:set a psg register with a argument "value"
;u_char psg_get(u_char reg);
:get value from psg register
;void psg_init();
:initialize psg
;void psg_tone(u_char channel, int period);
:set a given tone for the channel (0-2)
;void psg_noise(u_char period);
:set the global noise period
;void psg_volume(u_char channel, u_char volume);
:set channel's volume
;void psg_envelope(u_char waveform, int period, u_char channels);
:set the volume envelope of number argument "waveform", with the given period, on a group of channels (ORed bits)
;void psg_channels(u_char tone_channels, u_char noise_channels);
:set noise or tone generation on a group of channels (ORed bits)
;u_char psg_tone_channels();
:get the group of channels currently generating tone (ORed bits)
;u_char psg_noise_channels();
:get the group of channels currently generating noise (ORed bits)
-------------------------------------
== Line drawing functions(cited from line.h) ==
LINE.H : line drawing functions (header)
;DITHER(I, Y) (dithpat[I][Y & 1])
:get a dithered pattern of intensity argument "I" on the screen line argument "Y"
;extern u_char dithpat[5][2];
;extern void surface_line(surface_t*, int x1, int y1, int x2, int y2);
:Draw a line on a surface
<ref>cf:ex11.c,ex5.c</ref>
;extern void line(int x1, int y1, int x2, int y2);
:Draw a line on video
<ref>cf:N/A</ref>
;extern void line_slow(int x1, int y1, int x2, int y2);
:Draw a line on video (slow)
<ref>cf:N/A</ref>
;extern void calculate_side(int x1, int y1, int x2, int y2, int low[], int high[]);
:Calculate a triangle side
<ref>cf:ex10.c</ref>
;extern void hline(int x1, int y1, int x2, u_char value);
:Draw horizontal line on video. Argument "value" can be a bit pattern. note: x1 <= x2
<ref>cf:ex10.c</ref>
extern void surface_hline(surface_t *s, int x1, int y1, int x2, u_char value);
:Draw horizontal line on surface. Argument "value" can be a bit pattern. note: x1 <= x2
<ref>cf:ex10.c</ref>
== Note1(cited from gfx.h) ==
This is a work-in-progress, meaning that most of this code is unstable
and it's subject to future changes. Also, most of it is very hackish,
not properly cleaned up nor tested.
== Note2(cited from readme) ==
Currently it is a work-in-progress (currently targeted at MSX 1.x series)
I decided to release this unfinished code anyway because:
* it works. well, the examples DO work ya know :)
* it might be useful to someone else (writing code, learning, ...)
* my lack of time isn't helping to move forward
SO... give it a try, look at the cool examples, send patches :)
Check the Changelog to see some of the most recent features.
Hope you enjoy it. Happy coding!
== Note from editors of WIKI ==
There's no single technical document or specification in this package but well commented in each source and header files. We pick up, edit and integrate these comments here as a reference.
Changed these issues.
* "\a" means "argument" in original comments so it is expanded to word "argument" for convenience here.
* Order of sentences are changed to make definition first and comments are second.
* Sample file names are added as far as possible.
/*=========================================================================
GFX - a small graphics library
Copyright (C) 2004 Rafael de Oliveira Jannone
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact the author:
by e-mail : rafael AT jannone DOT org
homepage : http://jannone.org/gfxlib
ICQ UIN : 10115284
See the License at http://www.gnu.org/copyleft/lesser.txt
=========================================================================*/