home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xibm.zip / apa16 / apa16Text.c < prev    next >
C/C++ Source or Header  |  1992-03-19  |  17KB  |  702 lines

  1. /***********************************************************
  2. Copyright 1991 by the Massachusetts Institute of Technology
  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 the Massachusetts
  11. Institute of Technology (M.I.T.) not be used in advertising or publicity
  12. pertaining to distribution of the software without specific, written
  13. prior permission.
  14.  
  15. M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21. SOFTWARE.
  22.  
  23. ******************************************************************/
  24.  
  25. #ifndef lint
  26. static char *rcsid = "$Id: apa16Text.c,v 5.4 1992/03/20 01:01:14 jfc Exp $";
  27. #endif
  28.  
  29. #include    "X.h"
  30. #include    "Xmd.h"
  31. #include    "Xproto.h"
  32. #include    "misc.h"
  33. #include    "dixfontstr.h"
  34. #include    "gcstruct.h"
  35. #include    "scrnintstr.h"
  36. #include    "regionstr.h"
  37. #include    "pixmapstr.h"
  38.  
  39. #include    "mfb.h"
  40.  
  41. #include    "ibmTrace.h"
  42.  
  43. #include    "OScompiler.h"
  44. #include    "apa16Decls.h"
  45. #include    "apa16Hdwr.h"
  46. #include    "apa16Font.h"
  47. #include    "apa16Text.h"
  48.  
  49. #ifndef NO_FUNCTION_PROTOTYPES
  50. static void apa16UncachedImageText8(DrawablePtr, GCPtr, int, int, int, char *, FontEncoding);
  51. static int apa16UncachedPolyText8();
  52. static void apa16FastCopyChars(apa16FontPtr, int, int, int, char *, int);
  53. static void apa16CopyCharsClip1(apa16FontPtr, int, int, int, char *, int, BoxPtr);
  54. static void apa16CopyCharsClipN(apa16FontPtr, int, int, int, char *, int, RegionPtr);
  55. #else
  56. static void apa16UncachedImageText8();
  57. static int apa16UncachedPolyText8();
  58. static void apa16FastCopyChars(), apa16CopyCharsClip1(), apa16CopyCharsClipN();
  59. #endif
  60.  
  61. void
  62. apa16ImageText8(pDrawable, pGC, x, y, count, chars)
  63. DrawablePtr      pDrawable;
  64. GCPtr         pGC;
  65. int         x, y;
  66. int         count;
  67. char        *chars;
  68. {
  69.   FontPtr pFont;
  70.   apa16FontPtr aFont;
  71.   RegionPtr pRegion;
  72.   int w;
  73.   int i;
  74.  
  75.   if ((pGC->planemask & 1) == 0 || count == 0)
  76.     return;
  77.  
  78.   pFont = pGC->font;
  79.   aFont = (apa16FontPtr)FontGetPrivate(pFont,apa16FontPrivateIndex);
  80.  
  81.   if (aFont == 0 || pDrawable->type != DRAWABLE_WINDOW ||
  82.       ! APA16_FONT_CACHED(aFont))
  83.     {
  84.       apa16UncachedImageText8(pDrawable, pGC, x, y, count, chars, Linear8Bit);
  85.       return;
  86.     }
  87.  
  88.   TRACE(("apa16ImageText8(%x,%x,%d,%d,%d,%x) %x\n",
  89.     pDrawable,pGC,x,y,count,chars,chars[0]));
  90.  
  91.   x += pDrawable->x;
  92.   y += pDrawable->y;
  93.  
  94.   pRegion = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip;
  95.  
  96.   w = 0;
  97.  
  98.   if (aFont->afWidth > 0)
  99.     w += count * aFont->afWidth;
  100.   else
  101.     for (i = 0; i < count; i++)
  102.       w += aFont->afChars->chars[chars[i]]->metrics.characterWidth;
  103.  
  104.   /* If it were known that the area drawn did not extend beyond the bounding
  105.      box of the font, this statement could be conditional on
  106.  
  107.      if (pGC->fgPixel == 0 || pGC->bgPixel == 1)
  108.      
  109.      */
  110.     {
  111.       register unsigned short cmd;
  112.       int descent = pFont->info.fontDescent;
  113.       int ascent = pFont->info.fontAscent;
  114.       BoxRec box;
  115.       BoxPtr pbox;
  116.       int n;
  117.  
  118.       if (pGC->bgPixel)
  119.     {
  120.       APA16_GET_CMD_FILL(RROP_WHITE, cmd);
  121.     }
  122.       else
  123.     {
  124.       APA16_GET_CMD_FILL(RROP_BLACK, cmd);
  125.     }
  126.  
  127.       /* Clear an area starting at (x,y - ascent),
  128.      with width = (sum of char overall widths)
  129.      and height = ascent + descent */
  130.  
  131.       box.x1 = x;
  132.       box.x2 = x + w;
  133.       box.y1 = y - ascent;
  134.       box.y2 = y + descent;
  135.  
  136.       /* The apa16 code only uses the mi region code, so it is not
  137.      necessary to call via the function pointer in the screen
  138.      structure. */
  139.       switch (miRectIn(pRegion, &box))
  140.     {
  141.     case rgnIN:
  142.       FILL_RECT(cmd, box.x2, box.y2, w, ascent + descent);
  143.       break;
  144.  
  145.     case rgnOUT:
  146.       break;
  147.  
  148.     case rgnPART:
  149.       n = REGION_NUM_RECTS(pRegion);
  150.       pbox = REGION_RECTS(pRegion);
  151.  
  152.       while(n-- > 0)
  153.         {
  154.           int x1 = MAX(x, pbox->x1);
  155.           int y1 = MAX(y - ascent, pbox->y1);
  156.           int x2 = MIN(x + w, pbox->x2);
  157.           int y2 = MIN(y + descent, pbox->y2);
  158.           if (x2 > x1 && y2 > y1)
  159.         { FILL_RECT(cmd, x2, y2, x2 - x1, y2 - y1); }
  160.           pbox++;
  161.         }
  162.       break;
  163.     }
  164.       /* This is actually incorrect: it should print whatever parts of
  165.      the characters extend beyond the bounding box.  */
  166.       if (pGC->fgPixel == pGC->bgPixel)
  167.     return;
  168.     }
  169.  
  170.     {
  171.       register unsigned short cmd;
  172.       register int i;
  173.       int descent, ascent;
  174.       BoxRec box;
  175.       char c;
  176.  
  177.       /* Verify that all the characters are cached. */
  178.  
  179.       i = count;
  180.       for(i = 0; i < count; i++)
  181.     if (!APA16_CHAR8_CACHED(aFont,chars[i]))
  182.       break;
  183.       if (i != count && !apa16CacheChars(aFont, (unsigned char *)chars, count))
  184.     goto fail;
  185.  
  186.       APA16_TOUCH_FONT(aFont, 0);
  187.  
  188.       if (pGC->fgPixel)
  189.     {
  190.       APA16_GET_CMD_COPY(ROP_RECT_COPY, GXor, cmd);
  191.     }
  192.       else
  193.     {
  194.       APA16_GET_CMD_COPY(ROP_RECT_COPY, GXandInverted, cmd);
  195.     }
  196.  
  197.       /* Assume that no character extends further to the left of the
  198.      origin than the first character and that no other character
  199.      draws to the right of the right edge of the last character.
  200.      It is possible to design a font where this assumption is false.  */
  201.  
  202.       c = chars[0];
  203.       if (aFont->afChars->chars[c] == 0)
  204.     c = aFont->afDefChar;
  205.  
  206.       /* Image text definition requires the window to be cleared to the
  207.          font ascent and descent, but this test must check the max bounds
  208.          because some characters could extend outside the region.  */
  209.  
  210.       descent = FONTMAXBOUNDS(pFont,descent);
  211.       ascent = FONTMAXBOUNDS(pFont,ascent);
  212.       box.x1 = x + aFont->afChars->chars[c]->metrics.leftSideBearing;
  213.       box.y1 = y - ascent;
  214.       box.y2 = y + descent;
  215.  
  216.       c = chars[count - 1];
  217.       if (aFont->afChars->chars[c] == 0)
  218.     c = aFont->afDefChar;
  219.  
  220.       box.x2 = x + w - aFont->afChars->chars[c]->metrics.characterWidth
  221.     + aFont->afChars->chars[c]->metrics.rightSideBearing;
  222.  
  223.       /* If no clipping needs to be done, use the fast routine. */
  224.       if (miRectIn(pRegion, &box) == rgnIN)
  225.     {
  226.       apa16FastCopyChars(aFont, x, box.y2, cmd, chars, count);
  227.       return;
  228.     }
  229.  
  230.       if(REGION_NUM_RECTS(pRegion) == 1)
  231.     apa16CopyCharsClip1(aFont, x, y, cmd, chars, count, REGION_RECTS(pRegion));
  232.       else
  233.     apa16CopyCharsClipN(aFont, x, y, cmd, chars, count, pRegion);
  234.       return;
  235.     }
  236.  fail:
  237.   apa16UncachedImageText8(pDrawable, pGC, x-pDrawable->x, y-pDrawable->y,
  238.               count, chars, Linear8Bit);
  239.   return;
  240. }
  241.  
  242.  
  243. int
  244. apa16PolyText8(pDrawable, pGC, xOrig, y, count, chars)
  245. DrawablePtr      pDrawable;
  246. GCPtr         pGC;
  247. int         xOrig, y;
  248. int         count;
  249. char        *chars;
  250. {
  251.   int x;
  252.   FontPtr pFont;
  253.   apa16FontPtr aFont;
  254.   RegionPtr pRegion;
  255.  
  256.   if (count == 0)
  257.     return xOrig;
  258.  
  259.   pFont = pGC->font;
  260.   aFont = (apa16FontPtr)FontGetPrivate(pFont,apa16FontPrivateIndex);
  261.  
  262.   if (aFont == 0 || pDrawable->type != DRAWABLE_WINDOW
  263.       || (pGC->planemask & 1) == 0
  264.       || APA16_FONT_CACHED(aFont) == 0)
  265.     {
  266.       return apa16UncachedPolyText8(pDrawable, pGC, xOrig, y, count, chars, Linear8Bit);
  267.     }
  268.  
  269.   TRACE(("apa16PolyText8(%x,%x,%d,%d,%d,%x) %x\n",
  270.     pDrawable,pGC,xOrig,y,count,chars,chars[0]));
  271.  
  272.   x = xOrig + pDrawable->x;
  273.   y += pDrawable->y;
  274.  
  275.   pRegion = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip;
  276.  
  277.   {
  278.     register unsigned short cmd;
  279.     register int i;
  280.     int descent, ascent;
  281.     int w;
  282.     BoxRec box;
  283.     char c;
  284.  
  285.     /* Verify that all the characters are cached.  This could be made
  286.        smarter, by copying the cached characters and only drawing the
  287.        uncached characters using the slow method. */
  288.  
  289.     i = count;
  290.     for(i = 0; i < count; i++)
  291.       if (!APA16_CHAR8_CACHED(aFont,chars[i]))
  292.     break;
  293.     if (i != count && !apa16CacheChars(aFont, (unsigned char *)chars, count))
  294.       return apa16UncachedPolyText8(pDrawable, pGC, xOrig,
  295.                     y - pDrawable->y, count, chars, Linear8Bit);
  296.  
  297.     APA16_TOUCH_FONT(aFont, 0);
  298.  
  299.     w = 0;
  300.     if (aFont->afWidth > 0)
  301.       w += count * aFont->afWidth;
  302.     else
  303.       for(i = 0; i < count; i++)
  304.     {
  305.       CharInfoPtr cip = aFont->afChars->chars[chars[i]];
  306.       if (cip)
  307.         w += cip->metrics.characterWidth;
  308.       else
  309.         w += aFont->afDefWidth;
  310.     }
  311.  
  312.     switch(((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop)
  313.       {
  314.       case RROP_WHITE:
  315.     APA16_GET_CMD_COPY(ROP_RECT_COPY, GXor, cmd);
  316.     break;
  317.       case RROP_BLACK:
  318.     APA16_GET_CMD_COPY(ROP_RECT_COPY, GXandInverted, cmd);
  319.     break;
  320.       case RROP_INVERT:
  321.     APA16_GET_CMD_COPY(ROP_RECT_COPY, GXxor, cmd);
  322.     break;
  323.       case RROP_NOP:
  324.       default:    /* for compiler data flow analysis */
  325.     return xOrig + w;
  326.       }
  327.  
  328.     c = chars[0];
  329.     if (aFont->afChars->chars[c] == 0)
  330.       c = aFont->afDefChar;
  331.  
  332.     descent = FONTMAXBOUNDS(pFont,descent);
  333.     ascent = FONTMAXBOUNDS(pFont,ascent);
  334.     box.x1 = x - aFont->afChars->chars[c]->metrics.leftSideBearing;
  335.     box.y1 = y - ascent;
  336.     box.y2 = y + descent;
  337.  
  338.     c = chars[count - 1];
  339.     if (aFont->afChars->chars[c] == 0)
  340.       c = aFont->afDefChar;
  341.  
  342.     box.x2 = x + w - aFont->afChars->chars[c]->metrics.characterWidth
  343.       + aFont->afChars->chars[c]->metrics.rightSideBearing;
  344.  
  345.     if (miRectIn(pRegion, &box) == rgnIN)
  346.       apa16FastCopyChars(aFont, x, box.y2, cmd, chars, count);
  347.     else if(REGION_NUM_RECTS(pRegion) == 1)
  348.       apa16CopyCharsClip1(aFont, x, y, cmd, chars, count, REGION_RECTS(pRegion));
  349.     else
  350.       apa16CopyCharsClipN(aFont, x, y, cmd, chars, count, pRegion);
  351.     return xOrig + w;
  352.   }
  353. }
  354.  
  355. /* Code stolen from mipolytext.c */
  356. void
  357. apa16ImageText16(pDraw, pGC, x, y, count, chars)
  358. DrawablePtr      pDraw;
  359. GCPtr         pGC;
  360. int         x, y;
  361. int         count;
  362. char        *chars;
  363. {
  364.     CharInfoPtr *charinfo;
  365.     unsigned long n;
  366.     FontPtr font = pGC->font;
  367.  
  368.     TRACE(("apa16ImageText16(%x,%x,%d,%d,%d,%x) %x,%x\n", pDraw, pGC, x, y, count, chars, chars[0], chars[1]));
  369.  
  370.     if(!(charinfo = (CharInfoPtr *)ALLOCATE_LOCAL(count*sizeof(CharInfoPtr))))
  371.     return;
  372.     GetGlyphs(font, (unsigned long)count, (unsigned char *)chars,
  373.           (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
  374.           &n, charinfo);
  375.     if (n != 0)
  376.       {
  377.     QUEUE_WAIT();
  378.         (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n,
  379.                    charinfo, FONTGLYPHS(font));
  380.       }
  381.     DEALLOCATE_LOCAL(charinfo);
  382. }
  383.  
  384.  
  385. static int
  386. apa16UncachedPolyText8(pDraw, pGC, x, y, count, chars)
  387.     DrawablePtr pDraw;
  388.     GCPtr    pGC;
  389.     int        x, y;
  390.     int     count;
  391.     char    *chars;
  392. {
  393.     register CharInfoPtr *charinfo;
  394.     unsigned long n, i;
  395.     int w;
  396.  
  397.     TRACE(("apa16PolyText8(%x,%x,%d,%d,%d,%x) %x (uncached)\n", pDraw, pGC, x, y, count, chars, chars[0]));
  398.  
  399.     if(!(charinfo = (CharInfoPtr *)ALLOCATE_LOCAL(count*sizeof(CharInfoPtr ))))
  400.     return x;
  401.     GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
  402.           Linear8Bit, &n, charinfo);
  403.     w = 0;
  404.     for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
  405.     if (n != 0)
  406.       {
  407.     QUEUE_WAIT();
  408.     (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, x, y, n,
  409.                   charinfo, FONTGLYPHS(pGC->font));
  410.       }
  411.     DEALLOCATE_LOCAL(charinfo);
  412.     return x+w;
  413. }
  414.  
  415.  
  416. int
  417. apa16PolyText16(pDraw, pGC, x, y, count, chars)
  418.     DrawablePtr pDraw;
  419.     GCPtr    pGC;
  420.     int        x, y;
  421.     int        count;
  422.     unsigned short *chars;
  423. {
  424.     register CharInfoPtr *charinfo;
  425.     unsigned long n, i;
  426.     int w;
  427.  
  428.     if(!(charinfo = (CharInfoPtr *)ALLOCATE_LOCAL(count*sizeof(CharInfoPtr))))
  429.     return x;
  430.     GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
  431.           (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
  432.           &n, charinfo);
  433.     TRACE(("apa16PolyText16(%x,%x,%d,%d,%d,%x) %x,%x\n", pDraw, pGC, x, y, count, chars, chars[0], chars[1]));
  434.     w = 0;
  435.     for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
  436.     if (n != 0)
  437.       {
  438.     QUEUE_WAIT();
  439.     (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, x, y, n,
  440.                   charinfo, FONTGLYPHS(pGC->font));
  441.       }
  442.     DEALLOCATE_LOCAL(charinfo);
  443.     return x+w;
  444. }
  445.  
  446. static void
  447. apa16UncachedImageText8(DrawablePtr pDraw, GCPtr pGC, int x, int y,
  448.             int count, char *chars, FontEncoding fontEncoding)
  449. {
  450.     register CharInfoPtr *charinfo;
  451.     unsigned long n;
  452.     FontPtr font = pGC->font;
  453.  
  454.     if(!(charinfo = (CharInfoPtr *)ALLOCATE_LOCAL(count*sizeof(CharInfoPtr))))
  455.     return;
  456.     GetGlyphs(font, (unsigned long)count, (unsigned char *)chars,
  457.           fontEncoding, &n, charinfo);
  458.  
  459.     TRACE(("apa16UncachedImageText8\n"));
  460.  
  461.     if (n != 0)
  462.       {
  463.     (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n,
  464.                    charinfo, FONTGLYPHS(font));
  465.       }
  466.     DEALLOCATE_LOCAL(charinfo);
  467.     return;
  468. }
  469.  
  470. /* This is called when all chars are unclipped.  It avoids reloading
  471.    the dest y coordinate register for each character, so drawing is
  472.    about 25% faster. */
  473.  
  474. static void
  475. apa16FastCopyChars(font,x,y,cmd,chars,count)
  476. apa16FontPtr font;
  477. int x,y;
  478. int cmd;
  479. char *chars;
  480. int count;
  481. {
  482.   register apa16FCCharInfo *fcip = font->afChars;
  483.   int descent = FONTMAXBOUNDS(font->afFont,descent);
  484.  
  485.   /* COPY_RECT_SETY reserves space for count commands and loads the
  486.      text y register */
  487.   COPY_RECT_SETY(count,y);
  488.  
  489.   cmd |= EXEC_MASK;
  490.  
  491.   while(count-- > 0)
  492.     {
  493.       register CharInfoPtr cip;
  494.       char c = *chars++;
  495.       int x2, h, w;
  496.  
  497.       cip = fcip->chars[c];
  498.       if (cip == 0)
  499.     {
  500.       c = font->afDefChar;
  501.       cip = fcip->chars[c];
  502.     }
  503.       x2 = x + cip->metrics.rightSideBearing;
  504.       h = cip->metrics.ascent + descent;
  505.  
  506.       if (h > 0 && (w = GLYPHWIDTHPIXELS(cip)) > 0)
  507.     {
  508.       COPY_RECT_CONT(cmd, x2, APA16_CHAR8_CACHE_X(fcip, c),
  509.              APA16_CHAR8_CACHE_Y(fcip, c), w, h);
  510.     }
  511.  
  512.       x += cip->metrics.characterWidth;
  513.     }
  514.   return;
  515. }
  516.  
  517. /* Draw characters, clipping with a single rectangle.
  518.    When possible, this function also avoids reloading the y register.  */
  519.  
  520. static void
  521. apa16CopyCharsClip1(font, x, y, cmd, chars, count, pbox)
  522. apa16FontPtr font;
  523. int x,y;
  524. int cmd;
  525. char *chars;
  526. int count;
  527. BoxPtr pbox;
  528. {
  529.   register apa16FCCharInfo *fcip = font->afChars;
  530.   char def = font->afDefChar;
  531.   int descent = FONTMAXBOUNDS(font->afFont,descent);
  532.   short lasty;
  533.  
  534.   RESERVE_QUEUE(7 * count);
  535.  
  536.   apa16Qoffset--;
  537.   REG_LOAD(10,y+descent,1);
  538.  
  539.   lasty = y + descent;
  540.  
  541.   cmd |= EXEC_MASK;
  542.  
  543.   while (count-- > 0)
  544.     {
  545.       int x1, y1, x2, y2, xc, yc;
  546.       char c = *chars++;
  547.       register CharInfoPtr cip = fcip->chars[c];
  548.  
  549.       if (cip == 0)
  550.     {
  551.       c = def;
  552.       cip = fcip->chars[c];
  553.     }
  554.  
  555.       x1 = x + cip->metrics.leftSideBearing;
  556.       if (x1 < pbox->x1)
  557.     {
  558.       x1 = pbox->x1;
  559.     }
  560.  
  561.       xc = APA16_CHAR8_CACHE_X(fcip, c);
  562.       x2 = x + cip->metrics.rightSideBearing;
  563.       if (x2 > pbox->x2)
  564.     {
  565.       xc += (pbox->x2 - x2);
  566.       x2 = pbox->x2;
  567.     }
  568.       if (x2 <= x1)
  569.     {
  570.       x += cip->metrics.characterWidth;
  571.       continue;
  572.     }
  573.  
  574.       y1 = y - cip->metrics.ascent;
  575.       if (y1 < pbox->y1)
  576.     {
  577.       y1 = pbox->y1;
  578.     }
  579.  
  580.       yc = APA16_CHAR8_CACHE_Y(fcip, c);
  581.       y2 = y + descent;
  582.       if (y2 > pbox->y2)
  583.     {
  584.       yc += (pbox->y2 - y2);
  585.       y2 = pbox->y2;
  586.     }
  587.  
  588.       if (y2 > y1)
  589.     {
  590.       if (y2 != lasty)
  591.         {
  592.           apa16Qoffset--;
  593.           REG_LOAD(10,y2,1);
  594.           lasty = y2;
  595.         }
  596.       COPY_RECT_CONT(cmd, x2, xc, yc, x2 - x1, y2 - y1);
  597.     }
  598.  
  599.       x += cip->metrics.characterWidth;
  600.     }
  601.   return;
  602. }
  603.  
  604.  
  605. static void
  606. apa16CopyCharsClipN(font, x, y, cmd, chars, count, pRegion)
  607. apa16FontPtr font;
  608. int x,y;
  609. int cmd;
  610. char *chars;
  611. int count;
  612. RegionPtr pRegion;
  613. {
  614.   int descent = FONTMAXBOUNDS(font->afFont,descent);
  615.   int nbox = REGION_NUM_RECTS(pRegion);
  616.   BoxPtr pbox = REGION_RECTS(pRegion);
  617.   apa16FCCharInfo *fcip = font->afChars;
  618.  
  619.   while(count-- > 0)
  620.     {
  621.       BoxRec box;
  622.       char c = *chars++;
  623.  
  624.       if (fcip->chars[c] == 0)
  625.     c = font->afDefChar;
  626.  
  627.       box.x1 = x+fcip->chars[c]->metrics.leftSideBearing;
  628.       box.x2 = x+fcip->chars[c]->metrics.rightSideBearing;
  629.       box.y1 = y-fcip->chars[c]->metrics.ascent;
  630.       box.y2 = y+descent;
  631.  
  632.       if (box.x1 >= box.x2 || box.y1 >= box.y2)
  633.     {
  634.       x += fcip->chars[c]->metrics.characterWidth;
  635.       continue;
  636.     }
  637.       switch(miRectIn(pRegion, &box))
  638.     {
  639.     case rgnIN:
  640.       COPY_RECT(cmd, box.x2, box.y2,
  641.             APA16_CHAR8_CACHE_X(fcip, c),
  642.             APA16_CHAR8_CACHE_Y(fcip, c),
  643.             box.x2 - box.x1, box.y2 - box.y1);
  644.       break;
  645.  
  646.     case rgnOUT:
  647.       break;
  648.  
  649.     case rgnPART:
  650.       {
  651.         BoxPtr pboxtmp = pbox;
  652.         int nboxtmp = nbox;
  653.         while (nboxtmp-- > 0)
  654.           {
  655.         int x1, x2, y1, y2, xc, yc;
  656.  
  657.         x1 = box.x1;
  658.         if (x1 < pboxtmp->x1)
  659.           {
  660.             x1 = pboxtmp->x1;
  661.           }
  662.  
  663.         xc = APA16_CHAR8_CACHE_X(fcip, c);
  664.         x2 = box.x2;
  665.         if (x2 > pboxtmp->x2)
  666.           {
  667.             xc += (pboxtmp->x2 - x2);
  668.             x2 = pboxtmp->x2;
  669.           }
  670.         if (x2 <= x1)
  671.           {
  672.             pboxtmp++;
  673.             continue;
  674.           }
  675.  
  676.         y1 = box.y1;
  677.         if (y1 < pboxtmp->y1)
  678.           {
  679.             y1 = pboxtmp->y1;
  680.           }
  681.         
  682.         yc = APA16_CHAR8_CACHE_Y(fcip, c);
  683.         y2 = box.y2;
  684.         if (y2 > pboxtmp->y2)
  685.           {
  686.             yc += (pboxtmp->y2 - y2);
  687.             y2 = pboxtmp->y2;
  688.           }
  689.         if (y2 > y1)
  690.           {
  691.             COPY_RECT(cmd, x2, y2, xc, yc, x2 - x1, y2 - y1);
  692.           }
  693.         pboxtmp++;
  694.           } /* end while nboxtmp */
  695.       }
  696.     } /* end switch */
  697.       x += fcip->chars[c]->metrics.characterWidth;
  698.     } /* end while count */
  699.   return;
  700. }
  701.  
  702.