~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/xfs/difs/charinfo.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: charinfo.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $ */
 
2
/*
 
3
 
 
4
Copyright 1990, 1991, 1998  The Open Group
 
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.
 
11
 
 
12
The above copyright notice and this permission notice shall be included in
 
13
all copies or substantial portions of the Software.
 
14
 
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
18
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
19
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
20
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
21
 
 
22
Except as contained in this notice, the name of The Open Group shall not be
 
23
used in advertising or otherwise to promote the sale, use or other dealings
 
24
in this Software without prior written authorization from The Open Group.
 
25
 
 
26
 * Copyright 1990, 1991 Network Computing Devices;
 
27
 * Portions Copyright 1987 by Digital Equipment Corporation 
 
28
 *
 
29
 * Permission to use, copy, modify, distribute, and sell this software and
 
30
 * its documentation for any purpose is hereby granted without fee, provided
 
31
 * that the above copyright notice appear in all copies and that both that
 
32
 * copyright notice and this permission notice appear in supporting
 
33
 * documentation, and that the names of Network Computing Devices, or Digital
 
34
 * not be used in advertising or publicity pertaining to distribution
 
35
 * of the software without specific, written prior permission.
 
36
 *
 
37
 * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
 
38
 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
 
39
 * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
 
40
 * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
 
41
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 
42
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 
43
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 
44
 * THIS SOFTWARE.
 
45
 */
 
46
/*
 
47
 * Defines GetExtents() and GetBitmaps(), which are
 
48
 * called from routines in fontinfo.c.
 
49
 * This file was once on the other side of
 
50
 * the font library interface as util/fsfuncs.c.
 
51
 */
 
52
/* $XFree86: xc/programs/xfs/difs/charinfo.c,v 1.12 2001/12/14 20:01:33 dawes Exp $ */
 
53
 
 
54
#include <X11/Xos.h>
 
55
#include "misc.h"
 
56
#include "fontstruct.h"
 
57
#include "fontutil.h"
 
58
#include "clientstr.h"
 
59
#define FSMD_H
 
60
#include "FSproto.h"
 
61
#include "difs.h"
 
62
 
 
63
extern void TwoByteSwap(unsigned char *, int);
 
64
extern void FourByteSwap(unsigned char *, int);
 
65
 
 
66
#define GLWIDTHBYTESPADDED(bits,nbytes) \
 
67
        ((nbytes) == 1 ? (((bits)+7)>>3)        /* pad to 1 byte */ \
 
68
        :(nbytes) == 2 ? ((((bits)+15)>>3)&~1)  /* pad to 2 bytes */ \
 
69
        :(nbytes) == 4 ? ((((bits)+31)>>3)&~3)  /* pad to 4 bytes */ \
 
70
        :(nbytes) == 8 ? ((((bits)+63)>>3)&~7)  /* pad to 8 bytes */ \
 
71
        : 0)
 
72
 
 
73
#define GLYPH_SIZE(ch, nbytes)          \
 
74
        GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
 
75
                        (ch)->metrics.leftSideBearing, (nbytes))
 
76
 
 
77
#define n2dChars(pfi)   (((pfi)->lastRow - (pfi)->firstRow + 1) * \
 
78
                         ((pfi)->lastCol - (pfi)->firstCol + 1))
 
79
 
 
80
#if 0
 
81
static CharInfoRec  junkDefault;
 
82
#endif
 
83
 
 
84
typedef int (*MetricsFunc)(FontPtr, unsigned long, unsigned char *, 
 
85
                           FontEncoding, unsigned long *, CharInfoPtr *);
 
86
 
 
87
static int
 
88
getCharInfos (
 
89
    FontPtr     pfont,
 
90
    int         num_ranges,
 
91
    fsRange     *range,
 
92
    Bool        ink_metrics,
 
93
    int         *nump,          /* return */
 
94
    CharInfoPtr **retp)         /* return */
 
