home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Milan_1991 / Devcon91.2 / Bullet / prtface.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-01  |  9.7 KB  |  367 lines

  1. /*
  2. **    $Id$
  3. **
  4. **      prtface typeface print utility
  5. **
  6. **      (C) Copyright 1991 Robert R. Burns
  7. **          All Rights Reserved
  8. */
  9. #ifdef   DEBUG
  10. #define  D(a)    printf a
  11. #else
  12. #define  D(a)
  13. #endif
  14. #include <exec/types.h>
  15. #include <dos/rdargs.h>
  16. #include <graphics/rastport.h>
  17. #include <graphics/view.h>
  18. #include "libraries/diskfonttag.h"
  19. #include "libraries/glyph.h"
  20.  
  21. #include <clib/exec_protos.h>
  22. #include <clib/dos_protos.h>
  23. #include <clib/graphics_protos.h>
  24. #include <clib/utility_protos.h>
  25. #include <clib/diskfont_protos.h>
  26. #include "clib/bullet_protos.h"
  27. #include <pragmas/exec_pragmas.h>
  28. #include <pragmas/dos_pragmas.h>
  29. #include <pragmas/graphics_pragmas.h>
  30. #include <pragmas/utility_pragmas.h>
  31. #include <pragmas/diskfont_pragmas.h>
  32. #include "pragmas/bullet_pragmas.h"
  33.  
  34. #include <math.h>
  35. #include <string.h>
  36. #undef    strchr
  37. #undef    strcmp
  38. #undef    strcpy
  39. #undef    strrchr
  40. #undef    memset
  41.  
  42. extern struct Library *SysBase;
  43. extern struct Library *DOSBase;
  44.  
  45. extern struct RastPort PrinterRP;
  46. extern WORD MaxX, MaxY, DPIX, DPIY;
  47.  
  48. #define  TEMPLATE    "NAME,ALL/S"
  49.  
  50. #define  O_NAME        0
  51. #define  O_ALL        1
  52. #define  O_COUNT    2
  53.  
  54. #define  MAXFILESIZE    4000
  55.  
  56. struct Library *GfxBase = 0;
  57. struct Library *UtilityBase = 0;
  58. struct Library *DiskfontBase = 0;
  59. struct RDArgs *RDArgs = 0;
  60. BPTR OTFile = 0;
  61. struct Library *BulletBase = 0;
  62. struct GlyphEngine *GlyphEngine = 0;
  63. struct TagItem OTags[MAXFILESIZE / sizeof(struct TagItem)];
  64. PLANEPTR Template = 0;
  65. struct TextFont *FFont = 0;
  66.  
  67. void
  68. endGame(format, arg1, arg2, arg3, arg4)
  69. char *format, *arg1, *arg2, *arg3, *arg4;
  70. {
  71.     if (format) {
  72.     D((format, arg1, arg2, arg3, arg4));
  73.     printf(format, arg1, arg2, arg3, arg4);
  74.     }
  75.     if (Template)
  76.     FreeRaster(Template, DPIX, DPIY);
  77.     if (GlyphEngine)
  78.     CloseEngine(GlyphEngine);
  79.     if (BulletBase)
  80.     CloseLibrary(BulletBase);
  81.     if (OTFile)
  82.     Close(OTFile);
  83.     if (RDArgs)
  84.     FreeArgs(RDArgs);
  85.     if (DiskfontBase)
  86.     CloseLibrary(DiskfontBase);
  87.     if (UtilityBase)
  88.     CloseLibrary(UtilityBase);
  89.     ClosePrinter();
  90.     if (FFont)
  91.     CloseFont(FFont);
  92.     if (GfxBase)
  93.     CloseLibrary(GfxBase);
  94.     if (format)
  95.     exit(5);
  96.     exit(0);
  97. }
  98.  
  99.  
  100. ULONG
  101. setInfo(ge, tag)
  102. struct GlyphEngine *ge;
  103. LONG tag;
  104. {
  105.     return (SetInfoA(ge, (struct TagItem *) & tag));
  106. }
  107.  
  108. ULONG
  109. obtainInfo(ge, tag)
  110. struct GlyphEngine *ge;
  111. LONG tag;
  112. {
  113.     return (ObtainInfoA(ge, (struct TagItem *) & tag));
  114. }
  115.  
  116. ULONG
  117. releaseInfo(ge, tag)
  118. struct GlyphEngine *ge;
  119. LONG tag;
  120. {
  121.     return (ReleaseInfoA(ge, (struct TagItem *) & tag));
  122. }
  123.  
  124. void
  125. main()
  126. {
  127.     struct GlyphMap *glyph;
  128.     ULONG result, *options[O_COUNT];
  129.     int i, x, ux, uy, dx, dy, pageNo;
  130.     ULONG pointHeight;
  131.     ULONG chId;
  132.     char pathStore[256], *filePath, *s, pageFilled, colFilled, legend[8];
  133.     struct TTextAttr tta;
  134.     struct TagItem tags[3];
  135.  
  136.     D(("Test\nOpenLibrarys..."));
  137.     GfxBase = OpenLibrary("graphics.library", 0);
  138.     if (!GfxBase)
  139.     endGame("ERROR: cannot open \"graphics.library\"\n");
  140.     if (OpenPrinter())
  141.     endGame("ERROR: cannot open \"printer.device\"\n");
  142.     UtilityBase = OpenLibrary("utility.library", 0);
  143.     if (!UtilityBase)
  144.     endGame("ERROR: cannot open \"utility.library\"\n");
  145.     DiskfontBase = OpenLibrary("diskfont.library", 0);
  146.     if (!DiskfontBase)
  147.     endGame("ERROR: cannot open \"diskfont.library\"\n");
  148.     D(("ReadArgs..."));
  149.     memset(options, 0, sizeof(options));
  150.     RDArgs = ReadArgs(TEMPLATE, (LONG *) options, 0);
  151.     if (!RDArgs)
  152.     endGame("ERROR: invalid arguments\n");
  153.  
  154.     D((" .\n"));
  155.     /* generate .otag file path */
  156.     strcpy(pathStore, "FONTS:");
  157.     filePath = pathStore + 6;
  158.     if (options[0])
  159.     strcpy(filePath, (char *) options[O_NAME]);
  160.     else
  161.     strcpy(filePath, "LetterGothic.font");
  162.     s = strrchr(filePath, '.');
  163.     if ((s == 0) || (strcmp(s, ".font")))
  164.     endGame("ERROR: NAME not .font name\n");
  165.  
  166.     strcpy(s, OTSUFFIX);
  167.  
  168.     D((".otag file \"%s\"\n", filePath));
  169.     /* open .otag file */
  170.     OTFile = Open(filePath, MODE_OLDFILE);
  171.     if (!OTFile) {
  172.     if (!strchr(filePath, ':')) {
  173.         filePath = pathStore;
  174.         OTFile = Open(filePath, MODE_OLDFILE);
  175.     }
  176.     }
  177.  
  178.     if (!OTFile)
  179.     endGame("no font file \"%s\"\n", filePath);
  180.  
  181.     strcpy(s, ".font");
  182.     D((".font file \"%s\"\n", filePath));
  183.  
  184.     /* read and verify the .otag */
  185.     if (Read(OTFile, OTags, sizeof(struct TagItem)) != sizeof(struct TagItem))
  186.     endGame("OTFile read fail (8 bytes)\n");
  187.  
  188.     if (OTags[0].ti_Tag != OT_FileIdent)
  189.     endGame(".otag first tag $%lx, not $%lx\n", OTags[0].ti_Tag,
  190.         OT_FileIdent);
  191.  
  192.     Seek(OTFile, 0, OFFSET_END);
  193.     if (Seek(OTFile, 0, OFFSET_BEGINNING) != OTags[0].ti_Data)
  194.     endGame(".otag file size wrong\n");
  195.  
  196.     if (OTags[0].ti_Data > MAXFILESIZE)
  197.     endGame(".otag file size %ld larger than program maximum %ld\n",
  198.         OTags[0].ti_Data, MAXFILESIZE);
  199.  
  200.     /* this is a valid .otag file header, read it */
  201.     if (Read(OTFile, OTags, OTags[0].ti_Data) != OTags[0].ti_Data)
  202.     endGame(".otag read failure\n");
  203.  
  204.     /* patch indirect pointers */
  205.     for (i = 0; i < OTags[0].ti_Data / sizeof(struct TagItem); i++) {
  206.     if (OTags[i].ti_Tag == TAG_DONE)
  207.         break;
  208.     if (OTags[i].ti_Tag & OT_Indirect)
  209.         OTags[i].ti_Data += (ULONG) OTags;
  210.     }
  211.  
  212.     /* ensure the associated glyph library is open */
  213.     /* get the library name */
  214.     s = (char *) GetTagData(OT_Engine, 0, OTags);
  215.     if (!s)
  216.     endGame("no OT_Engine tag\n");
  217.  
  218.     if (strcmp(s, "bullet"))
  219.     endGame("OT_Engine not \"bullet\" but \"%s\"\n", s);
  220.  
  221.     BulletBase = OpenLibrary("bullet.library", 0);
  222.     if (!BulletBase)
  223.     endGame("OpenLibrary \"bullet.library\" failed\n");
  224.  
  225.     GlyphEngine = OpenEngine();
  226.  
  227.     if (!GlyphEngine)
  228.     endGame("OpenEngine failed\n");
  229.  
  230.     result = setInfo(GlyphEngine, OT_OTagPath, filePath, TAG_DONE);
  231.     if (result)
  232.     endGame("setInfo(OTagPath) result %ld\n", result);
  233.  
  234.     result = setInfo(GlyphEngine, OT_OTagList, OTags, TAG_DONE);
  235.     if (result)
  236.     endGame("setInfo(OTagList) result %ld\n", result);
  237.  
  238.     uy = (MaxY - 1) / 17;        /* 17 vertical box units */
  239.     ux = uy * DPIX / DPIY;        /* ? horizontal box units */
  240.     pointHeight = ((uy * 36) << 16) / DPIY;    /* 1/2 vertical box height */
  241.  
  242.     D(("ux %ld uy %ld, pointHeight $%08lx\n", uy, ux, pointHeight));
  243.  
  244.     if (result = setInfo(GlyphEngine, OT_PointHeight, pointHeight,
  245.             OT_DeviceDPI, (DPIX << 16) | DPIY, TAG_DONE))
  246.     endGame("setInfo(20 points) failed %ld\n", result);
  247.  
  248.     /* get labeling font */
  249.     tags[0].ti_Tag = OT_DeviceDPI;
  250.     tags[0].ti_Data = (DPIX << 16) | DPIY;
  251.     tags[1].ti_Tag = OT_PointHeight;
  252.     tags[1].ti_Data = pointHeight / 2;
  253.     tags[2].ti_Tag = TAG_DONE;
  254.     tta.tta_Name = "LetterGothic.font";
  255.     tta.tta_YSize = 0;
  256.     tta.tta_Flags = 0;
  257.     tta.tta_Style = FSF_TAGGED;
  258.     tta.tta_Tags = tags;
  259.     FFont = OpenDiskFont((struct TextAttr *) & tta);
  260.     if (!FFont)
  261.     endGame("OpenDiskFont failed\n");
  262.     SetFont(&PrinterRP, FFont);
  263.  
  264.     Template = AllocRaster(DPIX, DPIY);
  265.     if (!Template)
  266.     endGame("AllocRaster failed\n");
  267.  
  268.     *strrchr(filePath, '.') = '\0';    /* get rid of .font */
  269.     filePath = FilePart(filePath);
  270.     pageNo = 0;
  271.     chId = 0;
  272.     SetAPen(&PrinterRP, 1);
  273.     SetDrMd(&PrinterRP, JAM1);
  274.     do {
  275.     pageFilled = 0;
  276.     x = ux / 2;
  277.     SetRast(&PrinterRP, 0);
  278.     do {
  279.         colFilled = 0;
  280.         do {
  281.         if (chId == 0x3000)
  282.             chId = 0xe800;
  283.         if (result = setInfo(GlyphEngine, OT_GlyphCode, chId, TAG_DONE))
  284.             endGame("setInfo() failed %ld\n", result);
  285.         if (!obtainInfo(GlyphEngine, OT_GlyphMap, &glyph, TAG_DONE)) {
  286.             dx = x + ux / 4 +
  287.                 (glyph->glm_XOrigin >> 16) + glyph->glm_BlackLeft;
  288.             dy = ((chId & 0xf) + 2) * uy - ux / 4 -
  289.                 (glyph->glm_YOrigin >> 16) + glyph->glm_BlackTop;
  290.             for (i = (glyph->glm_BMRows * glyph->glm_BMModulo / 4) - 1;
  291.                 i >= 0; i--)
  292.             ((ULONG *) Template)[i] =
  293.                 ((ULONG *) glyph->glm_BitMap)[i];
  294.             BltTemplate(((char *) Template) +
  295.                 (glyph->glm_BlackTop * glyph->glm_BMModulo) +
  296.                 ((glyph->glm_BlackLeft / 16) * 2),
  297.                 glyph->glm_BlackLeft & 0xf,
  298.                 glyph->glm_BMModulo, &PrinterRP, dx, dy,
  299.                 glyph->glm_BlackWidth, glyph->glm_BlackHeight);
  300.             releaseInfo(GlyphEngine, OT_GlyphMap, glyph, TAG_DONE);
  301.             colFilled = 1;
  302.         }
  303.         chId++;
  304.         }
  305.         while (((!colFilled) || (chId & 0xf)) &&
  306.             (chId < (options[O_ALL] ? 0x10000 : 0x0370)));
  307.         if (colFilled) {
  308.         /* fill in the top of this column */
  309.         Move(&PrinterRP, x + ((ux - 4 * FFont->tf_XSize) / 2),
  310.             uy / 2 + (uy / 2 - FFont->tf_YSize) / 2 +
  311.             FFont->tf_Baseline);
  312.         sprintf(legend, "%03X", (chId - 1) >> 4);
  313.         D(("colFilled %s_\n", legend));
  314.         legend[3] = '_';
  315.         Text(&PrinterRP, legend, 4);
  316.         /* draw vertical left hash mark */
  317.         if (pageFilled)
  318.             Move(&PrinterRP, x, uy / 2);
  319.         else
  320.             Move(&PrinterRP, x, 0);
  321.         Draw(&PrinterRP, x, MaxY - 1);
  322.         pageFilled = 1;
  323.         x += ux;
  324.         }
  325.     }
  326.     while (((x + ux) < (MaxX - 1)) &&
  327.         (chId < (options[O_ALL] ? 0x10000 : 0x0370)));
  328.  
  329.     if (pageFilled) {
  330.         D(("pageFilled\n"));
  331.         /* draw last vertical right hash mark */
  332.         Move(&PrinterRP, x, 0);
  333.         Draw(&PrinterRP, x, MaxY - 1);
  334.  
  335.         for (i = 0; i < 16; i++) {
  336.         /* fill in left legends */
  337.         Move(&PrinterRP, 0, (i + 1) * uy +
  338.             (uy - FFont->tf_YSize) / 2 + FFont->tf_Baseline);
  339.         sprintf(legend, "%X", i);
  340.         Text(&PrinterRP, legend, 1);
  341.         /* fill in horizontal top hash marks */
  342.         Move(&PrinterRP, ux / 2, (i + 1) * uy);
  343.         Draw(&PrinterRP, x, (i + 1) * uy);
  344.         }
  345.  
  346.         /* fill in last horizontal bottom hash marks */
  347.         Move(&PrinterRP, ux / 2, 17 * uy);
  348.         Draw(&PrinterRP, x, 17 * uy);
  349.  
  350.         /* label the typeface */
  351.         Move(&PrinterRP, ux,
  352.             (uy / 2 - FFont->tf_YSize) / 2 + FFont->tf_Baseline);
  353.         Text(&PrinterRP, filePath, strlen(filePath));
  354.  
  355.         sprintf(legend, "Page %2d", ++pageNo);
  356.         Move(&PrinterRP, x - ux / 2 -
  357.             TextLength(&PrinterRP, legend, strlen(legend)),
  358.             (uy / 2 - FFont->tf_YSize) / 2 + FFont->tf_Baseline);
  359.         Text(&PrinterRP, legend, strlen(legend));
  360.         /* print this page */
  361.         Print();
  362.     }
  363.     }
  364.     while (chId < (options[O_ALL] ? 0x10000 : 0x0370));
  365.     endGame(0);
  366. }
  367.