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 >
C/C++ Source or Header  |  1991-06-09  |  12KB  |  371 lines

  1. /* Copyright 1991 by Michael Jansson, All rights reserved.
  2.  
  3.  NAME:  Rotate
  4.  USAGE: Rotate [-q] <font name> <text string>
  5.  VERSION: 1.2
  6.  
  7. This is a small program that will display a text string that is both
  8. rotating and changing size.  It is a typical example of the use of the
  9. vfont.library functions:  OpenVFont, ChangeVFont and VText.  
  10. Use the -q switch only if you are running under OS 2.0+. It will make
  11. this program run faster.
  12.  
  13. The program opens a screen and a window in a normal intuition fashion. 
  14. Then it opens two font instances of the same font class, which are used
  15. in a double-buffering fashion. This is done by:
  16.  1) changing size and direction of one font
  17.  2) erase the previous rendered text by using the previously 
  18.     used font and render in the background color
  19.  3) render the text with the font that was changed during step 1
  20.  4) Swap the fonts so that step 1 will change the old font etc.
  21.  5) start all over with step 1 again...
  22. The time when the screen is blank will be very short (between step 2 
  23. and 3) since the previously used font and the new font will both have 
  24. all used character of the string cached (at least when the characters
  25. are sufficiently small). It will therefor give a steady impression and 
  26. not a flicker.
  27. */
  28.  
  29. #include <intuition/intuition.h>
  30. #include <intuition/screens.h>
  31. #include <clib/dos_protos.h>
  32. #include <clib/exec_protos.h>
  33. #include <clib/intuition_protos.h>
  34. #include <clib/graphics_protos.h>
  35. #include <pragmas/dos.h>
  36. #include <pragmas/exec.h>
  37. #include <pragmas/intuition.h>
  38. #include <pragmas/graphics.h>
  39. #include <math.h>
  40. #include <stdio.h>
  41. #include <time.h>
  42. #include <ctype.h>
  43. #include <vfont/curve.h>
  44. #include <vfont/vfont.h>
  45. #include <clib/vfontlib.pro>
  46. #include <pragmas/vfontlib.pra>
  47.  
  48. /* Some constans in the fixpoint format. */
  49. #define FIX_PI_256  1608
  50. #define PI_256  0.024543692
  51.  
  52. /* Some macros. (It's done this way to improve the readability of the code). */
  53. #define SwapFont(f1, f2)    {VFont *f3=f1; f1=f2; f2=f3;}
  54. #define RotatePoint(x,y,angle,ox,oy)    {long tx,ty;\
  55.     tx = costab[angle]*(x) - sintab[angle]*(y);     \
  56.     ty = costab[angle]*(y) + sintab[angle]*(x);     \
  57.     x = tx/FIXOFFSET+(ox);                          \
  58.     y = ty/FIXOFFSET+(oy);                          \
  59. }
  60. #define MyPutS(str)     Write(Output(), str "\n", (long)strlen(str)+1L)
  61.  
  62.  
  63. /* This is the parameter that is used when the font is opened.
  64.    It is very similar to the intuition.library structure TextAttr.
  65.    The TextAttr is distinguished from a TextVAttr (notice the 
  66.    extra "V" in the name) by the one bit flag  VectorFont, which
  67.    corresponds to the sign bit of the ta_YSize field of the TextAttr 
  68.    structure. You may use a plain TextAttr if you are satisfied with
  69.    the default values for the vector font extension of the structure
  70.    when you open a font with the OpenVFont function.
  71.  
  72.    The width or the height may be set to zero to indicate that you
  73.    want the default width or height. The library will then set it so 
  74.    that the proportions will be preserved, e.g. a 32x16 large font class
  75.    opened as a 64x0 large font will be set to be 64x32.
  76. */
  77. TextVAttr tattr = {
  78.     (UBYTE *)"vwire.font",      /* The name of the class. */
  79.     32,                         /* The height */
  80.     1,                          /* It is a vector font. */
  81.     FS_NORMAL,                  /* The style. */
  82.     FPF_DESIGNED|FPF_DISKFONT,  /* The flags. */
  83.  
  84.     /* The field below are specific for vector fonts. */
  85.     (UBYTE *)"John",            /* Our name for this font instance. */
  86.                                 /*      Default: An unique name is created. */
  87.     0,                          /* Initial width. */
  88.                                 /*      Default: 0, i.e. default width. */
  89.                                 /* VFlags. */
  90.     VFB_VERBOSE |               /*  Let the library inform the user when error occurs. */
  91.     VFB_EXCLUSIVE |             /*  Don't let others use the font. */
  92.     VFB_ANYSIZE                 /*  Use font class with any size. */
  93. };
  94.  
  95.  
  96.  
  97. /* Some intuition structure used when opening the screen and the window. */
  98.  
  99. #define ProgramName (UBYTE *)"Rotate v1.2 - Copyright 1991 by Michael Jansson"
  100. #define width 640L
  101. #define height 512L            /* Change this to 400 for NTSC. */
  102.  
  103. struct NewScreen newscreen = {
  104.     0,0,width,height,1,         /* Screen dimensions. */
  105.     0,-1,                       /* Pen colors. */
  106.     LACE|HIRES,                 /* View modes. */
  107.     CUSTOMSCREEN,               /* Screen type. */
  108.     NULL,                       /* Default screen font (none). */
  109.     ProgramName,                /* Screen title. */
  110.     NULL,                       /* Gadgets (none). */
  111.     NULL                        /* CustomBitMap (none). */
  112. };
  113.  
  114. struct NewWindow newwindow = {
  115.     0,0,width,height,           /* Window dimensions. */
  116.     0,-1,                       /* Pen colors. */
  117.     0UL,                        /* IDCMPFlags (none). */
  118.         SIMPLE_REFRESH |        /* Flags. (We want a really simple window). */
  119.         NOCAREREFRESH |
  120.         BORDERLESS,
  121.     NULL,                       /* Gadgets. (none). */
  122.     NULL,                       /* Check mark. (none). */
  123.     ProgramName,                /* Title. */
  124.     NULL,                       /* Screen (set it to our screen when it is open). */
  125.     NULL,                       /* BitMap. (none). */
  126.     0,0,width,height,           /* Min/Max dimensions. */
  127.     CUSTOMSCREEN                /* Window type. */
  128. };
  129.  
  130. /* Library names. */
  131. #define INTUITION   (UBYTE *)"intuition.library"
  132. #define GRAPHICS    (UBYTE *)"graphics.library"
  133. #define VFONTS      (UBYTE *)"vfont.library"
  134.  
  135. /* The size of the AreInfo buffer (Intuition stuff). */
  136. #define AREABUFFSIZE 1000L
  137. #define AREABUFFSIZE5 5000L
  138.  
  139. /* Global data. */
  140. UBYTE myBuffer[AREABUFFSIZE5];
  141. struct AreaInfo myArea;
  142. struct TmpRas myTmpRas;
  143.  
  144. /* Global data that is allocated/opened. */
  145. struct Library *IntuitionBase = NULL;
  146. struct Library *vFontBase = NULL;
  147. struct Library *GfxBase = NULL;
  148. struct Screen *screen = NULL;
  149. struct Window *window = NULL;
  150. PLANEPTR myPlane = NULL;
  151. VFont *font1 = NULL, *font2 = NULL;
  152.  
  153. /* 
  154.     Function that will deallocate the used resources. 
  155. */
  156. void
  157. _abort(void)
  158. {
  159.     if (font1)
  160.            CloseVFont(font1);
  161.     if (font2)
  162.            CloseVFont(font2);
  163.     if (myPlane)
  164.         FreeRaster(myPlane, width, height);
  165.     if (window)
  166.         CloseWindow(window);
  167.     if (screen)
  168.         CloseScreen(screen);
  169.     if (vFontBase)
  170.         CloseLibrary(vFontBase);
  171.     if (IntuitionBase)
  172.         CloseLibrary(IntuitionBase);
  173.     if (GfxBase)
  174.         CloseLibrary(GfxBase);
  175.     exit(0L);
  176. }
  177.  
  178.  
  179. /*
  180.     This function changes the rendering direction, the character orientation
  181.     and the size of a font. This is done by calling the ChangeVFont function. 
  182. */
  183. void
  184. AdjustFont(VFont *font, FIX alfa, ULONG ysize, UBYTE *string)
  185. {
  186.     VFont req;
  187.  
  188.     /* Fill in a template with the values that we want to use in the */
  189.     /* font and call ChangeVFont() to alter the font. */
  190.     req.AlfaPath = alfa;
  191.     req.UpVector = alfa;
  192.     req.YSize = ysize;
  193.     req.XSize = 0; /* Use default size. */
  194.     ChangeVFont(font, (UBYTE)(VCM_PATH|VCM_UP|VCM_SIZE), &req, (long)FALSE);
  195.     do {
  196.         MakeChar(font, font->Class, *string);
  197.     } while(*++string);
  198. }
  199.  
  200.  
  201. /*
  202.     This is the main part of the program.
  203. */
  204. void
  205. main(int argc, UBYTE **argv)
  206. {
  207.     struct RastPort *RPort;
  208.     FIX sintab[256];
  209.     FIX costab[256];
  210.     FIX ysize = IntToFix(4);
  211.     long x,y,len,slen;
  212.     UBYTE *string, alfa = 0;
  213.     BOOL quick_flg = FALSE;
  214.     short i;
  215.  
  216.     /* Process the CLI parameters. */
  217.     if (argc<3) {
  218.         MyPutS("Usage: rotate [-q] font textstring");
  219.         MyPutS("Example: rotate emerald \"A string\"");
  220.         string = (UBYTE *)"vFont 2.0 (Rotate 1.2)";
  221.     } else {
  222.         if (argv[1][0]=='-' && tolower(argv[1][1])=='q') {
  223.             if (argc<4) {
  224.                 MyPutS("Bad parameters! Try: rotate [-q] font textstring");
  225.                 string = (UBYTE *)"vFont 2.0 (Rotate 1.2)";
  226.             } else {
  227.                 quick_flg = TRUE;
  228.                 tattr.Name = argv[2];
  229.                 string = argv[3];
  230.             }
  231.         } else {
  232.             quick_flg = FALSE;
  233.             tattr.Name = argv[1];
  234.             string = argv[2];
  235.         }
  236.     }
  237.  
  238.     /* Open the needed libraries. */
  239.     if (!(IntuitionBase = OpenLibrary(INTUITION, 0L))
  240.     || !(GfxBase = OpenLibrary(GRAPHICS, 0L))
  241.     || !(vFontBase = OpenLibrary(VFONTS, 0L))) {
  242.         MyPutS("Can't open the vfont libarary.");
  243.         _abort();
  244.     }
  245.  
  246.     /* Open the first font by using a TextVAttr (or TextAttr) structure. */
  247.     if ((font1 = OpenVFont(&tattr))==NULL) {
  248.         MyPutS("Didn't manage to open that font.");
  249.         _abort();
  250.     }
  251.     /* Open the second font. */
  252.     if ((font2 = OpenVFont(&tattr))==NULL) {
  253.         MyPutS("Didn't manage to open that font.");
  254.         _abort();
  255.     }
  256.  
  257.     /* Open a screen. */
  258.     if (!(screen = OpenScreen(&newscreen))) {
  259.         MyPutS("Couldn't open screen.");
  260.         _abort();
  261.     }
  262.  
  263. /*
  264.     It is faster to render in a screen's rastport than to render in a window's
  265.     rastport, since a window contains a layer that many renderings is clipped
  266.     against (including redering done by the vfont library).
  267.  
  268.     VText will unfortunately not work on an un-layered rastport under OS 1.2-1.3 
  269.     due to a fault graphics library function, which is fixed under OS 2.0+
  270. */
  271.     if (quick_flg) 
  272.          RPort = &screen->RastPort;
  273.     else {
  274.  
  275.         /* Open a window. */
  276.         newwindow.Screen = screen;
  277.         if (!(window=OpenWindow(&newwindow))) {
  278.             MyPutS("Failed to open a window.");
  279.             _abort();
  280.         }
  281.          RPort = window->RPort;
  282.     }
  283.     SetDrMd(RPort, (long)JAM1);
  284.  
  285.  
  286. /*
  287.     The vfont.library function VText uses the graphics.library
  288.     functions AreaDraw/Move/End. They, in turn, requires that you
  289.     add some data structures to the rastport, known as the AreInfo
  290.     and the TmpRast structures.
  291. */
  292.     /* Add a TmpRas. */
  293.     if (!(myPlane=AllocRaster(width, height)))
  294.         _abort();
  295.     InitTmpRas(&myTmpRas, myPlane, (long)RASSIZE(width, height));
  296.     RPort->TmpRas = &myTmpRas;
  297.  
  298.     /* Add a AreaInfo. */
  299.     InitArea(&myArea, myBuffer, AREABUFFSIZE);
  300.     RPort->AreaInfo = &myArea;
  301.  
  302.  
  303.     /* Build the sin and the cos tables to speed up the rendering. */
  304.     for (i=0; i<256; i++) {
  305.         sintab[i] = FloatToFix(sin(PI_256*i));
  306.         costab[i] = FloatToFix(cos(PI_256*i));
  307.     }
  308.  
  309.     /* Initiate some variables. */
  310.     slen = strlen(string);
  311.     AdjustFont(font1, (FIX)alfa*FIX_PI_256, (ULONG)FixToInt(ysize), string);
  312.     len = (long)VTextLength(font1, string, (UWORD)slen)/2;
  313.     x = -len;
  314.     y = font1->Baseline/2;
  315.     RotatePoint(x,y,alfa, screen->Width>>1, screen->Height>>1);
  316.     SetVFont(RPort, font1);
  317.  
  318.     ScreenToFront(screen);
  319.  
  320.     /* Rotate and zoom in on the string. */
  321.     do {
  322.         /* Do step 1 (see explanation above). */
  323.         AdjustFont(font2, (FIX)alfa*FIX_PI_256, (ULONG)FixToInt(ysize), string);
  324.         len = (long)VTextLength(font2, string, (UWORD)slen)/2;
  325.         Move(RPort, x, y);
  326.         x = -len;
  327.         y = font2->Baseline/2;
  328.         RotatePoint(x,y,alfa, screen->Width>>1, screen->Height>>1);
  329.  
  330.         /* Do step 2. */
  331.         SetAPen(RPort, 0L);
  332.         VText(RPort, string, slen);
  333.  
  334.         /* Do step 3. */
  335.         SetAPen(RPort, 1L);
  336.         Move(RPort, x, y);
  337.         SetVFont(RPort, font2);
  338.         VText(RPort, string, slen);
  339.  
  340.         /* Do step 4. */
  341.         SwapFont(font1, font2);
  342.  
  343.         alfa += 10;
  344.         ysize = ysize*105/100;
  345.  
  346.         Chk_Abort();
  347.  
  348.     } while ((len<200) && (ysize<IntToFix(200)));
  349.  
  350.     /* Do some more rotation without the zooming. */
  351.     for (i=0; i<100; i++) {
  352.         AdjustFont(font2, (FIX)alfa*FIX_PI_256, (ULONG)FixToInt(ysize), string);
  353.         len = (long)VTextLength(font2, string, (UWORD)slen)/2;
  354.         Move(RPort, x, y);
  355.         x = -len;
  356.         y = font2->Baseline/2;
  357.         RotatePoint(x,y,alfa, screen->Width>>1, screen->Height>>1);
  358.         SetAPen(RPort, 0L);
  359.         VText(RPort, string, slen);
  360.         SetAPen(RPort, 1L);
  361.         Move(RPort, x, y);
  362.         SetVFont(RPort, font2);
  363.         VText(RPort, string, slen);
  364.         SwapFont(font1, font2);
  365.         alfa += 10;
  366.         Chk_Abort();
  367.     }
  368.  
  369.     _abort();
  370. }
  371.