95
{
 
96
    CharInfoPtr *xchars, *xci;
 
97
    int         nchars;
 
98
    FontInfoPtr pinfo = &pfont->info;
 
99
    unsigned int r, c;
 
100
    unsigned char   ch[2];
 
101
    int         firstCol = pinfo->firstCol;
 
102
    int         firstRow = pinfo->firstRow;
 
103
    int         lastRow = pinfo->lastRow;
 
104
    int         lastCol = pinfo->lastCol;
 
105
    fsRange     local_range, *rp;
 
106
    int         i;
 
107
    FontEncoding    encoding;
 
108
    int         err;
 
109
    unsigned long   glyphCount;
 
110
    unsigned short  defaultCh;
 
111
    CharInfoPtr     defaultPtr;
 
112
    MetricsFunc     metrics_func;
 
113
    
 
114
    /*
 
115
     * compute nchars
 
116
     */
 
117
    if (num_ranges == 0) {
 
118
        if (lastRow)
 
119
            nchars = n2dChars(pinfo);
 
120
        else
 
121
            nchars = lastCol - firstCol + 1;
 
122
        local_range.min_char_low = firstCol;
 
123
        local_range.min_char_high = firstRow;
 
124
        local_range.max_char_low = lastCol;
 
125
        local_range.max_char_high = lastRow;
 
126
        range = &local_range;
 
127
        num_ranges = 1;
 
128
    } else {
 
129
        nchars = 0;
 
130
        for (i = 0, rp = range; i < num_ranges; i++, rp++) {
 
131
            if (rp->min_char_high > rp->max_char_high ||
 
132
                rp->min_char_low > rp->max_char_low)
 
133
                return BadCharRange;
 
134
            nchars += (rp->max_char_high - rp->min_char_high + 1) *
 
135
                      (rp->max_char_low - rp->min_char_low + 1);
 
136
        }
 
137
    }
 
138
 
 
139
    xchars = (CharInfoPtr *) fsalloc (sizeof (CharInfoPtr) * nchars);
 
140
    if (!xchars)
 
141
        return AllocError;
 
142
    bzero (xchars, sizeof (CharInfoPtr) * nchars);
 
143
 
 
144
    if (ink_metrics)
 
145
        metrics_func = (MetricsFunc)pfont->get_metrics;
 
146
    else
 
147
        metrics_func = pfont->get_glyphs;
 
148
 
 
149
    xci = xchars;
 
150
    encoding = Linear16Bit;
 
151
    if (lastRow)
 
152
        encoding = TwoD16Bit;
 
153
    defaultCh = pinfo->defaultCh;
 
154
    ch[0] = defaultCh >> 8;
 
155
    ch[1] = defaultCh & 0xff;
 
156
    /* get the default character */
 
157
    (*metrics_func) (pfont, 1, ch, encoding,
 
158
                          &glyphCount, &defaultPtr);
 
159
    if (glyphCount != 1)
 
160
        defaultPtr = 0;
 
161
    
 
162
    /* for each range, get each character individually, undoing the
 
163
     default character substitution so we get zero metrics for
 
164
     non-existent characters. */
 
165
    for (i = 0, rp = range; i < num_ranges; i++, rp++) {
 
166
        for (r = rp->min_char_high; r <= rp->max_char_high; r++)
 
167
        {
 
168
            for (c = rp->min_char_low; c <= rp->max_char_low; c++) {
 
169
                ch[0] = r;
 
170
                ch[1] = c;
 
171
                err = (*metrics_func) (pfont, 1, ch, encoding,
 
172
                                            &glyphCount, xci);
 
173
                if (err != Successful)
 
174
                {
 
175
                    fsfree (xchars);
 
176
                    return err;
 
177
                }
 
178
#if 0
 
179
                if (glyphCount != 1 || 
 
180
                   (*xci == defaultPtr && defaultCh != ((r<<8)+c)))
 
181
                    *xci = &junkDefault;
 
182
#endif
 
183
                xci++;
 
184
            }
 
185
        }
 
186
    }
 
187
    *retp = xchars;
 
188
    *nump = nchars;
 
189
    return Successful;
 
190
}
 
191
 
 
192
int
 
193
GetExtents(
 
194
    ClientPtr   client,
 
195
    FontPtr     pfont,
 
196
    Mask        flags,
 
197
    unsigned long num_ranges,
 
198
    fsRange    *range,
 
199
    unsigned long *num_extents, /* return */
 
200
    fsXCharInfo **data)         /* return */
 
