home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / fonts / lib / font / bitmap / fontink.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-10  |  6.5 KB  |  209 lines

  1. /*
  2.  * $XConsortium: fontink.c,v 1.2 91/05/10 15:58:28 keith Exp $
  3.  *
  4.  * Copyright 1990 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Keith Packard, MIT X Consortium
  24.  */
  25.  
  26. #include "fontfilest.h"
  27.  
  28. static unsigned char ink_mask_msb[8] = {
  29.     0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
  30. };
  31.  
  32. static unsigned char ink_mask_lsb[8] = {
  33.     0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
  34. };
  35.  
  36. FontCharInkMetrics(pFont, pCI, pInk)
  37.     FontPtr     pFont;
  38.     CharInfoPtr pCI;
  39.     xCharInfo  *pInk;
  40. {
  41.     int         leftBearing,
  42.                 ascent,
  43.                 descent;
  44.     register int vpos,
  45.                 hpos,
  46.                 bpos;
  47.     int         bitmapByteWidth,
  48.                 bitmapByteWidthPadded;
  49.     int         bitmapBitWidth;
  50.     int         span;
  51.     register unsigned char *p;
  52.     unsigned char *ink_mask;
  53.     register int bmax;
  54.     register unsigned char charbits;
  55.  
  56.     if (pFont->bit == MSBFirst)
  57.     ink_mask = ink_mask_msb;
  58.     else if (pFont->bit == LSBFirst)
  59.     ink_mask = ink_mask_lsb;
  60.     pInk->characterWidth = pCI->metrics.characterWidth;
  61.     pInk->attributes = pCI->metrics.attributes;
  62.  
  63.     leftBearing = pCI->metrics.leftSideBearing;
  64.     ascent = pCI->metrics.ascent;
  65.     descent = pCI->metrics.descent;
  66.     bitmapBitWidth = GLYPHWIDTHPIXELS(pCI);
  67.     bitmapByteWidth = GLYPHWIDTHBYTES(pCI);
  68.     bitmapByteWidthPadded = BYTES_PER_ROW(bitmapBitWidth, pFont->glyph);
  69.     span = bitmapByteWidthPadded - bitmapByteWidth;
  70.  
  71.     p = (unsigned char *) pCI->bits;
  72.     for (vpos = descent + ascent; --vpos >= 0;) {
  73.     for (hpos = bitmapByteWidth; --hpos >= 0;) {
  74.         if (*p++ != 0)
  75.         goto found_ascent;
  76.     }
  77.     p += span;
  78.     }
  79.     /*
  80.      * special case -- font with no bits gets all zeros
  81.      */
  82.     pInk->leftSideBearing = leftBearing;
  83.     pInk->rightSideBearing = leftBearing;
  84.     pInk->ascent = 0;
  85.     pInk->descent = 0;
  86.     return;
  87. found_ascent:
  88.     pInk->ascent = vpos - descent + 1;
  89.  
  90.     p = ((unsigned char *) pCI->bits) + bitmapByteWidthPadded * 
  91.     (descent + ascent - 1) + bitmapByteWidth;
  92.  
  93.     for (vpos = descent + ascent; --vpos >= 0;) {
  94.     for (hpos = bitmapByteWidth; --hpos >= 0;) {
  95.         if (*--p != 0)
  96.         goto found_descent;
  97.     }
  98.     p -= span;
  99.     }
  100. found_descent:
  101.     pInk->descent = vpos - ascent + 1;
  102.  
  103.     bmax = 8;
  104.     for (hpos = 0; hpos < bitmapByteWidth; hpos++) {
  105.     charbits = 0;
  106.     p = (unsigned char *) pCI->bits + hpos;
  107.     for (vpos = descent + ascent; --vpos >= 0; p += bitmapByteWidthPadded)
  108.         charbits |= *p;
  109.     if (charbits) {
  110.         if (hpos == bitmapByteWidth - 1)
  111.         bmax = bitmapBitWidth - (hpos << 3);
  112.         p = ink_mask;
  113.         for (bpos = bmax; --bpos >= 0;) {
  114.         if (charbits & *p++)
  115.             goto found_left;
  116.         }
  117.     }
  118.     }
  119. found_left:
  120.     pInk->leftSideBearing = leftBearing + (hpos << 3) + bmax - bpos - 1;
  121.  
  122.     bmax = bitmapBitWidth - ((bitmapByteWidth - 1) << 3);
  123.     for (hpos = bitmapByteWidth; --hpos >= 0;) {
  124.     charbits = 0;
  125.     p = (unsigned char *) pCI->bits + hpos;
  126.     for (vpos = descent + ascent; --vpos >= 0; p += bitmapByteWidthPadded)
  127.         charbits |= *p;
  128.     if (charbits) {
  129.         p = ink_mask + bmax;
  130.         for (bpos = bmax; --bpos >= 0;) {
  131.         if (charbits & *--p)
  132.             goto found_right;
  133.         }
  134.     }
  135.     bmax = 8;
  136.     }
  137. found_right:
  138.     pInk->rightSideBearing = leftBearing + (hpos << 3) + bpos + 1;
  139. }
  140.  
  141. #define    ISBITONMSB(x, line)    ((line)[(x)/8] & (1 << (7-((x)%8))))
  142. #define    SETBITMSB(x, line)    ((line)[(x)/8] |= (1 << (7-((x)%8))))
  143. #define    ISBITONLSB(x, line)    ((line)[(x)/8] & (1 << ((x)%8)))
  144. #define    SETBITLSB(x, line)    ((line)[(x)/8] |= (1 << ((x)%8)))
  145.  
  146. #define Min(a,b)    ((a)<(b)?(a):(b))
  147. #define Max(a,b)    ((a)>(b)?(a):(b))
  148.  
  149. FontCharReshape(pFont, pSrc, pDst)
  150.     FontPtr     pFont;
  151.     CharInfoPtr pSrc,
  152.                 pDst;
  153. {
  154.     int         x,
  155.                 y;
  156.     unsigned char *in_line,
  157.                *out_line;
  158.     unsigned char *oldglyph,
  159.                *newglyph;
  160.     int         inwidth;
  161.     int         outwidth,
  162.                 outheight;
  163.     int         out_bytes,
  164.                 in_bytes;
  165.     int         y_min,
  166.                 y_max,
  167.                 x_min,
  168.                 x_max;
  169.  
  170.     newglyph = (unsigned char *) pDst->bits;
  171.     outwidth = pDst->metrics.rightSideBearing - pDst->metrics.leftSideBearing;
  172.     outheight = pDst->metrics.descent + pDst->metrics.ascent;
  173.     out_bytes = BYTES_PER_ROW(outwidth, pFont->glyph);
  174.  
  175.     oldglyph = (unsigned char *) pSrc->bits;
  176.     inwidth = pSrc->metrics.rightSideBearing - pSrc->metrics.leftSideBearing;
  177.     in_bytes = BYTES_PER_ROW(inwidth, pFont->glyph);
  178.  
  179.     bzero(newglyph, out_bytes * outheight);
  180.     in_line = oldglyph;
  181.     out_line = newglyph;
  182.     y_min = Max(-pSrc->metrics.ascent, -pDst->metrics.ascent);
  183.     y_max = Min(pSrc->metrics.descent, pDst->metrics.descent);
  184.     x_min = Max(pSrc->metrics.leftSideBearing, pDst->metrics.leftSideBearing);
  185.     x_max = Min(pSrc->metrics.rightSideBearing, pDst->metrics.rightSideBearing);
  186.     in_line += (y_min + pSrc->metrics.ascent) * in_bytes;
  187.     out_line += (y_min + pDst->metrics.ascent) * out_bytes;
  188.     if (pFont->bit == MSBFirst) {
  189.     for (y = y_min; y < y_max; y++) {
  190.         for (x = x_min; x < x_max; x++) {
  191.         if (ISBITONMSB(x - pSrc->metrics.leftSideBearing, in_line))
  192.             SETBITMSB(x - pDst->metrics.leftSideBearing, out_line);
  193.         }
  194.         in_line += in_bytes;
  195.         out_line += out_bytes;
  196.     }
  197.     } else {
  198.     for (y = y_min; y < y_max; y++) {
  199.         for (x = x_min; x < x_max; x++) {
  200.         if (ISBITONLSB(x - pSrc->metrics.leftSideBearing, in_line))
  201.             SETBITLSB(x - pDst->metrics.leftSideBearing, out_line);
  202.         }
  203.         in_line += in_bytes;
  204.         out_line += out_bytes;
  205.     }
  206.     }
  207.     return;
  208. }
  209.