home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xibm.zip / mpel / mpelFont.c < prev    next >
C/C++ Source or Header  |  1991-09-17  |  20KB  |  731 lines

  1. /*
  2.  * Copyright IBM Corporation 1987,1988,1989
  3.  *
  4.  * All Rights Reserved
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose and without fee is hereby granted,
  8.  * provided that the above copyright notice appear in all copies and that 
  9.  * both that copyright notice and this permission notice appear in
  10.  * supporting documentation, and that the name of IBM not be
  11.  * used in advertising or publicity pertaining to distribution of the
  12.  * software without specific, written prior permission.
  13.  *
  14.  * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  15.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  16.  * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  17.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  18.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  19.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  20.  * SOFTWARE.
  21.  *
  22. */
  23. /***********************************************************
  24.         Copyright IBM Corporation 1987,1988
  25.  
  26.                       All Rights Reserved
  27.  
  28. Permission to use, copy, modify, and distribute this software and its 
  29. documentation for any purpose and without fee is hereby granted, 
  30. provided that the above copyright notice appear in all copies and that
  31. both that copyright notice and this permission notice appear in 
  32. supporting documentation, and that the name of IBM not be
  33. used in advertising or publicity pertaining to distribution of the
  34. software without specific, written prior permission.  
  35.  
  36. IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  37. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  38. IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  39. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  40. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  41. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  42. SOFTWARE.
  43.  
  44. ******************************************************************/
  45.  
  46. /* $Header: /andrew/X11/r3src/release/server/ddx/ibm/mpel/RCS/mpelFont.c,v 6.5 89/04/29 21:38:15 jeff Exp $ */
  47. /* $Source: /andrew/X11/r3src/release/server/ddx/ibm/mpel/RCS/mpelFont.c,v $ */
  48.  
  49. #ifndef lint
  50. static char *rcsid = "$Id: mpelFont.c,v 6.5 89/04/29 21:38:15 jeff Exp $";
  51. #endif
  52.  
  53. #include "Xproto.h"
  54. #include "Xmd.h"
  55. #include "misc.h"
  56. #include "dixfontstr.h"
  57. #include "scrnintstr.h"
  58.  
  59. #include "ibmTrace.h"
  60.  
  61. #include "mpelHdwr.h"
  62. #include "mpelFifo.h"
  63. #include "mpelFont.h"
  64.  
  65. static    mpelATFRegion    *mpelRegion;
  66. static    mpelMpelFont    mpelFonts[MPEL_ATF_NUMFONTS];
  67.  
  68. static    mpelXFont    *mpelFontBeingMapped;
  69. static    int         mpelFontHosed;
  70.  
  71. /***==================================================================***/
  72.  
  73. static    mpelATFRegion    *mpelSave;
  74.  
  75. void
  76. mpelSaveFonts()
  77. {
  78. int    i;
  79.  
  80.     TRACE(("mpelSaveFonts()\n"));
  81.     mpelSave= (mpelATFRegion *)Xalloc(sizeof(mpelATFRegion));
  82.     if (mpelSave==NULL) {
  83.     ErrorF("couldn't allocate save space in mpelSaveFonts\n");
  84.     }
  85.     bcopy(mpelRegion,mpelSave,sizeof(mpelATFRegion));
  86.     for (i=0;i<MPEL_ATF_NUMFONTS;i++) {
  87.     mpelFonts[i].myRegion=   mpelSave;
  88.     mpelFonts[i].myHeader=    &mpelSave->atfHeaders[i];
  89.     mpelFonts[i].myLookup=     (unsigned short int *) mpelSave->lookup[i];
  90.     }
  91.     mpelRegion= mpelSave;
  92.     return;
  93. }
  94.  
  95. /***==================================================================***/
  96.  
  97. void
  98. mpelRestoreFonts()
  99. {
  100. int    i;
  101.  
  102.     TRACE(("mpelRestoreFonts()\n"));
  103.     mpelRegion= (mpelATFRegion *)MPEL_ATF_REGION;
  104.     MPEL_ATF_LOC_PTR= mpelAddr(MPEL_ATF_REGION);
  105.     if (mpelSave!=NULL) {
  106.     bcopy(mpelSave,mpelRegion,sizeof(mpelATFRegion));
  107.     Xfree(mpelSave);
  108.     mpelSave= NULL;
  109.     }
  110.     else {
  111.     ErrorF("mpelRestoreFonts called with nothing saved\n");
  112.     }
  113.     for (i=0;i<MPEL_ATF_NUMFONTS;i++) {
  114.     mpelFonts[i].myRegion=   mpelRegion;
  115.     mpelFonts[i].myHeader=    &mpelRegion->atfHeaders[i];
  116.     mpelFonts[i].myLookup=     (unsigned short int *) mpelRegion->lookup[i];
  117.     }
  118.     return;
  119. }
  120.  
  121. /***==================================================================***/
  122.  
  123. static void
  124. mpelMFontInit(mFont,w,h)
  125.     mpelMpelFont    *mFont;
  126.     int            w,h;
  127. {
  128.     int            i;
  129.  
  130.     TRACE(("mpelMFontInit(mFont=0x%x,w=%d,h=%d)\n",mFont,w,h));
  131.  
  132.     mFont->nextFreePt=    1;
  133.     for (i=0;i<256;i++) {
  134.     mFont->myLookup[i]= i+1;
  135.     }
  136.     mFont->myLookup[255]= 0;
  137.     mFont->xFonts=      NULL;
  138.     mFont->myHeader->fd.width=    w;
  139.     mFont->myHeader->fd.height=    h;
  140.     mFont->myHeader->fd.baseline= (((h+3)/4)*4)-h;
  141.     mFont->myHeader->fd.bitsperchar= 16*((w+3)/4)*((h+3)/4);
  142.     return;
  143. }
  144.  
  145. /***==================================================================***/
  146.  
  147. static void
  148. mpelRegionInit(rgn)
  149.     mpelATFRegion    *rgn;
  150. {
  151.     int            i;
  152.  
  153.     TRACE(("mpelRegionInit(sRgn=0x%x)\n",rgn));
  154.  
  155.     rgn->usage.nextFreeBand=    0;
  156.     rgn->usage.nextUse=    0;
  157.     for (i=0;i<MPEL_ATF_NUMBANDS;i++) {
  158.     rgn->bands[i].nextBand=    i+1;
  159.     rgn->bands[i].nextPtrn=    0;
  160.     }
  161.     rgn->bands[MPEL_ATF_MAXBAND].nextBand= MPEL_ATF_NOBAND;
  162.     for (i=0;i<MPEL_ATF_NUMFONTS;i++) {
  163.     mpelMFontInit(&rgn->usage.myFonts[i],0,0);
  164.     }
  165.     return;
  166. }
  167.  
  168. /***==================================================================***/
  169.  
  170. void
  171. mpelInitFonts()
  172. {
  173.     mpelATFLocTable    *loc;
  174.     mpelATFHeader    *fnt;
  175.     unsigned short int *lookup;
  176.     int             i;
  177.     unsigned long int tmp;
  178.  
  179.     TRACE(("mpelInitFonts()\n"));
  180.  
  181.     mpelRegion= (mpelATFRegion *)MPEL_ATF_REGION;
  182.     bzero(mpelRegion,sizeof(mpelATFRegion));
  183.  
  184.     /* initialize locations table */
  185.     loc= &mpelRegion->atfLocations;
  186.     loc->numEntries=    MPEL_ATF_NUMFONTS;
  187.     for (i=0;i<MPEL_ATF_NUMFONTS;i++) {
  188.     fnt=        &mpelRegion->atfHeaders[i];
  189.     lookup=        (unsigned short int *) mpelRegion->lookup[i];
  190.  
  191.     loc->entries[i].fid=    100+i;
  192.     tmp= (unsigned long int)mpelAddr(fnt);
  193.     loc->entries[i].addrHigh=    (tmp>>16)&0xffff;
  194.     loc->entries[i].addrLow=    (tmp&0xffff);
  195.  
  196.     fnt->size=    (unsigned long int)(((char *)(&lookup[256]))-((char *)fnt));
  197.     fnt->class=         2;
  198.         fnt->fontId=        100+i;
  199.         fnt->fontStyle=        0;
  200.         fnt->fontAttribute=    0;
  201.         fnt->fd.fontTotalChars=    256;
  202.         fnt->fd.tblWordSize=    256;
  203.         fnt->fd.baseline=    0;
  204.         fnt->fd.capline=    0;
  205.         fnt->fd.width=        0;
  206.         fnt->fd.height=        0;
  207.         fnt->fd.bitsperchar=    0;
  208.     fnt->fd.underlineTop=    0;
  209.     fnt->fd.underlineBase=    0;
  210.     fnt->fd.monoPitch=    0x80;
  211.         fnt->fd.lookupTblOffset= (unsigned long int)(((CARD16 *)lookup)-((CARD16 *)fnt));
  212.  
  213.     mpelFonts[i].myRegion=    mpelRegion;
  214.     mpelFonts[i].myHeader=    fnt;
  215.     mpelFonts[i].myLookup=    lookup;
  216.     }
  217.  
  218.     mpelRegion->usage.myFonts=    &mpelFonts[0];
  219.     mpelRegionInit(mpelRegion);
  220.     return;
  221. }
  222.  
  223. /***==================================================================***/
  224.  
  225. static mpelXFont *
  226. mpelGetFont(width,height,fontrows,fontcols,firstcol,firstrow)
  227.     int    width;
  228.     int    height;
  229.     unsigned int fontrows, fontcols, firstcol,firstrow;
  230. {
  231.     mpelMpelFont    *mFont,*freeMFont= NULL;
  232.     mpelATFHeader    *hdr= NULL;
  233.     int            i,found= FALSE;
  234.     int            bitsPerChar;
  235.     mpelXFont        *xFont;
  236.     int nchars = fontrows * fontcols;
  237.  
  238.     TRACE(("mpelGetFont(width=%d,height=%d,%d,%d,%d,%d)\n",width,height,
  239.     fontrows, fontcols, firstcol, firstrow));
  240.  
  241.     bitsPerChar= ((width+3)/4)*((height+3)/4)*16;
  242.  
  243.     if (bitsPerChar/16>MPEL_BAND_PTRNSIZE)
  244.     return(NULL);    /* too big */
  245.     
  246.     for (i=0;i<MPEL_ATF_NUMFONTS;i++) {
  247.     mFont= &mpelFonts[i];
  248.     hdr= mFont->myHeader;
  249.     if (hdr->fd.width==width) {
  250.         found= TRUE;
  251.         break;
  252.     }
  253.     else if ((!freeMFont)&&(hdr->fd.bitsperchar==0)) {
  254.         freeMFont= mFont;
  255.     }
  256.     }
  257.     if ((!found)&&(!freeMFont))
  258.     return(NULL);
  259. /* we assume mFont is consistent, so init and free had
  260.  * better take care of initializing it
  261.  */
  262.     if (!found) {
  263.     mFont=    freeMFont;
  264.     mpelMFontInit(mFont,width,height);
  265.     hdr=    mFont->myHeader;
  266.     }
  267.  
  268.     xFont= (mpelXFont *)Xalloc(sizeof(mpelXFont));
  269.     xFont->myMpelFont=    mFont;
  270.     xFont->mpelId=    hdr->fontId;
  271.     xFont->numMapped=    0;
  272.     xFont->width=    width;
  273.     xFont->height=    height;
  274.     xFont->nChars=    nchars;
  275.     xFont->mpelMap=    (CARD8 *)Xalloc(nchars * sizeof(CARD8));
  276.     bzero(xFont->mpelMap,(nchars*sizeof(CARD8)));
  277.     xFont->fontcols=    fontcols;
  278.     xFont->fontrows=    fontrows;
  279.     xFont->firstcol=    firstcol;
  280.     xFont->firstrow=    firstrow;
  281.     xFont->currentBand=    MPEL_ATF_NOBAND;
  282.     xFont->lastUse=    mFont->myRegion->usage.nextUse++;
  283.     xFont->nextXFont=    mFont->xFonts;
  284.     mFont->xFonts=    xFont;
  285.     return xFont;
  286. }
  287.  
  288. /***==================================================================***/
  289.  
  290. static void
  291. mpelCleanXFont(xFont)
  292.     mpelXFont    *xFont;
  293. {
  294.     mpelMpelFont    *mFont= xFont->myMpelFont;
  295.     mpelATFRegion    *rgn= mFont->myRegion;
  296.     int             band,i;
  297.  
  298.     TRACE(("mpelCleanXFont(0x%x) %x/%x chars\n",xFont,
  299.         xFont->numMapped,xFont->nChars));
  300.  
  301.     MPELNoOp(2,&MPELNoOpData);
  302.     MPELWaitFifo();
  303.     /* First, free any bands the font is holding */
  304.     band= xFont->currentBand;
  305.     while (band!=MPEL_ATF_NOBAND) {
  306.     rgn->bands[band].nextPtrn=    0;
  307.     if (rgn->bands[band].nextBand==MPEL_ATF_NOBAND) {
  308.         rgn->bands[band].nextBand= rgn->usage.nextFreeBand;
  309.         rgn->usage.nextFreeBand= xFont->currentBand;
  310.         band= MPEL_ATF_NOBAND;
  311.     }
  312.     else band= rgn->bands[band].nextBand;
  313.     }
  314.     xFont->currentBand= MPEL_ATF_NOBAND;
  315.  
  316.     /* then free any code points */
  317.     for (i=0;i<xFont->nChars;i++) {
  318.     register int ch = xFont->mpelMap[i];
  319.     if (ch) {
  320. #if DEBUG > 2
  321.         TRACE(("\tfreeing char %x from font %x\n", ch, xFont));
  322. #endif
  323.         mFont->myLookup[ch]= mFont->nextFreePt;
  324.         mFont->nextFreePt= ch;
  325.         xFont->mpelMap[i]= 0;
  326.         xFont->numMapped--;
  327.     }
  328.     }
  329. #ifndef NDEBUG
  330.     if (xFont->numMapped!=0) {
  331.     ErrorF("WSGO!! %d still mapped in CleanXFont\n",xFont->numMapped);
  332.     xFont->numMapped= 0;
  333.     }
  334. #endif
  335.     if (xFont==mpelFontBeingMapped)
  336.     mpelFontHosed= TRUE;
  337.     return ;
  338. }
  339.  
  340. /***==================================================================***/
  341.  
  342. static void 
  343. mpelDeleteXFont(xFont)
  344.    mpelXFont    *xFont;
  345. {
  346.     mpelXFont        **lastFont;
  347.     mpelMpelFont     *mFont= xFont->myMpelFont;
  348.  
  349.     TRACE(("mpelDeleteXFont(0x%x)\n",xFont));
  350.  
  351.     /* clean up structures first */
  352.     mpelCleanXFont(xFont);
  353.  
  354.     /* Remove xFont from mFont's list of fonts... */
  355.     lastFont= &mFont->xFonts;
  356.     while ((*lastFont)&&(*lastFont!=xFont)) {
  357.     lastFont= &((*lastFont)->nextXFont);
  358.     }
  359.     if (*lastFont)    *lastFont= xFont->nextXFont;
  360.     else         ErrorF("WSGO!! mpelDeleteXFont couldn't find xFont\n");
  361.  
  362.     /* if xFont was the last X font using mFont, initialize mFont */
  363.     if (mFont->xFonts==NULL)
  364.     mpelMFontInit(mFont,0,0);
  365.  
  366.     if (xFont->mpelMap)
  367.     Xfree(xFont->mpelMap);
  368.     Xfree(xFont);
  369.     return ;
  370. }
  371.  
  372. /***==================================================================***/
  373.  
  374. static void
  375. mpelNeedCodePoints(xFont)
  376.     mpelXFont    *xFont;
  377. {
  378.     mpelMpelFont    *mFont= xFont->myMpelFont;
  379.     mpelXFont        *oldestFont,*tmpFont;
  380.     int            oldest;
  381.  
  382.     TRACE(("mpelNeedCodePoints(0x%x)\n",xFont));
  383.     oldest= xFont->lastUse= ++mFont->myRegion->usage.nextUse;
  384.     oldestFont= xFont;
  385.  
  386.     tmpFont= mFont->xFonts;
  387.     while (tmpFont) {
  388.     if ((tmpFont->lastUse<oldest)&&(tmpFont->numMapped)) {
  389.         oldest= tmpFont->lastUse;
  390.         oldestFont= tmpFont;
  391.     }
  392.     tmpFont= tmpFont->nextXFont;
  393.     }
  394.     mpelCleanXFont(oldestFont);
  395.     if (!mFont->nextFreePt) {
  396.     ErrorF("WSGO!! CleanXFont didn't free points\n");
  397.     }
  398.     return ;
  399. }
  400.  
  401. /***==================================================================***/
  402.  
  403. static void
  404. mpelNeedBands(xFont)
  405.     mpelXFont    *xFont;
  406. {
  407.     mpelATFRegion    *rgn= xFont->myMpelFont->myRegion;
  408.     mpelMpelFont    *mFont;
  409.     mpelXFont        *oldestFont,*tmpFont;
  410.     int             oldest,i;
  411.  
  412.     TRACE(("mpelNeedBands(0x%x)\n",xFont));
  413.     oldest= xFont->lastUse= ++rgn->usage.nextUse;
  414.     oldestFont= xFont;
  415.     for (i=0;i<MPEL_ATF_NUMFONTS;i++) {
  416.     mFont= &rgn->usage.myFonts[i];
  417.     tmpFont= mFont->xFonts;
  418.     while (tmpFont) {
  419.         if ((tmpFont->lastUse<oldest)&&
  420.                 (tmpFont->currentBand!=MPEL_ATF_NOBAND)) {
  421.         oldest= tmpFont->lastUse;
  422.         oldestFont= tmpFont;
  423.         }
  424.         tmpFont= tmpFont->nextXFont;
  425.     }
  426.     }
  427.     mpelCleanXFont(oldestFont);
  428.     if (rgn->usage.nextFreeBand==MPEL_ATF_NOBAND) {
  429.     ErrorF("WSGO!! CleanXFont didn't free bands\n");
  430.     }
  431.     return ;
  432. }
  433.  
  434. /***==================================================================***/
  435.  
  436. static void
  437. mpelGetBand(xFont)
  438.     mpelXFont    *xFont;
  439. {
  440.     mpelMpelFont    *mFont= xFont->myMpelFont;
  441.     mpelATFRegion    *rgn= mFont->myRegion;
  442.     int             band;
  443.  
  444.     TRACE(("mpelGetBand(xFont=0x%x)\n",xFont));
  445.  
  446.     if (rgn->usage.nextFreeBand==MPEL_ATF_NOBAND) 
  447.     mpelNeedBands(xFont);
  448.  
  449.     band= rgn->usage.nextFreeBand;
  450.     rgn->usage.nextFreeBand= rgn->bands[band].nextBand;
  451.     rgn->bands[band].nextBand= xFont->currentBand;
  452.     rgn->bands[band].nextPtrn= 0;
  453.     xFont->currentBand= band;
  454.     return ;
  455. }
  456.  
  457. /***==================================================================***/
  458.  
  459. static unsigned char
  460. mpelMapChar(xFont,ch,ptrn)
  461.     mpelXFont    *xFont;
  462.     unsigned short     ch;
  463.     unsigned char    *ptrn;
  464. {
  465.     mpelMpelFont    *mFont= xFont->myMpelFont;
  466.     mpelATFBand        *bands= &mFont->myRegion->bands[0];
  467.     int             newPt=0,band= MPEL_ATF_NOBAND;
  468.     CARD16        *ptrnOut;
  469.  
  470.     TRACE(("mpelMapChar(xFont=0x%x,ch=%d,ptrn=0x%x)\n",xFont,ch,ptrn));
  471.  
  472.     /* find a code point */
  473.     if (mFont->nextFreePt==0) {
  474.     mpelNeedCodePoints(xFont);
  475.     if (mpelFontHosed)
  476.        return(0);
  477.     }
  478.     newPt= mFont->nextFreePt;
  479. #if DEBUG > 1
  480.     TRACE(("\tnewPt = %x\n", newPt));
  481. #endif
  482.     mFont->nextFreePt=    mFont->myLookup[newPt];
  483.     xFont->mpelMap[ch]=    newPt;
  484.     xFont->numMapped++;
  485.  
  486.     /* find someplace to stick the pattern */
  487.     while (band==MPEL_ATF_NOBAND) {
  488.     if (xFont->currentBand==MPEL_ATF_NOBAND) {
  489.         mpelGetBand(xFont);
  490.         if (mpelFontHosed) {
  491.         xFont->numMapped--;
  492. #ifdef DEBUG
  493.         TRACE(("error mapping char\n"));
  494. #endif
  495.         return(0);
  496.         }
  497.     }
  498.     band= xFont->currentBand;
  499.     if (bandSpaceLeft((&bands[band]))<fontWordSize(mFont)) {
  500.         mpelGetBand(xFont);
  501.         if (mpelFontHosed) {
  502.         xFont->numMapped--;
  503. #ifdef DEBUG
  504.         TRACE(("error mapping char\n"));
  505. #endif
  506.         return(0);
  507.         }
  508.         band= xFont->currentBand;
  509.     }
  510.     }
  511.  
  512.     ptrnOut= bandNextSpace(&bands[band]);
  513.     mpelTransmogrify(fontWidth(xFont),fontHeight(xFont),ptrn,ptrnOut);
  514.     bands[band].nextPtrn+= fontWordSize(mFont);
  515.     mFont->myLookup[newPt]= ((CARD16 *)ptrnOut)-((CARD16 *)mFont->myHeader)-
  516.                         sizeof(mpelATFHeader)/2;
  517.     return newPt ;
  518. }
  519.  
  520.  
  521. /***==================================================================***/
  522.  
  523. Bool
  524. mpelRealizeFont( pScr, pFont )
  525.     ScreenPtr    pScr;
  526.     FontPtr    pFont;
  527. {
  528.     xCharInfo        *maxb = &pFont->info.maxbounds;
  529.     xCharInfo        *minb = &pFont->info.minbounds;
  530.     mpelXFont        *xFont;
  531.     unsigned int    fontrows, fontcols;
  532.     unsigned int    firstrow, firstcol;
  533.     int            nChars;
  534.  
  535.     TRACE(("mpelRealizeFont(pScr= 0x%x,pFont= 0x%x)\n",pScr,pFont));
  536.  
  537.     if (pFont->info.constantMetrics) {
  538.     firstcol = pFont->info.firstCol;
  539.     fontcols = nChars = pFont->info.lastCol - firstcol + 1;
  540.     firstrow = pFont->info.firstRow;
  541.     if (pFont->info.lastRow > 0) {
  542.         fontrows = pFont->info.lastRow - firstrow + 1; 
  543.         nChars *= fontrows;
  544.     } else {
  545.         fontrows = 1;
  546.     }
  547.     xFont = mpelGetFont(pFont->info.maxbounds.characterWidth,
  548.                 pFont->info.fontAscent + pFont->info.fontDescent,
  549.                 fontrows, fontcols, firstcol, firstrow);
  550.     FontSetPrivate(pFont,mpelFontPrivateIndex,(pointer)xFont);
  551.     if (xFont) {
  552.         if(fontrows > 0) {
  553.         register unsigned short tmp = pFont->info.defaultCh;
  554.         xFont->defaultCh = ((tmp >> 8) - firstrow) * fontcols + (tmp & 255) - firstcol;
  555.         } else {
  556.         xFont->defaultCh = pFont->info.defaultCh;
  557.         }
  558.         return TRUE;
  559.     }
  560.     } else {
  561.     FontSetPrivate(pFont,mpelFontPrivateIndex,0);
  562.     }
  563.     return mfbRealizeFont(pScr,pFont) ;
  564. }
  565.  
  566. /***==================================================================***/
  567.  
  568. Bool
  569. mpelUnrealizeFont( pScr, pFont)
  570.     ScreenPtr    pScr;
  571.     FontPtr    pFont;
  572. {
  573.     mpelXFont *mpf = (mpelXFont *)FontGetPrivate(pFont, mpelFontPrivateIndex);
  574.     TRACE(("mpelUnrealizeFont(pScr=0x%x,pFont=0x%x)\n"));
  575.     if ((unsigned int)mpf > 40) {
  576.     mpelDeleteXFont(mpf);
  577.     }
  578.     FontSetPrivate(pFont, mpelFontPrivateIndex, 0);
  579.     return TRUE ;
  580. }
  581.  
  582. /***==================================================================***/
  583. #ifdef DEBUG
  584.  
  585. static int
  586. mpelMFontUsage(mFont)
  587.     mpelMpelFont    *mFont;
  588. {
  589.     mpelATFRegion    *rgn= mFont->myRegion;
  590.     mpelXFont        *xFont;
  591.     int            i,
  592.             nXFonts=0,
  593.             nBands=0,
  594.             nChars= 0,
  595.             bandSpaceUsed=0,
  596.             usage=0;
  597.  
  598.     if (!mFont->myHeader->fd.bitsperchar) {
  599.     ErrorF("inactive\n");
  600.     return 0 ;
  601.     }
  602.     xFont= mFont->xFonts;
  603.     while (xFont) {
  604.     nXFonts++;
  605.     i= xFont->currentBand;
  606.     nChars+= xFont->numMapped;
  607.     while (i!=MPEL_ATF_NOBAND) {
  608.          nBands++;
  609.          bandSpaceUsed+= rgn->bands[i].nextPtrn;
  610.          i= rgn->bands[i].nextBand;
  611.          if (nBands>MPEL_ATF_NUMBANDS) {
  612.         ErrorF("WSGO! Too many bands\n");
  613.         return MPEL_ATF_NUMBANDS ;
  614.          }
  615.     }
  616.     xFont= xFont->nextXFont;
  617.     }
  618.  
  619.     if (nBands) 
  620.         usage= (100*bandSpaceUsed)/(nBands*MPEL_BAND_PTRNSIZE);
  621.  
  622.     ErrorF("[%d bits], %d X fonts, %d chars, %d bands (%%%d usage)\n",
  623.                     mFont->myHeader->fd.bitsperchar,
  624.                     nXFonts,nChars,nBands,usage);
  625.     return nBands ;
  626. }
  627. #endif
  628.  
  629. /***==================================================================***/
  630.  
  631. #if defined(DEBUG) && !defined(NDEBUG)
  632. static void
  633. mpelATFUsage( rgn )
  634.     mpelATFRegion    *rgn;
  635. {
  636.     int        i,
  637.         count=0,
  638.         bandKnt=0;
  639.  
  640.     ErrorF("Megapel ATF Region usage (0x%x):\n",rgn);
  641.     ErrorF("nextFreeBand:    %d\n",rgn->usage.nextFreeBand);
  642.     ErrorF("nextUse:        %d\n",rgn->usage.nextUse);
  643.     ErrorF("Annotation fonts:\n");
  644.     for (i=0;i<MPEL_ATF_NUMFONTS;i++) {
  645.     ErrorF("font %d: ",i);
  646.     bandKnt+= mpelMFontUsage(&rgn->usage.myFonts[i]);
  647.     }
  648.  
  649.     for (count=0,i=rgn->usage.nextFreeBand;i!=MPEL_ATF_NOBAND;
  650.                         i=rgn->bands[i].nextBand) {
  651.     count++;
  652.     }
  653.     ErrorF("free Bands: %d\n",count);
  654.     bandKnt+= count;
  655.     if (bandKnt<MPEL_ATF_NUMBANDS) {
  656.     ErrorF("Warning!! Missing bands (%d should be %d)\n",bandKnt,
  657.                             MPEL_ATF_NUMBANDS);
  658.     }
  659.     if (bandKnt>MPEL_ATF_NUMBANDS) {
  660.     ErrorF("Warning!! Too many bands (%d should be %d)\n",bandKnt,
  661.                             MPEL_ATF_NUMBANDS);
  662.     }
  663.     return ;
  664. }
  665. #endif
  666.  
  667. /***==================================================================***/
  668.  
  669. void
  670. mpelRemap(
  671.     mpelXFont        *xFont,
  672.     int             nCh,
  673.     unsigned     char    *inStr,
  674.     unsigned    char    *outStr,
  675.     CharInfoPtr     *ppci,        /* array of character info */
  676.     FontEncoding     encoding)
  677. {
  678.     int fontsize = (encoding == Linear16Bit || encoding == TwoD16Bit);
  679.     int firstrow = xFont->firstrow;
  680.     int cols = xFont->fontcols;
  681.     int    i;
  682.  
  683.     TRACE(("mpelRemap(xFont=0x%x,nCh=%d,inStr=%x,outStr=%x,encoding %d) %x\n",
  684.         xFont, nCh, inStr, outStr, encoding, *inStr));
  685.  
  686. #ifdef DEBUG
  687. #if TRACE_X && 0
  688.     if (ibmTrace) {
  689.     ErrorF("\tchars: ");
  690.     for (i = 0; i < nCh; i++)
  691.         ErrorF("%02x ", inStr[i]);
  692.     ErrorF("\n\tfirstrow = %x, firstcol = %x\n", firstrow, xFont->firstcol);
  693.     }
  694. #endif
  695.     if ( !strncmp( inStr, "dUmp", 4 ) )
  696.     mpelATFUsage( xFont->myMpelFont->myRegion ) ;
  697. #endif /* DEBUG */
  698.  
  699.     mpelFontBeingMapped= xFont;
  700.     mpelFontHosed= FALSE;
  701.  
  702.     for (i=0;i<nCh;i++) {
  703.     unsigned short ch;
  704.     if (mpelFontHosed) {
  705.         i=0;
  706.         mpelFontHosed= FALSE;
  707.     }
  708.     if (fontsize) {
  709.         register unsigned short tmp;
  710.         tmp = *inStr++;
  711.         ch = *inStr++;
  712.         if (tmp >= firstrow && tmp < firstrow + xFont->fontrows &&
  713.             ch >= xFont->firstcol && ch < xFont->firstcol + cols) {
  714.             ch += (tmp - xFont->firstrow) * cols;
  715.         } else {
  716.             ch = xFont->defaultCh;
  717.         }
  718.     } else {
  719.         ch = *inStr++ - xFont->firstcol;
  720.         if (ch > xFont->nChars)
  721.             ch = xFont->defaultCh;
  722.     }
  723.     if (xFont->mpelMap[ch]!=0) 
  724.         outStr[i]= xFont->mpelMap[ch];
  725.     else
  726.             outStr[i]= mpelMapChar(xFont,ch,ppci[i]->bits);
  727.     xFont->lastUse= ++xFont->myMpelFont->myRegion->usage.nextUse;
  728.     }
  729.     return;
  730. }
  731.