201
{
 
202
    unsigned long size;
 
203
    fsXCharInfo *ci;
 
204
    fsXCharInfo cilocal;
 
205
    char *pci;
 
206
    CharInfoPtr *xchars, *xchars_cur;
 
207
    CharInfoPtr xci;
 
208
    int         nchars;
 
209
    int         err;
 
210
    
 
211
    if (flags & LoadAll)
 
212
        num_ranges = 0;
 
213
    err = getCharInfos (pfont, num_ranges, range,
 
214
                        client->major_version > 1 ? TRUE : FALSE,
 
215
                        &nchars, &xchars);
 
216
    if (err != Successful)
 
217
        return err;
 
218
    
 
219
    size = SIZEOF(fsXCharInfo) * nchars;
 
220
    pci = (char *) fsalloc(size);
 
221
    if (!pci) {
 
222
        fsfree (xchars);
 
223
        return AllocError;
 
224
    }
 
225
 
 
226
    ci = (fsXCharInfo *) pci;
 
227
    *num_extents = nchars;
 
228
    
 
229
    /* pack the data */
 
230
    xchars_cur = xchars;
 
231
    while (nchars--) {
 
232
        xci = *xchars_cur++;
 
233
        cilocal.ascent = xci->metrics.ascent;
 
234
        cilocal.descent = xci->metrics.descent;
 
235
        cilocal.left = xci->metrics.leftSideBearing;
 
236
        cilocal.right = xci->metrics.rightSideBearing;
 
237
        cilocal.width = xci->metrics.characterWidth;
 
238
        cilocal.attributes = xci->metrics.attributes;
 
239
        memcpy(pci, &cilocal, SIZEOF(fsXCharInfo));
 
240
        pci += SIZEOF(fsXCharInfo);
 
241
    }
 
242
    
 
243
    fsfree (xchars);
 
244
    
 
245
    *data = ci;
 
246
    
 
247
    return Successful;
 
248
}
 
249
 
 
250
static int
 
251
packGlyphs (
 
252
    ClientPtr   client,
 
253
    FontPtr     pfont,
 
254
    int         format,
 
255
    Mask        flags,
 
256
    unsigned long num_ranges,
 
257
    fsRange    *range,
 
258
    int        *tsize,
 
259
    unsigned long *num_glyphs,
 
260
    fsOffset32  **offsets,
 
261
    pointer     *data,
 
262
    int         *freeData)
 
