2 * Copyright (C) 2000, Matias Atria
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 /* Bitmap manipulation routines */
26 /* bit_masks[n] contains a BmUnit with `n' contiguous bits */
28 static BmUnit bit_masks[] = {
30 0xf, 0x1f, 0x3f, 0x7f,
34 0xfff, 0x1fff, 0x3fff, 0x7fff,
37 0x1ffff, 0x3ffff, 0x7ffff,
38 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff,
39 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff,
40 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
42 #endif /* BITMAP_BYTES > 2 */
43 #endif /* BITMAP_BYTES > 1 */
47 #define SHOW_OP_DATA (DEBUGGING(BITMAP_OPS) && DEBUGGING(BITMAP_DATA))
51 * Some useful macros to manipulate bitmap data
52 * SEGMENT(m,n) = bit mask for a segment of `m' contiguous bits
53 * starting at column `n'. These macros assume that
54 * m + n <= BITMAP_BITS, 0 <= m, n.
56 #ifdef WORD_BIG_ENDIAN
57 #define SEGMENT(m,n) (bit_masks[m] << (BITMAP_BITS - (m) - (n)))
59 #define SEGMENT(m,n) (bit_masks[m] << (n))
62 /* sampling and shrinking routines shamelessly stolen from xdvi */
64 static int sample_count[] = {
65 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
66 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
67 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
68 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
69 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
70 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
71 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
72 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
73 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
74 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
75 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
76 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
77 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
78 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
79 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
80 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
83 /* bit_swap[j] = j with all bits inverted (i.e. msb -> lsb) */
84 static Uchar bit_swap[] = {
85 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
86 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
87 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
88 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
89 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
90 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
91 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
92 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
93 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
94 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
95 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
96 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
97 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
98 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
99 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
100 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
101 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
102 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
103 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
104 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
105 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
106 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
107 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
108 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
109 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
110 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
111 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
112 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
113 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
114 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
115 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
116 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
121 * next we have three bitmap functions to convert bitmaps in LSB bit order
122 * with 8, 16 and 32 bits per unit, to our internal format. The differences
123 * are minimal, but writing a generic function to handle all unit sizes is
127 BITMAP *bitmap_convert_lsb8(Uchar *bits, int w, int h)
132 register Uchar *curr;
136 DEBUG((DBG_BITMAP_OPS, "convert LSB %dx%d@8 -> bitmap\n", w, h));
138 bm = bitmap_alloc_raw(w, h);
140 /* this is the number of bytes in the original bitmap */
142 unit = (Uchar *)bm->data;
143 end = unit + bm->stride;
145 /* we try to do this as fast as we can */
146 for(i = 0; i < h; i++) {
147 #ifdef WORD_LITTLE_ENDIAN
148 memcpy(unit, curr, bytes);
153 for(j = 0; j < bytes; curr++, j++)
154 unit[j] = bit_swap[*curr];
156 memzero(unit + bytes, bm->stride - bytes);
160 bitmap_print(stderr, bm);
164 BITMAP *bitmap_convert_msb8(Uchar *data, int w, int h)
172 bm = bitmap_alloc(w, h);
174 unit = (Uchar *)bm->data;
176 for(i = 0; i < h; i++) {
177 #ifdef WORD_LITTLE_ENDIAN
180 for(j = 0; j < bytes; curr++, j++)
181 unit[j] = bit_swap[*curr];
183 memcpy(unit, curr, bytes);
186 memzero(unit + bytes, bm->stride - bytes);
190 bitmap_print(stderr, bm);
195 BITMAP *bitmap_copy(BITMAP *bm)
197 BITMAP *nb = bitmap_alloc(bm->width, bm->height);
199 DEBUG((DBG_BITMAP_OPS, "copy %dx%d\n", bm->width, bm->height));
200 memcpy(nb->data, bm->data, bm->height * bm->stride);
204 BITMAP *bitmap_alloc(int w, int h)
211 bm->stride = BM_BYTES_PER_LINE(bm);
213 bm->data = (BmUnit *)xcalloc(h, bm->stride);
220 BITMAP *bitmap_alloc_raw(int w, int h)
227 bm->stride = BM_BYTES_PER_LINE(bm);
229 bm->data = (BmUnit *)xmalloc(h * bm->stride);
236 void bitmap_destroy(BITMAP *bm)
243 void bitmap_print(FILE *out, BITMAP *bm)
247 static const char labels[] = {
248 '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'
257 for(j = 2; j <= bm->width; j++)
263 fprintf(out, "%d", (j - sub)/10);
268 for(j = 0; j < bm->width; j++)
269 putc(labels[j % 10], out);
271 for(i = 0; i < bm->height; i++) {
273 a = (BmUnit *)((char *)bm->data + i * bm->stride);
274 fprintf(out, "%3d ", i+1);
275 for(j = 0; j < bm->width; j++) {
280 if(mask == LASTMASK) {
290 void bitmap_set_col(BITMAP *bm, int row, int col, int count, int state)
295 ptr = __bm_unit_ptr(bm, col, row);
296 mask = FIRSTMASKAT(col);
303 /* move to next row */
304 ptr = bm_offset(ptr, bm->stride);
309 * to use this function you should first make sure that
310 * there is room for `count' bits in the scanline
312 * A general-purpose (but not very efficient) function to paint `n' pixels
313 * on a bitmap, starting at position (x, y) would be:
315 * bitmap_paint_bits(__bm_unit_ptr(bitmap, x, y), x % BITMAP_BITS, n)
318 void bitmap_paint_bits(BmUnit *ptr, int n, int count)
321 if(n + count > BITMAP_BITS) {
322 *ptr |= SEGMENT(BITMAP_BITS - n, n);
323 count -= BITMAP_BITS - n;
326 *ptr |= SEGMENT(count, n);
330 /* paint the middle */
331 for(; count >= BITMAP_BITS; count -= BITMAP_BITS)
332 *ptr++ = bit_masks[BITMAP_BITS];
336 *ptr |= SEGMENT(count, 0);
340 * same as paint_bits but clears pixels instead of painting them. Written
341 * as a separate function for efficiency reasons.
343 void bitmap_clear_bits(BmUnit *ptr, int n, int count)
345 if(n + count > BITMAP_BITS) {
346 *ptr &= ~SEGMENT(BITMAP_BITS - n, n);
347 count -= BITMAP_BITS;
350 *ptr &= ~SEGMENT(count, n);
354 for(; count >= BITMAP_BITS; count -= BITMAP_BITS)
358 *ptr &= ~SEGMENT(count, 0);
361 /* the general function to paint rows. Still used by the PK reader, but that
362 * will change soon (The GF reader already uses bitmap_paint_bits()).
364 void bitmap_set_row(BITMAP *bm, int row, int col, int count, int state)
368 ptr = __bm_unit_ptr(bm, col, row);
370 bitmap_paint_bits(ptr, col & (BITMAP_BITS-1), count);
372 bitmap_clear_bits(ptr, col & (BITMAP_BITS-1), count);
376 * Now several `flipping' operations
379 void bitmap_flip_horizontally(BITMAP *bm)
386 nb.width = bm->width;
387 nb.height = bm->height;
388 nb.stride = bm->stride;
389 nb.data = xcalloc(bm->height, bm->stride);
392 tptr = __bm_unit_ptr(&nb, nb.width-1, 0);
393 for(h = 0; h < bm->height; h++) {
394 BmUnit *fline, *tline;
399 tmask = FIRSTMASKAT(nb.width-1);
400 for(w = 0; w < bm->width; w++) {
403 if(fmask == LASTMASK) {
408 if(tmask == FIRSTMASK) {
414 fptr = bm_offset(fptr, bm->stride);
415 tptr = bm_offset(tptr, bm->stride);
417 DEBUG((DBG_BITMAP_OPS, "flip_horizontally (%d,%d) -> (%d,%d)\n",
418 bm->width, bm->height, nb.width, nb.height));
422 bitmap_print(stderr, bm);
425 void bitmap_flip_vertically(BITMAP *bm)
432 nb.width = bm->width;
433 nb.height = bm->height;
434 nb.stride = bm->stride;
435 nb.data = xcalloc(bm->height, bm->stride);
438 tptr = __bm_unit_ptr(&nb, 0, nb.height-1);
439 for(h = 0; h < bm->height; h++) {
440 BmUnit *fline, *tline;
445 for(w = 0; w < bm->width; w++) {
448 if(fmask == LASTMASK) {
455 fptr = bm_offset(fptr, bm->stride);
456 tptr = (BmUnit *)((char *)tptr - bm->stride);
458 DEBUG((DBG_BITMAP_OPS, "flip_vertically (%d,%d) -> (%d,%d)\n",
459 bm->width, bm->height, nb.width, nb.height));
463 bitmap_print(stderr, bm);
466 void bitmap_flip_diagonally(BITMAP *bm)
473 nb.width = bm->width;
474 nb.height = bm->height;
475 nb.stride = bm->stride;
476 nb.data = xcalloc(bm->height, bm->stride);
479 tptr = __bm_unit_ptr(&nb, nb.width-1, nb.height-1);
480 for(h = 0; h < bm->height; h++) {
481 BmUnit *fline, *tline;
486 tmask = FIRSTMASKAT(nb.width-1);
487 for(w = 0; w < bm->width; w++) {
490 if(fmask == LASTMASK) {
495 if(tmask == FIRSTMASK) {
501 fptr = bm_offset(fptr, bm->stride);
502 tptr = bm_offset(tptr, -nb.stride);
504 DEBUG((DBG_BITMAP_OPS, "flip_diagonally (%d,%d) -> (%d,%d)\n",
505 bm->width, bm->height, nb.width, nb.height));
509 bitmap_print(stderr, bm);
512 void bitmap_rotate_clockwise(BITMAP *bm)
519 nb.width = bm->height;
520 nb.height = bm->width;
521 nb.stride = BM_BYTES_PER_LINE(&nb);
522 nb.data = xcalloc(nb.height, nb.stride);
525 tptr = __bm_unit_ptr(&nb, nb.width - 1, 0);
527 tmask = FIRSTMASKAT(nb.width-1);
528 for(h = 0; h < bm->height; h++) {
529 BmUnit *fline, *tline;
534 for(w = 0; w < bm->width; w++) {
537 if(fmask == LASTMASK) {
543 tline = bm_offset(tline, nb.stride);
545 fptr = bm_offset(fptr, bm->stride);
546 if(tmask == FIRSTMASK) {
553 DEBUG((DBG_BITMAP_OPS, "rotate_clockwise (%d,%d) -> (%d,%d)\n",
554 bm->width, bm->height, nb.width, nb.height));
557 bm->width = nb.width;
558 bm->height = nb.height;
559 bm->stride = nb.stride;
561 bitmap_print(stderr, bm);
564 void bitmap_rotate_counter_clockwise(BITMAP *bm)
571 nb.width = bm->height;
572 nb.height = bm->width;
573 nb.stride = BM_BYTES_PER_LINE(&nb);
574 nb.data = xcalloc(nb.height, nb.stride);
577 tptr = __bm_unit_ptr(&nb, 0, nb.height - 1);
580 for(h = 0; h < bm->height; h++) {
581 BmUnit *fline, *tline;
586 for(w = 0; w < bm->width; w++) {
589 if(fmask == LASTMASK) {
594 /* go to previous row */
595 tline = bm_offset(tline, -nb.stride);
597 fptr = bm_offset(fptr, bm->stride);
598 if(tmask == LASTMASK) {
605 DEBUG((DBG_BITMAP_OPS, "rotate_counter_clockwise (%d,%d) -> (%d,%d)\n",
606 bm->width, bm->height, nb.width, nb.height));
609 bm->width = nb.width;
610 bm->height = nb.height;
611 bm->stride = nb.stride;
613 bitmap_print(stderr, bm);
616 void bitmap_flip_rotate_clockwise(BITMAP *bm)
623 nb.width = bm->height;
624 nb.height = bm->width;
625 nb.stride = BM_BYTES_PER_LINE(&nb);
626 nb.data = xcalloc(nb.height, nb.stride);
629 tptr = __bm_unit_ptr(&nb, nb.width-1, nb.height-1);
631 tmask = FIRSTMASKAT(nb.width-1);
632 for(h = 0; h < bm->height; h++) {
633 BmUnit *fline, *tline;
638 for(w = 0; w < bm->width; w++) {
641 if(fmask == LASTMASK) {
646 /* go to previous line */
647 tline = bm_offset(tline, -nb.stride);
649 fptr = bm_offset(fptr, bm->stride);
650 if(tmask == FIRSTMASK) {
656 DEBUG((DBG_BITMAP_OPS, "flip_rotate_clockwise (%d,%d) -> (%d,%d)\n",
657 bm->width, bm->height, nb.width, nb.height));
660 bm->width = nb.width;
661 bm->height = nb.height;
662 bm->stride = nb.stride;
664 bitmap_print(stderr, bm);
667 void bitmap_flip_rotate_counter_clockwise(BITMAP *bm)
674 nb.width = bm->height;
675 nb.height = bm->width;
676 nb.stride = BM_BYTES_PER_LINE(&nb);
677 nb.data = xcalloc(nb.height, nb.stride);
683 for(h = 0; h < bm->height; h++) {
684 BmUnit *fline, *tline;
689 for(w = 0; w < bm->width; w++) {
692 if(fmask == LASTMASK) {
697 /* go to next line */
698 tline = bm_offset(tline, nb.stride);
700 fptr = bm_offset(fptr, bm->stride);
701 if(tmask == LASTMASK) {
708 DEBUG((DBG_BITMAP_OPS, "flip_rotate_counter_clockwise (%d,%d) -> (%d,%d)\n",
709 bm->width, bm->height, nb.width, nb.height));
712 bm->width = nb.width;
713 bm->height = nb.height;
714 bm->stride = nb.stride;
716 bitmap_print(stderr, bm);
720 void bitmap_transform(BITMAP *map, DviOrientation orient)
723 case MDVI_ORIENT_TBLR:
725 case MDVI_ORIENT_TBRL:
726 bitmap_flip_horizontally(map);
728 case MDVI_ORIENT_BTLR:
729 bitmap_flip_vertically(map);
731 case MDVI_ORIENT_BTRL:
732 bitmap_flip_diagonally(map);
734 case MDVI_ORIENT_RP90:
735 bitmap_rotate_counter_clockwise(map);
737 case MDVI_ORIENT_RM90:
738 bitmap_rotate_clockwise(map);
740 case MDVI_ORIENT_IRP90:
741 bitmap_flip_rotate_counter_clockwise(map);
743 case MDVI_ORIENT_IRM90:
744 bitmap_flip_rotate_clockwise(map);
751 * Count the number of non-zero bits in a box of dimensions w x h, starting
752 * at column `step' in row `data'.
754 * Shamelessly stolen from xdvi.
756 static int do_sample(BmUnit *data, int stride, int step, int w, int h)
758 BmUnit *ptr, *end, *cp;
763 ptr = data + step / BITMAP_BITS;
764 end = bm_offset(data, h * stride);
765 shift = FIRSTSHIFTAT(step);
769 #ifndef WORD_BIG_ENDIAN
770 wid = BITMAP_BITS - shift;
778 #ifdef WORD_BIG_ENDIAN
781 for(cp = ptr; cp < end; cp = bm_offset(cp, stride))
782 n += sample_count[(*cp >> shift) & bit_masks[wid]];
783 #ifndef WORD_BIG_ENDIAN
786 #ifdef WORD_BIG_ENDIAN
792 if(shift == BITMAP_BITS) {
802 void mdvi_shrink_box(DviContext *dvi, DviFont *font,
803 DviFontChar *pk, DviGlyph *dest)
809 hs = dvi->params.hshrink;
810 vs = dvi->params.vshrink;
813 x = (int)glyph->x / hs;
814 if((int)glyph->x - x * hs > 0)
816 dest->w = x + ROUND((int)glyph->w - glyph->x, hs);
818 z = (int)glyph->y + 1;
822 dest->h = y + ROUND((int)glyph->h - z, vs) + 1;
824 dest->y = glyph->y / vs;
825 dest->data = MDVI_GLYPH_EMPTY;
826 DEBUG((DBG_BITMAPS, "shrink_box: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n",
827 glyph->w, glyph->h, glyph->x, glyph->y,
828 dest->w, dest->h, dest->x, dest->y));
831 void mdvi_shrink_glyph(DviContext *dvi, DviFont *font,
832 DviFontChar *pk, DviGlyph *dest)
834 int rows_left, rows, init_cols;
836 BmUnit *old_ptr, *new_ptr;
837 BITMAP *oldmap, *newmap;
840 int sample, min_sample;
847 hs = dvi->params.hshrink;
848 vs = dvi->params.vshrink;
850 min_sample = vs * hs * dvi->params.density / 100;
853 oldmap = (BITMAP *)glyph->data;
855 x = (int)glyph->x / hs;
856 init_cols = (int)glyph->x - x * hs;
861 w = x + ROUND((int)glyph->w - glyph->x, hs);
863 cols = (int)glyph->y + 1;
865 rows = cols - y * vs;
870 h = y + ROUND((int)glyph->h - cols, vs) + 1;
872 /* create the new glyph */
873 newmap = bitmap_alloc(w, h);
876 dest->y = glyph->y / vs;
880 old_ptr = oldmap->data;
881 old_stride = oldmap->stride;
882 new_ptr = newmap->data;
883 new_stride = newmap->stride;
884 rows_left = glyph->h;
889 cols_left = glyph->w;
893 while(cols_left > 0) {
896 sample = do_sample(old_ptr, old_stride,
897 glyph->w - cols_left, cols, rows);
898 if(sample >= min_sample)
908 new_ptr = bm_offset(new_ptr, new_stride);
909 old_ptr = bm_offset(old_ptr, rows * old_stride);
913 DEBUG((DBG_BITMAPS, "shrink_glyph: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n",
914 glyph->w, glyph->h, glyph->x, glyph->y,
915 dest->w, dest->h, dest->x, dest->y));
916 if(DEBUGGING(BITMAP_DATA))
917 bitmap_print(stderr, newmap);
920 void mdvi_shrink_glyph_grey(DviContext *dvi, DviFont *font,
921 DviFontChar *pk, DviGlyph *dest)
924 int cols_left, cols, init_cols;
925 long sampleval, samplemax;
938 hs = dvi->params.hshrink;
939 vs = dvi->params.vshrink;
943 map = (BITMAP *)glyph->data;
945 x = (int)glyph->x / hs;
946 init_cols = (int)glyph->x - x * hs;
951 w = x + ROUND((int)glyph->w - glyph->x, hs);
953 cols = (int)glyph->y + 1;
955 rows = cols - y * vs;
960 h = y + ROUND((int)glyph->h - cols, vs) + 1;
963 /* before touching anything, do this */
964 image = dev->create_image(dev->device_data, w, h, BITMAP_BITS);
966 mdvi_shrink_glyph(dvi, font, pk, dest);
970 /* save these colors */
971 pk->fg = MDVI_CURRFG(dvi);
972 pk->bg = MDVI_CURRBG(dvi);
975 npixels = samplemax + 1;
976 pixels = get_color_table(&dvi->device, npixels, pk->fg, pk->bg,
977 dvi->params.gamma, dvi->params.density);
980 colortab[0] = pk->fg;
981 colortab[1] = pk->bg;
982 pixels = &colortab[0];
985 /* setup the new glyph */
988 dest->y = glyph->y / vs;
994 rows_left = glyph->h;
996 while(rows_left && y < h) {
1000 cols_left = glyph->w;
1002 while(cols_left && x < w) {
1003 if(cols > cols_left)
1005 sampleval = do_sample(old_ptr, map->stride,
1006 glyph->w - cols_left, cols, rows);
1007 /* scale the sample value by the number of grey levels */
1008 if(npixels - 1 != samplemax)
1009 sampleval = ((npixels-1) * sampleval) / samplemax;
1010 ASSERT(sampleval < npixels);
1011 dev->put_pixel(image, x, y, pixels[sampleval]);
1017 dev->put_pixel(image, x, y, pixels[0]);
1018 old_ptr = bm_offset(old_ptr, rows * map->stride);
1025 for(x = 0; x < w; x++)
1026 dev->put_pixel(image, x, y, pixels[0]);
1028 DEBUG((DBG_BITMAPS, "shrink_glyph_grey: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n",
1029 glyph->w, glyph->h, glyph->x, glyph->y,
1030 dest->w, dest->h, dest->x, dest->y));