~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to fb/fbglyph.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $XdotOrg: xserver/xorg/fb/fbglyph.c,v 1.5 2005/07/03 07:01:23 daniels Exp $
 
3
 * $XFree86: xc/programs/Xserver/fb/fbglyph.c,v 1.12tsi Exp $
 
4
 *
 
5
 * Copyright Ā© 1998 Keith Packard
 
6
 *
 
7
 * Permission to use, copy, modify, distribute, and sell this software and its
 
8
 * documentation for any purpose is hereby granted without fee, provided that
 
9
 * the above copyright notice appear in all copies and that both that
 
10
 * copyright notice and this permission notice appear in supporting
 
11
 * documentation, and that the name of Keith Packard not be used in
 
12
 * advertising or publicity pertaining to distribution of the software without
 
13
 * specific, written prior permission.  Keith Packard makes no
 
14
 * representations about the suitability of this software for any purpose.  It
 
15
 * is provided "as is" without express or implied warranty.
 
16
 *
 
17
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
18
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 
19
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
20
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 
21
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 
22
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
23
 * PERFORMANCE OF THIS SOFTWARE.
 
24
 */
 
25
 
 
26
#ifdef HAVE_DIX_CONFIG_H
 
27
#include <dix-config.h>
 
28
#endif
 
29
 
 
30
#include "fb.h"
 
31
#include        <X11/fonts/fontstruct.h>
 
32
#include        "dixfontstr.h"
 
33
 
 
34
#define dummyScreen screenInfo.screens[0]
 
35
      
 
36
Bool
 
37
fbGlyphIn (RegionPtr    pRegion,
 
38
           int          x,
 
39
           int          y,
 
40
           int          width,
 
41
           int          height)
 
42
{
 
43
    BoxRec  box;
 
44
    BoxPtr  pExtents = REGION_EXTENTS (dummyScreen, pRegion);
 
45
 
 
46
    /*
 
47
     * Check extents by hand to avoid 16 bit overflows
 
48
     */
 
49
    if (x < (int) pExtents->x1) 
 
50
        return FALSE;
 
51
    if ((int) pExtents->x2 < x + width) 
 
52
        return FALSE;
 
53
    if (y < (int) pExtents->y1)
 
54
        return FALSE;
 
55
    if ((int) pExtents->y2 < y + height)
 
56
        return FALSE;
 
57
    box.x1 = x;
 
58
    box.x2 = x + width;
 
59
    box.y1 = y;
 
60
    box.y2 = y + height;
 
61
    return RECT_IN_REGION (dummyScreen, pRegion, &box) == rgnIN;
 
62
}
 
63
 
 
64
#ifdef FB_24BIT
 
65
#ifndef FBNOPIXADDR
 
66
 
 
67
#define WRITE1(d,n,fg)  ((d)[n] = (CARD8) fg)
 
68
#define WRITE2(d,n,fg)  (*(CARD16 *) &(d[n]) = (CARD16) fg)
 
69
#define WRITE4(d,n,fg)  (*(CARD32 *) &(d[n]) = (CARD32) fg)
 
70
#if FB_UNIT == 6 && IMAGE_BYTE_ORDER == LSBFirst
 
71
#define WRITE8(d)       (*(FbBits *) &(d[0]) = fg)
 
72
#else
 
73
#define WRITE8(d)       WRITE4(d,0,_ABCA), WRITE4(d,4,_BCAB)
 
74
#endif
 
75
                         
 
76
/*
 
77
 * This is a bit tricky, but it's brief.  Write 12 bytes worth
 
78
 * of dest, which is four pixels, at a time.  This gives constant
 
79
 * code for each pattern as they're always aligned the same
 
80
 *
 
81
 *  a b c d  a b c d  a b c d   bytes
 
82
 *  A B C A  B C A B  C A B C   pixels
 
83
 * 
 
84
 *    f0        f1       f2
 
85
 *  A B C A  B C A B  C A B C   pixels LSB
 
86
 *  C A B C  A B C A  B C A B   pixels MSB
 
87
 *
 
88
 *              LSB     MSB
 
89
 *  A           f0      f1
 
90
 *  B           f1      f2
 
91
 *  C           f2      f0
 
92
 *  A B         f0      f2
 
93
 *  B C         f1      f0
 
94
 *  C A         f2      f1
 
95
 *  A B C A     f0      f1
 
96
 *  B C A B     f1      f2
 
97
 *  C A B C     f2      f0
 
98
 */
 
99
 
 
100
#undef _A
 
101
#undef _B
 
102
#undef _C
 
103
#undef _AB
 
104
#undef _BC
 
105
#undef _CA
 
106
#undef _ABCA
 
107
#undef _BCAB
 
108
#undef _CABC
 
