EXAMPLE 9: Now we are going to see an example on drawing shadows
and the use of
Affine transform.
=========================================================================================
public class a : pcs {
// Always remember, class name = file name
public override void init() {
base.init();
// Should be last statement in init()
}
public override void run() {
gm("dn");
// Turn off auto-display
//----------------------- Drawing a pattern on
the background -----------------------
cls="y0";gm("sps");
// Set color to yellow.
for(int i=-180;i<181;i+=4) {
// Fill drawing area with horizontal yellow
kf=i;of=2;lf=360;gm("crf");
// lines, 2 pixels thick to use as background
}
xs="Windows.NET Programming At
Its Best ";
xs+=xs;
// String to be drawn twice.
//--------------------------- Drawing the string's
shadow ---------------------------
fns="crb24";
// Set font to bold courier, size 24.
lf=of=320;gm("bn");
// Create 320 X 320 Bitmap.
gm("sdb");
// Set output device to (bip) to draw on it.
cls="S92";gm("sps");
// Set color to (20% opaque) black
char[]XC=xs.ToCharArray();
for (x=0;x<xs.Length;x++)
{ // Scan arch string, assign its char's one by
os=""+XC[x];
// one to (os) then create (gpp) representing
gm("ct");
// the char.
lf=150;of=180-5*x;kb=true;
// Modify (utp) to xfrm char's to points of
ad=(90-5*x);
// rad=150 and different angles starting at 180
gm("stu");
// and making a full circle.
gm("gtf");
// Xfrm & fill (gpp) of each char.
}
gm("sdd");
// Return output device to its default setting.
k=2;gm("bb");
// Blurr (bic) to make it look like a shadow.
jf=0;kf=-10;gm("br");
// Draw the bitmap with the shadow on it off
// center by 10 pixels (down)
//------------------------------- Drawing the string --------------------------------
cls="b0";gm("sps");
// Set color to pure blue
for (x=0;x<xs.Length;x++) {
// Draw the same circle of chars directly on
os=""+XC[x];
// the default graphical output device,
gm("ct");
// exactly at its center
lf=150;of=180-5*x;kb=true;
ad=90-5*x;
gm("stu");
gm("gtf");
}
//-------------------------- Drawing the large "PC#" shadow -------------------------
gm("stu");
// Reset (utp)
fns="trb84";
// Change font to a larger Times Roman font.
lf=of=200;gm("bn");
// Create 200 X 200 Bitmap object
gm("sdb");
// Set output device to (bip)
cls="S92";gm("sps");
// Set Color to black with 20% opacity.
os="PC#";gm("ctf");
// Draw-fill the string on the bitmap.
gm("sdd");
// Return to default output device setting.
k=3;gm("bb");
// Blur the shadow on (bip).
jf=0;kf=-15;gm("br");
// Draw shadow shifted 15 pixels down.
//--------------------------- Drawing the large
"PC#" body --------------------------
os="PC#";gm("ct");
// Create text object
cls="y39o09";id=10;
// cls=brightest-darkest colors, depth=10
ad=60;ks="d";gm("grs");
// Shear angle=60,render with sp effects-depth
gm("d");
// Display graphics.
}
}
=========================================================================================
TUTORIAL:
Why have we turned auto-display off?
The program runs slow and flickers a lot, so it seemed to be more
covenient to keep
display off until the drawing is complete.
Why did we need the yellow background pattern?
To improve shadows' look. There are three factors which make Shadows
look real:
(1) Drawing something rough on the background.
(2) Drawing them in partially transparent gray color.
(3)
Blurring them.
AFFINE TRANSFORM:
Affine transform is a mapping between the current coordinate system
and a new coordinate
system which you like to switch to. It can be represented by a matrix which contains the
scaling,
shearing and translation parameters.
The order of operations is important. For example, rotating
an object around form's
center then moving it to a new location is not the same as if you move the object first
then
rotate it.
With PC# you need not to worry. You call method gm("stu") or
gm("stp") with all the
parameters at once and everything will be done at the right order. Mode "stu" is for
"unit
transform setup" which is a general Affine transform for shapes, bitmaps, brushes,
etc. Mode "stp" is for the printer.
Affine transform parameters:
jf,kf The original coordinates of object's
center relative to form's center (before
the transform is
applied to the object) If you create all your objects
centered at Form's center, you'll have no need to assign values to jf,kf.
lf,of The (x,y) displacements of the
object. In case the original object center
was at (0,0),
(lf,of) simply mean the new location of the object center.
jd,kd The scale factors. If equal to
(2,0.5), the object will be enlarged to double
the size horizontally
and reduced to half the size vertically. If either
value
is negative, the object will be inverted. For example (jd=-1) produces a
mirror image of the original object with the vertical axis acting as the mirror.
id,od The shear factors. The effects
of shearing have been discussed before.
ad The rotation angle
in degrees. You need to understand that the rotation is
going to be around object's center which is point (jf,kf) not around form's
center.
ob Normal order concatenation.
Setting (ob=true) means that you like to
concatenate the transform
you are setting to the original transform with
the original
one applied first. Note: if both (ib,ob) are set to false, the
new transform will replace the original one.
ib Reverse order concatenation.
Setting (ib=true) means that you like to
concatenate the transform
you are setting to the original transform with
the original
one applied last. Note: if both (ib,ob) are set to false, the
new transform will replace the original one.
Transformation order:
As stated before, PC# takes care of applying each of the required
transformations at the
correct order. However, if you are concatenating transforms, you need to care about the
concatenation
order. Assuming you are interested in scaling shearing and/or rotating
objects around their centers then displacing
their center to a new location, you should
keep the following order: Scale - Shear - Rotate - Translate.
=========================================================================================