BSD 4_4_Lite2 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Sun, 25 Apr 1993 21:20:18 +0000 (13:20 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Sun, 25 Apr 1993 21:20:18 +0000 (13:20 -0800)
Work on file usr/src/contrib/X11R5-hp300/mit/server/ddx/hpbsd/topcat/tcText.c

Synthesized-from: CSRG/cd3/4.4BSD-Lite2

usr/src/contrib/X11R5-hp300/mit/server/ddx/hpbsd/topcat/tcText.c [new file with mode: 0644]

diff --git a/usr/src/contrib/X11R5-hp300/mit/server/ddx/hpbsd/topcat/tcText.c b/usr/src/contrib/X11R5-hp300/mit/server/ddx/hpbsd/topcat/tcText.c
new file mode 100644 (file)
index 0000000..00e57d0
--- /dev/null
@@ -0,0 +1,908 @@
+
+/*
+
+Copyright (c) 1986, 1987 by Hewlett-Packard Company
+Copyright (c) 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
+TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
+PURPOSE.  Hewlett-Packard shall not be liable for errors 
+contained herein or direct, indirect, special, incidental or 
+consequential damages in connection with the furnishing, 
+performance, or use of this material.
+
+This software is not subject to any license of the American
+Telephone and Telegraph Company or of the Regents of the
+University of California.
+
+*/
+/***********************************************************************
+ *  file: topcatText.c
+ *
+ *
+ *  ******************************************************************
+ *  *  (c) Copyright Hewlett-Packard Company, 1987.  All rights are  *
+ *  *  reserved.  Copying or other reproduction of this program      *
+ *  *  except for archival purposes is prohibited without prior      *
+ *  *  written consent of Hewlett-Packard Company.                  *
+ *  ******************************************************************
+ *
+ *  ImageText and PolyText routines for the topcat displays
+ *
+ *             Hewlett Packard -- Corvallis Workstation Operation
+ *             Project -- port of X11 to HP9000
+ *             Harry Phinney -- MTS
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#ifndef hpux
+#  include <sys/ioctl.h>
+#  include <grfioctl.h>
+#else
+#  include <sys/graphics.h>
+#endif
+
+#include "X.h"
+#include "Xproto.h"
+#include "../cfb/cfb.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+
+#include "mi.h"
+#include "topcat.h"
+#include "hpFonts.h"
+
+extern u_char XHP_NewRule[16][6]; /* array of replacement rules */
+
+
+static void
+waitAwhile(screenPlanes)
+     unsigned int screenPlanes;
+{
+}
+
+static void
+setRegs(hardware, pGC, zmask)
+     TOPCAT *hardware;
+     GCPtr pGC;
+     unsigned int zmask;
+{
+    if (pGC->bgPixel == -1)
+    {
+       /*
+        * handle special case of PolyText, so PolyText can be fast if
+        * it uses a solid fill
+        */
+       hardware->write_enable = zmask & pGC->fgPixel;
+       hardware->window_move_replacement_rule = XHP_NewRule[pGC->alu][4];
+       hardware->write_enable = zmask & ~pGC->fgPixel;
+       hardware->window_move_replacement_rule = XHP_NewRule[pGC->alu][5];
+    }
+    else
+    {
+       /*
+        * Set registers for normal ImageText case.  Note that pGC->alu
+        * is ignored, and GXcopy is forced.
+        */
+       hardware->write_enable = zmask & ~pGC->fgPixel & ~pGC->bgPixel;
+       hardware->window_move_replacement_rule = XHP_NewRule[GXcopy] [0];
+       hardware->write_enable = zmask & ~pGC->fgPixel & pGC->bgPixel;
+       hardware->window_move_replacement_rule = XHP_NewRule[GXcopy] [1];
+       hardware->write_enable = zmask & pGC->fgPixel & ~pGC->bgPixel;
+       hardware->window_move_replacement_rule = XHP_NewRule[GXcopy] [2];
+       hardware->write_enable = zmask & pGC->fgPixel & pGC->bgPixel;
+       hardware->window_move_replacement_rule = XHP_NewRule[GXcopy] [3];
+    }
+
+    hardware->frame_buf_write_enable = zmask;
+    hardware->write_enable = zmask;
+    hardware->pixel_write_replacement_rule = GXcopy;
+}
+
+/************************************************************************
+ *  Routine:    tcImageOptText
+ *              Render text strings to the display with "optimized" fonts.
+ *              Uses the Topcat block mover to place the character if the
+ *              character has been "optimized" (stored in offscreen memory).
+ *              If it's not in offscreen then we call pGC->ImageGlyphBlt.
+ *              It is assumed that these are *terminal fonts*, drawn left
+ *              to right, and have the most-used characters stored in
+ *              offscreen memory. The characters must be stored in increasing
+ *             order in the chunks, e.g. char 78 *must* be further down the
+ *             list of chunks than char 57, though char 63 doesn't have to 
+ *             be stored in offscreen. No chunk can have holes - the chars
+ *             must be contiguous within a chunk. In the example above, if
+ *             char 63 isn't stored, 57 and 78 *must* be in different chunks.
+ *
+ *             If pGC->bgPixel is -1, then assume we are being called by
+ *             PolyText, and make the glyph background a no-op (transparent).
+ *             This allows PolyText to be fast iff FillStyle == Solid.
+ *
+ *  Inputs: pDraw points to the drawable we're to print to
+ *          pGC points to the GC we're to use
+ *          x, y is the starting location for the string in the drawable
+ *          count is the number of characters we're to put out
+ *          chars points to an array of the characters we're to put out(!)
+ *          encoding is Linear8Bit, Linear16Bit, etc.
+ *
+ *  Returns: nothing
+ *
+ *  Side Effects: none
+ *
+ */
+void
+tcImageOptTEText8(pDraw, pGC, dstx, dsty, count, chars /*, encoding */)
+    DrawablePtr pDraw;
+    GCPtr       pGC;
+    int         dstx, dsty;
+    int         count;
+    u_char      *chars;
+    /* FontEncoding encoding; */
+{
+#if 0
+    FontEncoding encoding = Linear8Bit; /* should be passed in ... */
+    register TOPCAT *hardware = getTcHardware(pDraw->pScreen);
+    unsigned long screenPlanes = getPlanesMask(pDraw->pScreen);
+    unsigned long zmask = pGC->planemask & screenPlanes;
+    int fore = pGC->fgPixel;
+    int back = pGC->bgPixel;
+
+    FontPtr pfont = pGC->font;
+    CharInfoPtr pCI = pfont->pCI;
+    register unsigned int firstCol = FONTFIRSTCOL(pfont);
+    int numCols = FONTLASTCOL(pfont) - firstCol + 1;
+    unsigned int chDefault = FONTDEFAULTCH(pfont);
+
+    hpFontRec *pfrec = (hpFontRec *)(pfont->devPriv[pDraw->pScreen->myNum]);
+    hpChunk *pChunk;
+    Bool fDefaultExists = pfrec->fDefaultExists;
+
+    RegionPtr pRegion =
+       ((cfbPrivGC *)pGC->devPrivates[cfbGCPrivateIndex].ptr)->pCompositeClip;
+    register BoxPtr pBox = REGION_RECTS(pRegion);
+    int nbox = REGION_NUM_RECTS(pRegion);
+
+    int x, y, dx, dy, h, w;
+    int srcx, srcy;
+    int found; /* flag for in/out of offscreen */
+
+   /*
+    * some stupid applications send a request to output a zero length
+    * string, so I have to check for it.
+    */
+    if (!count)
+       return;
+
+   /*
+    * absolutize the coordinates 
+    */
+    dstx += pDraw->x;
+    dsty += pDraw->y;
+
+    /*
+     * adjust dsty from char baseline to top edge
+     * because we assume terminal fonts, all ascents are the same
+     */
+    dsty -= FONTMAXBOUNDS(pfont,ascent);
+
+    while (screenPlanes & hardware->move_active)
+       waitAwhile(screenPlanes);
+    
+    setRegs(hardware, pGC, zmask);
+
+    switch (encoding)
+    {
+      case Linear8Bit: 
+      case TwoD8Bit:
+       for (; nbox--; pBox++)
+       {                       /* for each clip box */
+           /*
+            * because we assume terminal fonts, we just need the w & h 
+            * of any random character from the font
+            * (since they're all the same)
+            */
+           w = pfrec->maxWidth;
+           h = pfrec->maxHeight;
+           y = dsty;
+           dx = 0;
+           dy = 0;
+
+           /*
+            * clip the height only once since all chars are same height&ascent
+            */
+           if (y < pBox->y1)
+           {
+               dy = pBox->y1 - y;
+               h -= dy;
+               y = pBox->y1;
+           }
+           if (y+h > pBox->y2)
+               h -= y + h - pBox->y2;
+               
+           /* 
+            * if any part is in the y-band of the box, write it
+            */
+           if (h > 0)
+           {
+               register u_char *str = chars;
+               register unsigned char st;
+               register slen = count;
+               x = dstx;
+
+               if (x < pBox->x1)
+               {
+                   /*
+                    * while the character is to the left of the clipping
+                    * rectangle, go to the next character
+                    */
+                   while (x+w <= pBox->x1)
+                   {
+                       if (--slen == 0)
+                           break;
+                       x += w;
+                       str++;
+                   }
+                   if (!slen)
+                       continue;
+                   /*
+                    * clip the first "in" character to the edge
+                    */
+                   if ((dx = pBox->x1 - x) < 0)
+                       dx = 0;
+                   if (x+dx >= pBox->x2)
+                       continue;
+               }
+
+               /*
+                * trim length to right edge of pBox 
+                */
+               if ((x + w*slen) >= pBox->x2)
+               {
+                   /* compute ceiling((pBox->x2 - x)/w) */
+                   slen = min((pBox->x2 - x + w - 1)/w, slen);
+                   if (slen <= 0)
+                       continue;
+               }
+
+               /*
+                * if the first glyph is clipped by the left edge,
+                * put it out
+                */
+               if (dx)
+               {
+                   st = *str++; 
+                   slen--;
+                   while (!fDefaultExists &&
+                          ((st < firstCol) || (st > FONTLASTCOL(pfont)) ||
+                           !pCI[st - firstCol].exists))
+                   {
+                       /*
+                        * if the default char doesn't exist, and this character
+                        * doesn't exist, then go on to next character
+                        */
+                       if (!--slen)
+                           continue;
+                       st = *str++;
+                   }
+                   found = 0;
+                   /*
+                    * find the char's location in offscreen (hopefully)
+                    */
+                   if (st >= pfrec->firstChar && st <= pfrec->lastChar)
+                   {
+                       srcx = 
+                           (pChunk = pfrec->ppChunk[(st - pfrec->firstChar) >> 5])->x +
+                               ((st - pfrec->firstChar) % 32) * pfrec->maxWidth;
+                       srcy = pChunk->y;
+                       found = 1;
+                   }
+                   if (!found)
+                   {
+                       CharInfoPtr pci;
+                       int oldTranslate = pGC->miTranslate;
+                       pGC->miTranslate = 0; /* we already translated it */
+                       if ((st < firstCol) || (st > FONTLASTCOL(pfont)) ||
+                           !(pci = &pCI[st - firstCol])->exists)
+                       {
+                           /*
+                            * we know the default char exists, or we
+                            * would have skipped over this glyph.
+                            * So put out the default glyph
+                            */
+                           pci = &pCI[chDefault - firstCol];
+                       }
+                       if (back == -1)
+                       {
+                           (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, x, 
+                                                     dsty + FONTMAXBOUNDS(pfont,ascent),
+                                                     1, &pci, FONTGLYPHS(pfont));
+                           hardware->write_enable = zmask & fore;
+                           hardware->window_move_replacement_rule = 
+                               XHP_NewRule[pGC->alu][4];
+                           hardware->write_enable = zmask & ~fore;
+                           hardware->window_move_replacement_rule =
+                               XHP_NewRule[pGC->alu][5];
+                       }
+                       else
+                       {
+                           (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, 
+                                                      dsty + FONTMAXBOUNDS(pfont,ascent),
+                                                      1, &pci, FONTGLYPHS(pfont));
+                           hardware->write_enable = zmask & ~fore & ~back;
+                           hardware->window_move_replacement_rule = 
+                               XHP_NewRule[GXcopy] [0];
+                           hardware->write_enable = zmask & ~fore & back;
+                           hardware->window_move_replacement_rule = 
+                               XHP_NewRule[GXcopy] [1];
+                           hardware->write_enable = zmask & fore & ~back;
+                           hardware->window_move_replacement_rule = 
+                               XHP_NewRule[GXcopy] [2];
+                           hardware->write_enable = zmask & fore & back;
+                           hardware->window_move_replacement_rule = 
+                               XHP_NewRule[GXcopy] [3];
+                       }
+                       pGC->miTranslate = oldTranslate;
+                       hardware->write_enable = zmask;
+                       hardware->frame_buf_write_enable = zmask;
+                       hardware->pixel_write_replacement_rule = GXcopy;
+                   }
+                   else
+                   {
+                       /*
+                        * use the block mover to place the glyph
+                        */
+
+                       if (!slen)
+                       {
+                           if (x+w > pBox->x2)
+                           {
+                               /* clip last char to right edge */
+                               w = pBox->x2 - x;
+                           }
+                       }
+
+                       while (screenPlanes & hardware->move_active) 
+                           waitAwhile(screenPlanes);
+                       hardware->source_x = srcx + dx;
+                       hardware->source_y = srcy + dy;
+                       hardware->dest_x = x + dx;
+                       hardware->dest_y = y;
+                       hardware->window_width = w - dx;
+                       hardware->window_height = h;
+                       hardware->start_move = zmask;
+                   }
+                   x += w; /* move to start pos of next char on screen */
+                   if (!slen)
+                       continue;
+               }
+
+               /*
+                * completely inside the clip box, put out each character
+                */
+               for (st = *str++; slen--; st = *str++)
+               {
+                   if (!fDefaultExists &&
+                       ((st < firstCol) || (st > numCols) ||
+                        !pCI[st - firstCol].exists))
+                   {
+                       /*
+                        * if the default char doesn't exist, and this
+                        * character doesn't exist, then do nothing
+                        */
+                       continue;
+                   }
+
+                   found = 0;
+                   if (st >= pfrec->firstChar && st <= pfrec->lastChar)
+                   {
+                       srcx =
+                           (pChunk = pfrec->ppChunk[(st - pfrec->firstChar) >> 5])->x +
+                               ((st - pfrec->firstChar) % 32) * pfrec->maxWidth;
+                       srcy = pChunk->y;
+                       found = 1;
+                   }
+
+                   if (!found)
+                   {
+                       /*
+                        * the char wasn't in any chunk, so call ImageGlyphBlt
+                        */
+                       CharInfoPtr pci;
+                       int oldTranslate = pGC->miTranslate;
+                       pGC->miTranslate = 0; /* we already translated it */
+                       if ((st < firstCol) || (st > numCols) ||
+                           !(pci = &pCI[st - firstCol])->exists)
+                       {
+                           /*
+                            * we know the default char exists, or we
+                            * would have skipped over this glyph.
+                            * So put out the default glyph
+                            */
+                           pci = &pCI[chDefault - firstCol];
+                       }
+                       if (back == -1)
+                       {
+                           (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, x, 
+                                                     dsty + FONTMAXBOUNDS(pfont,ascent),
+                                                     1, &pci, FONTGLYPHS(pfont));
+                           hardware->write_enable = zmask & fore;
+                           hardware->window_move_replacement_rule = 
+                               XHP_NewRule[pGC->alu][4];
+                           hardware->write_enable = zmask & ~fore;
+                           hardware->window_move_replacement_rule =
+                               XHP_NewRule[pGC->alu][5];
+                       }
+                       else
+                       {
+                           (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, 
+                                                      dsty + FONTMAXBOUNDS(pfont,ascent),
+                                                      1, &pci, FONTGLYPHS(pfont));
+                           hardware->write_enable = zmask & ~fore & ~back;
+                           hardware->window_move_replacement_rule = 
+                               XHP_NewRule[GXcopy] [0];
+                           hardware->write_enable = zmask & ~fore & back;
+                           hardware->window_move_replacement_rule = 
+                               XHP_NewRule[GXcopy] [1];
+                           hardware->write_enable = zmask & fore & ~back;
+                           hardware->window_move_replacement_rule = 
+                               XHP_NewRule[GXcopy] [2];
+                           hardware->write_enable = zmask & fore & back;
+                           hardware->window_move_replacement_rule = 
+                               XHP_NewRule[GXcopy] [3];
+                       }
+                       pGC->miTranslate = oldTranslate;
+                       hardware->write_enable = zmask;
+                       hardware->frame_buf_write_enable = zmask;
+                       hardware->pixel_write_replacement_rule = GXcopy;
+                   }
+                   else
+                   {
+                       /*
+                        * use the block mover to place the glyph
+                        */
+
+                       if (!slen)
+                       {
+                           if (x+w > pBox->x2)
+                           {
+                               /* clip last char to right edge */
+                               w = pBox->x2 - x;
+                           }
+                       }
+
+                       while(screenPlanes & hardware->move_active) 
+                           waitAwhile(screenPlanes);
+                       hardware->source_x = srcx;
+                       hardware->source_y = srcy + dy;
+                       hardware->dest_x = x;
+                       hardware->dest_y = y;
+                       hardware->window_width = w;
+                       hardware->window_height = h;
+                       hardware->start_move = zmask;
+                   }
+                   x += w; /* move to start pos of next char on screen */
+               }
+           }
+       }
+       break;
+      case Linear16Bit:
+      case TwoD16Bit:
+       break;
+    }
+#endif
+}
+
+/************************************************************************
+ *  Routine:    tcImageVarText
+ *              Render text strings to the display with "optimized" fonts
+ *             in the case where the font is variable-width, and varible
+ *             ascent, etc.
+ *              Uses the Topcat block mover to place the character if the
+ *              character has been "optimized" (stored in offscreen memory).
+ *              If it's not in offscreen then we call pGC->ImageGlyphBlt.
+ *              It is assumed that these characters are drawn left
+ *              to right, and have the most-used characters stored in
+ *              offscreen memory. The characters must be stored in increasing
+ *             order in the chunks, e.g. char 78 *must* be further down the
+ *             list of chunks than char 57, though char 63 doesn't have to 
+ *             be stored in offscreen. No chunk can have holes - the chars
+ *             must be contiguous within a chunk. In the example above, if
+ *             char 63 isn't stored, 57 and 78 *must* be in different chunks.
+ *
+ *             If pGC->bgPixel is -1, then assume we are being called by
+ *             PolyText, and make the glyph background a no-op (transparent).
+ *             This allows PolyText to be fast iff FillStyle == Solid.
+ *
+ *  Inputs: pDraw points to the drawable we're to print to
+ *          pGC points to the GC we're to use
+ *          x, y is the starting location for the string in the drawable
+ *          count is the number of characters we're to put out
+ *          chars points to an array of the characters we're to put out
+ *          encoding is Linear8Bit, Linear16Bit, etc.
+ *
+ *  Returns: nothing
+ *
+ *  Side Effects: none
+ *
+ */
+void
+tcImageOptText8(pDraw, pGC, dstx, dsty, count, chars /*, encoding */)
+    DrawablePtr pDraw;
+    GCPtr       pGC;
+    int         dstx, dsty;
+    int         count;
+    u_char      *chars;
+    /* FontEncoding encoding; */
+{
+#if 0
+    FontEncoding encoding = Linear8Bit; /* should be passed in ... */
+    register TOPCAT *hardware = getTcHardware(pDraw->pScreen);
+    int XHP_bits = hardware->bits;
+    unsigned long screenPlanes = getPlanesMask(pDraw->pScreen);
+    unsigned long zmask = pGC->planemask & screenPlanes;
+    int fore = pGC->fgPixel;
+    int back = pGC->bgPixel;
+
+    FontPtr pfont = pGC->font;
+    unsigned int firstCol = FONTFIRSTCOL(pfont);
+    unsigned int numCols = FONTLASTCOL(pfont) - firstCol + 1;
+    unsigned int chDefault = FONTDEFAULTCH(pfont);
+
+    int miny, maxy, minx, maxx;
+
+    CharInfoPtr pCI = pfont->pCI;
+    CharInfoPtr *ppCI;
+    ExtentInfoRec info;
+
+    hpFontRec *pfrec = (hpFontRec *)(pfont->devPriv[pDraw->pScreen->myNum]);
+    hpChunk *pChunk;
+    int numChunks = pfrec->NumChunks;
+    hpCharRange *pRange;
+    unsigned int maxWidth = pfrec->maxWidth;
+
+    RegionPtr pRegion =
+       ((cfbPrivGC *)pGC->devPrivates[cfbGCPrivateIndex].ptr)->pCompositeClip;
+    register BoxPtr pBox = REGION_RECTS(pRegion);
+    int nbox = REGION_NUM_RECTS(pRegion);
+
+    register int i, x, y, dx, dy, h, w, oldAlu, oldFS;
+    int n;
+    CARD32 oldFG;
+    int srcx, srcy;
+    int found = 0; /* flag for in/out of offscreen */
+
+    if (!count)
+       return;
+
+    if (back != -1)
+    {
+       /*
+        * Fill the background rectangle to the background color
+        */
+
+       /*
+        * build the array of CharInfo struct pointers for glyphs in the string
+        */
+       if (!(ppCI = (CharInfoPtr *)ALLOCATE_LOCAL(count*sizeof(CharInfoPtr))))
+           return;
+       GetGlyphs(pfont, count, chars, Linear8Bit, &n, ppCI);
+       QueryGlyphExtents(pGC->font, ppCI, n, &info);
+
+       oldAlu = pGC->alu;
+       oldFG = pGC->fgPixel;
+       oldFS = pGC->fillStyle;
+       /* fill in the background */
+       pGC->alu = (long) GXcopy;
+       pGC->fgPixel = (long) pGC->bgPixel;
+       pGC->fillStyle = (long) FillSolid;
+       tcPaintBlockClipped(pDraw,pGC,
+           dstx + 
+               ((pDraw->type == DRAWABLE_WINDOW) ? pDraw->x : PIXER(pDraw)->pChunk->x),
+           dsty - FONTASCENT(pGC->font) + 
+               ((pDraw->type == DRAWABLE_WINDOW) ? pDraw->y : PIXER(pDraw)->pChunk->y),
+           info.overallWidth,
+           FONTASCENT(pGC->font) + FONTDESCENT(pGC->font));
+       /*
+        * put the GC back except for alu
+        * in an ImageText, the effective alu is GXcopy
+        */
+       pGC->fgPixel = oldFG;
+       pGC->fillStyle = oldFS;
+    }
+
+    /*
+     * absolutize the coordinates 
+     */
+    dstx += pDraw->x;
+    dsty += pDraw->y;
+
+    miny = dsty - FONTMAXBOUNDS(pfont,ascent);
+    maxy = dsty + FONTMAXBOUNDS(pfont,descent);
+    minx = dstx + FONTMINBOUNDS(pfont,leftSideBearing); /* is this right? */
+    maxx = dstx + count * maxWidth;
+
+    waitbusy(screenPlanes, hardware);
+    /*
+     * set a PolyText type of replacement rule.
+     * we've cleared the background rectangle for the string in the case
+     * of an Imagetext call.
+     */
+    hardware->write_enable = zmask & fore;
+    hardware->window_move_replacement_rule = XHP_NewRule[pGC->alu][4];
+    hardware->write_enable = zmask & ~fore;
+    hardware->window_move_replacement_rule = XHP_NewRule[pGC->alu][5];
+
+    hardware->write_enable = zmask;
+    hardware->frame_buf_write_enable = zmask;
+    hardware->pixel_write_replacement_rule = GXcopy;
+
+    switch (encoding)
+    {
+      case Linear8Bit: 
+      case TwoD8Bit:
+       while (nbox--)
+       {                       /* for each clip box */
+           /*
+            * check to see if any characters may be in the clip box
+            * if any part may be in the box, write it
+            */
+           if ((pBox->x1 <= maxx) && (minx <= pBox->x2) &&
+               (pBox->y1 <= maxy) && (miny <= pBox->y2))
+           {
+               register int slen = count;
+               register u_char *str = chars;
+               register unsigned char st = *str++;
+               CharInfoPtr pci = pCI + st - firstCol;
+
+               x = dstx;
+
+               while ((st < firstCol) || (st > numCols) || !pci->exists)
+               {
+                   /*
+                    * check for non-existent glyphs & replace w/the default
+                    * or skip it if the default doesn't exist
+                    */
+                   if ((chDefault < firstCol) || 
+                       !pCI[chDefault - firstCol].exists)
+                   {
+                       /*
+                        * if the default char doesn't exist, then do nothing
+                        */
+                       st = *str++;
+                       pci = pCI + st - firstCol;
+                       if (--slen == 0)
+                           break;
+                       continue;
+                   }
+                   pci = pCI + chDefault - firstCol;
+                   st = chDefault;
+               }
+
+               /*
+                * while the character is to the left of the clipping
+                * rectangle, go to the next character
+                */
+               while ((x+(w = pci->metrics.characterWidth)) <= pBox->x1)
+               {
+                   if (--slen <= 0)
+                   {
+                       if (slen < 0) slen = 0;
+                       break;
+                   }
+                   x += w;
+                   st = *str++;
+                   pci = pCI + st - firstCol;
+                   if (!pci->exists)
+                   {
+                       pci = pCI + (chDefault - firstCol);
+                       st = chDefault;
+                   }
+               }
+
+               /*
+                * clip the first "in" character to the edge
+                */
+               if ((dx = pBox->x1 - (x+pci->metrics.leftSideBearing)) < 0)
+                   dx = 0;
+               if ((x+dx+pci->metrics.leftSideBearing) > pBox->x2)
+                   slen = 0;
+
+               /*
+                * in the clip box, put out each character
+                */
+               while (slen--)
+               {               /* for each char left in the string */
+                   pci = &pCI[st - firstCol];
+                   if ((st < firstCol) || (st > numCols) || !pci->exists)
+                   {
+                       /*
+                        * check for non-existent glyphs & replace w/the default
+                        */
+                       st = chDefault;
+                       pci = &pCI[chDefault - firstCol];
+                       if (st < firstCol || (st > numCols) || !pci->exists)
+                       {
+                           /*
+                            * if the default doesn't exist, skip the char
+                            */
+                           st = *str++;
+                           continue;
+                       }
+                   }
+
+                   /*
+                    * find the char's location in offscreen (hopefully)
+                    */
+                   found = 0; /* flag for in/out of offscreen */
+
+                   for (i = 0, pRange = pfrec->pRange; i < numChunks; i++, pRange++)
+                   {
+                       if (st <= pRange->endChar)
+                       {
+                           if (st >= pRange->startChar)
+                           {
+                               found = 1; /* we found it */
+                               pChunk = pfrec->ppChunk[i]; 
+                               srcx = pChunk->x + maxWidth * (st - pRange->startChar);
+                               srcy = pChunk->y;
+                               break;
+                           }
+                           else
+                           {
+                               /*
+                                * it's not in any of the chunks
+                                */
+                               break;
+                           }
+                       }
+                   }
+
+                   if (!found)
+                   {
+                       /*
+                        * the char wasn't in any chunk, so call ImageGlyphBlt
+                        */
+                       CharInfoPtr localpci = &pCI[st - firstCol];
+                       int oldTranslate = pGC->miTranslate;
+                       pGC->miTranslate = 0; /* we already translated it */
+                       if (back == -1)
+                           (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, x, dsty,
+                                                     1, &localpci, FONTGLYPHS(pfont));
+                       else
+                           (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, dsty,
+                                                      1, &localpci, FONTGLYPHS(pfont));
+                       hardware->write_enable = zmask & fore;
+                       hardware->window_move_replacement_rule = 
+                           XHP_NewRule[pGC->alu][4];
+                       hardware->write_enable = zmask & ~fore;
+                       hardware->window_move_replacement_rule =
+                           XHP_NewRule[pGC->alu][5];
+                       hardware->write_enable = zmask;
+                       hardware->frame_buf_write_enable = zmask;
+                       hardware->pixel_write_replacement_rule = GXcopy;
+
+                       pGC->miTranslate = oldTranslate; /* put it back */
+                   }
+                   else
+                   {
+                       /*
+                        * use the block mover to place the glyph
+                        */
+
+                       w = GLWIDTHPIXELS(pci);
+                       if (x+w+pci->metrics.leftSideBearing > pBox->x2)
+                       {
+                           /* clip to right edge */
+                           w = pBox->x2 - (x + pci->metrics.leftSideBearing);
+                       }
+
+                       /*
+                        * clip the height of the glyph
+                        */
+                       y = dsty - pci->metrics.ascent;
+                       dy = 0;
+                       h = GLHEIGHTPIXELS(pci);
+                       if (y < pBox->y1)
+                       {
+                           dy = pBox->y1 - y;
+                           h -= dy;
+                           y = pBox->y1;
+                       }
+                       if (y+h > pBox->y2)
+                           h -= y + h -pBox->y2;
+                       
+                       if ((h > 0) && (w > dx))
+                       {
+                           waitbusy(screenPlanes, hardware);
+                           hardware->source_x = (srcx + dx) << XHP_bits;
+                           hardware->source_y = srcy + dy;
+                           hardware->dest_x = (x + dx + 
+                                               pci->metrics.leftSideBearing) << XHP_bits;
+                           hardware->dest_y = y;
+                           hardware->window_width = (w - dx) << XHP_bits;
+                           hardware->window_height = h;
+                           hardware->start_move = zmask;
+                       }
+                   }
+                   /* move to start pos of next char on screen */
+                   x += pci->metrics.characterWidth;
+                   dx = 0;
+                   if (x >= pBox->x2)
+                       slen = 0; /* no more within pBox */
+                   st = *str++;
+               }
+           }
+           pBox++;
+       }
+       break;
+      case Linear16Bit:
+      case TwoD16Bit:
+       break;
+    }
+    if (back != -1)
+       /* put the alu back right */ 
+       pGC->alu = oldAlu; 
+    DEALLOCATE_LOCAL(ppCI);
+#endif
+}
+
+int
+tcPolyOptText8(pDraw, pGC, dstx, dsty, count, chars /*, encoding */)
+    DrawablePtr pDraw;
+    GCPtr       pGC;
+    int         dstx, dsty;
+    int         count;
+    u_char      *chars;
+    /* FontEncoding encoding; */
+{
+#if 0
+    if ((pGC->alu == GXcopy) && (pGC->fillStyle == FillSolid))
+    {
+       /*
+        * it looks enough like an imagetext that we can use tcImage???Text
+        */
+       register FontPtr pFont = pGC->font;
+       int oldBackground;
+       CharInfoPtr pci = pFont->pCI;
+       unsigned char *thischar = chars;
+
+       /*
+        * set background to -1 to tell tcImage???Text that the background
+        * should be transparent (no-op)
+        */
+       oldBackground = pGC->bgPixel;
+       pGC->bgPixel = -1;
+       (* pGC->ops->ImageText8)(pDraw, pGC, dstx, dsty, count, chars);
+       pGC->bgPixel = oldBackground;
+
+       while (count--)
+       {
+           dstx += pci[*thischar].metrics.characterWidth;
+           thischar++;
+       }
+       return dstx;
+    }
+    else
+       return miPolyText8(pDraw, pGC, dstx, dsty, count, chars);
+#endif
+}