109
 
 
110
#if IMAGE_BYTE_ORDER == MSBFirst
 
111
#define _A      f1
 
112
#define _B      f2
 
113
#define _C      f0
 
114
#define _AB     f2
 
115
#define _BC     f0
 
116
#define _CA     f1
 
117
#define _ABCA   f1
 
118
#define _BCAB   f2
 
119
#define _CABC   f0
 
120
#define CASE(a,b,c,d)   ((a << 3) | (b << 2) | (c << 1) | d)
 
121
#else
 
122
#define _A      f0
 
123
#define _B      f1
 
124
#define _C      f2
 
125
#define _AB     f0
 
126
#define _BC     f1
 
127
#define _CA     f2
 
128
#define _ABCA   f0
 
129
#define _BCAB   f1
 
130
#define _CABC   f2
 
131
#define CASE(a,b,c,d)   (a | (b << 1) | (c << 2) | (d << 3))
 
132
#endif
 
133
 
 
134
void
 
135
fbGlyph24 (FbBits   *dstBits,
 
136
           FbStride dstStride,
 
137
           int      dstBpp,
 
138
           FbStip   *stipple,
 
139
           FbBits   fg,
 
140
           int      x,
 
141
           int      height)
 
142
{
 
143
    int     lshift;
 
144
    FbStip  bits;
 
145
    CARD8   *dstLine;
 
146
    CARD8   *dst;
 
147
    FbStip  f0, f1, f2;
 
148
    int     n;
 
149
    int     shift;
 
150
 
 
151
    f0 = fg;
 
152
    f1 = FbRot24(f0,16);
 
153
    f2 = FbRot24(f0,8);
 
154
    
 
155
    dstLine = (CARD8 *) dstBits;
 
156
    dstLine += (x & ~3) * 3;
 
157
    dstStride *= (sizeof (FbBits) / sizeof (CARD8));
 
158
    shift = x & 3;
 
159
    lshift = 4 - shift;
 
160
    while (height--)
 
161
    {
 
162
        bits = *stipple++;
 
163
        n = lshift;
 
164
        dst = dstLine;
 
165
        while (bits)
 
166
        {
 
167
            switch (FbStipMoveLsb (FbLeftStipBits (bits, n), 4, n)) {
 
168
            case CASE(0,0,0,0):
 
169
                break;
 
170
            case CASE(1,0,0,0):
 
171
                WRITE2(dst,0,_AB);
 
172
                WRITE1(dst,2,_C);
 
173
                break;
 
174
            case CASE(0,1,0,0):
 
175
                WRITE1(dst,3,_A);
 
176
                WRITE2(dst,4,_BC);
 
177
                break;
 
178
            case CASE(1,1,0,0):
 
179
                WRITE4(dst,0,_ABCA);
 
180
                WRITE2(dst,4,_BC);
 
181
                break;
 
182
            case CASE(0,0,1,0):
 
183
                WRITE2(dst,6,_AB);
 
184
                WRITE1(dst,8,_C);
 
185
                break;
 
186
            case CASE(1,0,1,0):
 
187
                WRITE2(dst,0,_AB);
 
188
                WRITE1(dst,2,_C);
 
189
                
 
190
                WRITE2(dst,6,_AB);
 
191
                WRITE1(dst,8,_C);
 
192
                break;
 
193
            case CASE(0,1,1,0):
 
194
                WRITE1(dst,3,_A);
 
195
                WRITE4(dst,4,_BCAB);
 
196
                WRITE1(dst,8,_C);
 
197
                break;
 
198
            case CASE(1,1,1,0):
 
199
                WRITE8(dst);
 
200
                WRITE1(dst,8,_C);
 
201
                break;
 
202
            case CASE(0,0,0,1):
 
203
                WRITE1(dst,9,_A);
 
204
                WRITE2(dst,10,_BC);
 
205
                break;
 
206
            case CASE(1,0,0,1):
 
207
                WRITE2(dst,0,_AB);
 
208
                WRITE1(dst,2,_C);
 
209
                
 
210
                WRITE1(dst,9,_A);
 
211
                WRITE2(dst,10,_BC);
 
212
                break;
 
213
            case CASE(0,1,0,1):
 
214
                WRITE1(dst,3,_A);
 
215
                WRITE2(dst,4,_BC);
 
216
                
 
217
                WRITE1(dst,9,_A);
 
218
                WRITE2(dst,10,_BC);
 
219
                break;
 
220
            case CASE(1,1,0,1):
 
221
                WRITE4(dst,0,_ABCA);
 
222
                WRITE2(dst,4,_BC);
 
223
                
 
224
                WRITE1(dst,9,_A);
 
225
                WRITE2(dst,10,_BC);
 
226
                break;
 
227
            case CASE(0,0,1,1):
 
228
                WRITE2(dst,6,_AB);
 
229
                WRITE4(dst,8,_CABC);
 
230
                break;
 
231
            case CASE(1,0,1,1):
 
232
                WRITE2(dst,0,_AB);
 
233
                WRITE1(dst,2,_C);
 
234
                
 
235
                WRITE2(dst,6,_AB);
 
236
                WRITE4(dst,8,_CABC);
 
237
                break;
 
238
            case CASE(0,1,1,1):
 
239
                WRITE1(dst,3,_A);
 
240
                WRITE4(dst,4,_BCAB);
 
241
                WRITE4(dst,8,_CABC);
 
242
                break;
 
243
            case CASE(1,1,1,1):
 
244
                WRITE8(dst);
 
245
                WRITE4(dst,8,_CABC);
 
246
                break;
 
247
            }
 
248
            bits = FbStipLeft (bits, n);
 
249
            n = 4;
 
250
            dst += 12;
 
251
        }
 
252
        dstLine += dstStride;
 
253
    }
 
254
}
 
