xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

fbglyph.c (7420B)


      1 /*
      2  *
      3  * Copyright © 1998 Keith Packard
      4  *
      5  * Permission to use, copy, modify, distribute, and sell this software and its
      6  * documentation for any purpose is hereby granted without fee, provided that
      7  * the above copyright notice appear in all copies and that both that
      8  * copyright notice and this permission notice appear in supporting
      9  * documentation, and that the name of Keith Packard not be used in
     10  * advertising or publicity pertaining to distribution of the software without
     11  * specific, written prior permission.  Keith Packard makes no
     12  * representations about the suitability of this software for any purpose.  It
     13  * is provided "as is" without express or implied warranty.
     14  *
     15  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     17  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     21  * PERFORMANCE OF THIS SOFTWARE.
     22  */
     23 
     24 #ifdef HAVE_DIX_CONFIG_H
     25 #include <dix-config.h>
     26 #endif
     27 
     28 #include "fb.h"
     29 #include	<X11/fonts/fontstruct.h>
     30 #include	"dixfontstr.h"
     31 
     32 static Bool
     33 fbGlyphIn(RegionPtr pRegion, int x, int y, int width, int height)
     34 {
     35     BoxRec box;
     36     BoxPtr pExtents = RegionExtents(pRegion);
     37 
     38     /*
     39      * Check extents by hand to avoid 16 bit overflows
     40      */
     41     if (x < (int) pExtents->x1)
     42         return FALSE;
     43     if ((int) pExtents->x2 < x + width)
     44         return FALSE;
     45     if (y < (int) pExtents->y1)
     46         return FALSE;
     47     if ((int) pExtents->y2 < y + height)
     48         return FALSE;
     49     box.x1 = x;
     50     box.x2 = x + width;
     51     box.y1 = y;
     52     box.y2 = y + height;
     53     return RegionContainsRect(pRegion, &box) == rgnIN;
     54 }
     55 
     56 void
     57 fbPolyGlyphBlt(DrawablePtr pDrawable,
     58                GCPtr pGC,
     59                int x,
     60                int y,
     61                unsigned int nglyph, CharInfoPtr * ppci, void *pglyphBase)
     62 {
     63     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
     64     CharInfoPtr pci;
     65     unsigned char *pglyph;      /* pointer bits in glyph */
     66     int gx, gy;
     67     int gWidth, gHeight;        /* width and height of glyph */
     68     FbStride gStride;           /* stride of glyph */
     69     void (*glyph) (FbBits *, FbStride, int, FbStip *, FbBits, int, int);
     70     FbBits *dst = 0;
     71     FbStride dstStride = 0;
     72     int dstBpp = 0;
     73     int dstXoff = 0, dstYoff = 0;
     74 
     75     glyph = 0;
     76     if (pGC->fillStyle == FillSolid && pPriv->and == 0) {
     77         dstBpp = pDrawable->bitsPerPixel;
     78         switch (dstBpp) {
     79         case 8:
     80             glyph = fbGlyph8;
     81             break;
     82         case 16:
     83             glyph = fbGlyph16;
     84             break;
     85         case 32:
     86             glyph = fbGlyph32;
     87             break;
     88         }
     89     }
     90     x += pDrawable->x;
     91     y += pDrawable->y;
     92 
     93     while (nglyph--) {
     94         pci = *ppci++;
     95         pglyph = FONTGLYPHBITS(pglyphBase, pci);
     96         gWidth = GLYPHWIDTHPIXELS(pci);
     97         gHeight = GLYPHHEIGHTPIXELS(pci);
     98         if (gWidth && gHeight) {
     99             gx = x + pci->metrics.leftSideBearing;
    100             gy = y - pci->metrics.ascent;
    101             if (glyph && gWidth <= sizeof(FbStip) * 8 &&
    102                 fbGlyphIn(fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) {
    103                 fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff,
    104                               dstYoff);
    105                 (*glyph) (dst + (gy + dstYoff) * dstStride, dstStride, dstBpp,
    106                           (FbStip *) pglyph, pPriv->xor, gx + dstXoff, gHeight);
    107                 fbFinishAccess(pDrawable);
    108             }
    109             else {
    110                 gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip);
    111                 fbPushImage(pDrawable,
    112                             pGC,
    113                             (FbStip *) pglyph,
    114                             gStride, 0, gx, gy, gWidth, gHeight);
    115             }
    116         }
    117         x += pci->metrics.characterWidth;
    118     }
    119 }
    120 
    121 void
    122 fbImageGlyphBlt(DrawablePtr pDrawable,
    123                 GCPtr pGC,
    124                 int x,
    125                 int y,
    126                 unsigned int nglyph, CharInfoPtr * ppciInit, void *pglyphBase)
    127 {
    128     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
    129     CharInfoPtr *ppci;
    130     CharInfoPtr pci;
    131     unsigned char *pglyph;      /* pointer bits in glyph */
    132     int gWidth, gHeight;        /* width and height of glyph */
    133     FbStride gStride;           /* stride of glyph */
    134     Bool opaque;
    135     int n;
    136     int gx, gy;
    137     void (*glyph) (FbBits *, FbStride, int, FbStip *, FbBits, int, int);
    138     FbBits *dst = 0;
    139     FbStride dstStride = 0;
    140     int dstBpp = 0;
    141     int dstXoff = 0, dstYoff = 0;
    142 
    143     glyph = 0;
    144     if (pPriv->and == 0) {
    145         dstBpp = pDrawable->bitsPerPixel;
    146         switch (dstBpp) {
    147         case 8:
    148             glyph = fbGlyph8;
    149             break;
    150         case 16:
    151             glyph = fbGlyph16;
    152             break;
    153         case 32:
    154             glyph = fbGlyph32;
    155             break;
    156         }
    157     }
    158 
    159     x += pDrawable->x;
    160     y += pDrawable->y;
    161 
    162     if (TERMINALFONT(pGC->font)
    163         && !glyph) {
    164         opaque = TRUE;
    165     }
    166     else {
    167         int xBack, widthBack;
    168         int yBack, heightBack;
    169 
    170         ppci = ppciInit;
    171         n = nglyph;
    172         widthBack = 0;
    173         while (n--)
    174             widthBack += (*ppci++)->metrics.characterWidth;
    175 
    176         xBack = x;
    177         if (widthBack < 0) {
    178             xBack += widthBack;
    179             widthBack = -widthBack;
    180         }
    181         yBack = y - FONTASCENT(pGC->font);
    182         heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
    183         fbSolidBoxClipped(pDrawable,
    184                           fbGetCompositeClip(pGC),
    185                           xBack,
    186                           yBack,
    187                           xBack + widthBack,
    188                           yBack + heightBack,
    189                           fbAnd(GXcopy, pPriv->bg, pPriv->pm),
    190                           fbXor(GXcopy, pPriv->bg, pPriv->pm));
    191         opaque = FALSE;
    192     }
    193 
    194     ppci = ppciInit;
    195     while (nglyph--) {
    196         pci = *ppci++;
    197         pglyph = FONTGLYPHBITS(pglyphBase, pci);
    198         gWidth = GLYPHWIDTHPIXELS(pci);
    199         gHeight = GLYPHHEIGHTPIXELS(pci);
    200         if (gWidth && gHeight) {
    201             gx = x + pci->metrics.leftSideBearing;
    202             gy = y - pci->metrics.ascent;
    203             if (glyph && gWidth <= sizeof(FbStip) * 8 &&
    204                 fbGlyphIn(fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) {
    205                 fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff,
    206                               dstYoff);
    207                 (*glyph) (dst + (gy + dstYoff) * dstStride, dstStride, dstBpp,
    208                           (FbStip *) pglyph, pPriv->fg, gx + dstXoff, gHeight);
    209                 fbFinishAccess(pDrawable);
    210             }
    211             else {
    212                 gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip);
    213                 fbPutXYImage(pDrawable,
    214                              fbGetCompositeClip(pGC),
    215                              pPriv->fg,
    216                              pPriv->bg,
    217                              pPriv->pm,
    218                              GXcopy,
    219                              opaque,
    220                              gx,
    221                              gy,
    222                              gWidth, gHeight, (FbStip *) pglyph, gStride, 0);
    223             }
    224         }
    225         x += pci->metrics.characterWidth;
    226     }
    227 }