Holds a PixData object in raw form.
struct RawPixData
- bool fixed
- float w0
- float h0
- int scale
- int nobj
- bool filled
- char *coordstr[MAXOBJS]
- char *npointstr
- char *drawtype
Description:
RawPixData is an aggregate struct used to feed data to the PixData class, which converts the data to a QPixmap.
Each RawPixData variable defines up to MAXOBJS "thingies" to draw. Each "thingy" consists of a series of coordinate pairs describing the vector positions to use when drawing. There are three types of "thingies" you can draw using RawPixData:
Currently, MAXOBJS==10.
- circles
- N-sided polygons
- Sequence of line segments
Because you can't assign values to 2D C-arrays without pre-defining the array dimensions, we store some of the data for all of the "thingies" as strings. That way, you can create a QPixmap using less than MAXOBJS "thingies".
I have since thought about creating a format for the PixData class that is nothing but an array of strings, each of which contains data for a PixData object. However, I've since decided that it ain't broke, so why fix it? If there's really a big need for vector-drawn pixmaps, someone can always modify this class and create that format.
Please note: The following documentation of the struct members is not in order. The list at the beginning of this documentation specifies that. I've reordered the descriptions of the members to make the documentation flow more smoothly.
- int scale
This is something of a conversion factor: it specifies how to convert from vector units to pixels. Together with w0 and h0, scale specifies the size of the graphic you're defining. Specifically:
- pixmap width = scale*w0
- pixmap height = scaleh0
You can set scale=1 and set w0 and h0 to the width and height in pixels of the graphic. It is easier, however, to decide on a fixed coordinate system that you can easily subdivide and use scale to convert from these "normalized" units to pixels.
See w0 and h0 for more info.
- float w0
The width of the graphic you're defining, in "normalized" units.- float h0
The height of the graphic you're defining, in "normalized" units.
The "normalized units" are just convenient units you decide upon, units that make the coordinates easier to visualize. They also allow you to specify the size of the graphic [as well as the size and position of the things you're drawing] in terms on proportions.
For example, several of the pixmaps used in the AudioPanel have h0=1.0 and w0=2.0 - that is, the pixmaps are twice as wide as they are tall. This also makes it really easy to remember where the center of the graphic is: (1.0,0.5). By using these "normalized" coordinates, scale then specifies the size of the graphic in pixels.
- bool fixed
If set, indicates that the resulting QPixmap has a fixed size and should never be rescaled by PixData.
- bool filled
If set, indicates that circles and polygons should be filled with the foreground color. If filled==false, circles and polygons are not filled.
- int nobj
The number of "thingies" you're going to draw on this graphic - i.e. circles, polygons, and lines. It must be a number less than MAXOBJS [that means < 10 currently].
- char *drawtype
An array of characters indicating the type of "thingy" to draw. NOTE: Do not treat this as a string! I.e. don't put any whitespaces between the characters. The possible non-whitespace characters are:
- 'p'
- A polygon.
- 'c'
- A circle.
- 'l'
- A sequence of line segments.
There should be exactly nobj elements in this array.
For example, if nobj==4, then drawtype="pcp" indicates that the first object is a polygon, the second is a circle, and the third is another polygon.
- char *npointstr
A string containing nobj numbers, separated by whitespace. The numbers are the lengths of each "array" of coordinates specified in coordstr. So, npointstr="3 7 5 5 10" indicates that the 3rd object contains 5 points.
See coordstr for more info.
- char *coordstr[MAXOBJS]
An array of strings containing the data of each object. This is the meaty part of the RawPixData structure.
The first nobj strings in the array must contain coordinates for the object being drawn. Each coordinate is a piar of floating point numbers separated by a comma. The coordinates in each string are separated by normal whitespace. The number of coordinates in coordstr[i] MUST be the same as the ith value specified in npointstr.
There are some additional restrictions placed on coordstr:
- drawtype[i]=='c'
coordstr[i] should contain exactly two coordinates: the upper-left and lower-right corners of a bounding box for a circle.- drawtype[i]=='p'
coordstr[i] contains the corners of a polygon. For a square or rectangle, you need 5 coordinates. For an octagon, you'd need 9.- drawtype[i]=='l'
You might expect that you can only specify two coordinates in coordstr[i], but this isn't the case. You must have an even number of coordinates. This way, you can draw several line segments using only one "object". The first coordinate is the starting point of the first line segment. The third coordinate is the starting point of the second line segment. And so on...The coordinates should be positive floating point numbers and should be less than w0 and h0 for the x- and y-coordinate, respectively. The coordinate " 0.0,0.0 " is in the upper-left corner of the pixmap.
There is one final, but important, subtlety to the coordinates. It has to do with roundoff error.
Suppose you had a square pixmap: w0=1.0, h0=1.0. You want to draw a circle in the center of this pixmap. So, you set up a RawPixData variable and set:
coordstr={"0.3,0.3 0.7,0.7",
"","","","","","","","",""};
You'll get a circle, but it won't be centered. At least, not always. The circle may be centered at some scales, but a bit off-center at others. This is due to roundoff error, and it defeats the whole purpose of a vector-drawn pixmap.
It turns out that, because of roundoff error, the coordinate "0.5,0.5" isn't exactly the center. Pixels aren't infinitessimally small. So, to take roundoff into account, you need to subtract "by a little bit". How much is enough? That rather depends: what precision of floating point number do you use in your coordinates? What's the largest size you ever intend to scale this baby to? In general, one order of magnitude less than precision works well. So, in our example, we should really have:
coordstr={"0.3,0.3 0.69,0.69",
"","","","","","","","",""};
If, however, you intended to scale this baby up to 1000x1000 pixels, you might want to use:
coordstr={"0.3,0.3 0.699,0.699",
"","","","","","","","",""};
As you can see, you'll need to fiddle with this a bit.Example
To end this documentation, I want to give you an example. This is the actual, honest-to-goodness definition of the RawPixData variable for the power button icon. It's direct from the source code, and specifies two line segments, side-by-side, centered inside of a circle.
RawPixData powerd={ FALSE, 1.0, 1.0, 32, 2, FALSE, {".25,.25 .74,.74", ".49,.375 .49,.624 .5,.375 .5,.624", "","","","","","","",""}, "2 4", "cl" };
Copyright 1997 by John Weiss [John.Weiss@colorado.edu]
"generated by doc++"?! More like mangled generated by doc++