263
{
 
264
    int         i;
 
265
    fsOffset32  *lengths, *l;
 
266
    unsigned long size = 0;
 
267
    pointer     gdata;
 
268
    unsigned char *gd;
 
269
    int         bitorder, byteorder, scanlinepad, scanlineunit, mappad;
 
270
    int         height = 0, dstbpr = 0, charsize = 0;
 
271
    int         dst_off = 0, src_off;
 
272
    Bool        contiguous, reformat;
 
273
    int         nchars;
 
274
    int         src_glyph_pad = pfont->glyph;
 
275
    int         src_bit_order = pfont->bit;
 
276
    int         src_byte_order = pfont->byte;
 
277
    int         err;
 
278
    int         max_ascent = 0, max_descent = 0;
 
279
    int         min_left = 0, max_right;
 
280
    int         srcbpr;
 
281
    int         lshift = 0, rshift = 0, dst_left_bytes = 0, src_left_bytes = 0;
 
282
    unsigned char   *srcp;
 
283
    unsigned char   *dstp;
 
284
    unsigned char   bits1, bits2;
 
285
    int             width;
 
286
    int             src_extra;
 
287
    int             dst_extra;
 
288
    int             r, w;
 
289
    CharInfoPtr *bitChars, *bitCharsFree, bitc;
 
290
    CharInfoPtr *inkChars, *inkCharsFree = 0, inkc;
 
291
    FontInfoPtr pinfo = &pfont->info;
 
292
    xCharInfo   *bitm, *inkm;
 
293
    
 
294
    err = CheckFSFormat(format, (fsBitmapFormatMask) ~ 0,
 
295
                        &bitorder, &byteorder, &scanlineunit, &scanlinepad, &mappad);
 
296
    
 
297
    if (err != Successful)
 
298
        return err;
 
299
    
 
300
    if (flags & LoadAll)
 
301
        num_ranges = 0;
 
302
    
 
303
    err = getCharInfos (pfont, num_ranges, range, FALSE, &nchars, &bitCharsFree);
 
304
    
 
305
    if (err != Successful)
 
306
        return err;
 
307
    
 
308
    /* compute dstbpr for padded out fonts */
 
309
    reformat = bitorder != src_bit_order || byteorder != src_byte_order;
 
310
 
 
311
    /* we need the ink metrics when shrink-wrapping a TE font (sigh),
 
312
     * but only for protocol version > 1 */
 
313
    if (mappad != BitmapFormatImageRectMax &&
 
314
        pinfo->inkMetrics &&
 
315
        client->major_version > 1)
 
316
    {
 
317
        err = getCharInfos (pfont, num_ranges, range, TRUE, &nchars, &inkCharsFree);
 
318
        if (err != Successful)
 
319
        {
 
320
            fsfree (bitCharsFree);
 
321
            return err;
 
322
        }
 
323
        reformat = TRUE;
 
324
    }
 
325
 
 
326
    /* get space for glyph offsets */
 
327
    lengths = (fsOffset32 *) fsalloc(SIZEOF(fsOffset32) * nchars);
 
328
    if (!lengths) {
 
329
        fsfree (bitCharsFree);
 
330
        fsfree (inkCharsFree);
 
331
        return AllocError;
 
332
    }
 
333
    
 
334
    switch (mappad)
 
335
    {
 
336
    case BitmapFormatImageRectMax:
 
337
        max_ascent = FONT_MAX_ASCENT(pinfo);
 
338
        max_descent = FONT_MAX_DESCENT(pinfo);
 
339
        height = max_ascent + max_descent;
 
340
        /* do font ascent and font descent match bitmap bounds ? */
 
341
        if (height != pinfo->minbounds.ascent + pinfo->minbounds.descent)
 
342
            reformat = TRUE;
 
343
        /* fall through */
 
344
    case BitmapFormatImageRectMaxWidth:
 
345
        min_left = FONT_MIN_LEFT(pinfo);
 
346
        max_right = FONT_MAX_RIGHT(pinfo);
 
347
        if (min_left != pinfo->maxbounds.leftSideBearing)
 
348
            reformat = TRUE;
 
349
        if (max_right != pinfo->maxbounds.rightSideBearing)
 
350
            reformat = TRUE;
 
351
        dstbpr = GLWIDTHBYTESPADDED(max_right - min_left, scanlinepad);
 
352
        break;
 
353
    case BitmapFormatImageRectMin:
 
354
        break;
 
355
    }
 
356
    if (mappad == BitmapFormatImageRectMax)
 
357
        charsize = dstbpr * height;
 
358
    size = 0;
 
359
    gdata = 0;
 
360
    contiguous = TRUE;
 
361
    l = lengths;
 
362
    inkChars = inkCharsFree;
 
363
    bitChars = bitCharsFree;
 
364
    for (i = 0; i < nchars; i++)
 
365
    {
 
366
        inkc = bitc = *bitChars++;
 
367
        /* when ink metrics != bitmap metrics, use ink metrics */
 
368
        if (inkChars)
 
369
            inkc = *inkChars++;
 
370
        l->position = size;
 
371
        /*
 
372
         * Do not repad characters with no bits except for those
 
373
         * with non-zero width.
 
374
         */
 
375
        if (bitc && (bitc->bits || bitc->metrics.characterWidth)) {
 
376
            if (!gdata)
 
377
                gdata = (pointer) bitc->bits;
 
378
            if ((char *) gdata + size != bitc->bits)
 
379
                contiguous = FALSE;
 
380
            if (mappad == BitmapFormatImageRectMin)
 
381
                dstbpr = GLYPH_SIZE(inkc, scanlinepad);
 
382
            if (dstbpr != GLYPH_SIZE(bitc, src_glyph_pad)) reformat = TRUE;
 
383
            if (mappad != BitmapFormatImageRectMax)
 
384
            {
 
385
                height = inkc->metrics.ascent + inkc->metrics.descent;
 
386
                charsize = height * dstbpr;
 
387
            }
 
388
            l->length = charsize;
 
389
            size += charsize;
 
390
        }
 
391
        else
 
392
            l->length = 0;
 
393
        l++;
 
394
    }
 
395
    if (contiguous && !reformat)
 
396
    {
 
397
        *num_glyphs = nchars;
 
398
        *freeData = FALSE;
 
399
        *data = gdata;
 
400
        *tsize = size;
 
401
        *offsets = lengths;
 
402
        fsfree (bitCharsFree);
 
403
        fsfree (inkCharsFree);
 
404
        return Successful;
 
405
    }
 
406
    if (size)
 
407
    {
 
408
        gdata = (pointer) fsalloc(size);
 
409
        if (!gdata) {
 
410
            fsfree (bitCharsFree);
 
411
            fsfree (inkCharsFree);
 
412
            fsfree (lengths);
 
413
            return AllocError;
 
414
        }
 
415
        bzero ((char *) gdata, size);
 
416
    }
 
417
    else
 
418
        gdata = NULL;
 
419
    
 
420
    *freeData = TRUE;
 
421
    l = lengths;
 
422
    gd = gdata;
 
423
    
 
424
    /* finally do the work */
 
425
    bitChars = bitCharsFree;
 
426
    inkChars = inkCharsFree;
 
427
    for (i = 0; i < nchars; i++, l++) 
 
428
    {
 
429
        inkc = bitc = *bitChars++;
 
430
        if (inkChars)
 
431
            inkc = *inkChars++;
 
432
 
 
433
        /* ignore missing chars */
 
434
        if (l->length == 0)
 
435
            continue;
 
436
        
 
437
        bitm = &bitc->metrics;
 
438
        inkm = &inkc->metrics;
 
439
 
 
440
        /* start address for the destination of bits for this char */
 
441
 
 
442
        dstp = gd;
 
443
 
 
444
        if (mappad == BitmapFormatImageRectMax)
 
445
            height = max_ascent + max_descent;
 
446
        else
 
447
            height = inkm->ascent + inkm->descent;
 
448
 
 
449
        /* adjust destination and calculate shift offsets */
 
450
        switch (mappad) {
 
451
        case BitmapFormatImageRectMax:
 
452
            /* leave the first padded rows blank */
 
453
            if (max_ascent > inkm->ascent)
 
454
            {
 
455
                height -= (max_ascent - inkm->ascent);
 
456
                dstp += dstbpr * (max_ascent - inkm->ascent);
 
457
            }
 
458
            if (max_descent > inkm->descent)
 
459
            {
 
460
                height -= (max_descent - inkm->descent);
 
461
            }
 
462
            /* fall thru */
 
463
        case BitmapFormatImageRectMaxWidth:
 
464
            dst_off = inkm->leftSideBearing - min_left;
 
465
            if (dst_off < 0) dst_off = 0;
 
466
            break;
 
467
        case BitmapFormatImageRectMin:
 
468
            dst_off = 0;
 
469
            dstbpr = GLYPH_SIZE(inkc, scanlinepad);
 
470
            break;
 
471
        }
 
472
 
 
473
        srcbpr = GLYPH_SIZE (bitc, src_glyph_pad);
 
474
        srcp = (unsigned char *) bitc->bits;
 
475
 
 
476
        /* adjust source */
 
477
        src_off = 0;
 
478
        if (inkm != bitm)
 
479
        {
 
480
            srcp += (bitm->ascent - inkm->ascent) * srcbpr;
 
481
            src_off = inkm->leftSideBearing - bitm->leftSideBearing;
 
482
        }
 
483
 
 
484
        dst_left_bytes = dst_off >> 3;
 
485
        dst_off &= 7;
 
486
        src_left_bytes = src_off >> 3;
 
487
        src_off &= 7;
 
488
 
 
489
        /* minimum of source/dest bytes per row */
 
490
        width = srcbpr - src_left_bytes;
 
491
        if (width > dstbpr - dst_left_bytes)
 
492
            width = dstbpr - dst_left_bytes;
 
493
        /* extra bytes in source and dest for padding */
 
494
        src_extra = srcbpr - width - src_left_bytes;
 
495
        dst_extra = dstbpr - width - dst_left_bytes;
 
496
        
 
497
#define MSBBitLeft(b,c) ((b) << (c))
 
498
#define MSBBitRight(b,c)        ((b) >> (c))
 
499
#define LSBBitLeft(b,c) ((b) >> (c))
 
500
#define LSBBitRight(b,c)        ((b) << (c))
 
501
 
 
502
        if (dst_off == src_off)
 
503
        {
 
504
            if (srcbpr == dstbpr && src_left_bytes == dst_left_bytes)
 
505
            {
 
506
                r = height * srcbpr;
 
507
                memmove( dstp, srcp, r);
 
508
                dstp += r;
 
509
            }
 
510
            else
 
511
            {
 
512
                for (r =  height; r; r--)
 
513
                {
 
514
                    dstp += dst_left_bytes;
 
515
                    srcp += src_left_bytes;
 
516
                    for (w = width; w; w--)
 
517
                        *dstp++ = *srcp++;
 
518
                    dstp += dst_extra;
 
519
                    srcp += src_extra;
 
520
                }
 
521
            }
 
522
        }
 
523
        else
 
524
        {
 
525
            if (dst_off > src_off)
 
526
            {
 
527
                rshift = dst_off - src_off;
 
528
                lshift = 8 - rshift;
 
529
            }
 
530
            else
 
531
            {
 
532
                lshift = src_off - dst_off;
 
533
                rshift = 8 - lshift;
 
534
                /* run the loop one fewer time if necessary */
 
535
                if (src_extra <= dst_extra)
 
536
                {
 
537
                    dst_extra++;
 
538
                    width--;
 
539
                }
 
540
                else
 
541
                    src_extra--;
 
542
            }
 
543
            
 
544
            for (r = inkm->ascent + inkm->descent; r; r--)
 
545
            {
 
546
                dstp += dst_left_bytes;
 
547
                srcp += src_left_bytes;
 
548
                bits2 = 0;
 
549
                /* fetch first part of source when necessary */
 
550
                if (dst_off < src_off)
 
551
                    bits2 = *srcp++;
 
552
                /*
 
553
                 * XXX I bet this does not work when
 
554
                 * src_bit_order != src_byte_order && scanlineunit > 1
 
555
                 */
 
556
                for (w = width; w; w--)
 
557
                {
 
558
                    bits1 = *srcp++;
 
559
                    if (src_bit_order == MSBFirst)
 
560
                    {
 
561
                        *dstp++ = MSBBitRight(bits1, rshift) |
 
562
                                 MSBBitLeft (bits2, lshift);
 
563
                    }
 
564
                    else
 
565
                    {
 
566
                        *dstp++ = LSBBitRight(bits1, rshift) |
 
567
                                 LSBBitLeft (bits2, lshift);
 
568
                    }
 
569
                    bits2 = bits1;
 
570
                }
 
571
                /* get the last few bits if we have a place to store them */
 
572
                if (dst_extra > 0)
 
573
                {
 
574
                    if (src_bit_order == MSBFirst)
 
575
                        *dstp = MSBBitLeft (bits2, lshift);
 
576
                    else
 
577
                        *dstp = LSBBitLeft (bits2, lshift);
 
578
                }
 
579
                dstp += dst_extra;
 
580
                srcp += src_extra;
 
581
            }
 
582
        }
 
583
        /* skip the amount we just filled in */
 
584
        gd += l->length;
 
585
    }
 
586
    
 
587
    
 
588
    /* now do the bit, byte, word swapping */
 
589
    if (bitorder != src_bit_order)
 
590
        BitOrderInvert(gdata, size);
 
591
    if (byteorder != src_byte_order) 
 
592
    {
 
593
        if (scanlineunit == 2)
 
594
            TwoByteSwap(gdata, size);
 
595
        else if (scanlineunit == 4)
 
596
            FourByteSwap(gdata, size);
 
597
    }
 
598
    fsfree (bitCharsFree);
 
599
    fsfree (inkCharsFree);
 
600
    *num_glyphs = nchars;
 
601
    *data = gdata;
 
602
    *tsize = size;
 
603
    *offsets = lengths;
 
604
    
 
605
    return Successful;
 
606
}
 
607
 
 
608
/* ARGSUSED */
 
609
int
 
610
GetBitmaps(
 
611
    ClientPtr   client,
 
612
    FontPtr     pfont,
 
613
    fsBitmapFormat format,
 
614
    Mask        flags,
 
615
    unsigned long num_ranges,
 
616
    fsRange    *range,
 
617
    int        *size,
 
618
    unsigned long *num_glyphs,
 
619
    fsOffset32  **offsets,
 
620
    pointer    *data,
 
621
    int         *freeData)
 
622
{
 
623
    int err;
 
624
 
 
625
    assert(pfont);
 
626
 
 
627
    *size = 0;
 
628
    *data = (pointer) 0;
 
629
 
 
630
    err = LoadGlyphRanges(client, pfont, TRUE, num_ranges * 2, 0, 
 
631
                          (fsChar2b *)range);
 
632
 
 
633
    if (err != Successful)
 
634
        return err;
 
635
 
 
636
    return packGlyphs (client, pfont, format, flags,
 
637
                              num_ranges, range, size, num_glyphs,
 
638
                              offsets, data, freeData);
 
639
}