home *** CD-ROM | disk | FTP | other *** search
- /* 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();
- }
-