home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
517a.lha
/
VFont_v2.0
/
examples
/
rotate.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-09
|
12KB
|
371 lines
/* Copyright 1991 by Michael Jansson, All rights reserved.
NAME: Rotate
USAGE: Rotate [-q] <font name> <text string>
VERSION: 1.2
This is a small program that will display a text string that is both
rotating and changing size. It is a typical example of the use of the
vfont.library functions: OpenVFont, ChangeVFont and VText.
Use the -q switch only if you are running under OS 2.0+. It will make
this program run faster.
The program opens a screen and a window in a normal intuition fashion.
Then it opens two font instances of the same font class, which are used
in a double-buffering fashion. This is done by:
1) changing size and direction of one font
2) erase the previous rendered text by using the previously
used font and render in the background color
3) render the text with the font that was changed during step 1
4) Swap the fonts so that step 1 will change the old font etc.
5) start all over with step 1 again...
The time when the screen is blank will be very short (between step 2
and 3) since the previously used font and the new font will both have
all used character of the string cached (at least when the characters
are sufficiently small). It will therefor give a steady impression and
not a flicker.
*/
#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <pragmas/dos.h>
#include <pragmas/exec.h>
#include <pragmas/intuition.h>
#include <pragmas/graphics.h>
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <vfont/curve.h>
#include <vfont/vfont.h>
#include <clib/vfontlib.pro>
#include <pragmas/vfontlib.pra>
/* Some constans in the fixpoint format. */
#define FIX_PI_256 1608
#define PI_256 0.024543692
/* Some macros. (It's done this way to improve the readability of the code). */
#define SwapFont(f1, f2) {VFont *f3=f1; f1=f2; f2=f3;}
#define RotatePoint(x,y,angle,ox,oy) {long tx,ty;\
tx = costab[angle]*(x) - sintab[angle]*(y); \
ty = costab[angle]*(y) + sintab[angle]*(x); \
x = tx/FIXOFFSET+(ox); \
y = ty/FIXOFFSET+(oy); \
}
#define MyPutS(str) Write(Output(), str "\n", (long)strlen(str)+1L)
/* This is the parameter that is used when the font is opened.
It is very similar to the intuition.library structure TextAttr.
The TextAttr is distinguished from a TextVAttr (notice the
extra "V" in the name) by the one bit flag VectorFont, which
corresponds to the sign bit of the ta_YSize field of the TextAttr
structure. You may use a plain TextAttr if you are satisfied with
the default values for the vector font extension of the structure
when you open a font with the OpenVFont function.
The width or the height may be set to zero to indicate that you
want the default width or height. The library will then set it so
that the proportions will be preserved, e.g. a 32x16 large font class
opened as a 64x0 large font will be set to be 64x32.
*/
TextVAttr tattr = {
(UBYTE *)"vwire.font", /* The name of the class. */
32, /* The height */
1, /* It is a vector font. */
FS_NORMAL, /* The style. */
FPF_DESIGNED|FPF_DISKFONT, /* The flags. */
/* The field below are specific for vector fonts. */
(UBYTE *)"John", /* Our name for this font instance. */
/* Default: An unique name is created. */
0, /* Initial width. */
/* Default: 0, i.e. default width. */
/* VFlags. */
VFB_VERBOSE | /* Let the library inform the user when error occurs. */
VFB_EXCLUSIVE | /* Don't let others use the font. */
VFB_ANYSIZE /* Use font class with any size. */
};
/* Some intuition structure used when opening the screen and the window. */
#define ProgramName (UBYTE *)"Rotate v1.2 - Copyright 1991 by Michael Jansson"
#define width 640L
#define height 512L /* Change this to 400 for NTSC. */
struct NewScreen newscreen = {
0,0,width,height,1, /* Screen dimensions. */
0,-1, /* Pen colors. */
LACE|HIRES, /* View modes. */
CUSTOMSCREEN, /* Screen type. */
NULL, /* Default screen font (none). */
ProgramName, /* Screen title. */
NULL, /* Gadgets (none). */
NULL /* CustomBitMap (none). */
};
struct NewWindow newwindow = {
0,0,width,height, /* Window dimensions. */
0,-1, /* Pen colors. */
0UL, /* IDCMPFlags (none). */
SIMPLE_REFRESH | /* Flags. (We want a really simple window). */
NOCAREREFRESH |
BORDERLESS,
NULL, /* Gadgets. (none). */
NULL, /* Check mark. (none). */
ProgramName, /* Title. */
NULL, /* Screen (set it to our screen when it is open). */
NULL, /* BitMap. (none). */
0,0,width,height, /* Min/Max dimensions. */
CUSTOMSCREEN /* Window type. */
};
/* Library names. */
#define INTUITION (UBYTE *)"intuition.library"
#define GRAPHICS (UBYTE *)"graphics.library"
#define VFONTS (UBYTE *)"vfont.library"
/* The size of the AreInfo buffer (Intuition stuff). */
#define AREABUFFSIZE 1000L
#define AREABUFFSIZE5 5000L
/* Global data. */
UBYTE myBuffer[AREABUFFSIZE5];
struct AreaInfo myArea;
struct TmpRas myTmpRas;
/* Global data that is allocated/opened. */
struct Library *IntuitionBase = NULL;
struct Library *vFontBase = NULL;
struct Library *GfxBase = NULL;
struct Screen *screen = NULL;
struct Window *window = NULL;
PLANEPTR myPlane = NULL;
VFont *font1 = NULL, *font2 = NULL;
/*
Function that will deallocate the used resources.
*/
void
_abort(void)
{
if (font1)
CloseVFont(font1);
if (font2)
CloseVFont(font2);
if (myPlane)
FreeRaster(myPlane, width, height);
if (window)
CloseWindow(window);
if (screen)
CloseScreen(screen);
if (vFontBase)
CloseLibrary(vFontBase);
if (IntuitionBase)
CloseLibrary(IntuitionBase);
if (GfxBase)
CloseLibrary(GfxBase);
exit(0L);
}
/*
This function changes the rendering direction, the character orientation
and the size of a font. This is done by calling the ChangeVFont function.
*/
void
AdjustFont(VFont *font, FIX alfa, ULONG ysize, UBYTE *string)
{
VFont req;
/* Fill in a template with the values that we want to use in the */
/* font and call ChangeVFont() to alter the font. */
req.AlfaPath = alfa;
req.UpVector = alfa;
req.YSize = ysize;
req.XSize = 0; /* Use default size. */
ChangeVFont(font, (UBYTE)(VCM_PATH|VCM_UP|VCM_SIZE), &req, (long)FALSE);
do {
MakeChar(font, font->Class, *string);
} while(*++string);
}
/*
This is the main part of the program.
*/
void
main(int argc, UBYTE **argv)
{
struct RastPort *RPort;
FIX sintab[256];
FIX costab[256];
FIX ysize = IntToFix(4);
long x,y,len,slen;
UBYTE *string, alfa = 0;
BOOL quick_flg = FALSE;
short i;
/* Process the CLI parameters. */
if (argc<3) {
MyPutS("Usage: rotate [-q] font textstring");
MyPutS("Example: rotate emerald \"A string\"");
string = (UBYTE *)"vFont 2.0 (Rotate 1.2)";
} else {
if (argv[1][0]=='-' && tolower(argv[1][1])=='q') {
if (argc<4) {
MyPutS("Bad parameters! Try: rotate [-q] font textstring");
string = (UBYTE *)"vFont 2.0 (Rotate 1.2)";
} else {
quick_flg = TRUE;
tattr.Name = argv[2];
string = argv[3];
}
} else {
quick_flg = FALSE;
tattr.Name = argv[1];
string = argv[2];
}
}
/* Open the needed libraries. */
if (!(IntuitionBase = OpenLibrary(INTUITION, 0L))
|| !(GfxBase = OpenLibrary(GRAPHICS, 0L))
|| !(vFontBase = OpenLibrary(VFONTS, 0L))) {
MyPutS("Can't open the vfont libarary.");
_abort();
}
/* Open the first font by using a TextVAttr (or TextAttr) structure. */
if ((font1 = OpenVFont(&tattr))==NULL) {
MyPutS("Didn't manage to open that font.");
_abort();
}
/* Open the second font. */
if ((font2 = OpenVFont(&tattr))==NULL) {
MyPutS("Didn't manage to open that font.");
_abort();
}
/* Open a screen. */
if (!(screen = OpenScreen(&newscreen))) {
MyPutS("Couldn't open screen.");
_abort();
}
/*
It is faster to render in a screen's rastport than to render in a window's
rastport, since a window contains a layer that many renderings is clipped
against (including redering done by the vfont library).
VText will unfortunately not work on an un-layered rastport under OS 1.2-1.3
due to a fault graphics library function, which is fixed under OS 2.0+
*/
if (quick_flg)
RPort = &screen->RastPort;
else {
/* Open a window. */
newwindow.Screen = screen;
if (!(window=OpenWindow(&newwindow))) {
MyPutS("Failed to open a window.");
_abort();
}
RPort = window->RPort;
}
SetDrMd(RPort, (long)JAM1);
/*
The vfont.library function VText uses the graphics.library
functions AreaDraw/Move/End. They, in turn, requires that you
add some data structures to the rastport, known as the AreInfo
and the TmpRast structures.
*/
/* Add a TmpRas. */
if (!(myPlane=AllocRaster(width, height)))
_abort();
InitTmpRas(&myTmpRas, myPlane, (long)RASSIZE(width, height));
RPort->TmpRas = &myTmpRas;
/* Add a AreaInfo. */
InitArea(&myArea, myBuffer, AREABUFFSIZE);
RPort->AreaInfo = &myArea;
/* Build the sin and the cos tables to speed up the rendering. */
for (i=0; i<256; i++) {
sintab[i] = FloatToFix(sin(PI_256*i));
costab[i] = FloatToFix(cos(PI_256*i));
}
/* Initiate some variables. */
slen = strlen(string);
AdjustFont(font1, (FIX)alfa*FIX_PI_256, (ULONG)FixToInt(ysize), string);
len = (long)VTextLength(font1, string, (UWORD)slen)/2;
x = -len;
y = font1->Baseline/2;
RotatePoint(x,y,alfa, screen->Width>>1, screen->Height>>1);
SetVFont(RPort, font1);
ScreenToFront(screen);
/* Rotate and zoom in on the string. */
do {
/* Do step 1 (see explanation above). */
AdjustFont(font2, (FIX)alfa*FIX_PI_256, (ULONG)FixToInt(ysize), string);
len = (long)VTextLength(font2, string, (UWORD)slen)/2;
Move(RPort, x, y);
x = -len;
y = font2->Baseline/2;
RotatePoint(x,y,alfa, screen->Width>>1, screen->Height>>1);
/* Do step 2. */
SetAPen(RPort, 0L);
VText(RPort, string, slen);
/* Do step 3. */
SetAPen(RPort, 1L);
Move(RPort, x, y);
SetVFont(RPort, font2);
VText(RPort, string, slen);
/* Do step 4. */
SwapFont(font1, font2);
alfa += 10;
ysize = ysize*105/100;
Chk_Abort();
} while ((len<200) && (ysize<IntToFix(200)));
/* Do some more rotation without the zooming. */
for (i=0; i<100; i++) {
AdjustFont(font2, (FIX)alfa*FIX_PI_256, (ULONG)FixToInt(ysize), string);
len = (long)VTextLength(font2, string, (UWORD)slen)/2;
Move(RPort, x, y);
x = -len;
y = font2->Baseline/2;
RotatePoint(x,y,alfa, screen->Width>>1, screen->Height>>1);
SetAPen(RPort, 0L);
VText(RPort, string, slen);
SetAPen(RPort, 1L);
Move(RPort, x, y);
SetVFont(RPort, font2);
VText(RPort, string, slen);
SwapFont(font1, font2);
alfa += 10;
Chk_Abort();
}
_abort();
}