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 */
27 /* bit_masks[n] contains a BmUnit with `n' contiguous bits */
29 static BmUnit bit_masks[] = {
31 0xf, 0x1f, 0x3f, 0x7f,
35 0xfff, 0x1fff, 0x3fff, 0x7fff,
38 0x1ffff, 0x3ffff, 0x7ffff,
39 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff,
40 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff,
41 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
43 #endif /* BITMAP_BYTES > 2 */
44 #endif /* BITMAP_BYTES > 1 */
48 #define SHOW_OP_DATA (DEBUGGING(BITMAP_OPS) && DEBUGGING(BITMAP_DATA))
52 * Some useful macros to manipulate bitmap data
53 * SEGMENT(m,n) = bit mask for a segment of `m' contiguous bits
54 * starting at column `n'. These macros assume that
55 * m + n <= BITMAP_BITS, 0 <= m, n.
57 #ifdef WORD_BIG_ENDIAN
58 #define SEGMENT(m,n) (bit_masks[m] << (BITMAP_BITS - (m) - (n)))
60 #define SEGMENT(m,n) (bit_masks[m] << (n))
63 /* sampling and shrinking routines shamelessly stolen from xdvi */
65 static int sample_count[] = {
66 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
67 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
68 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
69 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
70 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
71 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
72 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
73 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
74 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
75 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
76 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
77 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
78 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
79 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
80 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
81 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
84 /* bit_swap[j] = j with all bits inverted (i.e. msb -> lsb) */
85 static Uchar bit_swap[] = {
86 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
87 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
88 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
89 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
90 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
91 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
92 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
93 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
94 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
95 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
96 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
97 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
98 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
99 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
100 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
101 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
102 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
103 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
104 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
105 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
106 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
107 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
108 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
109 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
110 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
111 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
112 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
113 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
114 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
115 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
116 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
117 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
122 * next we have three bitmap functions to convert bitmaps in LSB bit order
123 * with 8, 16 and 32 bits per unit, to our internal format. The differences
124 * are minimal, but writing a generic function to handle all unit sizes is
128 BITMAP *bitmap_convert_lsb8(Uchar *bits, int w, int h)
133 register Uchar *curr;
137 DEBUG((DBG_BITMAP_OPS, "convert LSB %dx%d@8 -> bitmap\n", w, h));
139 bm = bitmap_alloc_raw(w, h);
141 /* this is the number of bytes in the original bitmap */
143 unit = (Uchar *)bm->data;
144 end = unit + bm->stride;
146 /* we try to do this as fast as we can */
147 for(i = 0; i < h; i++) {
148 #ifdef WORD_LITTLE_ENDIAN
149 memcpy(unit, curr, bytes);
154 for(j = 0; j < bytes; curr++, j++)
155 unit[j] = bit_swap[*curr];
157 memzero(unit + bytes, bm->stride - bytes);
161 bitmap_print(stderr, bm);
165 BITMAP *bitmap_convert_msb8(Uchar *data, int w, int h)
173 bm = bitmap_alloc(w, h);
175 unit = (Uchar *)bm->data;
177 for(i = 0; i < h; i++) {
178 #ifdef WORD_LITTLE_ENDIAN
181 for(j = 0; j < bytes; curr++, j++)
182 unit[j] = bit_swap[*curr];
184 memcpy(unit, curr, bytes);
187 memzero(unit + bytes, bm->stride - bytes);
191 bitmap_print(stderr, bm);
196 BITMAP *bitmap_copy(BITMAP *bm)
198 BITMAP *nb = bitmap_alloc(bm->width, bm->height);
200 DEBUG((DBG_BITMAP_OPS, "copy %dx%d\n", bm->width, bm->height));
201 memcpy(nb->data, bm->data, bm->height * bm->stride);
205 BITMAP *bitmap_alloc(int w, int h)
212 bm->stride = BM_BYTES_PER_LINE(bm);
214 bm->data = (BmUnit *)mdvi_calloc(h, bm->stride);
221 BITMAP *bitmap_alloc_raw(int w, int h)
228 bm->stride = BM_BYTES_PER_LINE(bm);
230 bm->data = (BmUnit *)mdvi_malloc(h * bm->stride);
237 void bitmap_destroy(BITMAP *bm)
244 void bitmap_print(FILE *out, BITMAP *bm)
248 static const char labels[] = {
249 '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'
258 for(j = 2; j <= bm->width; j++)
264 fprintf(out, "%d", (j - sub)/10);
269 for(j = 0; j < bm->width; j++)
270 putc(labels[j % 10], out);
272 for(i = 0; i < bm->height; i++) {
274 a = (BmUnit *)((char *)bm->data + i * bm->stride);
275 fprintf(out, "%3d ", i+1);
276 for(j = 0; j < bm->width; j++) {
281 if(mask == LASTMASK) {
291 void bitmap_set_col(BITMAP *bm, int row, int col, int count, int state)
296 ptr = __bm_unit_ptr(bm, col, row);
297 mask = FIRSTMASKAT(col);
304 /* move to next row */
305 ptr = bm_offset(ptr, bm->stride);
310 * to use this function you should first make sure that
311 * there is room for `count' bits in the scanline
313 * A general-purpose (but not very efficient) function to paint `n' pixels
314 * on a bitmap, starting at position (x, y) would be:
316 * bitmap_paint_bits(__bm_unit_ptr(bitmap, x, y), x % BITMAP_BITS, n)
319 void bitmap_paint_bits(BmUnit *ptr, int n, int count)
322 if(n + count > BITMAP_BITS) {
323 *ptr |= SEGMENT(BITMAP_BITS - n, n);
324 count -= BITMAP_BITS - n;
327 *ptr |= SEGMENT(count, n);
331 /* paint the middle */
332 for(; count >= BITMAP_BITS; count -= BITMAP_BITS)
333 *ptr++ = bit_masks[BITMAP_BITS];
337 *ptr |= SEGMENT(count, 0);
341 * same as paint_bits but clears pixels instead of painting them. Written
342 * as a separate function for efficiency reasons.
344 void bitmap_clear_bits(BmUnit *ptr, int n, int count)
346 if(n + count > BITMAP_BITS) {
347 *ptr &= ~SEGMENT(BITMAP_BITS - n, n);
348 count -= BITMAP_BITS;
351 *ptr &= ~SEGMENT(count, n);
355 for(; count >= BITMAP_BITS; count -= BITMAP_BITS)
359 *ptr &= ~SEGMENT(count, 0);
362 /* the general function to paint rows. Still used by the PK reader, but that
363 * will change soon (The GF reader already uses bitmap_paint_bits()).
365 void bitmap_set_row(BITMAP *bm, int row, int col, int count, int state)
369 ptr = __bm_unit_ptr(bm, col, row);
371 bitmap_paint_bits(ptr, col & (BITMAP_BITS-1), count);
373 bitmap_clear_bits(ptr, col & (BITMAP_BITS-1), count);
377 * Now several `flipping' operations
380 void bitmap_flip_horizontally(BITMAP *bm)
387 nb.width = bm->width;
388 nb.height = bm->height;
389 nb.stride = bm->stride;
390 nb.data = mdvi_calloc(bm->height, bm->stride);
393 tptr = __bm_unit_ptr(&nb, nb.width-1, 0);
394 for(h = 0; h < bm->height; h++) {
395 BmUnit *fline, *tline;
400 tmask = FIRSTMASKAT(nb.width-1);
401 for(w = 0; w < bm->width; w++) {
404 if(fmask == LASTMASK) {
409 if(tmask == FIRSTMASK) {
415 fptr = bm_offset(fptr, bm->stride);
416 tptr = bm_offset(tptr, bm->stride);
418 DEBUG((DBG_BITMAP_OPS, "flip_horizontally (%d,%d) -> (%d,%d)\n",
419 bm->width, bm->height, nb.width, nb.height));
423 bitmap_print(stderr, bm);
426 void bitmap_flip_vertically(BITMAP *bm)
433 nb.width = bm->width;
434 nb.height = bm->height;
435 nb.stride = bm->stride;
436 nb.data = mdvi_calloc(bm->height, bm->stride);
439 tptr = __bm_unit_ptr(&nb, 0, nb.height-1);
440 for(h = 0; h < bm->height; h++) {
441 BmUnit *fline, *tline;
446 for(w = 0; w < bm->width; w++) {
449 if(fmask == LASTMASK) {
456 fptr = bm_offset(fptr, bm->stride);
457 tptr = (BmUnit *)((char *)tptr - bm->stride);
459 DEBUG((DBG_BITMAP_OPS, "flip_vertically (%d,%d) -> (%d,%d)\n",
460 bm->width, bm->height, nb.width, nb.height));
464 bitmap_print(stderr, bm);
467 void bitmap_flip_diagonally(BITMAP *bm)
474 nb.width = bm->width;
475 nb.height = bm->height;
476 nb.stride = bm->stride;
477 nb.data = mdvi_calloc(bm->height, bm->stride);
480 tptr = __bm_unit_ptr(&nb, nb.width-1, nb.height-1);
481 for(h = 0; h < bm->height; h++) {
482 BmUnit *fline, *tline;
487 tmask = FIRSTMASKAT(nb.width-1);
488 for(w = 0; w < bm->width; w++) {
491 if(fmask == LASTMASK) {
496 if(tmask == FIRSTMASK) {
502 fptr = bm_offset(fptr, bm->stride);
503 tptr = bm_offset(tptr, -nb.stride);
505 DEBUG((DBG_BITMAP_OPS, "flip_diagonally (%d,%d) -> (%d,%d)\n",
506 bm->width, bm->height, nb.width, nb.height));
510 bitmap_print(stderr, bm);
513 void bitmap_rotate_clockwise(BITMAP *bm)
520 nb.width = bm->height;
521 nb.height = bm->width;
522 nb.stride = BM_BYTES_PER_LINE(&nb);
523 nb.data = mdvi_calloc(nb.height, nb.stride);
526 tptr = __bm_unit_ptr(&nb, nb.width - 1, 0);
528 tmask = FIRSTMASKAT(nb.width-1);
529 for(h = 0; h < bm->height; h++) {
530 BmUnit *fline, *tline;
535 for(w = 0; w < bm->width; w++) {
538 if(fmask == LASTMASK) {
544 tline = bm_offset(tline, nb.stride);
546 fptr = bm_offset(fptr, bm->stride);
547 if(tmask == FIRSTMASK) {
554 DEBUG((DBG_BITMAP_OPS, "rotate_clockwise (%d,%d) -> (%d,%d)\n",
555 bm->width, bm->height, nb.width, nb.height));
558 bm->width = nb.width;
559 bm->height = nb.height;
560 bm->stride = nb.stride;
562 bitmap_print(stderr, bm);
565 void bitmap_rotate_counter_clockwise(BITMAP *bm)
572 nb.width = bm->height;
573 nb.height = bm->width;
574 nb.stride = BM_BYTES_PER_LINE(&nb);
575 nb.data = mdvi_calloc(nb.height, nb.stride);
578 tptr = __bm_unit_ptr(&nb, 0, nb.height - 1);
581 for(h = 0; h < bm->height; h++) {
582 BmUnit *fline, *tline;
587 for(w = 0; w < bm->width; w++) {
590 if(fmask == LASTMASK) {
595 /* go to previous row */
596 tline = bm_offset(tline, -nb.stride);
598 fptr = bm_offset(fptr, bm->stride);
599 if(tmask == LASTMASK) {
606 DEBUG((DBG_BITMAP_OPS, "rotate_counter_clockwise (%d,%d) -> (%d,%d)\n",
607 bm->width, bm->height, nb.width, nb.height));
610 bm->width = nb.width;
611 bm->height = nb.height;
612 bm->stride = nb.stride;
614 bitmap_print(stderr, bm);
617 void bitmap_flip_rotate_clockwise(BITMAP *bm)
624 nb.width = bm->height;
625 nb.height = bm->width;
626 nb.stride = BM_BYTES_PER_LINE(&nb);
627 nb.data = mdvi_calloc(nb.height, nb.stride);
630 tptr = __bm_unit_ptr(&nb, nb.width-1, nb.height-1);
632 tmask = FIRSTMASKAT(nb.width-1);
633 for(h = 0; h < bm->height; h++) {
634 BmUnit *fline, *tline;
639 for(w = 0; w < bm->width; w++) {
642 if(fmask == LASTMASK) {
647 /* go to previous line */
648 tline = bm_offset(tline, -nb.stride);
650 fptr = bm_offset(fptr, bm->stride);
651 if(tmask == FIRSTMASK) {
657 DEBUG((DBG_BITMAP_OPS, "flip_rotate_clockwise (%d,%d) -> (%d,%d)\n",
658 bm->width, bm->height, nb.width, nb.height));
661 bm->width = nb.width;
662 bm->height = nb.height;
663 bm->stride = nb.stride;
665 bitmap_print(stderr, bm);
668 void bitmap_flip_rotate_counter_clockwise(BITMAP *bm)
675 nb.width = bm->height;
676 nb.height = bm->width;
677 nb.stride = BM_BYTES_PER_LINE(&nb);
678 nb.data = mdvi_calloc(nb.height, nb.stride);
684 for(h = 0; h < bm->height; h++) {
685 BmUnit *fline, *tline;
690 for(w = 0; w < bm->width; w++) {
693 if(fmask == LASTMASK) {
698 /* go to next line */
699 tline = bm_offset(tline, nb.stride);
701 fptr = bm_offset(fptr, bm->stride);
702 if(tmask == LASTMASK) {
709 DEBUG((DBG_BITMAP_OPS, "flip_rotate_counter_clockwise (%d,%d) -> (%d,%d)\n",
710 bm->width, bm->height, nb.width, nb.height));
713 bm->width = nb.width;
714 bm->height = nb.height;
715 bm->stride = nb.stride;
717 bitmap_print(stderr, bm);
721 void bitmap_transform(BITMAP *map, DviOrientation orient)
724 case MDVI_ORIENT_TBLR:
726 case MDVI_ORIENT_TBRL:
727 bitmap_flip_horizontally(map);
729 case MDVI_ORIENT_BTLR:
730 bitmap_flip_vertically(map);
732 case MDVI_ORIENT_BTRL:
733 bitmap_flip_diagonally(map);
735 case MDVI_ORIENT_RP90:
736 bitmap_rotate_counter_clockwise(map);
738 case MDVI_ORIENT_RM90:
739 bitmap_rotate_clockwise(map);
741 case MDVI_ORIENT_IRP90:
742 bitmap_flip_rotate_counter_clockwise(map);
744 case MDVI_ORIENT_IRM90:
745 bitmap_flip_rotate_clockwise(map);
752 * Count the number of non-zero bits in a box of dimensions w x h, starting
753 * at column `step' in row `data'.
755 * Shamelessly stolen from xdvi.
757 static int do_sample(BmUnit *data, int stride, int step, int w, int h)
759 BmUnit *ptr, *end, *cp;
764 ptr = data + step / BITMAP_BITS;
765 end = bm_offset(data, h * stride);
766 shift = FIRSTSHIFTAT(step);
770 #ifndef WORD_BIG_ENDIAN
771 wid = BITMAP_BITS - shift;
779 #ifdef WORD_BIG_ENDIAN
782 for(cp = ptr; cp < end; cp = bm_offset(cp, stride))
783 n += sample_count[(*cp >> shift) & bit_masks[wid]];
784 #ifndef WORD_BIG_ENDIAN
787 #ifdef WORD_BIG_ENDIAN
793 if(shift == BITMAP_BITS) {
803 void mdvi_shrink_box(DviContext *dvi, DviFont *font,
804 DviFontChar *pk, DviGlyph *dest)
810 hs = dvi->params.hshrink;
811 vs = dvi->params.vshrink;
814 x = (int)glyph->x / hs;
815 if((int)glyph->x - x * hs > 0)
817 dest->w = x + ROUND((int)glyph->w - glyph->x, hs);
819 z = (int)glyph->y + 1;
823 dest->h = y + ROUND((int)glyph->h - z, vs) + 1;
825 dest->y = glyph->y / vs;
826 dest->data = MDVI_GLYPH_EMPTY;
827 DEBUG((DBG_BITMAPS, "shrink_box: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n",
828 glyph->w, glyph->h, glyph->x, glyph->y,
829 dest->w, dest->h, dest->x, dest->y));
832 void mdvi_shrink_glyph(DviContext *dvi, DviFont *font,
833 DviFontChar *pk, DviGlyph *dest)
835 int rows_left, rows, init_cols;
837 BmUnit *old_ptr, *new_ptr;
838 BITMAP *oldmap, *newmap;
841 int sample, min_sample;
848 hs = dvi->params.hshrink;
849 vs = dvi->params.vshrink;
851 min_sample = vs * hs * dvi->params.density / 100;
854 oldmap = (BITMAP *)glyph->data;
856 x = (int)glyph->x / hs;
857 init_cols = (int)glyph->x - x * hs;
862 w = x + ROUND((int)glyph->w - glyph->x, hs);
864 cols = (int)glyph->y + 1;
866 rows = cols - y * vs;
871 h = y + ROUND((int)glyph->h - cols, vs) + 1;
873 /* create the new glyph */
874 newmap = bitmap_alloc(w, h);
877 dest->y = glyph->y / vs;
881 old_ptr = oldmap->data;
882 old_stride = oldmap->stride;
883 new_ptr = newmap->data;
884 new_stride = newmap->stride;
885 rows_left = glyph->h;
890 cols_left = glyph->w;
894 while(cols_left > 0) {
897 sample = do_sample(old_ptr, old_stride,
898 glyph->w - cols_left, cols, rows);
899 if(sample >= min_sample)
909 new_ptr = bm_offset(new_ptr, new_stride);
910 old_ptr = bm_offset(old_ptr, rows * old_stride);
914 DEBUG((DBG_BITMAPS, "shrink_glyph: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n",
915 glyph->w, glyph->h, glyph->x, glyph->y,
916 dest->w, dest->h, dest->x, dest->y));
917 if(DEBUGGING(BITMAP_DATA))
918 bitmap_print(stderr, newmap);
921 void mdvi_shrink_glyph_grey(DviContext *dvi, DviFont *font,
922 DviFontChar *pk, DviGlyph *dest)
925 int cols_left, cols, init_cols;
926 long sampleval, samplemax;
939 hs = dvi->params.hshrink;
940 vs = dvi->params.vshrink;
944 map = (BITMAP *)glyph->data;
946 x = (int)glyph->x / hs;
947 init_cols = (int)glyph->x - x * hs;
952 w = x + ROUND((int)glyph->w - glyph->x, hs);
954 cols = (int)glyph->y + 1;
956 rows = cols - y * vs;
961 h = y + ROUND((int)glyph->h - cols, vs) + 1;
964 /* before touching anything, do this */
965 image = dev->create_image(dev->device_data, w, h, BITMAP_BITS);
967 mdvi_shrink_glyph(dvi, font, pk, dest);
971 /* save these colors */
972 pk->fg = MDVI_CURRFG(dvi);
973 pk->bg = MDVI_CURRBG(dvi);
976 npixels = samplemax + 1;
977 pixels = get_color_table(&dvi->device, npixels, pk->fg, pk->bg,
978 dvi->params.gamma, dvi->params.density);
981 colortab[0] = pk->fg;
982 colortab[1] = pk->bg;
983 pixels = &colortab[0];
986 /* setup the new glyph */
989 dest->y = glyph->y / vs;
995 rows_left = glyph->h;
997 while(rows_left && y < h) {
1001 cols_left = glyph->w;
1003 while(cols_left && x < w) {
1004 if(cols > cols_left)
1006 sampleval = do_sample(old_ptr, map->stride,
1007 glyph->w - cols_left, cols, rows);
1008 /* scale the sample value by the number of grey levels */
1009 if(npixels - 1 != samplemax)
1010 sampleval = ((npixels-1) * sampleval) / samplemax;
1011 ASSERT(sampleval < npixels);
1012 dev->put_pixel(image, x, y, pixels[sampleval]);
1018 dev->put_pixel(image, x, y, pixels[0]);
1019 old_ptr = bm_offset(old_ptr, rows * map->stride);
1026 for(x = 0; x < w; x++)
1027 dev->put_pixel(image, x, y, pixels[0]);
1029 DEBUG((DBG_BITMAPS, "shrink_glyph_grey: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n",
1030 glyph->w, glyph->h, glyph->x, glyph->y,
1031 dest->w, dest->h, dest->x, dest->y));