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