255
#endif
 
256
#endif
 
257
 
 
258
void
 
259
fbPolyGlyphBlt (DrawablePtr     pDrawable,
 
260
                GCPtr           pGC,
 
261
                int             x, 
 
262
                int             y,
 
263
                unsigned int    nglyph,
 
264
                CharInfoPtr     *ppci,
 
265
                pointer         pglyphBase)
 
266
{
 
267
    FbGCPrivPtr     pPriv = fbGetGCPrivate (pGC);
 
268
    CharInfoPtr     pci;
 
269
    unsigned char   *pglyph;            /* pointer bits in glyph */
 
270
    int             gx, gy;
 
271
    int             gWidth, gHeight;    /* width and height of glyph */
 
272
    FbStride        gStride;            /* stride of glyph */
 
273
#ifndef FBNOPIXADDR
 
274
    void            (*glyph) (FbBits *,
 
275
                              FbStride,
 
276
                              int,
 
277
                              FbStip *,
 
278
                              FbBits,
 
279
                              int,
 
280
                              int);
 
281
    FbBits          *dst = 0;
 
282
    FbStride        dstStride = 0;
 
283
    int             dstBpp = 0;
 
284
    int             dstXoff = 0, dstYoff = 0;
 
285
    
 
286
    glyph = 0;
 
287
    if (pGC->fillStyle == FillSolid && pPriv->and == 0)
 
288
    {
 
289
        fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
 
290
        switch (dstBpp) {
 
291
        case 8:     glyph = fbGlyph8; break;
 
292
        case 16:    glyph = fbGlyph16; break;
 
293
#ifdef FB_24BIT
 
294
        case 24:    glyph = fbGlyph24; break;
 
295
#endif
 
296
        case 32:    glyph = fbGlyph32; break;
 
297
        }
 
298
    }
 
299
#endif
 
300
    x += pDrawable->x;
 
301
    y += pDrawable->y;
 
302
 
 
303
    while (nglyph--)
 
304
    {
 
305
        pci = *ppci++;
 
306
        pglyph = FONTGLYPHBITS(pglyphBase, pci);
 
307
        gWidth = GLYPHWIDTHPIXELS(pci);
 
308
        gHeight = GLYPHHEIGHTPIXELS(pci);
 
309
        if (gWidth && gHeight)
 
310
        {
 
311
            gx = x + pci->metrics.leftSideBearing;
 
312
            gy = y - pci->metrics.ascent; 
 
313
#ifndef FBNOPIXADDR
 
314
            if (glyph && gWidth <= sizeof (FbStip) * 8 &&
 
315
                fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
 
316
            {
 
317
                (*glyph) (dst + (gy + dstYoff) * dstStride,
 
318
                          dstStride,
 
319
                          dstBpp,
 
320
                          (FbStip *) pglyph,
 
321
                          pPriv->xor,
 
322
                          gx + dstXoff,
 
323
                          gHeight);
 
324
            }
 
325
            else
 
326
#endif
 
327
            {
 
328
                gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
 
329
                fbPushImage (pDrawable,
 
330
                             pGC,
 
331
    
 
332
                             (FbStip *) pglyph,
 
333
                             gStride,
 
334
                             0,
 
335
    
 
336
                             gx,
 
337
                             gy,
 
338
                             gWidth, gHeight);
 
339
            }
 
340
        }
 
341
        x += pci->metrics.characterWidth;
 
342
    }
 
343
}
 
344
 
 
345
 
 
346
void
 
347
fbImageGlyphBlt (DrawablePtr    pDrawable,
 
348
                 GCPtr          pGC,
 
349
                 int            x, 
 
350
                 int            y,
 
351
                 unsigned int   nglyph,
 
352
                 CharInfoPtr    *ppciInit,
 
353
                 pointer        pglyphBase)
 
354
{
 
355
    FbGCPrivPtr     pPriv = fbGetGCPrivate(pGC);
 
356
    CharInfoPtr     *ppci;
 
357
    CharInfoPtr     pci;
 
358
    unsigned char   *pglyph;            /* pointer bits in glyph */
 
359
    int             gWidth, gHeight;    /* width and height of glyph */
 
360
    FbStride        gStride;            /* stride of glyph */
 
361
    Bool            opaque;
 
362
    int             n;
 
363
    int             gx, gy;
 
364
#ifndef FBNOPIXADDR
 
365
    void            (*glyph) (FbBits *,
 
366
                              FbStride,
 
367
                              int,
 
368
                              FbStip *,
 
369
                              FbBits,
 
370
                              int,
 
371
                              int);
 
372
    FbBits          *dst = 0;
 
373
    FbStride        dstStride = 0;
 
374
    int             dstBpp = 0;
 
375
    int             dstXoff = 0, dstYoff = 0;
 
376
    
 
377
    glyph = 0;
 
378
    if (pPriv->and == 0)
 
379
    {
 
380
        fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
 
381
        switch (dstBpp) {
 
382
        case 8:     glyph = fbGlyph8; break;
 
383
        case 16:    glyph = fbGlyph16; break;
 
384
#ifdef FB_24BIT
 
385
        case 24:    glyph = fbGlyph24; break;
 
386
#endif
 
387
        case 32:    glyph = fbGlyph32; break;
 
388
        }
 
389
    }
 
390
#endif
 
391
    
 
392
    x += pDrawable->x;
 
393
    y += pDrawable->y;
 
394
 
 
395
    if (TERMINALFONT (pGC->font)
 
396
#ifndef FBNOPIXADDR
 
397
        && !glyph
 
398
#endif
 
399
        )
 
400
    {
 
401
        opaque = TRUE;
 
402
    }
 
403
    else
 
404
    {
 
405
        int             xBack, widthBack;
 
406
        int             yBack, heightBack;
 
407
        
 
408
        ppci = ppciInit;
 
409
        n = nglyph;
 
410
        widthBack = 0;
 
411
        while (n--)
 
412
            widthBack += (*ppci++)->metrics.characterWidth;
 
413
        
 
414
        xBack = x;
 
415
        if (widthBack < 0)
 
416
        {
 
417
            xBack += widthBack;
 
418
            widthBack = -widthBack;
 
419
        }
 
420
        yBack = y - FONTASCENT(pGC->font);
 
421
        heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
 
422
        fbSolidBoxClipped (pDrawable,
 
423
                           fbGetCompositeClip(pGC),
 
424
                           xBack,
 
425
                           yBack,
 
426
                           xBack + widthBack,
 
427
                           yBack + heightBack,
 
428
                           fbAnd(GXcopy,pPriv->bg,pPriv->pm),
 
429
                           fbXor(GXcopy,pPriv->bg,pPriv->pm));
 
430
        opaque = FALSE;
 
431
    }
 
432
 
 
433
    ppci = ppciInit;
 
434
    while (nglyph--)
 
435
    {
 
436
        pci = *ppci++;
 
437
        pglyph = FONTGLYPHBITS(pglyphBase, pci);
 
438
        gWidth = GLYPHWIDTHPIXELS(pci);
 
439
        gHeight = GLYPHHEIGHTPIXELS(pci);
 
440
        if (gWidth && gHeight)
 
441
        {
 
442
            gx = x + pci->metrics.leftSideBearing;
 
443
            gy = y - pci->metrics.ascent; 
 
444
#ifndef FBNOPIXADDR
 
445
            if (glyph && gWidth <= sizeof (FbStip) * 8 &&
 
446
                fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
 
447
            {
 
448
                (*glyph) (dst + (gy + dstYoff) * dstStride,
 
449
                          dstStride,
 
450
                          dstBpp,
 
451
                          (FbStip *) pglyph,
 
452
                          pPriv->fg,
 
453
                          gx + dstXoff,
 
454
                          gHeight);
 
455
            }
 
456
            else
 
457
#endif
 
458
            {
 
459
                gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
 
460
                fbPutXYImage (pDrawable,
 
461
                              fbGetCompositeClip(pGC),
 
462
                              pPriv->fg,
 
463
                              pPriv->bg,
 
464
                              pPriv->pm,
 
465
                              GXcopy,
 
466
                              opaque,
 
467
    
 
468
                              gx,
 
469
                              gy,
 
470
                              gWidth, gHeight,
 
471
    
 
472
                              (FbStip *) pglyph,
 
473
                              gStride,
 
474
                              0);
 
475
            }
 
476
        }
 
477
        x += pci->metrics.characterWidth;
 
478
    }
 
479
}