home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / texmf / source / SpecHost / Post.c < prev    next >
C/C++ Source or Header  |  1995-06-13  |  30KB  |  1,157 lines

  1. /*
  2. **    SpecialHost for PasTeX
  3. **
  4. **    Copyright © by Olaf Barthel & Georg Heßmann
  5. **
  6. */
  7.  
  8. /*
  9. ** Post.c
  10. **
  11. ** Improvements to the PostScript support written by Giuseppe Ghibò.
  12. **
  13. ** latest revision: 13 Jun 1995 (ghi)
  14. */
  15.  
  16. #include "Global.h"
  17. #include "postlib.h"
  18.  
  19. /*#define DEBUG*/
  20.  
  21. STATIC VOID __regargs PSGetSize_S(struct parse_result *Result, float *width, float *height, float *hoff, float *voff, float *hoff_cp, float *voff_cp);
  22. STATIC VOID __regargs PSGetSize_P(float *width, float *height, float *hoff, float *voff, float *hoff_cp, float *voff_cp, LONG DVI_mag);
  23. STATIC BOOL __regargs FindBBox(STRPTR, struct bbox *);
  24. STATIC VOID __regargs Point_Transf(struct ctm *, float, float, float *, float *);
  25. STATIC VOID __regargs bb_new(struct ctm *, struct bbox *, struct bbox *);
  26. STATIC BOOL __regargs Is_MPfile(STRPTR);
  27. STATIC STRPTR __regargs FontMapAlias(STRPTR font_name);
  28.  
  29. #define MAXPSHEADERS 256
  30. #define TEMPSTRLEN MAX_FILENAME_LEN
  31. #define MAXMAPENTRIES 8192L
  32.  
  33. STATIC STRPTR PSHeaders[MAXPSHEADERS] = { NULL };
  34. STATIC UBYTE TempStr[MAX_FILENAME_LEN];
  35.  
  36. struct extra_transf *Extra_Transf;
  37. float    ET_CurrentPoint_x = 0.0f,
  38.     ET_CurrentPoint_y = 0.0f; /* point on page where extra transformations begin. */
  39.  
  40. struct Library *PSbase;
  41. STATIC struct PSparm     PSparm;
  42. STATIC struct BitMap    *BitMap;
  43. STATIC LONG         ActivationRecord;
  44. STATIC BOOL         Transferred;
  45.  
  46. #ifdef DEBUG
  47. STATIC struct Screen    *LocalScreen;
  48. STATIC struct Window    *LocalWindow;
  49. #endif    /* DEBUG */
  50.  
  51. extern void insertftrap(void);
  52. extern void deleteftrap(void);
  53.  
  54. STATIC VOID __saveds
  55. CopyPage(VOID)
  56. {
  57.     Transferred = TRUE;
  58.  
  59. #ifdef DEBUG
  60.     if(LocalScreen)
  61.     {
  62.         struct IntuiMessage *IntuiMessage;
  63.  
  64.         CopyMem(BitMap -> Plane[0], LocalScreen -> RastPort . BitMap -> Planes[0], LocalScreen -> RastPort . BitMap -> BytesPerRow * LocalScreen -> RastPort . BitMap -> Rows);
  65.  
  66.         ScreenToFront(LocalScreen);
  67.  
  68.         WaitPort(LocalWindow -> UserPort);
  69.  
  70.         while(IntuiMessage = (struct IntuiMessage *)GetMsg(LocalWindow -> UserPort))
  71.             ReplyMsg(IntuiMessage);
  72.     }
  73. #endif    /* DEBUG */
  74. }
  75.  
  76. void __saveds sigfpe(void)
  77. {
  78.     PSsignalfpe(ActivationRecord);
  79. }
  80.  
  81. void __saveds sigint(void)
  82. {
  83.     PSsignalint(ActivationRecord,1);
  84. }
  85.  
  86. /* (ghi) the function ProcessPostscript() is slightly changed from the one
  87.    provided by Olaf. Now we pass to the PostScript interpreter part of the
  88.    same code used by dvips. Of course, to place the PostScript picture in
  89.    the same (or similar) condition as if it was inside a PostScript file
  90.    created by dvips, we need to pass a PostScript ``glue code''. Then to
  91.    calculate the correct size of the picture according to the special used,
  92.    we have to determine the PostScript current transformation matrix. These
  93.    operations are performed by the function PSGetSizeDot() */
  94.  
  95. struct BitMap * __regargs
  96. ProcessPostscript(struct special_msg *Message,struct special_map *SpecialMap,struct parse_result *Result,LONG *Error)
  97. {
  98.     *Error = 0;
  99.     
  100.     BitMap = NULL;
  101.  
  102.     if(PSbase = OpenLibrary("post.library",15))
  103.     {
  104.         BPTR NIL;
  105.  
  106.         if(NIL = Open("NIL:",MODE_READWRITE))
  107.         {
  108.             LONG    NewWidth,
  109.                 NewHeight,
  110.                 H_OffSet,
  111.                 V_OffSet,
  112.                 X_DPI = Message -> hresolution,
  113.                 Y_DPI = Message -> vresolution;
  114.  
  115.             float    CurrentPoint_x = 0.0f, CurrentPoint_y = 0.0f;
  116.             STRPTR special_string = NULL, sp;
  117.  
  118.             memset(&PSparm,0,sizeof(struct PSparm));
  119.  
  120.             PSGetSizeDot(Result, &NewWidth, &NewHeight, &H_OffSet, &V_OffSet, &SpecialMap -> hoffset, &SpecialMap -> voffset);
  121.             SpecialMap -> width    = NewWidth;
  122.             SpecialMap -> height    = NewHeight;
  123.             
  124.             if ((special_string = AllocVecPooled(1024, MEMF_ANY)) == NULL)
  125.             {
  126.                 *Error = ERR_NO_MEM;
  127.                 Close(NIL);
  128.                 CloseLibrary(PSbase);
  129.                 PSbase = NULL;
  130.  
  131.                 if (psfig_status == PSFIG_END)
  132.                     psfig_status = PSFIG_OFF;
  133.  
  134.                 return(NULL);
  135.             }
  136.  
  137.             sp = special_string;
  138.  
  139.             sprintf(sp,"TeXDict begin %ld %ld %ld %ld %ld (noname) @start\n", \
  140.                 (LONG) (INTOSP((float) NewWidth/X_DPI) + 0.5), \
  141.                 (LONG) (INTOSP((float) NewHeight/Y_DPI) + 0.5), \
  142.                 Result -> DVI_mag, X_DPI, Y_DPI);
  143.             sp += strlen(sp);
  144.             sprintf(sp,"1 0 bop\nResolution neg VResolution neg vsize round -72 div 1 add mul a ");
  145.             sp += strlen(sp);
  146.  
  147.             if (psfig_status == PSFIG_END)
  148.             {
  149.                 sprintf(sp,"%ld %ld %ld %ld %ld %ld startTexFig\n", psfig_data . width, psfig_data . height, \
  150.                      psfig_data .llx, psfig_data . lly, psfig_data . urx, psfig_data . ury);
  151.  
  152.                 if (psfig_data . clip)
  153.                 {
  154.                     sp += strlen(sp);
  155.                     sprintf(sp,"doclip\n");
  156.                 }
  157.  
  158.                 if (psfig_data . angle != 0.0)
  159.                 {
  160.                     sp += strlen(sp);
  161.                     sprintf(sp,"%g rotate\n", psfig_data . angle);
  162.                 }
  163.             }
  164.             else
  165.                 sprintf(sp,"@beginspecial\n");
  166.  
  167.             sp += strlen(sp);
  168.  
  169.             if (Extra_Transf)
  170.             {
  171.                 CurrentPoint_x = (float) Result -> current_x / Result -> hres - ET_CurrentPoint_x;
  172.                 CurrentPoint_y = - (float) Result -> current_y / Result -> vres + ET_CurrentPoint_y;
  173.  
  174.                 sprintf(sp,"[%g %g %g %g %g %g] concat %g %g TR\n",
  175.                     Extra_Transf -> CTM . a,
  176.                     Extra_Transf -> CTM . b,
  177.                     Extra_Transf -> CTM . c,
  178.                     Extra_Transf -> CTM . d,
  179.                     INTOBP(Extra_Transf -> CTM . tx),
  180.                     INTOBP(Extra_Transf -> CTM . ty),
  181.                     INTOBP(CurrentPoint_x),
  182.                     INTOBP(CurrentPoint_y));
  183.                 sp += strlen(sp);
  184.             }
  185.  
  186.             if(Result -> gotcontrol & GOT_HSIZE)
  187.             {
  188.                 sprintf(sp,"%g @hsize ", INTOBP(Result -> hsize));
  189.                 sp += strlen(sp);
  190.             }
  191.  
  192.             if(Result -> gotcontrol & GOT_VSIZE)
  193.             {
  194.                 sprintf(sp,"%g @vsize ", INTOBP(Result -> vsize));
  195.                 sp += strlen(sp);
  196.             }
  197.  
  198.             if(Result -> gotcontrol & GOT_HSCALE)
  199.             {
  200.                 sprintf(sp,"%g @hscale ", Result -> hscale * 100.0);
  201.                 sp += strlen(sp);
  202.             }
  203.  
  204.             if(Result -> gotcontrol & GOT_VSCALE)
  205.             {
  206.                 sprintf(sp,"%g @vscale ", Result -> vscale * 100.0);
  207.                 sp += strlen(sp);
  208.             }
  209.  
  210.             if(Result -> gotcontrol & GOT_SCALE)
  211.             {
  212.                 sprintf(sp,"%g @hscale %g @vscale ", Result -> scale * 100.0, Result -> scale * 100.0);
  213.                 sp += strlen(sp);
  214.             }
  215.  
  216.             if(Result -> gotcontrol & GOT_HOFFSET)
  217.             {
  218.                 sprintf(sp,"%g @hoffset ", INTOBP(Result -> hoffset));
  219.                 sp += strlen(sp);
  220.             }
  221.  
  222.             if(Result -> gotcontrol & GOT_VOFFSET)
  223.             {
  224.                 sprintf(sp,"%g @voffset ", INTOBP(Result -> voffset));
  225.                 sp += strlen(sp);
  226.             }
  227.  
  228.             if (Result -> gotcontrol & GOT_ANGLE)
  229.             {
  230.                 sprintf(sp,"%g @angle ", Result -> angle);
  231.                 sp += strlen(sp);
  232.             }
  233.  
  234.             if (Result -> gotcontrol & GOT_CLIP)
  235.             {
  236.                 sprintf(sp,"@clip ");
  237.                 sp += strlen(sp);
  238.             }
  239.  
  240.             if((Result -> gotcontrol & (GOT_LLX | GOT_LLY | GOT_URX | GOT_URY)) == (GOT_LLX | GOT_LLY | GOT_URX | GOT_URY))
  241.             {
  242.                 sprintf(sp,"%g @llx %g @lly %g @urx %g @ury ",
  243.                     INTOBP(Result -> llx), INTOBP(Result -> lly),
  244.                     INTOBP(Result -> urx), INTOBP(Result -> ury));
  245.                 sp += strlen(sp);
  246.  
  247.                 if (Result -> gotcontrol & GOT_RWI)
  248.                 {
  249.                     sprintf(sp,"%g @rwi ", INTOBP(Result -> rwi));
  250.                     sp += strlen(sp);
  251.                 }
  252.                 if (Result -> gotcontrol & GOT_RHI)
  253.                 {
  254.                     sprintf(sp,"%g @rhi ", INTOBP(Result -> rhi));
  255.                     sp += strlen(sp);
  256.                 }
  257.             }
  258.  
  259.             if (psfig_status != PSFIG_END)
  260.             {
  261.                 sprintf(sp,"@setspecial\n");
  262.                 sp += strlen(sp);
  263.             }
  264.     
  265.             if(NewWidth > 30000 || NewHeight > 30000)
  266.                 *Error = ERR_TOO_LARGE;
  267.             else
  268.             {
  269.                 if(NewWidth < 1 || NewHeight < 1)
  270.                     *Error = ERR_TOO_SMALL;
  271.                 else
  272.                 {
  273.                     PrintLine("Page size %ld × %ld, %ld × %ld DPI",NewWidth,NewHeight,Message -> hresolution,Message -> vresolution);
  274.  
  275.                     if(BitMap = CreateBitMap(NewWidth,NewHeight,1,BMAP_MEMF_ANY,NULL))
  276.                     {
  277.                         LONG ResultCode;
  278.  
  279.                         insertftrap();
  280.  
  281.                         PSparm . page . depth    = 1;
  282.                         PSparm . page . ydir    = -1;
  283.                         PSparm . page . xden    = X_DPI;
  284.                         PSparm . page . yden    = Y_DPI;
  285.                         PSparm . page . xsize    = NewWidth;
  286.                         PSparm . page . ysize    = NewHeight;
  287.                         PSparm . page . yheight    = NewHeight;
  288.                         PSparm . page . xbytes    = BitMap -> BytesPerRow;
  289.                         PSparm . page . xoff    = H_OffSet;
  290.                         PSparm . page . yoff    = V_OffSet;
  291.                         PSparm . page . len    = PSparm . page . xbytes * PSparm . page . ysize;
  292.                         PSparm . page . buf[0]    = BitMap -> Planes[0]; /* (ghi) to store the PS picture in the same memory area passed to ShowDVI */
  293.  
  294.                         PSparm . copyfunc    = (APTR)CopyPage;
  295.                         PSparm . infh        = NIL;
  296.                         PSparm . outfh        = NIL;
  297.                         PSparm . errfh        = NIL;
  298.  
  299.                         ActivationRecord = PScreateact(&PSparm);
  300.  
  301.                         if(ActivationRecord <= errmax)
  302.                         {
  303.                             if(ActivationRecord)
  304.                                 *Error = 20000 + ActivationRecord;
  305.                             else
  306.                                 *Error = ERR_NO_MEM;
  307.                         }
  308.                         else
  309.                         {
  310.                             ULONG Flags = PSFLAGCLEAR | PSFLAGERASE;
  311. #ifdef DEBUG
  312.                             if(LocalScreen = OpenScreenTags(NULL,
  313.                                 SA_Width,    NewWidth,
  314.                                 SA_Height,    NewHeight,
  315.                                 SA_Depth,    1,
  316.                                 SA_DisplayID,    HIRESLACE_KEY,
  317.                                 SA_Quiet,    TRUE,
  318.                                 SA_AutoScroll,    TRUE,
  319.                                 SA_ShowTitle,    FALSE,
  320.                                 SA_Overscan,    OSCAN_STANDARD,
  321.                             TAG_DONE))
  322.                             {
  323.                                 if(!(LocalWindow = OpenWindowTags(NULL,
  324.                                     WA_Left,    0,
  325.                                     WA_Top,        0,
  326.                                     WA_Width,    LocalScreen -> Width,
  327.                                     WA_Height,    LocalScreen -> Height,
  328.                                     WA_RMBTrap,    TRUE,
  329.                                     WA_Backdrop,    TRUE,
  330.                                     WA_Borderless,    TRUE,
  331.                                     WA_CustomScreen,LocalScreen,
  332.                                     WA_Activate,    TRUE,
  333.                                     WA_IDCMP,    IDCMP_VANILLAKEY,
  334.                                 TAG_DONE)))
  335.                                 {
  336.                                     CloseScreen(LocalScreen);
  337.  
  338.                                     LocalScreen = NULL;
  339.                                 }
  340.                             }
  341. #endif    /* DEBUG */
  342.                             Transferred = FALSE;
  343.  
  344.                             if(Result -> psinit_file[0] && !(*Error))
  345.                             {
  346.                                 STRPTR s;
  347.  
  348.                                 if (s = EVP_FileSearch(Result -> psinit_file, psheaders_var, TempStr, TEMPSTRLEN))
  349.                                 {
  350.                                     PrintLine("Executing initialization file \"%s\"...", s);
  351.  
  352.                                     if(ResultCode = PSintstring(ActivationRecord,s,-1,PSFLAGFILE | Flags))
  353.                                         *Error = 20000 + ResultCode;
  354.                                     else
  355.                                         Flags = NULL;
  356.                                 }
  357.                                 else
  358.                                 {
  359.                                     PrintLine("\33bInitialization file \"%s\" not found.\33n", Result -> psinit_file);
  360.                                     *Error = 19999;
  361.                                 }
  362.                             }
  363.  
  364.                             if(Result -> psinit_string[0] && !(*Error))
  365.                             {
  366.                                 PrintLine("Executing initialization string...");
  367.  
  368.                                 if(ResultCode = PSintstring(ActivationRecord,Result -> psinit_string,strlen(Result -> psinit_string),PSFLAGSTRING | Flags))
  369.                                     *Error = 20000 + ResultCode;
  370.                                 else
  371.                                     Flags = NULL;
  372.                             }
  373.  
  374.                             if(!(*Error))
  375.                             {
  376.                                 STRPTR s;
  377.  
  378.                                 if (s = EVP_FileSearch("tex.pro", psheaders_var, TempStr, TEMPSTRLEN))
  379.                                 {
  380.                                     PrintLine("Executing file \"%s\"...",s);
  381.  
  382.                                     if(ResultCode = PSintstring(ActivationRecord,s,-1,PSFLAGFILE | Flags))
  383.                                         *Error = 20000 + ResultCode;
  384.                                     else
  385.                                         Flags = NULL;
  386.                                 }
  387.                                 else
  388.                                 {
  389.                                     PrintLine("\33bFile \"tex.pro\" not found.\33n");
  390.                                     *Error = 19999;
  391.                                 }
  392.                             }
  393.  
  394.                             if(!(*Error) && PSHeaders[0]) /* (ghi) we pass the headers (if there is at least one) to the PostScript interpreter */
  395.                             {
  396.                                 STRPTR s;
  397.                                 int i = 0;
  398.  
  399.                                 while (PSHeaders[i] && PSHeaders[i][0])
  400.                                 {
  401.                                     if (s = EVP_FileSearch(PSHeaders[i], psheaders_var, TempStr, TEMPSTRLEN))
  402.                                     {
  403.                                         PrintLine("Executing prologue file \"%s\"...", s);
  404.  
  405.                                         if(ResultCode = PSintstring(ActivationRecord,s,-1,PSFLAGFILE | Flags))
  406.                                         {
  407.                                             *Error = 20000 + ResultCode;
  408.                                             break;
  409.                                         }
  410.                                         else
  411.                                             Flags = NULL;
  412.                                     }
  413.                                     else
  414.                                     {
  415.                                         PrintLine("\33bPrologue file \"%s\" not found.\33n", PSHeaders[i]);
  416.                                         *Error = 19999;
  417.                                         break;
  418.                                     }
  419.                                     i++;
  420.                                 }
  421.                             }
  422.  
  423.                             if(!(*Error))
  424.                             {
  425.                                 STRPTR s;
  426.  
  427.                                 if (s = EVP_FileSearch("special.pro", psheaders_var, TempStr, TEMPSTRLEN))
  428.                                 {
  429.                                     PrintLine("Executing file \"%s\"...", s);
  430.  
  431.                                     if(ResultCode = PSintstring(ActivationRecord,s,-1,PSFLAGFILE | Flags))
  432.                                         *Error = 20000 + ResultCode;
  433.                                     else
  434.                                         Flags = NULL;
  435.                                 }
  436.                                 else
  437.                                 {
  438.                                     PrintLine("\33bFile \"special.pro\" not found.\33n");
  439.                                     *Error = 19999;
  440.                                 }
  441.                             }
  442.  
  443.                             if (!(*Error))
  444.                             {    /* (ghi) pass to the interpreter some PostScript glue code (see comment above) */
  445.                                 if (psfig_status == PSFIG_END)
  446.                                     PrintLine("Executing glue string for psfig special (startTexFig)...");
  447.                                 else
  448.                                     PrintLine("Executing glue string (@beginspecial)...");
  449.  
  450.                                 if(ResultCode = PSintstring(ActivationRecord,special_string,strlen(special_string),PSFLAGSTRING | Flags))
  451.                                     *Error = 20000 + ResultCode;
  452.                                 else
  453.                                     Flags = NULL;
  454.                             }
  455.  
  456.                             if(!(*Error))
  457.                             {
  458.                                 if (Is_MPfile(Result -> psfile))
  459.                                 {
  460.                                     BPTR fh;
  461.                                     UBYTE *buf, *mpbuf, *mpbufend;
  462.                                     STRPTR p, q, s;
  463.                                     LONG nfont = 0L;
  464.  
  465.                                     Init_FontMapName();
  466.                                     if (fh = Open(Result -> psfile, MODE_OLDFILE))
  467.                                     {
  468.                                         if (mpbuf = AllocVecPooled(8192L, MEMF_ANY))
  469.                                         {
  470.                                             s = mpbuf;
  471.                                             mpbufend = mpbuf + 8192L;
  472.  
  473.                                             if (buf = AllocVecPooled(256, MEMF_ANY))
  474.                                             {
  475.                                                 while (FGets(fh, buf, 256) && !strstr(buf, "%%EndProlog"))
  476.                                                 {
  477.                                                     if (p = strstr(buf, "%*Font:"))
  478.                                                     {
  479.                                                         p += 7;
  480.                                                         q = strtok(p, " \t");
  481.                                                         if (q && *q && s < mpbufend)
  482.                                                         {
  483.                                                             s += sprintf(s,"/%s /%s def\n", q, FontMapAlias(q));
  484.                                                             nfont++;
  485.                                                         }
  486.                                                     }
  487.                                                 }
  488.                                                 if (nfont > 0L)
  489.                                                 {
  490.                                                     sprintf(s, "/fshow {exch findfont exch scalefont setfont show}bind def\n");
  491.  
  492.                                                     PrintLine("Executing glue code for a METAPOST file...");
  493.  
  494.                                                     if (ResultCode = PSintstring(ActivationRecord, mpbuf, strlen(mpbuf), PSFLAGSTRING | Flags))
  495.                                                         *Error = 20000 + ResultCode;
  496.                                                     else
  497.                                                         Flags = NULL;
  498.                                                 }
  499.                                                 FreeVecPooled(buf);
  500.                                             }
  501.                                             FreeVecPooled(mpbuf);
  502.                                         }
  503.                                         Close(fh);
  504.                                     }
  505.                                 }
  506.  
  507.                                 PrintLine("Executing file \"%s\"...",Result -> psfile);
  508.  
  509.                                 if(ResultCode = PSintstring(ActivationRecord,Result -> psfile,-1,PSFLAGFILE | Flags))
  510.                                     *Error = 20000 + ResultCode;
  511. /*
  512.                                 else
  513.                                 {
  514.                                     if(!Transferred)
  515.                                     {
  516.                                         if(ResultCode = PSintstring(ActivationRecord,"showpage",8,PSFLAGSTRING))
  517.                                             *Error = 20000 + ResultCode;
  518.                                     }                                        
  519.                                 }
  520. */
  521.                             }
  522.  
  523.                             if (!(*Error))
  524.                             {    /* (ghi) pass to the interpreter some PostScript glue code (see comment above) */
  525.                                 if (psfig_status == PSFIG_END)
  526.                                 {
  527.                                     PrintLine("Executing glue string for psfig special (endTexFig)...");
  528.                                     sprintf(special_string,"endTexFig SI restore userdict /eop-hook known{eop-hook}if end userdict /end-hook known{end-hook}if\n");
  529.                                 }
  530.                                 else
  531.                                 {
  532.                                     PrintLine("Executing glue string (@endspecial)...");
  533.                                     sprintf(special_string,"@endspecial SI restore userdict /eop-hook known{eop-hook}if end userdict /end-hook known{end-hook}if\n");
  534.                                 }
  535.  
  536.                                 if(ResultCode = PSintstring(ActivationRecord,special_string,strlen(special_string),PSFLAGSTRING | Flags))
  537.                                     *Error = 20000 + ResultCode;
  538.                                 else
  539.                                     Flags = NULL;
  540.  
  541.                                 if(psfig_status == PSFIG_END)
  542.                                     psfig_status = PSFIG_OFF; /* re-init psfig_status */
  543.                             }
  544.  
  545.                             PSdeleteact(ActivationRecord);
  546. #ifdef DEBUG
  547.                             if(LocalWindow)
  548.                             {
  549.                                 CloseWindow(LocalWindow);
  550.  
  551.                                 LocalWindow = NULL;
  552.                             }
  553.  
  554.                             if(LocalScreen)
  555.                             {
  556.                                 CloseScreen(LocalScreen);
  557.  
  558.                                 LocalScreen = NULL;
  559.                             }
  560. #endif    /* DEBUG */
  561.                         }
  562.  
  563.                         deleteftrap();
  564.  
  565.                         if(*Error)
  566.                         {
  567.                             DeleteBitMap(BitMap);
  568.  
  569.                             BitMap = NULL;
  570.                         }
  571.                     }
  572.                     else
  573.                         *Error = ERR_NO_MEM;
  574.                 }
  575.             }
  576.  
  577.             Close(NIL);
  578.             if (special_string)
  579.                 FreeVecPooled(special_string);
  580.         }
  581.         else
  582.             *Error = ERR_NO_NIL;
  583.  
  584.         CloseLibrary(PSbase);
  585.         PSbase = NULL;
  586.     }
  587.     else
  588.         *Error = ERR_NO_POST;
  589.  
  590.     Free_FontMapName();
  591.  
  592.     if (psfig_status == PSFIG_END)
  593.         psfig_status = PSFIG_OFF; /* re-init psfig_status */
  594.  
  595.     return(BitMap);
  596. }
  597.  
  598. /* (ghi) Here follow some functions to get the size of the PostScript
  599.    picture */
  600.  
  601. /* (ghi) concatenates a transformation with the current transformation matrix. */
  602. VOID __regargs
  603. CTM_Transf(struct ctm *ctm, float x, float y, int transformation)
  604. {
  605.     float anew, bnew, cnew, dnew, costheta, sintheta;
  606.  
  607.     switch (transformation) {
  608.  
  609.         case TR_ROTATION:
  610.  
  611.             costheta = cos(x);
  612.             sintheta = sin(x);
  613.             anew =   ctm -> a * costheta + ctm -> c * sintheta;
  614.             bnew =   ctm -> b * costheta + ctm -> d * sintheta;
  615.             cnew = - ctm -> a * sintheta + ctm -> c * costheta;
  616.             dnew = - ctm -> b * sintheta + ctm -> d * costheta;
  617.             ctm -> a = anew;
  618.             ctm -> b = bnew;
  619.             ctm -> c = cnew;
  620.             ctm -> d = dnew;
  621.             break;
  622.  
  623.         case TR_SCALING:
  624.  
  625.             ctm -> a *= x;
  626.             ctm -> b *= x;
  627.             ctm -> c *= y;
  628.             ctm -> d *= y;
  629.             break;
  630.     
  631.         case TR_TRANSLATION:
  632.  
  633.             ctm -> tx += ctm -> a * x + ctm -> c * y;
  634.             ctm -> ty += ctm -> b * x + ctm -> d * y;
  635.             break;
  636.  
  637.         default:
  638.  
  639.             break;
  640.     }
  641. }
  642.  
  643.  
  644. /* (ghi) given a point (x,y) and the current transformation matrix ctm,
  645.    returns the transformed point (x1,y1). */
  646. STATIC VOID __regargs
  647. Point_Transf(struct ctm *ctm, float x, float y, float *x1, float *y1)
  648. {
  649.     *x1 = ctm -> a * x + ctm -> c * y + ctm -> tx;
  650.     *y1 = ctm -> b * x + ctm -> d * y + ctm -> ty;
  651. }
  652.  
  653.  
  654. /* (ghi) given the current transformation matrix and a bounding box,
  655.    returns the transformed bounding box. */
  656. STATIC VOID __regargs
  657. bb_new(struct ctm *ctm, struct bbox *bb, struct bbox *bbnew) {
  658.     
  659.     float x0, y0, x1, y1, x2, y2, x3, y3, xmin, xmax, ymin, ymax;
  660.  
  661.     xmin = ymin =  1.0e38;
  662.     xmax = ymax = -1.0e38;
  663.  
  664.     Point_Transf(ctm, bb -> llx, bb -> lly, &x0, &y0);
  665.     Point_Transf(ctm, bb -> urx, bb -> lly, &x1, &y1);
  666.     Point_Transf(ctm, bb -> urx, bb -> ury, &x2, &y2);
  667.     Point_Transf(ctm, bb -> llx, bb -> ury, &x3, &y3);
  668.     
  669.     xmin = min(xmin, x0);    ymin = min(ymin, y0);
  670.     xmin = min(xmin, x1);    ymin = min(ymin, y1);
  671.     xmin = min(xmin, x2);    ymin = min(ymin, y2);
  672.     xmin = min(xmin, x3);    ymin = min(ymin, y3);
  673.     xmax = max(xmax, x0);    ymax = max(ymax, y0);
  674.     xmax = max(xmax, x1);    ymax = max(ymax, y1);
  675.     xmax = max(xmax, x2);    ymax = max(ymax, y2);
  676.     xmax = max(xmax, x3);    ymax = max(ymax, y3);
  677.  
  678.     bbnew -> llx = xmin;
  679.     bbnew -> lly = ymin;
  680.     bbnew -> urx = xmax;
  681.     bbnew -> ury = ymax;
  682. }
  683.  
  684.  
  685. /* (ghi) PSGetSize_S, returns width, height and offset of picture to
  686.    process; y-axis is orientated from bottom to top for hoff and voff
  687.    and from top to bottom for hoff_cp and voff_cp.
  688.    hoff and voff are the offsets needed for the PostScript interpreter;
  689.    hoff_cp and voff_cp are the offsets relative to the current position.
  690.    Units are in inch. */
  691. STATIC VOID __regargs
  692. PSGetSize_S(struct parse_result *Result, float *width, float *height, float *hoff, float *voff, float *hoff_cp, float *voff_cp)
  693. {
  694.     float    hscale = 1.0,        vscale = 1.0,
  695.         hscale_rxi = 1.0,    vscale_rxi = 1.0,
  696.         hoffset = 0.0,        voffset=0.0,
  697.         angle = 0.0,
  698.         mag = (float)Result -> DVI_mag / 1000.0,
  699.         CurrentPoint_x=0.0f,    CurrentPoint_y=0.0f;
  700.  
  701.     struct bbox bb, bbnew;
  702.     struct ctm ctm;
  703.  
  704.     bb . llx = 0.0;
  705.     bb . lly = 0.0;
  706.     bb . urx = 8.0;        /* default width  = 8in */
  707.     bb . ury = 11.0;    /* default height = 11in */
  708.  
  709.     Init_CTM(&ctm); /* ctm = identity matrix */
  710.  
  711.     if (Result -> gotcontrol & GOT_HSCALE)
  712.         hscale = Result -> hscale;
  713.     
  714.     if (Result -> gotcontrol & GOT_VSCALE)
  715.         vscale = Result -> vscale;
  716.  
  717.     if (Result -> gotcontrol & GOT_SCALE)
  718.         hscale = vscale = Result -> scale;
  719.  
  720.     if (Result -> gotcontrol & GOT_HOFFSET)
  721.         hoffset = Result -> hoffset;
  722.  
  723.     if (Result -> gotcontrol & GOT_VOFFSET)
  724.         voffset = Result -> voffset;
  725.  
  726.     if (Result -> gotcontrol & GOT_ANGLE)
  727.         angle = Result -> angle;
  728.  
  729.     if ( (Result -> gotcontrol & (GOT_HOFFSET | GOT_VOFFSET)) == (GOT_HOFFSET | GOT_VOFFSET) && !(Result -> gotcontrol & (GOT_HSIZE | GOT_VSIZE | GOT_LLX | GOT_LLY | GOT_URX | GOT_URY | GOT_RWI | GOT_RHI)) )
  730.     {
  731.         BOOL success;
  732.  
  733.         success = FindBBox(Result -> psfile, &bb);
  734.         if (success)
  735.         {
  736.             if ((bb . urx - bb .llx) < 2.0/72.0)
  737.             {
  738.                 bb . urx += 9.0/72.0; /* at least 20bp large */
  739.                 bb . llx -= 9.0/72.0;
  740.             }
  741.             if ((bb . ury - bb . lly) < 2.0/72.0)
  742.             {
  743.                 bb . ury += 9.0/72.0; /* at least 20bp high */
  744.                 bb . lly -= 9.0/72.0;
  745.             }
  746.  
  747.             bb . urx += 1.0/72.0;
  748.             bb . llx -= 1.0/72.0;
  749.             bb . ury += 1.0/72.0;
  750.             bb . lly -= 1.0/72.0;
  751.  
  752.             Result -> llx = bb . llx;
  753.             Result -> lly = bb . lly;
  754.             Result -> urx = bb . urx;
  755.             Result -> ury = bb . ury;
  756.             Result -> hoffset += Result -> llx;
  757.             Result -> voffset += Result -> lly;
  758.             hoffset = Result -> hoffset;
  759.             voffset = Result -> voffset;
  760.             Result -> rwi = 10.0 * (Result -> urx - Result -> llx);
  761.             Result -> gotcontrol |= SUFFICIENT_PS_ARGS;
  762.         }
  763.     }
  764.  
  765.     if ((Result -> gotcontrol & (GOT_LLX | GOT_LLY | GOT_URX | GOT_URY)) == (GOT_LLX | GOT_LLY | GOT_URX | GOT_URY))
  766.     {
  767.         bb . llx = Result -> llx;
  768.         bb . lly = Result -> lly;
  769.         bb . urx = Result -> urx;
  770.         bb . ury = Result -> ury;
  771.     }
  772.  
  773.     if ((Result -> gotcontrol & (GOT_RWI | GOT_RHI)) == (GOT_RWI | GOT_RHI))
  774.     {
  775.         hscale_rxi = Result -> rwi / (10.0 * (bb . urx - bb . llx));
  776.         vscale_rxi = Result -> rhi / (10.0 * (bb . ury - bb . lly));
  777.     }
  778.     else if ((Result -> gotcontrol & GOT_RWI) == GOT_RWI)
  779.     {
  780.         hscale_rxi = Result -> rwi / (10.0 * (bb . urx - bb . llx));
  781.         vscale_rxi = hscale_rxi;
  782.     }
  783.     else
  784.     {        
  785.         if ((Result -> gotcontrol & GOT_RHI) == GOT_RHI)
  786.         {
  787.             vscale_rxi = Result -> rhi / (10.0 * (bb . ury - bb . lly));
  788.             hscale_rxi = vscale_rxi;
  789.         }
  790.     }
  791.  
  792. /* Performs PostScript transformations */
  793.  
  794.     if (Extra_Transf)
  795.     {
  796.         Copy_CTM(&ctm, &Extra_Transf -> CTM);
  797.  
  798.         CurrentPoint_x = (float) Result -> current_x / Result -> hres - ET_CurrentPoint_x;
  799.         CurrentPoint_y = - (float) Result -> current_y / Result -> vres + ET_CurrentPoint_y;
  800.  
  801.         CTM_Transf(&ctm, CurrentPoint_x, CurrentPoint_y, TR_TRANSLATION);
  802.     }
  803.  
  804.     CTM_Transf(&ctm, mag, mag, TR_SCALING);
  805.     CTM_Transf(&ctm, hoffset, voffset, TR_TRANSLATION);
  806.     CTM_Transf(&ctm, hscale, vscale, TR_SCALING);
  807.     CTM_Transf(&ctm, RAD(angle), 0.0f, TR_ROTATION);
  808.     CTM_Transf(&ctm, hscale_rxi, vscale_rxi, TR_SCALING);
  809.     CTM_Transf(&ctm, (float)-bb.llx, (float)-bb.lly, TR_TRANSLATION);
  810.  
  811.     bb_new(&ctm, &bb, &bbnew);
  812.     *width    = bbnew . urx - bbnew . llx;
  813.     *height    = bbnew . ury - bbnew . lly;
  814.     *hoff = bbnew . llx;
  815.     *voff = bbnew . lly;
  816.  
  817. /* hsize and vsize define the clipping area; the clipping area isn't
  818.    affected by scaling, translation or rotation. */
  819.  
  820.     if (Result -> gotcontrol & GOT_HSIZE)
  821.     {
  822.         *width = Result -> hsize ;
  823.         *hoff  = 0.0;
  824.     }
  825.  
  826.     if (Result -> gotcontrol & GOT_VSIZE)
  827.     {
  828.         *height = Result -> vsize ;
  829.         *voff = 0.0;
  830.     }
  831.  
  832.     if (Extra_Transf)
  833.     {
  834.         *hoff_cp = *hoff - CurrentPoint_x;
  835.         *voff_cp = *voff - CurrentPoint_y;
  836.     }
  837.     else
  838.     {
  839.         *hoff_cp = *hoff;
  840.         *voff_cp = *voff;
  841.     }
  842. }
  843.  
  844. /* (ghi) PSGetSizeDot() returns width, height and offsets
  845.    in 'dot' or 'pixels' of the PostScript picture to process.
  846.  
  847.    hoff, voff = offset to pass to the PostScript interpreter.
  848.    hoff_cp, voff_cp = offsets to pass to SpecialMap -> (h|v)offset.
  849. */
  850. VOID __regargs
  851. PSGetSizeDot(struct parse_result *Result, LONG *width, LONG *height, LONG *hoff, LONG *voff, LONG *hoff_cp, LONG *voff_cp)
  852. {
  853.     float f_width, f_height, f_hoff, f_voff, f_hoff_cp, f_voff_cp;
  854.  
  855.     if (psfig_status == PSFIG_END)
  856.         PSGetSize_P(&f_width, &f_height, &f_hoff, &f_voff, &f_hoff_cp, &f_voff_cp, Result -> DVI_mag);
  857.     else
  858.         PSGetSize_S(Result, &f_width, &f_height, &f_hoff, &f_voff, &f_hoff_cp, &f_voff_cp);
  859.  
  860.     *width     =   (LONG)(f_width   * Result -> hres + 0.5);
  861.     *height     =   (LONG)(f_height  * Result -> vres + 0.5);
  862.     *hoff     =   (LONG)(f_hoff    * Result -> hres + 0.5);
  863.     *voff     =   (LONG)(f_voff    * Result -> vres + 0.5);
  864.     *hoff_cp =   (LONG)(f_hoff_cp * Result -> hres + 0.5);
  865.     *voff_cp = - (LONG)(f_voff_cp * Result -> vres + 0.5);
  866. }
  867.  
  868. /* (ghi) Scans a PS file to find a BoundingBox. */
  869. STATIC BOOL __regargs
  870. FindBBox(STRPTR filename, struct bbox *bb)
  871. {
  872.     BYTE *buf,*s,*p;
  873.     BPTR fh;
  874.     BOOL success = FALSE;
  875.  
  876.     if ((fh = Open(filename,MODE_OLDFILE)) == DOSFALSE) {
  877.         return(FALSE);
  878.     }
  879.  
  880.     if ((buf = AllocVecPooled(256,MEMF_ANY)) == NULL) {
  881.         Close(fh);
  882.         return(FALSE);
  883.     }
  884.  
  885.     while (FGets(fh,buf,256) != NULL) {
  886.         if ((s=strstr(buf,"%%BoundingBox:")) != NULL)
  887.         {
  888.             s += 14; /* skip `%%BoundingBox:' */
  889.             if (strstr(s,"atend"))
  890.                 continue;
  891.             else
  892.             {
  893.                 p = strtok(s," \t");
  894.                 bb -> llx = atof(p)/72.0;
  895.                 p = strtok(NULL," \t");
  896.                 bb -> lly = atof(p)/72.0;
  897.                 p = strtok(NULL," \t");
  898.                 bb -> urx = atof(p)/72.0;
  899.                 p = strtok(NULL," \t");
  900.                 bb -> ury = atof(p)/72.0;
  901.                 success = TRUE;
  902.                 break;
  903.             }
  904.         }
  905.     }
  906.  
  907.     FreeVecPooled(buf);
  908.     Close(fh);
  909.  
  910.     return(success);
  911. }
  912.  
  913. /* (ghi) set the name of a PostScript header (prologue) */
  914. VOID __regargs
  915. Add_PSHeaderName(STRPTR Name)
  916. {
  917.     int i = 0;
  918.  
  919.     while (PSHeaders[i] && i < MAXPSHEADERS - 1)
  920.     {
  921.         if (!Stricmp(PSHeaders[i], Name))
  922.             return;
  923.         else
  924.             i++;
  925.         }
  926.  
  927.     if (PSHeaders[i] = AllocVecPooled(strlen(Name) + 1, MEMF_ANY))
  928.         strcpy(PSHeaders[i], Name);
  929. }
  930.  
  931. VOID __regargs
  932. Init_PSHeaders(VOID)
  933. {
  934.     int i = 0;
  935.  
  936.     while (PSHeaders[i] && i < MAXPSHEADERS)
  937.     {
  938.         FreeVecPooled(PSHeaders[i]);
  939.         PSHeaders[i++] = NULL;
  940.     }
  941. }
  942.  
  943. /* (ghi) Given a pointer to the struct psfig_data (GLOBAL), PSGetSize_P()
  944.    returns width, height, offsets of the picture, in inch
  945.    (y-axis orientated from bottom to top).
  946.    This function returns sizes from psfig specials. Psfig specials are those
  947.    created by the TeX/LaTeX macro package `psfig.sty' or `epsfig.sty'. These
  948.    kind of specials spread the data across two or more specials. The first
  949.    one special begins with \special{ps::[begin] ... startTexFig}, while the
  950.    last one with \special{ps::[end] endTexFig}.*/
  951. STATIC VOID __regargs
  952. PSGetSize_P(float *width, float *height, float *hoff, float *voff, float *hoff_cp, float *voff_cp, LONG DVI_mag)
  953. {
  954.     float    hscale = 1.0,    vscale = 1.0,
  955.         angle = 0.0,
  956.         wd = 0.0,    ht = 0.0,
  957.         mag = (float)DVI_mag/1000.0;
  958.  
  959.     struct bbox bb, bbnew;
  960.     struct ctm ctm;
  961.  
  962.     bb . llx = SPTOIN(psfig_data . llx);
  963.     bb . lly = SPTOIN(psfig_data . lly);
  964.     bb . urx = SPTOIN(psfig_data . urx);
  965.     bb . ury = SPTOIN(psfig_data . ury);
  966.     wd       = SPTOIN(psfig_data . width);
  967.     ht       = SPTOIN(psfig_data . height);
  968.     angle    = psfig_data . angle;
  969.  
  970.     /* initialize the current transformation matrix with the identity matrix */
  971.     ctm.a = ctm.d = 1.0;
  972.     ctm.b = ctm.c = ctm.tx = ctm.ty = 0.0;
  973.  
  974.     /* Performs PostScript transformations */
  975.  
  976.     hscale = wd / (bb . urx - bb . llx);
  977.     vscale = ht / (bb . ury - bb . lly);
  978.  
  979.     CTM_Transf(&ctm, mag, mag, TR_SCALING);
  980.     CTM_Transf(&ctm, hscale, vscale, TR_SCALING);
  981.     CTM_Transf(&ctm, (float)-bb.llx, (float)-bb.ury,TR_TRANSLATION);
  982.     CTM_Transf(&ctm, RAD(angle), 0.0f, TR_ROTATION);
  983.  
  984.     bb_new(&ctm, &bb, &bbnew);
  985.     *width    = bbnew . urx - bbnew . llx;
  986.     *height    = bbnew . ury - bbnew . lly;
  987.     *hoff = bbnew . llx;
  988.     *voff = bbnew . lly;
  989.  
  990.     if (psfig_data . angle != 0.0)
  991.     {
  992.         /* 0.15in are added to the width and the height of the picture.
  993.            This value compensate BoundingBox round errors. Same for
  994.            hoff and voff, which instead are added by -0.1in. */
  995.  
  996.         *width  = (wd * mag) + 0.15;
  997.         *height = (ht * mag) + 0.15;
  998.         *hoff   = - 0.1;
  999.         *voff   = - ht - 0.1;
  1000.     }
  1001.  
  1002.     *hoff_cp = *hoff;
  1003.     *voff_cp = *voff;
  1004. }
  1005.  
  1006. VOID __regargs
  1007. Init_CTM(struct ctm *ctm)
  1008. {
  1009.     ctm -> a = ctm -> d = 1.0;
  1010.     ctm -> b = ctm -> c = ctm -> tx = ctm -> ty = 0.0;
  1011. }
  1012.  
  1013. VOID __regargs
  1014. Copy_CTM(struct ctm *dest, struct ctm *source)
  1015. {
  1016.     memcpy(dest, source, sizeof(struct ctm));
  1017. }
  1018.  
  1019. /* This function returns TRUE if the file is a MP file, else it
  1020.    returns FALSE. */
  1021. STATIC BOOL __regargs
  1022. Is_MPfile(STRPTR name)
  1023. {
  1024.     BPTR fh;
  1025.     BOOL status = FALSE;
  1026.     UBYTE    *buf;
  1027.     STRPTR s;
  1028.     LONG linecnt = 0;
  1029.  
  1030.     if (fh = Open(name, MODE_OLDFILE))
  1031.     {
  1032.         if ((buf = AllocVecPooled(256, MEMF_ANY)) == NULL)
  1033.         {
  1034.             Close(fh);
  1035.             return(FALSE);
  1036.         }
  1037.  
  1038.         while (FGets(fh, buf, 256) != NULL && linecnt < 20)
  1039.         {
  1040.             if ((s = strstr(buf, "%%Creator: MetaPost")) != NULL)
  1041.             {
  1042.                 status = TRUE;    /* a metapost file found */
  1043.                 break;
  1044.             }
  1045.             else if (strstr(buf, "%%EndProlog") != NULL)
  1046.                 break;
  1047.             else
  1048.                 linecnt++;
  1049.         }
  1050.  
  1051.         Close(fh);
  1052.         FreeVecPooled(buf);
  1053.     }
  1054.  
  1055.     return(status);
  1056. }
  1057.  
  1058. struct FontMapName
  1059. {
  1060.     STRPTR name_ori, name_alias;
  1061. };
  1062.  
  1063. STATIC struct FontMapName *FontMapName = NULL;
  1064.  
  1065. /* Init_FontMapName() initializes the array `FontMapName' with
  1066.    entries from the file `psfonts.map'. */
  1067. VOID __regargs Init_FontMapName(VOID)
  1068. {
  1069.     BPTR FileMap;
  1070.     UBYTE *buf;
  1071.     STRPTR name_ori, name_alias;
  1072.     LONG namecnt = 0L;
  1073.  
  1074.     if (FontMapName != NULL)
  1075.         return;
  1076.  
  1077.     if (buf = AllocVecPooled(256, MEMF_ANY))
  1078.     {
  1079.         if (FileMap = EVP_Open("psfonts.map", psheaders_var, NULL, NULL, MODE_OLDFILE))
  1080.         {
  1081.             if (FontMapName = AllocVecPooled(sizeof(struct FontMapName) * MAXMAPENTRIES, MEMF_ANY))
  1082.             {
  1083.                 while (FGets(FileMap, buf, 256) != NULL && namecnt < MAXMAPENTRIES-1)
  1084.                 {
  1085.                     name_ori = strtok(buf, " \t");
  1086.                     name_alias = strtok(NULL, " \t\n");
  1087.  
  1088.                     if (name_ori != NULL && name_alias != NULL)
  1089.                     {
  1090.                         if (*name_ori != '\0' && *name_alias != '\0')
  1091.                         {
  1092.                             if (FontMapName[namecnt].name_ori = AllocVecPooled(strlen(name_ori) + 1, MEMF_ANY))
  1093.                             {
  1094.                                 if (FontMapName[namecnt].name_alias = AllocVecPooled(strlen(name_alias) + 1, MEMF_ANY))
  1095.                                 {
  1096.                                     strcpy(FontMapName[namecnt].name_ori, name_ori);
  1097.                                     strcpy(FontMapName[namecnt].name_alias, name_alias);
  1098.                                     namecnt++;
  1099.                                 }
  1100.                                 else
  1101.                                 {
  1102.                                     FreeVecPooled(FontMapName[namecnt].name_ori);
  1103.                                     break; /* Not enough mem. exit from the while cycle. */
  1104.                                 }
  1105.                             }
  1106.                             
  1107.                         }
  1108.                     }
  1109.                 }
  1110.                 FontMapName[namecnt].name_ori = NULL;
  1111.             }
  1112.             Close(FileMap);
  1113.         }
  1114.         FreeVecPooled(buf);
  1115.     }
  1116. }
  1117.  
  1118. /* Free_FontMapName() frees all the memory allocated for the
  1119.    `FontMapName' structure. */
  1120. VOID __regargs Free_FontMapName(VOID)
  1121. {
  1122.     LONG i;
  1123.  
  1124.     if (FontMapName)
  1125.     {
  1126.         for (i = 0; FontMapName[i].name_ori != NULL; i++)
  1127.         {
  1128.             FreeVecPooled(FontMapName[i].name_ori);
  1129.             FreeVecPooled(FontMapName[i].name_alias);
  1130.         }
  1131.         FreeVecPooled(FontMapName);
  1132.         FontMapName = NULL;
  1133.     }
  1134. }
  1135.  
  1136. /* FontMapAlias(), finds an alias for the font `font_name' using the
  1137.    files `PSFonts.map'. If not found it returns a pointer to `font_name'. */
  1138. STATIC STRPTR __regargs FontMapAlias(STRPTR font_name)
  1139. {
  1140.     LONG i;
  1141.     STRPTR name_alias = font_name;
  1142.  
  1143.     if (FontMapName)
  1144.     {
  1145.         for (i = 0L; FontMapName[i].name_ori != NULL; i++)
  1146.         {
  1147.             if (!strcmp(font_name, FontMapName[i].name_ori))
  1148.             {
  1149.                 name_alias = FontMapName[i].name_alias;
  1150.                 break;
  1151.             }
  1152.         }
  1153.     }
  1154.  
  1155.     return(name_alias);
  1156. }
  1157.