diff options
Diffstat (limited to 'dvi/mdvi-lib/bitmap.c')
-rw-r--r-- | dvi/mdvi-lib/bitmap.c | 1032 |
1 files changed, 0 insertions, 1032 deletions
diff --git a/dvi/mdvi-lib/bitmap.c b/dvi/mdvi-lib/bitmap.c deleted file mode 100644 index 9014dba..0000000 --- a/dvi/mdvi-lib/bitmap.c +++ /dev/null @@ -1,1032 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* Bitmap manipulation routines */ - -#include <stdlib.h> - -#include "mdvi.h" -#include "color.h" - -/* bit_masks[n] contains a BmUnit with `n' contiguous bits */ - -static BmUnit bit_masks[] = { - 0x0, 0x1, 0x3, 0x7, - 0xf, 0x1f, 0x3f, 0x7f, - 0xff, -#if BITMAP_BYTES > 1 - 0x1ff, 0x3ff, 0x7ff, - 0xfff, 0x1fff, 0x3fff, 0x7fff, - 0xffff, -#if BITMAP_BYTES > 2 - 0x1ffff, 0x3ffff, 0x7ffff, - 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, - 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, - 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, - 0xffffffff -#endif /* BITMAP_BYTES > 2 */ -#endif /* BITMAP_BYTES > 1 */ -}; - -#ifndef NODEBUG -#define SHOW_OP_DATA (DEBUGGING(BITMAP_OPS) && DEBUGGING(BITMAP_DATA)) -#endif - -/* - * Some useful macros to manipulate bitmap data - * SEGMENT(m,n) = bit mask for a segment of `m' contiguous bits - * starting at column `n'. These macros assume that - * m + n <= BITMAP_BITS, 0 <= m, n. - */ -#ifdef WORD_BIG_ENDIAN -#define SEGMENT(m,n) (bit_masks[m] << (BITMAP_BITS - (m) - (n))) -#else -#define SEGMENT(m,n) (bit_masks[m] << (n)) -#endif - -/* sampling and shrinking routines shamelessly stolen from xdvi */ - -static int sample_count[] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 -}; - -/* bit_swap[j] = j with all bits inverted (i.e. msb -> lsb) */ -static Uchar bit_swap[] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff -}; - - -/* - * next we have three bitmap functions to convert bitmaps in LSB bit order - * with 8, 16 and 32 bits per unit, to our internal format. The differences - * are minimal, but writing a generic function to handle all unit sizes is - * hopelessly slow. - */ - -BITMAP *bitmap_convert_lsb8(Uchar *bits, int w, int h) -{ - BITMAP *bm; - int i; - Uchar *unit; - register Uchar *curr; - Uchar *end; - int bytes; - - DEBUG((DBG_BITMAP_OPS, "convert LSB %dx%d@8 -> bitmap\n", w, h)); - - bm = bitmap_alloc_raw(w, h); - - /* this is the number of bytes in the original bitmap */ - bytes = ROUND(w, 8); - unit = (Uchar *)bm->data; - end = unit + bm->stride; - curr = bits; - /* we try to do this as fast as we can */ - for(i = 0; i < h; i++) { -#ifdef WORD_LITTLE_ENDIAN - memcpy(unit, curr, bytes); - curr += bytes; -#else - int j; - - for(j = 0; j < bytes; curr++, j++) - unit[j] = bit_swap[*curr]; -#endif - memzero(unit + bytes, bm->stride - bytes); - unit += bm->stride; - } - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); - return bm; -} - -BITMAP *bitmap_convert_msb8(Uchar *data, int w, int h) -{ - BITMAP *bm; - Uchar *unit; - Uchar *curr; - int i; - int bytes; - - bm = bitmap_alloc(w, h); - bytes = ROUND(w, 8); - unit = (Uchar *)bm->data; - curr = data; - for(i = 0; i < h; i++) { -#ifdef WORD_LITTLE_ENDIAN - int j; - - for(j = 0; j < bytes; curr++, j++) - unit[j] = bit_swap[*curr]; -#else - memcpy(unit, curr, bytes); - curr += bytes; -#endif - memzero(unit + bytes, bm->stride - bytes); - unit += bm->stride; - } - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); - return bm; -} - - -BITMAP *bitmap_copy(BITMAP *bm) -{ - BITMAP *nb = bitmap_alloc(bm->width, bm->height); - - DEBUG((DBG_BITMAP_OPS, "copy %dx%d\n", bm->width, bm->height)); - memcpy(nb->data, bm->data, bm->height * bm->stride); - return nb; -} - -BITMAP *bitmap_alloc(int w, int h) -{ - BITMAP *bm; - - bm = xalloc(BITMAP); - bm->width = w; - bm->height = h; - bm->stride = BM_BYTES_PER_LINE(bm); - if(h && bm->stride) - bm->data = (BmUnit *)mdvi_calloc(h, bm->stride); - else - bm->data = NULL; - - return bm; -} - -BITMAP *bitmap_alloc_raw(int w, int h) -{ - BITMAP *bm; - - bm = xalloc(BITMAP); - bm->width = w; - bm->height = h; - bm->stride = BM_BYTES_PER_LINE(bm); - if(h && bm->stride) - bm->data = (BmUnit *)mdvi_malloc(h * bm->stride); - else - bm->data = NULL; - - return bm; -} - -void bitmap_destroy(BITMAP *bm) -{ - if(bm->data) - free(bm->data); - free(bm); -} - -void bitmap_print(FILE *out, BITMAP *bm) -{ - int i, j; - BmUnit *a, mask; - static const char labels[] = { - '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' - }; - int sub; - - a = bm->data; - fprintf(out, " "); - if(bm->width > 10) { - putchar('0'); - sub = 0; - for(j = 2; j <= bm->width; j++) - if((j %10) == 0) { - if((j % 100) == 0) { - fprintf(out, "*"); - sub += 100; - } else - fprintf(out, "%d", (j - sub)/10); - } else - putc(' ', out); - fprintf(out, "\n "); - } - for(j = 0; j < bm->width; j++) - putc(labels[j % 10], out); - putchar('\n'); - for(i = 0; i < bm->height; i++) { - mask = FIRSTMASK; - a = (BmUnit *)((char *)bm->data + i * bm->stride); - fprintf(out, "%3d ", i+1); - for(j = 0; j < bm->width; j++) { - if(*a & mask) - putc('#', out); - else - putc('.', out); - if(mask == LASTMASK) { - a++; - mask = FIRSTMASK; - } else - NEXTMASK(mask); - } - putchar('\n'); - } -} - -void bitmap_set_col(BITMAP *bm, int row, int col, int count, int state) -{ - BmUnit *ptr; - BmUnit mask; - - ptr = __bm_unit_ptr(bm, col, row); - mask = FIRSTMASKAT(col); - - while(count-- > 0) { - if(state) - *ptr |= mask; - else - *ptr &= ~mask; - /* move to next row */ - ptr = bm_offset(ptr, bm->stride); - } -} - -/* - * to use this function you should first make sure that - * there is room for `count' bits in the scanline - * - * A general-purpose (but not very efficient) function to paint `n' pixels - * on a bitmap, starting at position (x, y) would be: - * - * bitmap_paint_bits(__bm_unit_ptr(bitmap, x, y), x % BITMAP_BITS, n) - * - */ -void bitmap_paint_bits(BmUnit *ptr, int n, int count) -{ - /* paint the head */ - if(n + count > BITMAP_BITS) { - *ptr |= SEGMENT(BITMAP_BITS - n, n); - count -= BITMAP_BITS - n; - ptr++; - } else { - *ptr |= SEGMENT(count, n); - return; - } - - /* paint the middle */ - for(; count >= BITMAP_BITS; count -= BITMAP_BITS) - *ptr++ = bit_masks[BITMAP_BITS]; - - /* paint the tail */ - if(count > 0) - *ptr |= SEGMENT(count, 0); -} - -/* - * same as paint_bits but clears pixels instead of painting them. Written - * as a separate function for efficiency reasons. - */ -void bitmap_clear_bits(BmUnit *ptr, int n, int count) -{ - if(n + count > BITMAP_BITS) { - *ptr &= ~SEGMENT(BITMAP_BITS - n, n); - count -= BITMAP_BITS; - ptr++; - } else { - *ptr &= ~SEGMENT(count, n); - return; - } - - for(; count >= BITMAP_BITS; count -= BITMAP_BITS) - *ptr++ = 0; - - if(count > 0) - *ptr &= ~SEGMENT(count, 0); -} - -/* the general function to paint rows. Still used by the PK reader, but that - * will change soon (The GF reader already uses bitmap_paint_bits()). - */ -void bitmap_set_row(BITMAP *bm, int row, int col, int count, int state) -{ - BmUnit *ptr; - - ptr = __bm_unit_ptr(bm, col, row); - if(state) - bitmap_paint_bits(ptr, col & (BITMAP_BITS-1), count); - else - bitmap_clear_bits(ptr, col & (BITMAP_BITS-1), count); -} - -/* - * Now several `flipping' operations - */ - -void bitmap_flip_horizontally(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask, tmask; - int w, h; - - nb.width = bm->width; - nb.height = bm->height; - nb.stride = bm->stride; - nb.data = mdvi_calloc(bm->height, bm->stride); - - fptr = bm->data; - tptr = __bm_unit_ptr(&nb, nb.width-1, 0); - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fline = fptr; - tline = tptr; - fmask = FIRSTMASK; - tmask = FIRSTMASKAT(nb.width-1); - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= tmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - } else - NEXTMASK(fmask); - if(tmask == FIRSTMASK) { - tmask = LASTMASK; - tline--; - } else - PREVMASK(tmask); - } - fptr = bm_offset(fptr, bm->stride); - tptr = bm_offset(tptr, bm->stride); - } - DEBUG((DBG_BITMAP_OPS, "flip_horizontally (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -void bitmap_flip_vertically(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask; - int w, h; - - nb.width = bm->width; - nb.height = bm->height; - nb.stride = bm->stride; - nb.data = mdvi_calloc(bm->height, bm->stride); - - fptr = bm->data; - tptr = __bm_unit_ptr(&nb, 0, nb.height-1); - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fline = fptr; - tline = tptr; - fmask = FIRSTMASK; - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= fmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - tline++; - } else - NEXTMASK(fmask); - } - fptr = bm_offset(fptr, bm->stride); - tptr = (BmUnit *)((char *)tptr - bm->stride); - } - DEBUG((DBG_BITMAP_OPS, "flip_vertically (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -void bitmap_flip_diagonally(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask, tmask; - int w, h; - - nb.width = bm->width; - nb.height = bm->height; - nb.stride = bm->stride; - nb.data = mdvi_calloc(bm->height, bm->stride); - - fptr = bm->data; - tptr = __bm_unit_ptr(&nb, nb.width-1, nb.height-1); - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fline = fptr; - tline = tptr; - fmask = FIRSTMASK; - tmask = FIRSTMASKAT(nb.width-1); - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= tmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - } else - NEXTMASK(fmask); - if(tmask == FIRSTMASK) { - tmask = LASTMASK; - tline--; - } else - PREVMASK(tmask); - } - fptr = bm_offset(fptr, bm->stride); - tptr = bm_offset(tptr, -nb.stride); - } - DEBUG((DBG_BITMAP_OPS, "flip_diagonally (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -void bitmap_rotate_clockwise(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask, tmask; - int w, h; - - nb.width = bm->height; - nb.height = bm->width; - nb.stride = BM_BYTES_PER_LINE(&nb); - nb.data = mdvi_calloc(nb.height, nb.stride); - - fptr = bm->data; - tptr = __bm_unit_ptr(&nb, nb.width - 1, 0); - - tmask = FIRSTMASKAT(nb.width-1); - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fmask = FIRSTMASK; - fline = fptr; - tline = tptr; - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= tmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - } else - NEXTMASK(fmask); - /* go to next row */ - tline = bm_offset(tline, nb.stride); - } - fptr = bm_offset(fptr, bm->stride); - if(tmask == FIRSTMASK) { - tmask = LASTMASK; - tptr--; - } else - PREVMASK(tmask); - } - - DEBUG((DBG_BITMAP_OPS, "rotate_clockwise (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - bm->width = nb.width; - bm->height = nb.height; - bm->stride = nb.stride; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -void bitmap_rotate_counter_clockwise(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask, tmask; - int w, h; - - nb.width = bm->height; - nb.height = bm->width; - nb.stride = BM_BYTES_PER_LINE(&nb); - nb.data = mdvi_calloc(nb.height, nb.stride); - - fptr = bm->data; - tptr = __bm_unit_ptr(&nb, 0, nb.height - 1); - - tmask = FIRSTMASK; - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fmask = FIRSTMASK; - fline = fptr; - tline = tptr; - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= tmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - } else - NEXTMASK(fmask); - /* go to previous row */ - tline = bm_offset(tline, -nb.stride); - } - fptr = bm_offset(fptr, bm->stride); - if(tmask == LASTMASK) { - tmask = FIRSTMASK; - tptr++; - } else - NEXTMASK(tmask); - } - - DEBUG((DBG_BITMAP_OPS, "rotate_counter_clockwise (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - bm->width = nb.width; - bm->height = nb.height; - bm->stride = nb.stride; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -void bitmap_flip_rotate_clockwise(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask, tmask; - int w, h; - - nb.width = bm->height; - nb.height = bm->width; - nb.stride = BM_BYTES_PER_LINE(&nb); - nb.data = mdvi_calloc(nb.height, nb.stride); - - fptr = bm->data; - tptr = __bm_unit_ptr(&nb, nb.width-1, nb.height-1); - - tmask = FIRSTMASKAT(nb.width-1); - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fmask = FIRSTMASK; - fline = fptr; - tline = tptr; - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= tmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - } else - NEXTMASK(fmask); - /* go to previous line */ - tline = bm_offset(tline, -nb.stride); - } - fptr = bm_offset(fptr, bm->stride); - if(tmask == FIRSTMASK) { - tmask = LASTMASK; - tptr--; - } else - PREVMASK(tmask); - } - DEBUG((DBG_BITMAP_OPS, "flip_rotate_clockwise (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - bm->width = nb.width; - bm->height = nb.height; - bm->stride = nb.stride; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -void bitmap_flip_rotate_counter_clockwise(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask, tmask; - int w, h; - - nb.width = bm->height; - nb.height = bm->width; - nb.stride = BM_BYTES_PER_LINE(&nb); - nb.data = mdvi_calloc(nb.height, nb.stride); - - fptr = bm->data; - tptr = nb.data; - tmask = FIRSTMASK; - - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fmask = FIRSTMASK; - fline = fptr; - tline = tptr; - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= tmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - } else - NEXTMASK(fmask); - /* go to next line */ - tline = bm_offset(tline, nb.stride); - } - fptr = bm_offset(fptr, bm->stride); - if(tmask == LASTMASK) { - tmask = FIRSTMASK; - tptr++; - } else - NEXTMASK(tmask); - } - - DEBUG((DBG_BITMAP_OPS, "flip_rotate_counter_clockwise (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - bm->width = nb.width; - bm->height = nb.height; - bm->stride = nb.stride; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -#if 0 -void bitmap_transform(BITMAP *map, DviOrientation orient) -{ - switch(orient) { - case MDVI_ORIENT_TBLR: - break; - case MDVI_ORIENT_TBRL: - bitmap_flip_horizontally(map); - break; - case MDVI_ORIENT_BTLR: - bitmap_flip_vertically(map); - break; - case MDVI_ORIENT_BTRL: - bitmap_flip_diagonally(map); - break; - case MDVI_ORIENT_RP90: - bitmap_rotate_counter_clockwise(map); - break; - case MDVI_ORIENT_RM90: - bitmap_rotate_clockwise(map); - break; - case MDVI_ORIENT_IRP90: - bitmap_flip_rotate_counter_clockwise(map); - break; - case MDVI_ORIENT_IRM90: - bitmap_flip_rotate_clockwise(map); - break; - } -} -#endif - -/* - * Count the number of non-zero bits in a box of dimensions w x h, starting - * at column `step' in row `data'. - * - * Shamelessly stolen from xdvi. - */ -static int do_sample(BmUnit *data, int stride, int step, int w, int h) -{ - BmUnit *ptr, *end, *cp; - int shift, n; - int bits_left; - int wid; - - ptr = data + step / BITMAP_BITS; - end = bm_offset(data, h * stride); - shift = FIRSTSHIFTAT(step); - bits_left = w; - n = 0; - while(bits_left) { -#ifndef WORD_BIG_ENDIAN - wid = BITMAP_BITS - shift; -#else - wid = shift; -#endif - if(wid > bits_left) - wid = bits_left; - if(wid > 8) - wid = 8; -#ifdef WORD_BIG_ENDIAN - shift -= wid; -#endif - for(cp = ptr; cp < end; cp = bm_offset(cp, stride)) - n += sample_count[(*cp >> shift) & bit_masks[wid]]; -#ifndef WORD_BIG_ENDIAN - shift += wid; -#endif -#ifdef WORD_BIG_ENDIAN - if(shift == 0) { - shift = BITMAP_BITS; - ptr++; - } -#else - if(shift == BITMAP_BITS) { - shift = 0; - ptr++; - } -#endif - bits_left -= wid; - } - return n; -} - -void mdvi_shrink_box(DviContext *dvi, DviFont *font, - DviFontChar *pk, DviGlyph *dest) -{ - int x, y, z; - DviGlyph *glyph; - int hs, vs; - - hs = dvi->params.hshrink; - vs = dvi->params.vshrink; - glyph = &pk->glyph; - - x = (int)glyph->x / hs; - if((int)glyph->x - x * hs > 0) - x++; - dest->w = x + ROUND((int)glyph->w - glyph->x, hs); - - z = (int)glyph->y + 1; - y = z / vs; - if(z - y * vs <= 0) - y--; - dest->h = y + ROUND((int)glyph->h - z, vs) + 1; - dest->x = x; - dest->y = glyph->y / vs; - dest->data = MDVI_GLYPH_EMPTY; - DEBUG((DBG_BITMAPS, "shrink_box: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n", - glyph->w, glyph->h, glyph->x, glyph->y, - dest->w, dest->h, dest->x, dest->y)); -} - -void mdvi_shrink_glyph(DviContext *dvi, DviFont *font, - DviFontChar *pk, DviGlyph *dest) -{ - int rows_left, rows, init_cols; - int cols_left, cols; - BmUnit *old_ptr, *new_ptr; - BITMAP *oldmap, *newmap; - BmUnit m, *cp; - DviGlyph *glyph; - int sample, min_sample; - int old_stride; - int new_stride; - int x, y; - int w, h; - int hs, vs; - - hs = dvi->params.hshrink; - vs = dvi->params.vshrink; - - min_sample = vs * hs * dvi->params.density / 100; - - glyph = &pk->glyph; - oldmap = (BITMAP *)glyph->data; - - x = (int)glyph->x / hs; - init_cols = (int)glyph->x - x * hs; - if(init_cols <= 0) - init_cols += hs; - else - x++; - w = x + ROUND((int)glyph->w - glyph->x, hs); - - cols = (int)glyph->y + 1; - y = cols / vs; - rows = cols - y * vs; - if(rows <= 0) { - rows += vs; - y--; - } - h = y + ROUND((int)glyph->h - cols, vs) + 1; - - /* create the new glyph */ - newmap = bitmap_alloc(w, h); - dest->data = newmap; - dest->x = x; - dest->y = glyph->y / vs; - dest->w = w; - dest->h = h; - - old_ptr = oldmap->data; - old_stride = oldmap->stride; - new_ptr = newmap->data; - new_stride = newmap->stride; - rows_left = glyph->h; - - while(rows_left) { - if(rows > rows_left) - rows = rows_left; - cols_left = glyph->w; - m = FIRSTMASK; - cp = new_ptr; - cols = init_cols; - while(cols_left > 0) { - if(cols > cols_left) - cols = cols_left; - sample = do_sample(old_ptr, old_stride, - glyph->w - cols_left, cols, rows); - if(sample >= min_sample) - *cp |= m; - if(m == LASTMASK) { - m = FIRSTMASK; - cp++; - } else - NEXTMASK(m); - cols_left -= cols; - cols = hs; - } - new_ptr = bm_offset(new_ptr, new_stride); - old_ptr = bm_offset(old_ptr, rows * old_stride); - rows_left -= rows; - rows = vs; - } - DEBUG((DBG_BITMAPS, "shrink_glyph: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n", - glyph->w, glyph->h, glyph->x, glyph->y, - dest->w, dest->h, dest->x, dest->y)); - if(DEBUGGING(BITMAP_DATA)) - bitmap_print(stderr, newmap); -} - -void mdvi_shrink_glyph_grey(DviContext *dvi, DviFont *font, - DviFontChar *pk, DviGlyph *dest) -{ - int rows_left, rows; - int cols_left, cols, init_cols; - long sampleval, samplemax; - BmUnit *old_ptr; - void *image; - int w, h; - int x, y; - DviGlyph *glyph; - BITMAP *map; - Ulong *pixels; - int npixels; - Ulong colortab[2]; - int hs, vs; - DviDevice *dev; - - hs = dvi->params.hshrink; - vs = dvi->params.vshrink; - dev = &dvi->device; - - glyph = &pk->glyph; - map = (BITMAP *)glyph->data; - - x = (int)glyph->x / hs; - init_cols = (int)glyph->x - x * hs; - if(init_cols <= 0) - init_cols += hs; - else - x++; - w = x + ROUND((int)glyph->w - glyph->x, hs); - - cols = (int)glyph->y + 1; - y = cols / vs; - rows = cols - y * vs; - if(rows <= 0) { - rows += vs; - y--; - } - h = y + ROUND((int)glyph->h - cols, vs) + 1; - ASSERT(w && h); - - /* before touching anything, do this */ - image = dev->create_image(dev->device_data, w, h, BITMAP_BITS); - if(image == NULL) { - mdvi_shrink_glyph(dvi, font, pk, dest); - return; - } - - /* save these colors */ - pk->fg = MDVI_CURRFG(dvi); - pk->bg = MDVI_CURRBG(dvi); - - samplemax = vs * hs; - npixels = samplemax + 1; - pixels = get_color_table(&dvi->device, npixels, pk->fg, pk->bg, - dvi->params.gamma, dvi->params.density); - if(pixels == NULL) { - npixels = 2; - colortab[0] = pk->fg; - colortab[1] = pk->bg; - pixels = &colortab[0]; - } - - /* setup the new glyph */ - dest->data = image; - dest->x = x; - dest->y = glyph->y / vs; - dest->w = w; - dest->h = h; - - y = 0; - old_ptr = map->data; - rows_left = glyph->h; - - while(rows_left && y < h) { - x = 0; - if(rows > rows_left) - rows = rows_left; - cols_left = glyph->w; - cols = init_cols; - while(cols_left && x < w) { - if(cols > cols_left) - cols = cols_left; - sampleval = do_sample(old_ptr, map->stride, - glyph->w - cols_left, cols, rows); - /* scale the sample value by the number of grey levels */ - if(npixels - 1 != samplemax) - sampleval = ((npixels-1) * sampleval) / samplemax; - ASSERT(sampleval < npixels); - dev->put_pixel(image, x, y, pixels[sampleval]); - cols_left -= cols; - cols = hs; - x++; - } - for(; x < w; x++) - dev->put_pixel(image, x, y, pixels[0]); - old_ptr = bm_offset(old_ptr, rows * map->stride); - rows_left -= rows; - rows = vs; - y++; - } - - for(; y < h; y++) { - for(x = 0; x < w; x++) - dev->put_pixel(image, x, y, pixels[0]); - } - DEBUG((DBG_BITMAPS, "shrink_glyph_grey: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n", - glyph->w, glyph->h, glyph->x, glyph->y, - dest->w, dest->h, dest->x, dest->y)); -} - |