home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Washington_1988 / DevCon88.1 / AmigaTechniques / dfont2obj.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  13.8 KB  |  461 lines

  1. /****** DFont2Obj ****************************************************
  2. *
  3. *   NAME
  4. *       DFont2Obj - create a load file from a LoadSeg'd diskfont image
  5. *
  6. *   A hack, nothing more
  7. *  Copyright (c) 1988 Commodore-Amiga, Inc.
  8. *  Executables based on this information may be used in software
  9. *  for Commodore Amiga computers.  All other rights reserved.
  10. *  This information is provided "as is"; no warranties are made.
  11. *  All use is at your own risk, and no liability or responsibility is assumed.
  12. *********************************************************************/
  13. #include        "exec/types.h"
  14. #include        "exec/nodes.h"
  15. #include        "exec/lists.h"
  16. #include        "exec/memory.h"
  17. #include        "exec/ports.h"
  18. #include    "graphics/gfxbase.h"
  19. #include    "graphics/text.h"
  20. #include    "graphics/view.h"
  21. #include        "libraries/dos.h"
  22. #include    "libraries/diskfont.h"
  23.  
  24. #include    "stdio.h"
  25.  
  26. #ifdef    MANX
  27. #include    "functions.h"
  28. #endif
  29.  
  30. #define    HUNK_DATA    1002
  31. #define    HUNK_RELOC32    1004
  32. #define    HUNK_END    1010
  33. #define    HUNK_HEADER    1011
  34.  
  35. #ifndef    ColorTextFont
  36. #define    FSB_COLORFONT    6    /* this uses ColorTextFont structure */
  37. #define    FSF_COLORFONT    0x40
  38.  
  39. /******    ColorTextFont node ******************************************/
  40. /*-----    ctf_Flags --------------------------------------------------*/
  41. #define    CT_COLORMASK    0x000F    /* mask to get to following color styles */
  42. #define    CT_COLORFONT    0x0001    /* color map contains designer's colors */
  43. #define    CT_GREYFONT    0x0002    /* color map describes even-stepped */
  44.                 /* brightnesses from low to high */
  45. #define    CTB_MAPCOLOR    0    /* map ctf_FgColor to the rp_FgPen if it's */
  46. #define    CTF_MAPCOLOR    0x0001    /* is a valid color within ctf_Low..ctf_High */
  47.  
  48. /*-----    ColorTextFont ----------------------------------------------*/
  49. struct ColorTextFont {
  50.     struct TextFont ctf_TF;
  51.     UWORD    ctf_Flags;    /* extended flags */
  52.     UBYTE    ctf_Depth;    /* number of bit planes */
  53.     UBYTE    ctf_FgColor;    /* color that is remapped to FgPen */
  54.     UBYTE    ctf_Low;    /* lowest color represented here */
  55.     UBYTE    ctf_High;    /* highest color represented here */
  56.     UBYTE    ctf_PlanePick;    /* PlanePick ala Images */
  57.     UBYTE    ctf_PlaneOnOff;    /* PlaneOnOff ala Images */
  58.     APTR    ctf_ColorMap;    /* struct ColorMap * for font */
  59.     APTR    ctf_CharData[8]; /*pointers to bit planes ala tf_CharData */
  60. };
  61. #endif
  62.  
  63. struct ColorTextFont *FindName();
  64. struct GfxBase *OpenLibrary();
  65.  
  66. ULONG *hunkBase;
  67. FILE *file = 0;
  68.  
  69. ULONG FindRelocate(hunkNum, relocation, absolute)
  70. ULONG *hunkNum, *relocation, *absolute;
  71. {
  72.     ULONG num;
  73.     ULONG *currHunk;
  74.  
  75.     if (*absolute == 0) {
  76.     *hunkNum = *relocation = 0xffffffff;
  77.     return(0);
  78.     }
  79.     /* find offset of this absolute and cache in relocation array */
  80.     *relocation = ((ULONG) absolute) - ((ULONG) &hunkBase[1]);
  81.     /* find hunk and offset in hunk that this absolute points to */
  82.     num = 0;
  83.     currHunk = hunkBase;
  84.     while (currHunk) {
  85.     if ((*absolute >= ((ULONG) &currHunk[1])) &&
  86.         (*absolute < (((ULONG) currHunk) + currHunk[-1]))) {
  87.         *hunkNum = num;
  88.         return(*absolute - ((ULONG) &currHunk[1]));
  89.     }
  90.     num++;
  91.     currHunk = (ULONG *) (*currHunk<<2);
  92.     }
  93.     printf("ERROR: Could not find address 0x%lx in any hunk\n", *absolute);
  94.     fclose(file);
  95.     exit(20);
  96. }
  97.  
  98.  
  99. int GetNum(b)
  100. char *b;
  101. {
  102.     int result, base;
  103.  
  104.     result = 0;
  105.     base = 10;
  106.     while (*b) {
  107.     result *= base;
  108.     if ((*b >= '0') && (*b <= '9')) result += *b - '0';
  109.     else {
  110.         if (((*b >= 'a') && (*b <= 'f')) ||
  111.             ((*b >= 'A') && (*b <= 'F'))) {
  112.         if (base != 16) break;
  113.         result += (*b & 0x1f) + 9;
  114.         }
  115.         else if ((*b != 'x') && (*b != '$')) base = 16;
  116.         else break;
  117.     }
  118.     b++;
  119.     }
  120.     if (*b) {
  121.     printf("ERROR: ill formed number\n");
  122.     return(-1);
  123.     }
  124.     else return(result);
  125. }
  126.  
  127.  
  128. main(argc, argv)
  129. int argc;
  130. char *argv[];
  131. {
  132.     struct GfxBase *GfxBase;
  133.     ULONG temp, temp2;
  134.     ULONG *currHunk;
  135.     struct ColorTextFont *ctf, *ctf2;
  136.     int i, j, k;
  137.  
  138.     /* relocation information about the pointers in hunk 0    */
  139.     /* dfh_DF ln_Name, tf_Message mn_Node ln_Name,        */
  140.     /* tf_CharData, tf_CharLoc, tf_CharSpace, tf_CharKern,    */
  141.     /* ctf_ColorMap, ctf_ColorMap ColorTable, ctf_CharData[8]    */
  142.     ULONG hunkNum[16];        /* hunk number to relocate to */
  143.     ULONG relocation[16];    /* offset in hunk */
  144.  
  145.     GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0L);
  146.     if (GfxBase == 0) {
  147.     printf("ERROR: Cannot open \"graphics.library\"\n");
  148.     exit(100);
  149.     }
  150.     if (argc >= 3) {
  151.     file = fopen(argv[1], "w");
  152.     if (file == 0) {
  153.         printf("ERROR: open failed for font file\n");
  154.         argc = 0;
  155.     }
  156.     }
  157.     if (argc >= 3) {
  158.       /* see if more than one with this name */
  159.       ctf = FindName(&GfxBase->TextFonts, argv[2]);
  160.       if (ctf) {
  161.         if (FindName(ctf, argv[2])) {
  162.           /* yes: get the one with this size */
  163.           if (argc >= 4) {
  164.             i = GetNum(argv[3]);
  165.             if (i >= 0) {
  166.               while ((ctf) && (ctf->ctf_TF.tf_YSize != i))
  167.                 ctf = FindName(ctf, argv[2]);
  168.               if (ctf) {
  169.                 /* check for more than one */
  170.                 ctf2 = FindName(ctf, argv[2]);
  171.                 while ((ctf2) && (ctf2->ctf_TF.tf_YSize != i))
  172.                   ctf2 = FindName(ctf2, argv[2]);
  173.                 if (ctf2) {
  174.                   /* yes: get the one with this style */
  175.           if (argc >= 5) {
  176.             j = GetNum(argv[4]);
  177.             if (j >= 0) {
  178.               ctf = FindName(&GfxBase->TextFonts, argv[2]);
  179.               while ((ctf) && ((ctf->ctf_TF.tf_YSize != i) ||
  180.               (ctf->ctf_TF.tf_Style != j)))
  181.             ctf = FindName(ctf, argv[2]);
  182.               if (ctf) {
  183.             /* check for more than one */
  184.             ctf2 = FindName(ctf, argv[2]);
  185.             while ((ctf2) && ((ctf2->ctf_TF.tf_YSize != i) ||
  186.                 (ctf2->ctf_TF.tf_Style != j)))
  187.               ctf2 = FindName(ctf2, argv[2]);
  188.             if (ctf2) {
  189.               /* yes: get the one with this flags */
  190.               if (argc >= 6) {
  191.                 k = GetNum(argv[5]);
  192.                 if (k >= 0) {
  193.                   ctf = FindName(&GfxBase->TextFonts, argv[2]);
  194.                   while ((ctf) && ((ctf->ctf_TF.tf_YSize != i) ||
  195.                   (ctf->ctf_TF.tf_Style != j) ||
  196.                   (ctf->ctf_TF.tf_Flags != k)))
  197.                 ctf = FindName(ctf, argv[2]);
  198.                   if (ctf) {
  199.                 /* check for more than one */
  200.                 ctf2 = FindName(ctf, argv[2]);
  201.                 while ((ctf2) && ((ctf2->ctf_TF.tf_YSize != i)
  202.                     || (ctf->ctf_TF.tf_Style != j) ||
  203.                     (ctf->ctf_TF.tf_Flags != k)))
  204.                   ctf2 = FindName(ctf2, argv[2]);
  205.                 if (ctf2) {
  206.                   printf("WARNING: There exists more than one font matching the specification.\n");
  207.                   printf("         The first one found is being used.\n");
  208.                                 }
  209.                   }
  210.                   else /* ctf */ {
  211.                 printf("ERROR: No font with the specified flags\n");
  212.                 argc = 0;
  213.                   }
  214.                 }
  215.                 else /* k */ argc = 0;
  216.               }
  217.               else /* argc */ {
  218.                 printf("ERROR: More than one font with the specified name, size, and style\n");
  219.                 argc = 0;
  220.               }
  221.             }
  222.               }
  223.               else /* ctf */ {
  224.                 printf("ERROR: No font with the specified flags\n");
  225.             argc = 0;
  226.               }
  227.             }
  228.             else /* j */ argc = 0;
  229.           }
  230.           else /* argc */ {
  231.             printf("ERROR: More than one font with the specified name, and size\n");
  232.             argc = 0;
  233.           }
  234.         }
  235.           }
  236.           else /* ctf */ {
  237.         printf("ERROR: No font with the specified size\n");
  238.         argc = 0;
  239.           }
  240.             }
  241.             else /* i */ argc = 0;
  242.           }
  243.           else /* argc */ {
  244.             printf("ERROR: More than one font with the specified name\n");
  245.             argc = 0;
  246.           }
  247.         }
  248.       }
  249.       else /* ctf */ {
  250.         printf("ERROR: No font with the specified name\n");
  251.         argc = 0;
  252.       }
  253.       CloseLibrary(GfxBase);
  254.     }
  255.     if (argc < 3) {
  256.     printf(
  257.       "USAGE: DFont2Obj <file> <font-name> [<size>] [<style>] [<flags>]\n");
  258.     if (file) fclose(file);
  259.     exit(5);
  260.     }
  261.     if ((ctf->ctf_TF.tf_Flags & FPF_DISKFONT) == 0) {
  262.     printf("ERROR: font must be a disk font\n");
  263.     fclose(file);
  264.     exit(10);
  265.     }
  266.     printf("\"%s\" Y %ld S $%02lx F $%02lx\n",
  267.         ctf->ctf_TF.tf_Message.mn_Node.ln_Name, ctf->ctf_TF.tf_YSize,
  268.         ctf->ctf_TF.tf_Style, ctf->ctf_TF.tf_Flags);
  269.     hunkBase = (ULONG *) ((ULONG) ctf - 62);
  270. printf("hunkBase 0x%lx\n", hunkBase);
  271.     /* hunk header */
  272.     temp = HUNK_HEADER;
  273.     fwrite(&temp, 1, 4, file);
  274.     /* resident library names */
  275.     temp = 0;
  276.     fwrite(&temp, 1, 4, file);
  277.     /* table size */
  278.     temp = 1;            /* include the hunk base */
  279.     currHunk = hunkBase;
  280.     while (*currHunk) {
  281.     temp++;
  282.     currHunk = (ULONG *) (*currHunk<<2);
  283.     }
  284.     fwrite(&temp, 1, 4, file);
  285.     /* first hunk (zero) */
  286.     fwrite(currHunk, 1, 4, file);
  287.     /* last hunk (size-1) */
  288.     temp--;
  289.     fwrite(&temp, 1, 4, file);
  290.     /* hunk sizes */
  291.     currHunk = hunkBase;
  292.     do {
  293.     temp = (currHunk[-1]>>2) - 2;
  294.     fwrite(&temp, 1, 4, file);
  295.     currHunk = (ULONG *) (*currHunk<<2);
  296.     }
  297.     while (currHunk);
  298.     /* write first hunk */
  299.     /*   write the hunk start */
  300.     temp = HUNK_DATA;
  301.     fwrite(&temp, 1, 4, file);
  302.     /*   write the hunk size */
  303.     temp = (hunkBase[-1]>>2) - 2;
  304.     fwrite(&temp, 1, 4, file);
  305.     /*   write MOVEQ #100,D0 / RTS */
  306.     temp = 0x70644e75;
  307.     fwrite(&temp, 1, 4, file);
  308.     /*   write dfh_DF ln_Succ, ln_Pred */
  309.     temp = 0;
  310.     for (i = 0; i < 8; i++) fwrite(&temp, 1, 1, file);
  311.     /*   write dfh_DF ln_Type, ln_Pri */
  312.     temp = 0x0c000c00;        /* NT_FONT */
  313.     fwrite(&temp, 1, 2, file);
  314.     /*   write dfh_DF ln_Name */
  315.     temp = 0x1a;        /* 8 + offset(dfh_Name) */
  316.     hunkNum[0] = 0;
  317.     relocation[0] = 0xe;    /* 8 + offset(dfh_DF ... Name) */
  318.     fwrite(&temp, 1, 4, file);
  319.     /*   write dfh_FileID, dfh_Revision */
  320.     temp = 0x0f800000;        /* DFH_ID, revision 0 */
  321.     fwrite(&temp, 1, 4, file);
  322.     /*   write dfh_Segment, dfh_Name */
  323.     temp = 0;
  324.     for (i = 0; i < (4+MAXFONTNAME); i++) fwrite(&temp, 1, 1, file);
  325.     /*   write tf_Message mn_Node ln_Succ, ln_Pred */
  326.     for (i = 0; i < 8; i++) fwrite(&temp, 1, 1, file);
  327.     /*   write tf_Message mn_Node ln_Type, ln_Pri */
  328.     temp = 0x0c000c00;        /* NT_FONT */
  329.     fwrite(&temp, 1, 2, file);
  330.     /*   write tf_Message mn_Node ln_Name */
  331.     temp = 0x1a;        /* 8 + offset(dfh_Name) */
  332.     hunkNum[1] = 0;
  333.     relocation[1] = 0x44;    /* 8 + offset(tf ... Name) */
  334.     fwrite(&temp, 1, 4, file);
  335.     /*   write tf_Message mn_ReplyPort, mn_Length */
  336.     temp = 0;
  337.     fwrite(&temp, 1, 4, file);
  338.     fwrite(&temp, 1, 2, file);
  339.     /*   write tf_YSize thru tf_BoldSmear */
  340.     fwrite(&ctf->ctf_TF.tf_YSize, 1, 10, file);
  341.     /*   write tf_Accessors */
  342.     fwrite(&temp, 1, 2, file);
  343.     /*   write tf_LoChar thru tf_HiChar */
  344.     fwrite(&ctf->ctf_TF.tf_LoChar, 1, 2, file);
  345.     /*   write tf_CharData */
  346.     temp = FindRelocate(hunkNum+2, relocation+2, &ctf->ctf_TF.tf_CharData);
  347.     fwrite(&temp, 1, 4, file);
  348.     /*   write tf_Modulo */
  349.     fwrite(&ctf->ctf_TF.tf_Modulo, 1, 2, file);
  350.     /*   write tf_CharLoc */
  351.     temp = FindRelocate(hunkNum+3, relocation+3, &ctf->ctf_TF.tf_CharLoc);
  352.     fwrite(&temp, 1, 4, file);
  353.     /*   write tf_CharSpace */
  354.     temp = FindRelocate(hunkNum+4, relocation+4, &ctf->ctf_TF.tf_CharSpace);
  355.     fwrite(&temp, 1, 4, file);
  356.     /*   write tf_CharKern */
  357.     temp = FindRelocate(hunkNum+5, relocation+5, &ctf->ctf_TF.tf_CharKern);
  358.     fwrite(&temp, 1, 4, file);
  359.     /*   check for ColorTextFont */
  360.     if (ctf->ctf_TF.tf_Style & FSF_COLORFONT) {
  361.     fwrite(&ctf->ctf_Flags, 1, 8, file);
  362.     /*   ctf_ColorMap */
  363.     temp = FindRelocate(hunkNum+6, relocation+6, &ctf->ctf_ColorMap);
  364.     fwrite(&temp, 1, 4, file);
  365.     if (temp != 0) {
  366.         if (temp != 0x9a) {
  367.         printf("ERROR: ColorMap not immediately after ColorTextFont\n");
  368.         fclose(file);
  369.         exit(20);
  370.         }
  371.         /* ctf_ColorMap ColorTable */
  372.         temp = FindRelocate(hunkNum+7, relocation+7,
  373.             &((struct ColorMap *) ctf->ctf_ColorMap)->ColorTable);
  374.         if (temp != 0xa2) {
  375.         printf("ERROR: ColorTable not immediately after ColorMap\n");
  376.         fclose(file);
  377.         exit(20);
  378.         }
  379.     }
  380.     else hunkNum[7] = relocation[7] = 0xffffffff;
  381.  
  382.     /*   ctf_Planes */
  383.     for (i = 0; i < ctf->ctf_Depth; i++) {
  384.         temp = FindRelocate(hunkNum+i+8, relocation+i+8,
  385.             &ctf->ctf_CharData[i]);
  386.         fwrite(&temp, 1, 4, file);
  387.     }
  388.     temp = 0;
  389.     for (; i < 8; i++) {
  390.         hunkNum[i+8] = relocation[i+8] = 0xffffffff;
  391.         fwrite(&temp, 1, 4, file);
  392.     }
  393.     temp = sizeof(struct DiskFontHeader) + 8 -
  394.         sizeof(struct TextFont) + sizeof(struct ColorTextFont);
  395.     /* write ctf_ColorMap ColorTable if appropriate */
  396.     if (ctf->ctf_ColorMap) {
  397.         fwrite(ctf->ctf_ColorMap, 1, 4, file);
  398.         temp2 = 0xa2;
  399.         fwrite(&temp2, 1, 4, file);
  400.         temp += 8;
  401.     }
  402.     }
  403.     else {
  404.     for (i = 6; i < 16; i++) hunkNum[i] = relocation[i] = 0xffffffff;
  405.     temp = sizeof(struct DiskFontHeader) + 8;
  406.     }
  407.     /*   write the rest of this first hunk */
  408.     if (hunkBase[-1] - temp) {
  409.     fwrite(((ULONG) hunkBase) + temp, 1, hunkBase[-1] - temp - 4, file);
  410.     }
  411.     /* write the relocation record for this hunk */
  412.     temp = HUNK_RELOC32;
  413.     fwrite(&temp, 1, 4, file);
  414.     for (;;) {
  415.     /* find the minimum hunk not yet referenced */
  416.     temp = 0xffffffff;
  417.     for (i = 0; i < 15; i++)
  418.         if (hunkNum[i] < temp) temp = hunkNum[i];
  419.     if (temp == 0xffffffff) break;
  420.     /* count the relocation entries */
  421.     temp2 = 0;
  422.     for (i = 0; i < 15; i++)
  423.         if (hunkNum[i] == temp) temp2++;
  424.     /* write the offset count */
  425.     fwrite(&temp2, 1, 4, file);
  426.     /* write the hunk number */
  427.     fwrite(&temp, 1, 4, file);
  428.     /* write out all the matching relocation values */
  429.     for (i = 0; i < 15; i++)
  430.         if (hunkNum[i] == temp) {
  431.         fwrite(relocation+i, 1, 4, file);
  432.         hunkNum[i] = 0xffffffff;
  433.         }
  434.     }
  435.     /* terminate the relocation record for this hunk */
  436.     temp = 0;
  437.     fwrite(&temp, 1, 4, file);
  438.     /* write the hunk end mark */
  439.     temp = HUNK_END;
  440.     fwrite(&temp, 1, 4, file);
  441.     /* write any other hunks */
  442.     currHunk = (ULONG *) ((*hunkBase)<<2);
  443.     while (currHunk) {
  444.     /* write the hunk start */
  445.     temp = HUNK_DATA;
  446.     fwrite(&temp, 1, 4, file);
  447.     /*   write the hunk size */
  448.     temp = (currHunk[-1]>>2) - 2;
  449.     fwrite(&temp, 1, 4, file);
  450.     /* write the hunk */
  451.     fwrite(&currHunk[1], 1, currHunk[-1] - 8, file);
  452.     /* write the hunk end mark */
  453.     temp = HUNK_END;
  454.     fwrite(&temp, 1, 4, file);
  455.     currHunk = (ULONG *) ((*currHunk)<<2);
  456.     }
  457.     fclose(file);
  458. }
  459.