diff options
Diffstat (limited to 'engines/sci/tools/bdfgrid.cpp')
-rw-r--r-- | engines/sci/tools/bdfgrid.cpp | 3515 |
1 files changed, 0 insertions, 3515 deletions
diff --git a/engines/sci/tools/bdfgrid.cpp b/engines/sci/tools/bdfgrid.cpp deleted file mode 100644 index 81dd35a4fa..0000000000 --- a/engines/sci/tools/bdfgrid.cpp +++ /dev/null @@ -1,3515 +0,0 @@ -/* - * Copyright 2001 Computing Research Labs, New Mexico State University - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT - * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef lint -#ifdef __GNUC__ -static char rcsid[] __attribute__((unused)) = "$Id$"; -#else -static char rcsid[] = "$Id$"; -#endif -#endif - -#include "bdfP.h" - -#ifndef MYABS -#define MYABS(n) ((n) < 0 ? -(n) : (n)) -#endif - -#undef MAX -#define MAX(h, i) ((h) > (i) ? (h) : (i)) - -#undef MIN -#define MIN(l, o) ((l) < (o) ? (l) : (o)) - -double _bdf_cos_tbl[360] = { - 0.000000, 0.999848, 0.999391, 0.998630, 0.997564, 0.996195, - 0.994522, 0.992546, 0.990268, 0.987688, 0.984808, 0.981627, - 0.978148, 0.974370, 0.970296, 0.965926, 0.961262, 0.956305, - 0.951057, 0.945519, 0.939693, 0.933580, 0.927184, 0.920505, - 0.913545, 0.906308, 0.898794, 0.891007, 0.882948, 0.874620, - 0.866025, 0.857167, 0.848048, 0.838671, 0.829038, 0.819152, - 0.809017, 0.798636, 0.788011, 0.777146, 0.766044, 0.754710, - 0.743145, 0.731354, 0.719340, 0.707107, 0.694658, 0.681998, - 0.669131, 0.656059, 0.642788, 0.629320, 0.615661, 0.601815, - 0.587785, 0.573576, 0.559193, 0.544639, 0.529919, 0.515038, - 0.500000, 0.484810, 0.469472, 0.453990, 0.438371, 0.422618, - 0.406737, 0.390731, 0.374607, 0.358368, 0.342020, 0.325568, - 0.309017, 0.292372, 0.275637, 0.258819, 0.241922, 0.224951, - 0.207912, 0.190809, 0.173648, 0.156434, 0.139173, 0.121869, - 0.104528, 0.087156, 0.069756, 0.052336, 0.034899, 0.017452, - 0.000000, -0.017452, -0.034899, -0.052336, -0.069756, -0.087156, - -0.104528, -0.121869, -0.139173, -0.156434, -0.173648, -0.190809, - -0.207912, -0.224951, -0.241922, -0.258819, -0.275637, -0.292372, - -0.309017, -0.325568, -0.342020, -0.358368, -0.374607, -0.390731, - -0.406737, -0.422618, -0.438371, -0.453990, -0.469472, -0.484810, - -0.500000, -0.515038, -0.529919, -0.544639, -0.559193, -0.573576, - -0.587785, -0.601815, -0.615661, -0.629320, -0.642788, -0.656059, - -0.669131, -0.681998, -0.694658, -0.707107, -0.719340, -0.731354, - -0.743145, -0.754710, -0.766044, -0.777146, -0.788011, -0.798636, - -0.809017, -0.819152, -0.829038, -0.838671, -0.848048, -0.857167, - -0.866025, -0.874620, -0.882948, -0.891007, -0.898794, -0.906308, - -0.913545, -0.920505, -0.927184, -0.933580, -0.939693, -0.945519, - -0.951057, -0.956305, -0.961262, -0.965926, -0.970296, -0.974370, - -0.978148, -0.981627, -0.984808, -0.987688, -0.990268, -0.992546, - -0.994522, -0.996195, -0.997564, -0.998630, -0.999391, -0.999848, - -1.000000, -0.999848, -0.999391, -0.998630, -0.997564, -0.996195, - -0.994522, -0.992546, -0.990268, -0.987688, -0.984808, -0.981627, - -0.978148, -0.974370, -0.970296, -0.965926, -0.961262, -0.956305, - -0.951057, -0.945519, -0.939693, -0.933580, -0.927184, -0.920505, - -0.913545, -0.906308, -0.898794, -0.891007, -0.882948, -0.874620, - -0.866025, -0.857167, -0.848048, -0.838671, -0.829038, -0.819152, - -0.809017, -0.798636, -0.788011, -0.777146, -0.766044, -0.754710, - -0.743145, -0.731354, -0.719340, -0.707107, -0.694658, -0.681998, - -0.669131, -0.656059, -0.642788, -0.629320, -0.615661, -0.601815, - -0.587785, -0.573576, -0.559193, -0.544639, -0.529919, -0.515038, - -0.500000, -0.484810, -0.469472, -0.453990, -0.438371, -0.422618, - -0.406737, -0.390731, -0.374607, -0.358368, -0.342020, -0.325568, - -0.309017, -0.292372, -0.275637, -0.258819, -0.241922, -0.224951, - -0.207912, -0.190809, -0.173648, -0.156434, -0.139173, -0.121869, - -0.104528, -0.087156, -0.069756, -0.052336, -0.034899, -0.017452, - -0.000000, 0.017452, 0.034899, 0.052336, 0.069756, 0.087156, - 0.104528, 0.121869, 0.139173, 0.156434, 0.173648, 0.190809, - 0.207912, 0.224951, 0.241922, 0.258819, 0.275637, 0.292372, - 0.309017, 0.325568, 0.342020, 0.358368, 0.374607, 0.390731, - 0.406737, 0.422618, 0.438371, 0.453990, 0.469472, 0.484810, - 0.500000, 0.515038, 0.529919, 0.544639, 0.559193, 0.573576, - 0.587785, 0.601815, 0.615661, 0.629320, 0.642788, 0.656059, - 0.669131, 0.681998, 0.694658, 0.707107, 0.719340, 0.731354, - 0.743145, 0.754710, 0.766044, 0.777146, 0.788011, 0.798636, - 0.809017, 0.819152, 0.829038, 0.838671, 0.848048, 0.857167, - 0.866025, 0.874620, 0.882948, 0.891007, 0.898794, 0.906308, - 0.913545, 0.920505, 0.927184, 0.933580, 0.939693, 0.945519, - 0.951057, 0.956305, 0.961262, 0.965926, 0.970296, 0.974370, - 0.978148, 0.981627, 0.984808, 0.987688, 0.990268, 0.992546, - 0.994522, 0.996195, 0.997564, 0.998630, 0.999391, 0.999848, -}; - -double _bdf_sin_tbl[360] = { - 0.000000, 0.017452, 0.034899, 0.052336, 0.069756, 0.087156, - 0.104528, 0.121869, 0.139173, 0.156434, 0.173648, 0.190809, - 0.207912, 0.224951, 0.241922, 0.258819, 0.275637, 0.292372, - 0.309017, 0.325568, 0.342020, 0.358368, 0.374607, 0.390731, - 0.406737, 0.422618, 0.438371, 0.453990, 0.469472, 0.484810, - 0.500000, 0.515038, 0.529919, 0.544639, 0.559193, 0.573576, - 0.587785, 0.601815, 0.615661, 0.629320, 0.642788, 0.656059, - 0.669131, 0.681998, 0.694658, 0.707107, 0.719340, 0.731354, - 0.743145, 0.754710, 0.766044, 0.777146, 0.788011, 0.798636, - 0.809017, 0.819152, 0.829038, 0.838671, 0.848048, 0.857167, - 0.866025, 0.874620, 0.882948, 0.891007, 0.898794, 0.906308, - 0.913545, 0.920505, 0.927184, 0.933580, 0.939693, 0.945519, - 0.951057, 0.956305, 0.961262, 0.965926, 0.970296, 0.974370, - 0.978148, 0.981627, 0.984808, 0.987688, 0.990268, 0.992546, - 0.994522, 0.996195, 0.997564, 0.998630, 0.999391, 0.999848, - 1.000000, 0.999848, 0.999391, 0.998630, 0.997564, 0.996195, - 0.994522, 0.992546, 0.990268, 0.987688, 0.984808, 0.981627, - 0.978148, 0.974370, 0.970296, 0.965926, 0.961262, 0.956305, - 0.951057, 0.945519, 0.939693, 0.933580, 0.927184, 0.920505, - 0.913545, 0.906308, 0.898794, 0.891007, 0.882948, 0.874620, - 0.866025, 0.857167, 0.848048, 0.838671, 0.829038, 0.819152, - 0.809017, 0.798636, 0.788011, 0.777146, 0.766044, 0.754710, - 0.743145, 0.731354, 0.719340, 0.707107, 0.694658, 0.681998, - 0.669131, 0.656059, 0.642788, 0.629320, 0.615661, 0.601815, - 0.587785, 0.573576, 0.559193, 0.544639, 0.529919, 0.515038, - 0.500000, 0.484810, 0.469472, 0.453990, 0.438371, 0.422618, - 0.406737, 0.390731, 0.374607, 0.358368, 0.342020, 0.325568, - 0.309017, 0.292372, 0.275637, 0.258819, 0.241922, 0.224951, - 0.207912, 0.190809, 0.173648, 0.156434, 0.139173, 0.121869, - 0.104528, 0.087156, 0.069756, 0.052336, 0.034899, 0.017452, - 0.000000, -0.017452, -0.034899, -0.052336, -0.069756, -0.087156, - -0.104528, -0.121869, -0.139173, -0.156434, -0.173648, -0.190809, - -0.207912, -0.224951, -0.241922, -0.258819, -0.275637, -0.292372, - -0.309017, -0.325568, -0.342020, -0.358368, -0.374607, -0.390731, - -0.406737, -0.422618, -0.438371, -0.453990, -0.469472, -0.484810, - -0.500000, -0.515038, -0.529919, -0.544639, -0.559193, -0.573576, - -0.587785, -0.601815, -0.615661, -0.629320, -0.642788, -0.656059, - -0.669131, -0.681998, -0.694658, -0.707107, -0.719340, -0.731354, - -0.743145, -0.754710, -0.766044, -0.777146, -0.788011, -0.798636, - -0.809017, -0.819152, -0.829038, -0.838671, -0.848048, -0.857167, - -0.866025, -0.874620, -0.882948, -0.891007, -0.898794, -0.906308, - -0.913545, -0.920505, -0.927184, -0.933580, -0.939693, -0.945519, - -0.951057, -0.956305, -0.961262, -0.965926, -0.970296, -0.974370, - -0.978148, -0.981627, -0.984808, -0.987688, -0.990268, -0.992546, - -0.994522, -0.996195, -0.997564, -0.998630, -0.999391, -0.999848, - -1.000000, -0.999848, -0.999391, -0.998630, -0.997564, -0.996195, - -0.994522, -0.992546, -0.990268, -0.987688, -0.984808, -0.981627, - -0.978148, -0.974370, -0.970296, -0.965926, -0.961262, -0.956305, - -0.951057, -0.945519, -0.939693, -0.933580, -0.927184, -0.920505, - -0.913545, -0.906308, -0.898794, -0.891007, -0.882948, -0.874620, - -0.866025, -0.857167, -0.848048, -0.838671, -0.829038, -0.819152, - -0.809017, -0.798636, -0.788011, -0.777146, -0.766044, -0.754710, - -0.743145, -0.731354, -0.719340, -0.707107, -0.694658, -0.681998, - -0.669131, -0.656059, -0.642788, -0.629320, -0.615661, -0.601815, - -0.587785, -0.573576, -0.559193, -0.544639, -0.529919, -0.515038, - -0.500000, -0.484810, -0.469472, -0.453990, -0.438371, -0.422618, - -0.406737, -0.390731, -0.374607, -0.358368, -0.342020, -0.325568, - -0.309017, -0.292372, -0.275637, -0.258819, -0.241922, -0.224951, - -0.207912, -0.190809, -0.173648, -0.156434, -0.139173, -0.121869, - -0.104528, -0.087156, -0.069756, -0.052336, -0.034899, -0.017452, -}; - -double _bdf_tan_tbl[90] = { - 0.000000, 0.017455, 0.034921, 0.052408, 0.069927, 0.087489, - 0.105104, 0.122785, 0.140541, 0.158384, 0.176327, 0.194380, - 0.212557, 0.230868, 0.249328, 0.267949, 0.286745, 0.305731, - 0.324920, 0.344328, 0.363970, 0.383864, 0.404026, 0.424475, - 0.445229, 0.466308, 0.487733, 0.509525, 0.531709, 0.554309, - 0.577350, 0.600861, 0.624869, 0.649408, 0.674509, 0.700208, - 0.726543, 0.753554, 0.781286, 0.809784, 0.839100, 0.869287, - 0.900404, 0.932515, 0.965689, 1.000000, 1.035530, 1.072369, - 1.110613, 1.150368, 1.191754, 1.234897, 1.279942, 1.327045, - 1.376382, 1.428148, 1.482561, 1.539865, 1.600335, 1.664279, - 1.732051, 1.804048, 1.880726, 1.962611, 2.050304, 2.144507, - 2.246037, 2.355852, 2.475087, 2.605089, 2.747477, 2.904211, - 3.077684, 3.270853, 3.487414, 3.732051, 4.010781, 4.331476, - 4.704630, 5.144554, 5.671282, 6.313752, 7.115370, 8.144346, - 9.514364, 11.430052, 14.300666, 19.081137, 28.636253, 57.289962, -}; - -/* - * Determine the actual ink bounds. - */ -static int -#ifdef __STDC__ -_bdf_grid_ink_bounds(bdf_glyph_grid_t *grid, short *x, short *y, - short *width, short *height) -#else -_bdf_grid_ink_bounds(grid, x, y, width, height) -bdf_glyph_grid_t *grid; -short *x, *y, *width, *height; -#endif -{ - short bx, by, bwd, bht, minx, maxx, miny, maxy, dx, dy; - unsigned short bpr, ink, sel, col; - unsigned char *bmap, *masks; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - if (grid->sel.width != 0 && grid->sel.height != 0) { - sel = 1; - bx = by = 0; - bwd = grid->sel.width; - bht = grid->sel.height; - bmap = grid->sel.bitmap; - } else { - sel = 0; - bx = grid->glyph_x; - by = grid->glyph_y; - bwd = grid->glyph_bbx.width; - bht = grid->glyph_bbx.height; - bmap = grid->bitmap; - } - maxx = maxy = 0; - minx = bx + bwd; - miny = by + bht; - - bpr = ((bwd * grid->bpp) + 7) >> 3; - ink = 0; - - bwd += bx; - bht += by; - for (dy = by; dy < bht; dy++) { - for (col = bx * grid->bpp, dx = bx; dx < bwd; dx++, col += grid->bpp) { - if (bmap[(dy * bpr) + (col >> 3)] & masks[(col & 7) / grid->bpp]) { - ink = 1; - minx = MIN(minx, dx); - miny = MIN(miny, dy); - maxx = MAX(maxx, dx); - maxy = MAX(maxy, dy); - } - } - } - - *x = minx + ((sel) ? grid->sel.x : 0); - *y = miny + ((sel) ? grid->sel.y : 0); - if (ink == 0) - *width = *height = 0; - else { - *width = (maxx - minx) + 1; - *height = (maxy - miny) + 1; - } - return ink; -} - -/************************************************************************** - * - * Glyph grid create and destroy functions. - * - **************************************************************************/ - -/* - * Make a glyph grid with the glyph bitmap set in the bitmap. - */ -bdf_glyph_grid_t * -#ifdef __STDC__ -bdf_make_glyph_grid(bdf_font_t *font, long code, int unencoded) -#else -bdf_make_glyph_grid(font, code, unencoded) -bdf_font_t *font; -long code; -int unencoded; -#endif -{ - unsigned short si, di, col, colx, byte; - short ht, as, ds, gsize, bpr, x, y, nx, ny; - long l, r, m; - bdf_glyph_grid_t *gr; - bdf_glyph_t *gl, *glp; - bdf_property_t *p; - unsigned char *masks; - char name[24]; - - if (font == 0) - return 0; - - /* - * Allocate the grid and initialize it. - */ - gr = (bdf_glyph_grid_t *) malloc(sizeof(bdf_glyph_grid_t)); - (void) memset((char *) gr, 0, sizeof(bdf_glyph_grid_t)); - - /* - * Set the encoding and the unencoded flag. - */ - gr->bpp = font->bpp; - gr->encoding = code; - gr->unencoded = unencoded; - - /* - * Set the glyph grid spacing. - */ - gr->spacing = font->spacing; - - /* - * Set the point size and resolutions. - */ - gr->point_size = font->point_size; - gr->resolution_x = font->resolution_x; - gr->resolution_y = font->resolution_y; - - /* - * Set the CAP_HEIGHT and X_HEIGHT if they exist in the font. - */ - if ((p = bdf_get_font_property(font, "CAP_HEIGHT")) != 0) - gr->cap_height = (short) p->value.int32; - if ((p = bdf_get_font_property(font, "X_HEIGHT")) != 0) - gr->x_height = (short) p->value.int32; - - masks = 0; - switch (gr->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - /* - * Copy the font bounding box into the grid. - */ - (void) memcpy((char *) &gr->font_bbx, (char *) &font->bbx, - sizeof(bdf_bbx_t)); - - if (unencoded) { - gl = font->unencoded; - r = font->unencoded_used; - } else { - gl = font->glyphs; - r = font->glyphs_used; - } - - /* - * Locate the specified glyph using a simple binary search. - */ - glp = 0; - if (r > 0) { - for (l = 0; r >= l;) { - m = (l + r) >> 1; - glp = gl + m; - if (glp->encoding == code) - break; - if (glp->encoding > code) - r = m - 1; - else if (glp->encoding < code) - l = m + 1; - glp = 0; - } - } - - ht = gr->font_bbx.height; - as = gr->font_bbx.ascent; - ds = gr->font_bbx.descent; - - /* - * 1. Determine width and height needed from the largest of the - * width or height. - */ - gr->grid_width = gr->grid_height = - MAX(gr->font_bbx.width, gr->font_bbx.height); - - /* - * 2. Make sure the grid is at least a square of the largest of the width - * or height of the glyph itself to allow room for transformations. - */ - if (glp != 0) { - /* - * Set the glyph name and other metrics. - */ - if (glp->name) { - gr->name = (char *) malloc(strlen(glp->name) + 1); - (void) memcpy(gr->name, glp->name, strlen(glp->name) + 1); - } else { - sprintf(name, "char%ld", code); - gr->name = (char *) malloc(strlen(name) + 1); - (void) memcpy(gr->name, name, strlen(name) + 1); - } - gr->dwidth = glp->dwidth; - - /* - * Copy the glyph bounding box into the grid. - */ - (void) memcpy((char *) &gr->glyph_bbx, (char *) &glp->bbx, - sizeof(bdf_bbx_t)); - - if (glp->bbx.height < glp->bbx.ascent + glp->bbx.descent) - gsize = glp->bbx.ascent + glp->bbx.descent; - else - gsize = glp->bbx.height; - - /* - * Figure the maximum of the glyph width and height. - */ - gsize = MAX(gr->glyph_bbx.width, gsize); - - /* - * If either the grid width or grid height is less than the - * grid size just determined, then adjust them to the new grid size. - */ - gr->grid_width = MAX(gr->grid_width, gsize); - gr->grid_height = MAX(gr->grid_height, gsize); - } else { - /* - * The glyph doesn't exist, so make up a name for it. - */ - if (unencoded) - sprintf(name, "unencoded%ld", code); - else - sprintf(name, "char%ld", code); - gr->name = (char *) malloc(strlen(name) + 1); - (void) memcpy(gr->name, name, strlen(name) + 1); - } - - /* - * If the font has character-cell or mono spacing, make sure the grid - * device width is set to the width stored in the font. - */ - if (gr->spacing != BDF_PROPORTIONAL) - gr->dwidth = font->monowidth; - - /* - * Determine the vertical origin based on the font bounding box. - */ - if (ht >= as + ds) - gr->base_y = (((gr->grid_height >> 1) - (ht >> 1)) + ht) - ds; - else - gr->base_y = ((gr->grid_height >> 1) - ((as + ds) >> 1)) + as; - - /* - * The final adjust is to check to see if the glyph positioned relative to - * the baseline would cause the grid to change size. This sometimes - * happens in fonts that have incorrect metrics. - */ - if (gr->base_y + gr->glyph_bbx.descent > gr->grid_height) { - gsize = gr->base_y + gr->glyph_bbx.descent; - gr->grid_width = MAX(gsize, gr->grid_width); - gr->grid_height = MAX(gsize, gr->grid_height); - } - - /* - * Determine the horizontal origin based on the font bounding box and - * centered within the grid. - */ - gr->base_x = (gr->grid_width >> 1) - (gr->font_bbx.width >> 1); - if (gr->font_bbx.x_offset < 0) - gr->base_x += MYABS(gr->font_bbx.x_offset); - - /* - * Allocate double the storage needed for the grid bitmap. The extra - * storage will be used for transformations. - */ - gr->bytes = ((((gr->grid_width * gr->bpp) + 7) >> 3) * - gr->grid_height) << 1; - gr->bitmap = (unsigned char *) malloc(gr->bytes); - (void) memset((char *) gr->bitmap, 0, gr->bytes); - - /* - * Initialize the top-left coordinates of the glyph to the baseline - * coordinates. - */ - gr->glyph_x = gr->base_x; - gr->glyph_y = gr->base_y; - - /* - * If the glyph was not found, simply return the empty grid. - */ - if (glp == 0) - return gr; - - /* - * Determine the top-left coordinates of the glyph with respect to the - * baseline coordinates. - */ - gr->glyph_x = nx = gr->base_x + gr->glyph_bbx.x_offset; - gr->glyph_y = ny = gr->base_y - gr->glyph_bbx.ascent; - - /* - * Now copy the glyph bitmap to the appropriate location in the - * grid. - */ - bpr = ((gr->glyph_bbx.width * gr->bpp) + 7) >> 3; - gsize = ((gr->grid_width * gr->bpp) + 7) >> 3; - for (y = 0; y < gr->glyph_bbx.height; y++, ny++) { - for (colx = nx * gr->bpp, col = x = 0; x < gr->glyph_bbx.width; - x++, col += gr->bpp, colx += gr->bpp) { - si = (col & 7) / gr->bpp; - byte = glp->bitmap[(y * bpr) + (col >> 3)] & masks[si]; - if (byte) { - di = (colx & 7) / gr->bpp; - if (di < si) - byte <<= (si - di) * gr->bpp; - else if (di > si) - byte >>= (di - si) * gr->bpp; - gr->bitmap[(ny * gsize) + (colx >> 3)] |= byte; - } - } - } - - /* - * Always crop the glyph to the ink bounds before editing. - */ - bdf_grid_crop(gr, 0); - - /* - * Return the grid. - */ - return gr; -} - -void -#ifdef __STDC__ -bdf_free_glyph_grid(bdf_glyph_grid_t *grid) -#else -bdf_free_glyph_grid(grid) -bdf_glyph_grid_t *grid; -#endif -{ - if (grid == 0) - return; - - if (grid->name != 0) - free(grid->name); - if (grid->bytes > 0) - free((char *) grid->bitmap); - if (grid->sel.bytes > 0) - free((char *) grid->sel.bitmap); - free((char *) grid); -} - -/************************************************************************** - * - * Glyph grid resize functions. - * - **************************************************************************/ - -/* - * Enlarge the grid without affecting the font or glyph metrics. - */ -int -#ifdef __STDC__ -bdf_grid_enlarge(bdf_glyph_grid_t *grid, unsigned short width, - unsigned short height) -#else -bdf_grid_enlarge(grid, width, height) -bdf_glyph_grid_t *grid; -unsigned short width, height; -#endif -{ - unsigned short si, di, col, colx, byte; - short ht, wd, as, ds, x, y, nx, ny; - unsigned short gwd, ght, bytes, obpr, nbpr, gsize; - unsigned char *bitmap, *masks; - - if (grid == 0 || (width < grid->grid_width && height < grid->grid_height)) - return 0; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - ht = height; - as = grid->font_bbx.ascent; - ds = grid->font_bbx.descent; - - gwd = MAX(width, grid->grid_width); - ght = MAX(height, grid->grid_height); - gsize = MAX(gwd, ght); - - nbpr = ((gsize * grid->bpp) + 7) >> 3; - bytes = (nbpr * ght) << 1; - bitmap = (unsigned char *) malloc(bytes); - (void) memset((char *) bitmap, 0, bytes); - - /* - * Determine the new baseline. - */ - if (ht >= as + ds) - grid->base_y = (((ght >> 1) - (ht >> 1)) + ht) - ds; - else - grid->base_y = ((ght >> 1) - ((as + ds) >> 1)) + as; - - grid->base_x = (gwd >> 1) - (grid->font_bbx.width >> 1); - if (grid->font_bbx.x_offset < 0) - grid->base_x += MYABS(grid->font_bbx.x_offset); - - nx = grid->base_x + grid->glyph_bbx.x_offset; - ny = grid->base_y - grid->glyph_bbx.ascent; - - /* - * Now copy the bitmap into the new storage base on the new metrics - * values. - */ - obpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - wd = grid->glyph_x + grid->glyph_bbx.width; - ht = grid->glyph_y + grid->glyph_bbx.height; - for (y = grid->glyph_y; y < ht; y++, ny++) { - col = grid->glyph_x * grid->bpp; - colx = nx * grid->bpp; - for (x = grid->glyph_x; x < wd; - x++, col += grid->bpp, colx += grid->bpp) { - si = (col & 7) / grid->bpp; - byte = grid->bitmap[(y * obpr) + (col >> 3)] & masks[si]; - if (byte) { - di = (colx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - bitmap[(ny * nbpr) + (colx >> 3)] |= byte; - } - } - } - - /* - * Adjust the glyph coordinates. - */ - grid->glyph_x = grid->base_x + grid->glyph_bbx.x_offset; - grid->glyph_y = grid->base_y - grid->glyph_bbx.ascent; - - /* - * Get rid of the old grid bitmap and replace it with the new one. - */ - free((char *) grid->bitmap); - grid->bytes = bytes; - grid->bitmap = bitmap; - - /* - * Update the new grid width and height. - */ - grid->grid_width = grid->grid_height = gsize; - - /* - * Always mark the grid as being modified on a resize. - */ - grid->modified = 1; - - return 1; -} - -/* - * Change the font bounding box values and resize the grid bitmap if - * necessary. - */ -int -#ifdef __STDC__ -bdf_grid_resize(bdf_glyph_grid_t *grid, bdf_metrics_t *metrics) -#else -bdf_grid_resize(grid, metrics) -bdf_glyph_grid_t *grid; -bdf_metrics_t *metrics; -#endif -{ - int changed; - unsigned short si, di, col, colx, byte; - short ht, wd, as, ds, x, y, nx, ny; - unsigned short gwd, ght, bytes, obpr, nbpr, gsize; - unsigned char *bitmap, *masks; - - changed = 0; - - if (grid == 0 || metrics == 0) - return changed; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - /* - * Create new grid bitmaps in preparation for the various metrics changing. - */ - if (metrics->width > grid->grid_width || - metrics->height > grid->grid_height) { - changed = 1; - - ht = metrics->height; - as = metrics->ascent; - ds = metrics->descent; - - gwd = MAX(metrics->width, grid->grid_width); - ght = MAX(metrics->height, grid->grid_height); - - /* - * Get the larger of the two dimensions. - */ - gsize = MAX(gwd, ght); - - nbpr = ((gsize * grid->bpp) + 7) >> 3; - bytes = (nbpr * gsize) << 1; - bitmap = (unsigned char *) malloc(bytes); - (void) memset((char *) bitmap, 0, bytes); - - /* - * Determine the new baseline. - */ - if (ht >= as + ds) - grid->base_y = (((ght >> 1) - (ht >> 1)) + ht) - ds; - else - grid->base_y = ((ght >> 1) - ((as + ds) >> 1)) + as; - - grid->base_x = (gwd >> 1) - (metrics->width >> 1); - if (metrics->x_offset < 0) - grid->base_x += MYABS(metrics->x_offset); - - nx = grid->base_x + grid->glyph_bbx.x_offset; - ny = grid->base_y - grid->glyph_bbx.ascent; - - /* - * Now copy the bitmap into the new storage base on the new metrics - * values. - */ - obpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - wd = grid->glyph_x + grid->glyph_bbx.width; - ht = grid->glyph_y + grid->glyph_bbx.height; - for (y = grid->glyph_y; y < ht; y++, ny++) { - col = grid->glyph_x * grid->bpp; - colx = nx * grid->bpp; - for (x = grid->glyph_x; x < wd; - x++, col += grid->bpp, colx += grid->bpp) { - si = (col & 7) / grid->bpp; - byte = grid->bitmap[(y * obpr) + (col >> 3)] & masks[si]; - if (byte) { - di = (colx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - bitmap[(ny * nbpr) + (colx >> 3)] |= byte; - } - } - } - - /* - * Adjust the glyph coordinates. - */ - grid->glyph_x = grid->base_x + grid->glyph_bbx.x_offset; - grid->glyph_y = grid->base_y - grid->glyph_bbx.ascent; - - /* - * Get rid of the old grid bitmap and replace it with the new one. - */ - free((char *) grid->bitmap); - grid->bytes = bytes; - grid->bitmap = bitmap; - - /* - * Update the new grid width and height. - */ - grid->grid_width = grid->grid_height = gsize; - - /* - * Copy the metrics info into the font bounding box. - */ - grid->font_bbx.width = metrics->width; - grid->font_bbx.x_offset = metrics->x_offset; - grid->font_bbx.height = metrics->height; - grid->font_bbx.ascent = metrics->ascent; - grid->font_bbx.descent = metrics->descent; - grid->font_bbx.y_offset = metrics->y_offset; - } else { - /* - * The grid does not need to resized, but the baseline must - * be recalculated and the bitmap copied again. - */ - bytes = grid->bytes >> 1; - bitmap = grid->bitmap + bytes; - (void) memset((char *) bitmap, 0, bytes); - - ht = metrics->height; - as = metrics->ascent; - ds = metrics->descent; - - gwd = grid->grid_width; - ght = grid->grid_height; - - /* - * Determine the new baseline. - */ - if (ht >= as + ds) - grid->base_y = (((ght >> 1) - (ht >> 1)) + ht) - ds; - else - grid->base_y = ((ght >> 1) - ((as + ds) >> 1)) + as; - - grid->base_x = (gwd >> 1) - (metrics->width >> 1); - if (metrics->x_offset < 0) - grid->base_x += MYABS(metrics->x_offset); - - nx = grid->base_x + grid->glyph_bbx.x_offset; - ny = grid->base_y - grid->glyph_bbx.ascent; - - wd = grid->glyph_x + grid->glyph_bbx.width; - ht = grid->glyph_y + grid->glyph_bbx.height; - - obpr = nbpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - for (y = grid->glyph_y; y < ht; y++, ny++) { - col = grid->glyph_x * grid->bpp; - colx = nx * grid->bpp; - for (x = grid->glyph_x; x < wd; - x++, col += grid->bpp, colx += grid->bpp) { - si = (col & 7) / grid->bpp; - byte = grid->bitmap[(y * obpr) + (col >> 3)] & masks[si]; - if (byte) { - di = (colx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - bitmap[(ny * nbpr) + (colx >> 3)] |= byte; - } - } - } - - /* - * Copy the adjusted bitmap back into the main area. - */ - (void) memcpy((char *) grid->bitmap, (char *) bitmap, bytes); - - /* - * Adjust the glyph coordinates. - */ - grid->glyph_x = grid->base_x + grid->glyph_bbx.x_offset; - grid->glyph_y = grid->base_y - grid->glyph_bbx.ascent; - - /* - * Copy the metrics info into the font bounding box. - */ - grid->font_bbx.width = metrics->width; - grid->font_bbx.x_offset = metrics->x_offset; - grid->font_bbx.height = metrics->height; - grid->font_bbx.ascent = metrics->ascent; - grid->font_bbx.descent = metrics->descent; - grid->font_bbx.y_offset = metrics->y_offset; - } - - /* - * If the font is not proportional, make sure the device width is adjusted - * to meet the new font bounding box. - */ - if (changed && grid->spacing != BDF_PROPORTIONAL) - grid->dwidth = grid->font_bbx.width; - - /* - * Always mark the grid as being modified on a resize. - */ - grid->modified = 1; - - return changed; -} - -int -#ifdef __STDC__ -bdf_grid_crop(bdf_glyph_grid_t *grid, int grid_modified) -#else -bdf_grid_crop(grid, grid_modified) -bdf_glyph_grid_t *grid; -int grid_modified; -#endif -{ - int cropped; - short x, y, delta, maxx, minx, maxy, miny, col; - unsigned short bpr; - unsigned char *masks; - - cropped = 0; - if (grid == 0) - return cropped; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - - maxx = maxy = -1; - minx = miny = grid->grid_width; - for (y = 0; y < grid->grid_height; y++) { - for (col = x = 0; x < grid->grid_width; x++, col += grid->bpp) { - if (grid->bitmap[(y * bpr) + (col >> 3)] & - masks[(col & 7) / grid->bpp]) { - minx = MIN(minx, x); - maxx = MAX(maxx, x); - miny = MIN(miny, y); - maxy = MAX(maxy, y); - } - } - } - - /* - * Handle an empty bitmap as a special case. - */ - if (maxx == -1) { - /* - * If the glyph bounding box indicated something was there originally, - * then indicate that it was cropped. - */ - if (grid->glyph_bbx.width != 0 || grid->glyph_bbx.height != 0) - cropped = 1; - (void) memset((char *) &grid->glyph_bbx, 0, sizeof(bdf_bbx_t)); - grid->glyph_x = grid->base_x; - grid->glyph_y = grid->base_y; - if (cropped) - grid->modified = 1; - return cropped; - } - - /* - * Increment the max points so width and height calculations won't go - * wrong. - */ - maxx++; - maxy++; - - if (minx != grid->glyph_x) { - cropped = 1; - delta = minx - grid->glyph_x; - grid->glyph_x += delta; - grid->glyph_bbx.x_offset += delta; - } - if (maxx - minx != grid->glyph_bbx.width) { - cropped = 1; - delta = (maxx - minx) - grid->glyph_bbx.width; - grid->glyph_bbx.width += delta; - if (grid->spacing == BDF_PROPORTIONAL) - grid->dwidth += delta; - } - - if (miny != grid->glyph_y) { - cropped = 1; - delta = miny - grid->glyph_y; - grid->glyph_y += delta; - grid->glyph_bbx.y_offset = - grid->base_y - (grid->glyph_y + (maxy - miny)); - } - if (maxy - miny != grid->glyph_bbx.height) { - cropped = 1; - delta = (maxy - miny) - grid->glyph_bbx.height; - grid->glyph_bbx.height += delta; - grid->glyph_bbx.y_offset = - grid->base_y - (grid->glyph_y + (maxy - miny)); - grid->glyph_bbx.ascent = - grid->glyph_bbx.height + grid->glyph_bbx.y_offset; - grid->glyph_bbx.descent = -grid->glyph_bbx.y_offset; - } - - /* - * Indicate that the grid was modified if the glyph had to be cropped. - */ - if (cropped && grid_modified) - grid->modified = 1; - - return cropped; -} - -/************************************************************************** - * - * Glyph grid pixel functions. - * - **************************************************************************/ - -int -#ifdef __STDC__ -bdf_grid_set_pixel(bdf_glyph_grid_t *grid, short x, short y, int val) -#else -bdf_grid_set_pixel(grid, x, y, val) -bdf_glyph_grid_t *grid; -short x, y; -int val; -#endif -{ - unsigned short si, di, dx; - int set, bpr, delta; - unsigned char *masks; - - set = 0; - - if (grid == 0 || x < 0 || x >= grid->grid_width || - y < 0 || y >= grid->grid_height) - return set; - - si = 0; - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - si = 7; - break; - case 2: - masks = twobpp; - si = 3; - break; - case 4: - masks = fourbpp; - si = 1; - break; - } - - /* - * Remove any unused bits from the value. - */ - val &= masks[si]; - - dx = x * grid->bpp; - di = (dx & 7) / grid->bpp; - - /* - * Shift up the value to the appropriate place if necessary. - */ - if (di < si) - val <<= (si - di) * grid->bpp; - - /* - * Determine the bytes-per-row. - */ - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - - /* - * If the bit is already set, simply return with an indication that - * nothing changed. - */ - if ((grid->bitmap[(y * bpr) + (dx >> 3)] & masks[di]) == val) - return set; - - /* - * Set the bit. - */ - set = 1; - - /* - * Clear the bits that will take the new value. - */ - grid->bitmap[(y * bpr) + (dx >> 3)] &= ~masks[di]; - grid->bitmap[(y * bpr) + (dx >> 3)] |= val; - - /* - * Adjust the glyph bounding box. - */ - if (x < grid->glyph_x) { - delta = grid->glyph_x - x; - grid->glyph_bbx.width += delta; - grid->glyph_bbx.x_offset -= delta; - if (grid->spacing == BDF_PROPORTIONAL) - grid->dwidth = grid->glyph_bbx.width + grid->glyph_bbx.x_offset; - grid->glyph_x -= delta; - } else if (x >= grid->glyph_x + grid->glyph_bbx.width) { - delta = x - (grid->glyph_x + grid->glyph_bbx.width) + 1; - grid->glyph_bbx.width += delta; - if (grid->spacing == BDF_PROPORTIONAL) - grid->dwidth = grid->glyph_bbx.width + grid->glyph_bbx.x_offset; - } - if (y < grid->glyph_y) { - delta = grid->glyph_y - y; - grid->glyph_bbx.ascent += delta; - grid->glyph_bbx.height += delta; - grid->glyph_y -= delta; - } else if (y >= grid->glyph_y + grid->glyph_bbx.height) { - delta = y - (grid->glyph_y + grid->glyph_bbx.height) + 1; - grid->glyph_bbx.descent += delta; - grid->glyph_bbx.height += delta; - grid->glyph_bbx.y_offset = -grid->glyph_bbx.descent; - } - - /* - * Indicate that the glyph was modified. - */ - grid->modified = 1; - - return set; -} - -int -#ifdef __STDC__ -bdf_grid_clear_pixel(bdf_glyph_grid_t *grid, short x, short y) -#else -bdf_grid_clear_pixel(grid, x, y) -bdf_glyph_grid_t *grid; -short x, y; -#endif -{ - int cleared, bpr; - short delta, maxx, minx, maxy, miny, wd, ht; - unsigned short di, dx; - unsigned char *masks; - - cleared = 0; - - if (grid == 0 || x < 0 || x >= grid->grid_width || - y < 0 || y >= grid->grid_height) - return cleared; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - /* - * Determine the bytes-per-row. - */ - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - - dx = x * grid->bpp; - di = (dx & 7) / grid->bpp; - - /* - * If the bit is already clear, simply return with an indication that - * nothing changed. - */ - if (!(grid->bitmap[(y * bpr) + (dx >> 3)] & masks[di])) - return cleared; - - /* - * Clear the bit. - */ - cleared = 1; - grid->bitmap[(y * bpr) + (dx >> 3)] &= ~masks[di]; - - /* - * Determine the new min and max values. - */ - maxx = maxy = 0; - minx = miny = 32767; - - wd = grid->glyph_x + grid->glyph_bbx.width; - ht = grid->glyph_y + grid->glyph_bbx.height; - - for (y = grid->glyph_y; y < ht; y++) { - dx = grid->glyph_x * grid->bpp; - for (x = grid->glyph_x; x < wd; x++, dx += grid->bpp) { - di = (dx & 7) / grid->bpp; - if (grid->bitmap[(y * bpr) + (dx >> 3)] & masks[di]) { - minx = MIN(minx, x); - maxx = MAX(maxx, x); - miny = MIN(miny, y); - maxy = MAX(maxy, y); - } - } - } - - /* - * If this call clears the last bit in the image, set the glyph origin - * to the base and return. - */ - if (maxx == 0) { - grid->glyph_x = grid->base_x; - grid->glyph_y = grid->base_y; - if (grid->spacing == BDF_PROPORTIONAL) - grid->dwidth = 0; - (void) memset((char *) &grid->glyph_bbx, 0, sizeof(grid->glyph_bbx)); - grid->modified = 1; - return cleared; - } - - /* - * Figure out the left and right bearing changes. - */ - if (minx > grid->glyph_x) { - delta = minx - grid->glyph_x; - grid->glyph_bbx.width -= delta; - grid->glyph_bbx.x_offset += delta; - if (grid->spacing == BDF_PROPORTIONAL) - grid->dwidth = grid->glyph_bbx.width + grid->glyph_bbx.x_offset; - grid->glyph_x += delta; - } else if (maxx < wd - 1) { - delta = (wd - 1) - maxx; - grid->glyph_bbx.width -= delta; - if (grid->spacing == BDF_PROPORTIONAL) - grid->dwidth = grid->glyph_bbx.width + grid->glyph_bbx.x_offset; - } - - if (miny > grid->glyph_y) { - delta = miny - grid->glyph_y; - grid->glyph_bbx.ascent -= delta; - grid->glyph_bbx.height -= delta; - grid->glyph_y += delta; - } else if (maxy < ht - 1) { - delta = (ht - 1) - maxy; - grid->glyph_bbx.descent -= delta; - grid->glyph_bbx.height -= delta; - grid->glyph_bbx.y_offset = -grid->glyph_bbx.descent; - } - - /* - * Indicate that the glyph was modified. - */ - grid->modified = 1; - - return cleared; -} - -int -#ifdef __STDC__ -bdf_grid_invert_pixel(bdf_glyph_grid_t *grid, short x, short y, int val) -#else -bdf_grid_invert_pixel(grid, x, y, val) -bdf_glyph_grid_t *grid; -short x, y; -int val; -#endif -{ - short bpr, di; - unsigned char *masks; - - if (grid == 0 || x < 0 || x >= grid->grid_width || - y < 0 || y >= grid->grid_height) - return 0; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - /* - * Determine the bytes-per-row and mask index. - */ - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - di = ((x * grid->bpp) & 7) / grid->bpp; - - /* - * If the bit is set, then clear it, otherwise, set it. - */ - if (grid->bitmap[(y * bpr) + ((x * grid->bpp) >> 3)] & masks[di]) - return bdf_grid_clear_pixel(grid, x, y); - else - return bdf_grid_set_pixel(grid, x, y, val); -} - -/************************************************************************** - * - * Glyph grid bitmap transformation functions. - * - **************************************************************************/ - -short -#ifdef __STDC__ -_bdf_ceiling(double v) -#else -_bdf_ceiling(v) -double v; -#endif -{ - short val, neg; - - val = neg = 0; - if (v < 0) { - neg = 1; - while (v < -1.0) { - val++; - v += 1.0; - } - } else if (v > 0) { - while (v > 1.0) { - val++; - v -= 1.0; - } - if (v > 0.0) - val++; - } - return (!neg) ? val : -val; -} - -static int -#ifdef __STDC__ -_bdf_rotate_selection(bdf_glyph_grid_t *grid, int mul90, short degrees) -#else -_bdf_rotate_selection(grid, mul90, degrees) -bdf_glyph_grid_t *grid; -int mul90; -short degrees; -#endif -{ - int rotated, byte; - short wd, ht, nx, ny, cx, cy, x, y, col; - short ox, oy, shiftx, shifty, si, di; - double dx, dy; - unsigned short bytes, bpr; - unsigned char *scratch, *masks; - - rotated = 0; - - /* - * Check to see if the number of rotations would have no affect by - * checking if the count is a multiple of 4 (mod 4 == 0). - */ - if (grid == 0 || degrees == 0) - return rotated; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - bytes = grid->sel.bytes >> 1; - scratch = grid->sel.bitmap + bytes; - (void) memset((char *) scratch, 0, bytes); - - cx = grid->sel.width >> 1; - cy = grid->sel.height >> 1; - - wd = ht = MAX(grid->sel.width, grid->sel.height); - cx = cy = wd >> 1; - - bpr = ((wd * grid->bpp) + 7) >> 3; - - for (shiftx = shifty = y = 0; y < ht; y++) { - for (col = x = 0; x < wd; x++, col += grid->bpp) { - dx = (double)(x - cx); - dy = (double)(y - cy); - if (mul90) { - nx = cx + (short)((dx * _bdf_cos_tbl[degrees]) - - (dy * _bdf_sin_tbl[degrees])); - ny = cy + (short)((dx * _bdf_sin_tbl[degrees]) + - (dy * _bdf_cos_tbl[degrees])); - } else { - nx = cx + _bdf_ceiling((dx * _bdf_cos_tbl[degrees]) - - (dy * _bdf_sin_tbl[degrees])); - ny = cy + _bdf_ceiling((dx * _bdf_sin_tbl[degrees]) + - (dy * _bdf_cos_tbl[degrees])); - } - - /* - * Wrap the coordinates around the edges if necessary. - */ - if (nx < 0) { - shiftx = MIN(shiftx, nx); - nx += wd; - } else if (nx >= wd) { - ox = (nx - wd) + 1; - shiftx = MAX(shiftx, ox); - nx -= wd; - } - if (ny < 0) { - shifty = MIN(shifty, ny); - ny += ht; - } else if (ny >= ht) { - oy = (ny - ht) + 1; - shifty = MAX(shifty, oy); - ny -= ht; - } - - si = (col & 7) / grid->bpp; - byte = grid->sel.bitmap[(y * bpr) + (col >> 3)] & masks[si]; - if (byte) { - rotated = 1; - nx *= grid->bpp; - di = (nx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - scratch[(ny * bpr) + (nx >> 3)] |= byte; - } - } - } - - if (rotated) { - /* - * If a shift is required, then shift the scratch area back into - * the main bitmap. - */ - if (shiftx || shifty) { - (void) memset((char *) grid->sel.bitmap, 0, bytes); - for (y = 0; y < ht; y++) { - for (col = x = 0; x < wd; x++, col += grid->bpp) { - si = (col & 7) / grid->bpp; - byte = scratch[(y * bpr) + (col >> 3)] & masks[si]; - if (byte) { - nx = x - shiftx; - ny = y - shifty; - - if (nx < 0) - nx += wd; - else if (nx >= wd) - nx -= wd; - if (ny < 0) - ny += ht; - else if (ny >= ht) - ny -= ht; - - nx *= grid->bpp; - di = (nx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - grid->sel.bitmap[(ny * bpr) + (nx >> 3)] |= byte; - } - } - } - } else - /* - * Copy the scratch buffer back to the main buffer. - */ - (void) memcpy((char *) grid->sel.bitmap, (char *) scratch, bytes); - - /* - * Determine the new selection width and height. - */ - ox = oy = 0; - nx = ny = 16384; - for (y = 0; y < ht; y++) { - for (col = x = 0; x < wd; x++, col += grid->bpp) { - si = (col & 7) / grid->bpp; - if (grid->sel.bitmap[(y * bpr) + (col >> 3)] & masks[si]) { - ox = MAX(ox, x); - nx = MIN(nx, x); - oy = MAX(oy, y); - ny = MIN(ny, y); - } - } - } - - /* - * Recalculate the center corrdinates so the selection will be - * positioned nicely once it is shifted to the upper left corner. - */ - cx = grid->sel.width >> 1; - cy = grid->sel.height >> 1; - - /* - * Set the new width and height. - */ - grid->sel.width = (ox - nx) + 1; - grid->sel.height = (oy - ny) + 1; - - /* - * Shift again to force the selection to the upper left corner. - */ - if (nx || ny) { - (void) memset((char *) scratch, 0, bytes); - for (y = 0; y < ht; y++) { - for (col = x = 0; x < wd; x++, col += grid->bpp) { - si = (col & 7) / grid->bpp; - byte = grid->sel.bitmap[(y * bpr) + (col >> 3)] & - masks[si]; - if (byte) { - oy = y - ny; - ox = (x - nx) * grid->bpp; - di = (ox & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - scratch[(oy * bpr) + (ox >> 3)] |= byte; - } - } - } - (void) memcpy((char *) grid->sel.bitmap, (char *) scratch, bytes); - } - - /* - * Determine the new top left coordinates from the center coordinates. - */ - grid->sel.x = (grid->sel.x + cx) - (grid->sel.width >> 1); - grid->sel.y = (grid->sel.y + cy) - (grid->sel.height >> 1); - - /* - * If the rotation caused the selection rectangle to overlap the edges - * of the grid, shift it so it is completely visible again. - */ - if (grid->sel.x + grid->sel.width > grid->grid_width) - grid->sel.x -= (grid->sel.x + grid->sel.width) - grid->grid_width; - if (grid->sel.y + grid->sel.height > grid->grid_height) - grid->sel.y -= (grid->sel.y + grid->sel.height) - grid->grid_height; - - /* - * Mark the grid as being modified. - */ - grid->modified = 1; - } - - return rotated; -} - -static void -#ifdef __STDC__ -_bdf_rotate_resize(bdf_glyph_grid_t *grid, int mul90, short degrees, - int *resize) -#else -_bdf_rotate_resize(grid, mul90, degrees, resize) -bdf_glyph_grid_t *grid; -int mul90; -short degrees; -int *resize; -#endif -{ - unsigned short wd, ht; - short cx, cy, x1, y1, x2, y2; - double dx1, dy1, dx2, dy2; - bdf_metrics_t metrics; - - *resize = 0; - (void) memset((char *) &metrics, 0, sizeof(bdf_metrics_t)); - - metrics.x_offset = grid->font_bbx.x_offset; - metrics.width = grid->font_bbx.width; - metrics.ascent = grid->font_bbx.ascent; - metrics.descent = grid->font_bbx.descent; - metrics.height = grid->font_bbx.height; - metrics.y_offset = grid->font_bbx.y_offset; - - cx = grid->glyph_x + (grid->glyph_bbx.width >> 1); - cy = grid->glyph_y + (grid->glyph_bbx.height >> 1); - - /* - * Rotate the lower left and upper right corners and check for a potential - * resize. - */ - x1 = grid->glyph_x; - y1 = grid->glyph_y + grid->glyph_bbx.height; - x2 = grid->glyph_x + grid->glyph_bbx.width; - y2 = grid->glyph_y; - - dx1 = (double)(x1 - cx); - dy1 = (double)(y1 - cy); - dx2 = (double)(x2 - cx); - dy2 = (double)(y2 - cx); - - if (mul90) { - x1 = cx + (short)((dx1 * _bdf_cos_tbl[degrees]) - - (dy1 * _bdf_sin_tbl[degrees])); - y1 = cy + (short)((dx1 * _bdf_sin_tbl[degrees]) + - (dy1 * _bdf_cos_tbl[degrees])); - x2 = cx + (short)((dx2 * _bdf_cos_tbl[degrees]) - - (dy2 * _bdf_sin_tbl[degrees])); - y2 = cy + (short)((dx2 * _bdf_sin_tbl[degrees]) + - (dy2 * _bdf_cos_tbl[degrees])); - } else { - x1 = cx + _bdf_ceiling((dx1 * _bdf_cos_tbl[degrees]) - - (dy1 * _bdf_sin_tbl[degrees])); - y1 = cy + _bdf_ceiling((dx1 * _bdf_sin_tbl[degrees]) + - (dy1 * _bdf_cos_tbl[degrees])); - x2 = cx + _bdf_ceiling((dx2 * _bdf_cos_tbl[degrees]) - - (dy2 * _bdf_sin_tbl[degrees])); - y2 = cy + _bdf_ceiling((dx2 * _bdf_sin_tbl[degrees]) + - (dy2 * _bdf_cos_tbl[degrees])); - } - - wd = MYABS(x2 - x1); - ht = MYABS(y2 - y1); - if (wd > metrics.width) { - metrics.width += wd - grid->font_bbx.width; - *resize = 1; - } - if (ht > metrics.height) { - metrics.ascent += ht - grid->font_bbx.height; - metrics.height += ht - grid->font_bbx.height; - *resize = 1; - } - - /* - * Rotate the upper left and lower right corners and check for a potential - * resize. - */ - x1 = grid->glyph_x; - y1 = grid->glyph_y; - x2 = grid->glyph_x + grid->glyph_bbx.width; - y2 = grid->glyph_y + grid->glyph_bbx.height; - - dx1 = (double)(x1 - cx); - dy1 = (double)(y1 - cy); - dx2 = (double)(x2 - cx); - dy2 = (double)(y2 - cx); - - if (mul90) { - x1 = cx + (short)((dx1 * _bdf_cos_tbl[degrees]) - - (dy1 * _bdf_sin_tbl[degrees])); - y1 = cy + (short)((dx1 * _bdf_sin_tbl[degrees]) + - (dy1 * _bdf_cos_tbl[degrees])); - x2 = cx + (short)((dx2 * _bdf_cos_tbl[degrees]) - - (dy2 * _bdf_sin_tbl[degrees])); - y2 = cy + (short)((dx2 * _bdf_sin_tbl[degrees]) + - (dy2 * _bdf_cos_tbl[degrees])); - } else { - x1 = cx + _bdf_ceiling((dx1 * _bdf_cos_tbl[degrees]) - - (dy1 * _bdf_sin_tbl[degrees])); - y1 = cy + _bdf_ceiling((dx1 * _bdf_sin_tbl[degrees]) + - (dy1 * _bdf_cos_tbl[degrees])); - x2 = cx + _bdf_ceiling((dx2 * _bdf_cos_tbl[degrees]) - - (dy2 * _bdf_sin_tbl[degrees])); - y2 = cy + _bdf_ceiling((dx2 * _bdf_sin_tbl[degrees]) + - (dy2 * _bdf_cos_tbl[degrees])); - } - - wd = MYABS(x2 - x1); - ht = MYABS(y2 - y1); - if (wd > metrics.width) { - metrics.width += wd - grid->font_bbx.width; - *resize = 1; - } - if (ht > metrics.height) { - metrics.ascent += ht - grid->font_bbx.height; - metrics.height += ht - grid->font_bbx.height; - *resize = 1; - } - - if (*resize) - (void) bdf_grid_resize(grid, &metrics); -} - -static void -#ifdef __STDC__ -_bdf_shear_resize(bdf_glyph_grid_t *grid, short degrees, int neg, int *resize) -#else -_bdf_shear_resize(grid, degrees, neg, resize) -bdf_glyph_grid_t *grid; -short degrees; -int neg, *resize; -#endif -{ - unsigned short wd; - short x1, y1, x2, y2; - bdf_metrics_t metrics; - - *resize = 0; - (void) memset((char *) &metrics, 0, sizeof(bdf_metrics_t)); - - metrics.x_offset = grid->font_bbx.x_offset; - metrics.width = grid->font_bbx.width; - metrics.ascent = grid->font_bbx.ascent; - metrics.descent = grid->font_bbx.descent; - metrics.height = grid->font_bbx.height; - metrics.y_offset = grid->font_bbx.y_offset; - - /* - * Shear the lower left and upper right corners and check for a potential - * resize. - */ - x1 = 0; - y1 = grid->glyph_bbx.height; - x2 = grid->glyph_bbx.width; - y2 = 0; - - if (neg) { - x1 += (short)((double) y1 * _bdf_tan_tbl[degrees]); - x2 += (short)((double) y2 * _bdf_tan_tbl[degrees]); - } else { - x1 += (short)((double)(grid->glyph_bbx.height - y1) * - _bdf_tan_tbl[degrees]); - x2 += (short)((double)(grid->glyph_bbx.height - y2) * - _bdf_tan_tbl[degrees]); - } - - wd = MYABS(x2 - x1); - if (wd > metrics.width) { - metrics.width += wd - grid->font_bbx.width; - *resize = 1; - } - - /* - * Shear the upper left and lower right corners and check for a potential - * resize. - */ - x1 = 0; - y1 = 0; - x2 = grid->glyph_bbx.width; - y2 = grid->glyph_bbx.height; - - if (neg) { - x1 += (short)((double) y1 * _bdf_tan_tbl[degrees]); - x2 += (short)((double) y2 * _bdf_tan_tbl[degrees]); - } else { - x1 += (short)((double)(grid->glyph_bbx.height - y1) * - _bdf_tan_tbl[degrees]); - x2 += (short)((double)(grid->glyph_bbx.height - y2) * - _bdf_tan_tbl[degrees]); - } - - wd = MYABS(x2 - x1); - if (wd > metrics.width) { - metrics.width += wd - grid->font_bbx.width; - *resize = 1; - } - - if (*resize) - (void) bdf_grid_resize(grid, &metrics); -} - -/* - * Rotate the bitmap in the grid by some number of degrees. - */ -int -#ifdef __STDC__ -bdf_grid_rotate(bdf_glyph_grid_t *grid, short degrees, int *resize) -#else -bdf_grid_rotate(grid, degrees, resize) -bdf_glyph_grid_t *grid; -short degrees; -int *resize; -#endif -{ - int rotated, mul90; - short nx, ny, cx, cy, x, y, wd, ht; - short ox, oy, gx, gy, shiftx, shifty; - unsigned short si, di, col, byte; - double dx, dy; - unsigned short bytes, bpr; - unsigned char *scratch, *masks; - - rotated = 0; - - /* - * Make sure the number of degrees is between 0 and 359 and adjusted to a - * positive number of degrees if necessary. - */ - while (degrees < 0) - degrees += 360; - while (degrees >= 360) - degrees -= 360; - - if (grid == 0 || degrees == 0 || - (grid->glyph_bbx.width == 0 && grid->glyph_bbx.height == 0)) - return rotated; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - mul90 = ((degrees % 90) == 0) ? 1 : 0; - - /* - * Force the grid to resize if the rotation requires it. - */ - _bdf_rotate_resize(grid, mul90, degrees, resize); - - if (grid->sel.width != 0 && grid->sel.height != 0) - return _bdf_rotate_selection(grid, mul90, degrees); - - /* - * Halve the byte count in the grid for later use. - */ - bytes = grid->bytes >> 1; - - /* - * Point at the scratch buffer area and initialize it. - */ - scratch = grid->bitmap + bytes; - (void) memset((char *) scratch, 0, bytes); - - /* - * Determine the bytes per row. - */ - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - - /* - * Determine the center coordinates of the glyph bitmap rectangle. - */ - cx = grid->glyph_x + (grid->glyph_bbx.width >> 1); - cy = grid->glyph_y + (grid->glyph_bbx.height >> 1); - - /* - * Only run over the rectangle containing the glyph itself. - */ - gx = grid->glyph_x; - gy = grid->glyph_y; - - wd = gx + grid->glyph_bbx.width; - ht = gy + grid->glyph_bbx.height; - - /* - * Initialize the adjustment counts used if the bitmap - * wraps around the edge. - */ - shiftx = shifty = 0; - - for (y = gy; y < ht; y++) { - col = gx * grid->bpp; - for (x = gx; x < wd; x++, col += grid->bpp) { - - /* - * Rotate the point. - */ - dx = (double)(x - cx); - dy = (double)(y - cy); - if (mul90) { - nx = cx + (short)((dx * _bdf_cos_tbl[degrees]) - - (dy * _bdf_sin_tbl[degrees])); - ny = cy + (short)((dx * _bdf_sin_tbl[degrees]) + - (dy * _bdf_cos_tbl[degrees])); - } else { - nx = cx + _bdf_ceiling((dx * _bdf_cos_tbl[degrees]) - - (dy * _bdf_sin_tbl[degrees])); - ny = cy + _bdf_ceiling((dx * _bdf_sin_tbl[degrees]) + - (dy * _bdf_cos_tbl[degrees])); - } - - /* - * Wrap the coordinates around the edges if necessary. - */ - if (nx < 0) { - shiftx = MIN(shiftx, nx); - nx += grid->grid_width; - } else if (nx >= grid->grid_width) { - ox = (nx - grid->grid_width) + 1; - shiftx = MAX(shiftx, ox); - nx -= grid->grid_width; - } - if (ny < 0) { - shifty = MIN(shifty, ny); - ny += grid->grid_height; - } else if (ny >= grid->grid_height) { - oy = (ny - grid->grid_height) + 1; - shifty = MAX(shifty, oy); - ny -= grid->grid_height; - } - - si = (col & 7) / grid->bpp; - byte = grid->bitmap[(y * bpr) + (col >> 3)] & masks[si]; - if (byte) { - rotated = 1; - nx *= grid->bpp; - di = (nx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - scratch[(ny * bpr) + (nx >> 3)] |= byte; - } - } - } - - if (rotated) { - /* - * If a shift is required, then shift the scratch area back into - * the main bitmap. - */ - if (shiftx || shifty) { - (void) memset((char *) grid->bitmap, 0, bytes); - for (y = 0; y < grid->grid_height; y++) { - for (col = x = 0; x < grid->grid_width; - x++, col += grid->bpp) { - si = (col & 7) / grid->bpp; - byte = scratch[(y * bpr) + (col >> 3)] & masks[si]; - if (byte) { - nx = x - shiftx; - ny = y - shifty; - - if (nx < 0) - nx += grid->grid_width; - else if (nx >= grid->grid_width) - nx -= grid->grid_width; - if (ny < 0) - ny += grid->grid_height; - else if (ny >= grid->grid_height) - ny -= grid->grid_height; - - nx *= grid->bpp; - di = (nx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - grid->bitmap[(ny * bpr) + (nx >> 3)] |= byte; - } - } - } - } else - /* - * Copy the scratch buffer back to the main buffer. - */ - (void) memcpy((char *) grid->bitmap, (char *) scratch, bytes); - - /* - * Determine the new glyph bounding box and the top left coordinates. - */ - ox = oy = 0; - nx = ny = 16384; - for (y = 0; y < grid->grid_height; y++) { - for (col = x = 0; x < grid->grid_width; x++, col += grid->bpp) { - si = (col & 7) / grid->bpp; - if (grid->bitmap[(y * bpr) + (col >> 3)] & masks[si]) { - nx = MIN(nx, x); - ox = MAX(ox, x); - ny = MIN(ny, y); - oy = MAX(oy, y); - } - } - } - - /* - * Set the new top left corrdinates. - */ - grid->glyph_x = nx; - grid->glyph_y = ny; - - /* - * Set the new glyph bounding box. - */ - grid->glyph_bbx.width = (ox - nx) + 1; - grid->glyph_bbx.x_offset = nx - grid->base_x; - grid->glyph_bbx.height = (oy - ny) + 1; - grid->glyph_bbx.ascent = grid->base_y - ny; - grid->glyph_bbx.descent = grid->glyph_bbx.height - - grid->glyph_bbx.ascent; - grid->glyph_bbx.y_offset = -grid->glyph_bbx.descent; - - /* - * Mark the grid as being modified. - */ - grid->modified = 1; - } - - return rotated; -} - -int -#ifdef __STDC__ -bdf_grid_shear(bdf_glyph_grid_t *grid, short degrees, int *resize) -#else -bdf_grid_shear(grid, degrees, resize) -bdf_glyph_grid_t *grid; -short degrees; -int *resize; -#endif -{ - int sheared, neg; - short cx, cy, wd, ht, gx, gy, x, y; - short nx, ox, ny, oy, shiftx, shifty; - unsigned short bytes, bpr, si, di, col, byte; - unsigned char *scratch, *masks; - - sheared = 0; - - if (degrees == 0 || degrees < -45 || degrees > 45 || grid == 0 || - (grid->glyph_bbx.width == 0 && grid->glyph_bbx.height == 0)) - return sheared; - - if ((neg = (degrees < 0))) - degrees = -degrees; - - /* - * Check to see if the grid needs to be resized to hold the sheared glyph. - */ - _bdf_shear_resize(grid, degrees, neg, resize); - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - /* - * Halve the byte count in the grid for later use. - */ - bytes = grid->bytes >> 1; - - /* - * Point at the scratch buffer area and initialize it. - */ - scratch = grid->bitmap + bytes; - (void) memset((char *) scratch, 0, bytes); - - /* - * Determine the bytes per row. - */ - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - - /* - * Determine the center coordinates of the glyph bitmap rectangle. - */ - gx = grid->glyph_x; - gy = grid->glyph_y; - - cx = gx + (grid->glyph_bbx.width >> 1); - cy = gy + (grid->glyph_bbx.height >> 1); - - wd = gx + grid->glyph_bbx.width; - ht = gy + grid->glyph_bbx.height; - - shiftx = shifty = 0; - for (y = gy; y < ht; y++) { - col = gx * grid->bpp; - for (x = gx; x < wd; x++, col += grid->bpp) { - ny = y; - if (neg) - nx = x + (short)((double) y * _bdf_tan_tbl[degrees]); - else - nx = x + (short)((double)(gy + (ht - y)) * - _bdf_tan_tbl[degrees]); - - if (nx < 0) { - shiftx = MIN(shiftx, nx); - nx += grid->grid_width; - } else if (nx >= grid->grid_width) { - ox = (nx - grid->grid_width) + 1; - shiftx = MAX(shiftx, ox); - nx -= grid->grid_width; - } - if (ny < 0) { - shifty = MIN(shifty, ny); - ny += grid->grid_height; - } else if (ny >= grid->grid_height) { - oy = (ny - grid->grid_height) + 1; - shifty = MAX(shifty, oy); - ny -= grid->grid_height; - } - - si = (col & 7) / grid->bpp; - byte = grid->bitmap[(y * bpr) + (col >> 3)] & masks[si]; - if (byte) { - sheared = 1; - nx *= grid->bpp; - di = (nx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - scratch[(y * bpr) + (nx >> 3)] |= byte; - } - } - } - - if (sheared) { - /* - * If a shift is required, then shift the scratch area back into - * the main bitmap. - */ - if (shiftx || shifty) { - (void) memset((char *) grid->bitmap, 0, bytes); - for (y = 0; y < grid->grid_height; y++) { - for (col = x = 0; x < grid->grid_width; - x++, col += grid->bpp) { - si = (col & 7) / grid->bpp; - byte = scratch[(y * bpr) + (col >> 3)] & masks[si]; - if (byte) { - nx = x - shiftx; - ny = y - shifty; - - if (nx < 0) - nx += grid->grid_width; - else if (nx >= grid->grid_width) - nx -= grid->grid_width; - if (ny < 0) - ny += grid->grid_height; - else if (ny >= grid->grid_height) - ny -= grid->grid_height; - - nx *= grid->bpp; - di = (nx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - grid->bitmap[(ny * bpr) + (nx >> 3)] |= byte; - } - } - } - } else - /* - * Copy the scratch buffer back to the main buffer. - */ - (void) memcpy((char *) grid->bitmap, (char *) scratch, bytes); - - ox = oy = 0; - nx = ny = 16384; - for (y = 0; y < grid->grid_height; y++) { - for (col = x = 0; x < grid->grid_width; x++, col += grid->bpp) { - si = (col & 7) / grid->bpp; - if (grid->bitmap[(y * bpr) + (col >> 3)] & masks[si]) { - ox = MAX(ox, x); - nx = MIN(nx, x); - oy = MAX(oy, y); - ny = MIN(ny, y); - } - } - } - - /* - * Set the new top left corrdinates. - */ - grid->glyph_x = nx; - grid->glyph_y = ny; - - /* - * Set the new glyph bounding box. - */ - grid->glyph_bbx.width = (ox - nx) + 1; - grid->glyph_bbx.x_offset = nx - grid->base_x; - grid->glyph_bbx.height = (oy - ny) + 1; - grid->glyph_bbx.ascent = grid->base_y - ny; - grid->glyph_bbx.descent = grid->glyph_bbx.height - - grid->glyph_bbx.ascent; - grid->glyph_bbx.y_offset = -grid->glyph_bbx.descent; - - /* - * Mark the grid as being modified. - */ - grid->modified = 1; - } - - return sheared; -} - -int -#ifdef __STDC__ -bdf_grid_embolden(bdf_glyph_grid_t *grid) -#else -bdf_grid_embolden(grid) -bdf_glyph_grid_t *grid; -#endif -{ - int done; - short wd, ht, gx, gy, x, y; - unsigned short b1, b2, bpr, si, di, col; - unsigned char *masks; - - done = 0; - - if (grid == 0 || - (grid->glyph_bbx.width == 0 && grid->glyph_bbx.height == 0)) - return done; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - /* - * Determine the bytes per row. - */ - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - - gx = grid->glyph_x; - gy = grid->glyph_y; - - wd = gx + grid->glyph_bbx.width; - ht = gy + grid->glyph_bbx.height; - - if (grid->spacing == BDF_PROPORTIONAL || - (grid->spacing == BDF_MONOWIDTH && - grid->glyph_bbx.width < grid->font_bbx.width)) - /* - * Only allow horizontal expansion in the cases that make sense. - */ - wd++; - - for (y = gy; y < ht; y++) { - col = (wd - 1) * grid->bpp; - for (x = wd - 1; x > gx; x--, col -= grid->bpp) { - si = (col & 7) / grid->bpp; - di = ((col - grid->bpp) & 7) / grid->bpp; - b1 = grid->bitmap[(y * bpr) + (col >> 3)] & masks[si]; - b2 = grid->bitmap[(y * bpr) + ((col - grid->bpp) >> 3)] & - masks[di]; - if (!b1 && b2) { - if (di < si) - b2 >>= (si - di) * grid->bpp; - else if (di > si) - b2 <<= (di - si) * grid->bpp; - grid->bitmap[(y * bpr) + (col >> 3)] |= b2; - /* - * Mark the grid as being modified. - */ - done = grid->modified = 1; - } - } - } - - /* - * Adjust the glyph width so it will be reflected when the glyph is stored - * back in the font. - */ - grid->glyph_bbx.width = wd - gx; - - return done; -} - -/************************************************************************** - * - * Glyph grid selection functions. - * - **************************************************************************/ - -int -#ifdef __STDC__ -bdf_has_selection(bdf_glyph_grid_t *grid, short *x, short *y, - short *width, short *height) -#else -bdf_has_selection(grid, x, y, width, height) -bdf_glyph_grid_t *grid; -short *x, *y, *width, *height; -#endif -{ - if (grid == 0 || (grid->sel.width == 0 && grid->sel.height == 0)) - return 0; - - if (x != 0) - *x = grid->sel.x; - if (y != 0) - *y = grid->sel.y; - if (width != 0) - *width = grid->sel.width; - if (height != 0) - *height = grid->sel.height; - - return 1; -} - -/* - * Select a rectangle on the grid. - */ -void -#ifdef __STDC__ -bdf_set_selection(bdf_glyph_grid_t *grid, short x, short y, - short width, short height) -#else -bdf_set_selection(grid, x, y, width, height) -bdf_glyph_grid_t *grid; -short x, y, width, height; -#endif -{ - short nx, ny, wd, ht, ssize, dx, dy, col; - unsigned short bytes, bpr, sbpr, si, di, byte; - unsigned char *masks; - - if (grid == 0) - return; - - /* - * Make sure the specified rectangle is within reasonable bounds. - */ - if (x < 0 || x >= grid->grid_width) - x = 0; - if (y < 0 || y >= grid->grid_height) - y = 0; - - if (x + width > grid->grid_width) - width = (x + width) - grid->grid_width; - if (y + height > grid->grid_height) - height = (y + height) - grid->grid_height; - - grid->sel.x = x; - grid->sel.y = y; - grid->sel.width = width; - grid->sel.height = height; - - /* - * Allocate enough space to represent a square the size of the largest - * of the width and height of the selection. This allows rotation and - * flipping of the selected bitmap. - */ - ssize = MAX(width, height); - - bytes = ((((ssize * grid->bpp) + 7) >> 3) * ssize) << 1; - - /* - * If the selection is being removed (width and height are 0), then simply - * return. - */ - if (bytes == 0) - return; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - if (bytes > grid->sel.bytes) { - if (grid->sel.bytes == 0) - grid->sel.bitmap = (unsigned char *) malloc(bytes); - else - grid->sel.bitmap = (unsigned char *) - realloc((char *) grid->sel.bitmap, bytes); - grid->sel.bytes = bytes; - } else - bytes = grid->sel.bytes; - - /* - * Initialize the selection bitmap and copy the selected bits to it. - */ - (void) memset((char *) grid->sel.bitmap, 0, bytes); - - wd = x + width; - ht = y + height; - - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - sbpr = ((grid->sel.width * grid->bpp) + 7) >> 3; - - for (ny = 0, dy = y; dy < ht; dy++, ny++) { - col = x * grid->bpp; - for (nx = 0, dx = x; dx < wd; - dx++, nx += grid->bpp, col += grid->bpp) { - si = (col & 7) / grid->bpp; - byte = grid->bitmap[(dy * bpr) + (col >> 3)] & masks[si]; - if (byte) { - di = (nx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - grid->sel.bitmap[(ny * sbpr) + (nx >> 3)] |= byte; - } - } - } -} - -/* - * Detach a selection in preparation for moving it. What is does is clear the - * bits set in the selection from the main grid. Again, this is only used for - * move operations. - */ -void -#ifdef __STDC__ -bdf_detach_selection(bdf_glyph_grid_t *grid) -#else -bdf_detach_selection(grid) -bdf_glyph_grid_t *grid; -#endif -{ - short sx, sy, x, y, wd, ht, dx; - unsigned short bpr, sbpr, si, di, byte; - unsigned char *masks; - - if (grid == 0 || (grid->sel.width == 0 && grid->sel.height == 0)) - return; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - sbpr = ((grid->sel.width * grid->bpp) + 7) >> 3; - - wd = grid->sel.x + grid->sel.width; - ht = grid->sel.y + grid->sel.height; - - for (sy = 0, y = grid->sel.y; y < ht; y++, sy++) { - for (sx = 0, x = grid->sel.x; x < wd; x++, sx += grid->bpp) { - si = (sx & 7) / grid->bpp; - byte = grid->sel.bitmap[(sy * sbpr) + (sx >> 3)] & masks[si]; - if (byte) { - dx = x * grid->bpp; - di = (dx & 7) / grid->bpp; - grid->bitmap[(y * bpr) + (dx >> 3)] &= ~masks[di]; - } - } - } - - /* - * Crop the new image to determine the new bounds with the selection. - */ - (void) bdf_grid_crop(grid, 1); -} - -void -#ifdef __STDC__ -bdf_attach_selection(bdf_glyph_grid_t *grid) -#else -bdf_attach_selection(grid) -bdf_glyph_grid_t *grid; -#endif -{ - short sx, sy, x, y, wd, ht; - unsigned short bpr, sbpr, dx, di, si, byte; - unsigned char *masks; - - if (grid == 0 || (grid->sel.width == 0 && grid->sel.height == 0)) - return; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - sbpr = ((grid->sel.width * grid->bpp) + 7) >> 3; - - wd = grid->sel.x + grid->sel.width; - ht = grid->sel.y + grid->sel.height; - - for (sy = 0, y = grid->sel.y; y < ht; y++, sy++) { - for (sx = 0, x = grid->sel.x; x < wd; x++, sx += grid->bpp) { - si = (sx & 7) / grid->bpp; - byte = grid->sel.bitmap[(sy * sbpr) + (sx >> 3)] & masks[si]; - if (byte) { - dx = x * grid->bpp; - di = (dx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - grid->bitmap[(y * bpr) + (dx >> 3)] |= byte; - } - } - } - - /* - * Crop the new image to determine the new bounds with the selection. - */ - (void) bdf_grid_crop(grid, 1); -} - -/* - * Indicate the selection no longer exists by setting the width and height to - * 0. - */ -void -#ifdef __STDC__ -bdf_lose_selection(bdf_glyph_grid_t *grid) -#else -bdf_lose_selection(grid) -bdf_glyph_grid_t *grid; -#endif -{ - if (grid == 0) - return; - grid->sel.width = grid->sel.height = 0; -} - -/* - * Delete the selection by first detaching it which will erase the rectangle - * on the grid and then losing the selection. - */ -void -#ifdef __STDC__ -bdf_delete_selection(bdf_glyph_grid_t *grid) -#else -bdf_delete_selection(grid) -bdf_glyph_grid_t *grid; -#endif -{ - bdf_detach_selection(grid); - bdf_lose_selection(grid); -} - -/* - * Check to see if a coordinate pair is in the selected region. - */ -int -#ifdef __STDC__ -bdf_in_selection(bdf_glyph_grid_t *grid, short x, short y, short *set) -#else -bdf_in_selection(grid, x, y, set) -bdf_glyph_grid_t *grid; -short x, y, *set; -#endif -{ - short wd, ht; - unsigned short bpr, si, di, byte; - unsigned char *masks; - - if (grid == 0 || (grid->sel.width == 0 && grid->sel.height == 0)) - return 0; - - di = 0; - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - di = 7; - break; - case 2: - masks = twobpp; - di = 3; - break; - case 4: - masks = fourbpp; - di = 1; - break; - } - - bpr = ((grid->sel.width * grid->bpp) + 7) >> 3; - - wd = grid->sel.x + grid->sel.width; - ht = grid->sel.y + grid->sel.height; - - if ((x >= grid->sel.x && x < wd) && (y >= grid->sel.y && y < ht)) { - if (set) { - /* - * Adjust the byte back to an index value. - */ - x *= grid->bpp; - si = (x & 7) / grid->bpp; - byte = grid->sel.bitmap[(y * bpr) + (x >> 3)] & masks[si]; - if (di > si) - byte >>= (di - si) * grid->bpp; - *set = byte; - } - return 1; - } - - return 0; -} - -int -#ifdef __STDC__ -bdf_grid_shift(bdf_glyph_grid_t *grid, short xcount, short ycount) -#else -bdf_grid_shift(grid, xcount, ycount) -bdf_glyph_grid_t *grid; -short xcount, ycount; -#endif -{ - int sel, delta; - short xdir, ydir, x, y, wd, ht, dx, dy, nx, ny; - unsigned short bytes, bpr, si, di, byte, col; - unsigned char *scratch, *masks; - - if (grid == 0) - return 0; - - xdir = ydir = 1; - if (xcount < 0) { - xdir = -1; - xcount = -xcount; - } - - if (ycount < 0) { - ydir = -1; - ycount = -ycount; - } - - /* - * Adjust the shift counts if they are larger than they should be. - */ - if (xcount > grid->grid_width) - xcount -= grid->grid_width; - if (ycount > grid->grid_height) - ycount -= grid->grid_height; - - /* - * Adjust the counts to limit the shift to the boundaries of the grid. - */ - if (grid->sel.width != 0 && grid->sel.height != 0) { - /* - * The selection is being shifted. - */ - x = grid->sel.x; - y = grid->sel.y; - wd = grid->sel.width; - ht = grid->sel.height; - sel = 1; - } else { - x = grid->glyph_x; - y = grid->glyph_y; - wd = grid->glyph_bbx.width; - ht = grid->glyph_bbx.height; - sel = 0; - } - - /* - * If the width and height are 0, then simply return, because there - * is nothing to shift. - */ - if (wd == 0 && ht == 0) - return 0; - - if (xdir == 1 && x + wd + xcount > grid->grid_width) - xcount = grid->grid_width - (x + wd); - else if (xdir == -1 && xcount > x) - xcount = x; - - if (ydir == 1 && y + ht + ycount > grid->grid_height) - ycount = grid->grid_height - (y + ht); - else if (ydir == -1 && ycount > y) - ycount = y; - - if (xcount == 0 && ycount == 0) - return 0; - - /* - * If the selection is the one being shifted, adjust the X and Y - * coordinates and adjust the glyph metrics. - */ - if (sel) { - /* - * Determine the actual ink bounds of the selection so the - * glyph metrics can be adjusted if necessary. - */ - if (_bdf_grid_ink_bounds(grid, &x, &y, &wd, &ht)) { - /* - * Have to adjust the glyph metrics. - */ - x += xdir * xcount; - y += ydir * ycount; - if (x < grid->glyph_x) { - delta = grid->glyph_x - x; - grid->glyph_bbx.width += delta; - grid->glyph_bbx.x_offset -= delta; - if (grid->spacing == BDF_PROPORTIONAL) - grid->dwidth += delta; - grid->glyph_x -= delta; - } else if (x >= grid->glyph_x + grid->glyph_bbx.width) { - delta = x - (grid->glyph_x + grid->glyph_bbx.width); - grid->glyph_bbx.width += delta; - if (grid->spacing == BDF_PROPORTIONAL) - grid->dwidth += delta; - } - - if (y < grid->glyph_y) { - delta = grid->glyph_y - y; - grid->glyph_bbx.height += delta; - grid->glyph_bbx.ascent += delta; - grid->glyph_y -= delta; - } else if (y + ht >= grid->glyph_y + grid->glyph_bbx.height) { - delta = (y + ht) - (grid->glyph_y + grid->glyph_bbx.height); - grid->glyph_bbx.height += delta; - grid->glyph_bbx.y_offset -= delta; - grid->glyph_bbx.descent += delta; - } - - grid->modified = 1; - } - - /* - * Adjust the top-left coordinate of the selection rectangle. - */ - grid->sel.x += xdir * xcount; - grid->sel.y += ydir * ycount; - - return 1; - } - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - di = 7; - break; - case 2: - masks = twobpp; - di = 3; - break; - case 4: - masks = fourbpp; - di = 1; - break; - } - - /* - * The glyph itself is being shifted. - */ - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - bytes = grid->bytes >> 1; - scratch = grid->bitmap + bytes; - (void) memset((char *) scratch, 0, bytes); - - /* - * Shift just the glyph rectangle to keep things fast. - */ - wd += x; - ht += y; - for (dy = y; dy < ht; dy++) { - col = x * grid->bpp; - for (dx = x; dx < wd; dx++, col += grid->bpp) { - si = (col & 7) / grid->bpp; - byte = grid->bitmap[(dy * bpr) + (col >> 3)] & masks[si]; - if (byte) { - nx = dx + (xdir * xcount); - ny = dy + (ydir * ycount); - nx *= grid->bpp; - di = (nx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - scratch[(ny * bpr) + (nx >> 3)] |= byte; - } - } - } - - /* - * Copy the scratch buffer back to the main buffer. - */ - (void) memcpy((char *) grid->bitmap, (char *) scratch, bytes); - - /* - * Adjust the top-left coordinate of the glyph rectangle. - */ - grid->glyph_x += xdir * xcount; - grid->glyph_y += ydir * ycount; - - /* - * Adjust the glyph offsets relative to the baseline coordinates. - */ - grid->glyph_bbx.x_offset = grid->glyph_x - grid->base_x; - grid->glyph_bbx.y_offset = grid->base_y - - (grid->glyph_y + grid->glyph_bbx.height); - - /* - * Adjust the glyph ascent and descent. - */ - grid->glyph_bbx.ascent = grid->base_y - grid->glyph_y; - grid->glyph_bbx.descent = (grid->glyph_y + grid->glyph_bbx.height) - - grid->base_y; - - /* - * Mark the grid as being modified. - */ - grid->modified = 1; - - return 1; -} - - -int -#ifdef __STDC__ -bdf_grid_flip(bdf_glyph_grid_t *grid, short dir) -#else -bdf_grid_flip(grid, dir) -bdf_glyph_grid_t *grid; -short dir; -#endif -{ - int flipped, sel, delta; - short dx, dy, x, y, nx, ny, wd, ht; - unsigned short bytes, bpr, si, di, col, colx, byte; - unsigned char *bmap, *scratch, *masks; - - flipped = 0; - - if (grid == 0) - return flipped; - - if (grid->sel.width != 0 && grid->sel.height != 0) { - sel = 1; - x = y = 0; - wd = grid->sel.width; - ht = grid->sel.height; - bpr = ((wd * grid->bpp) + 7) >> 3; - bytes = grid->sel.bytes >> 1; - bmap = grid->sel.bitmap; - } else { - sel = 0; - x = grid->glyph_x; - y = grid->glyph_y; - wd = grid->glyph_bbx.width; - ht = grid->glyph_bbx.height; - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - bytes = grid->bytes >> 1; - bmap = grid->bitmap; - } - - /* - * If the width or height is 0, don't do anything. - */ - if (wd == 0 || ht == 0) - return flipped; - - nx = 0; - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - di = 7; - break; - case 2: - masks = twobpp; - di = 3; - break; - case 4: - masks = fourbpp; - di = 1; - break; - } - - /* - * Set and initialize the scratch area. - */ - scratch = bmap + bytes; - (void) memset((char *) scratch, 0, bytes); - - wd += x; - ht += y; - - if (dir < 0) { - /* - * Flip horizontally. - */ - for (dy = y; dy < ht; dy++) { - col = x * grid->bpp; - for (nx = wd - 1, dx = x; dx < wd; dx++, nx--, col += grid->bpp) { - si = (col & 7) / grid->bpp; - byte = bmap[(dy * bpr) + (col >> 3)] & masks[si]; - if (byte) { - flipped = 1; - colx = nx * grid->bpp; - di = (colx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - scratch[(dy * bpr) + (colx >> 3)] |= byte; - } - } - } - if (flipped) { - if (sel) - grid->sel.x += nx + 1; - else { - grid->glyph_x = nx + 1; - grid->glyph_bbx.x_offset = grid->glyph_x - grid->base_x; - } - } - } else { - /* - * Flip vertically. - */ - for (ny = ht - 1, dy = y; dy < ht; dy++, ny--) { - col = x * grid->bpp; - for (dx = x; dx < wd; dx++, col += grid->bpp) { - si = (col & 7) / grid->bpp; - byte = bmap[(dy * bpr) + (col >> 3)] & masks[si]; - if (byte) { - flipped = 1; - scratch[(ny * bpr) + (col >> 3)] |= byte; - } - } - } - if (flipped) { - if (sel) - grid->sel.y += ny + 1; - else { - grid->glyph_y = ny + 1; - grid->glyph_bbx.y_offset = grid->base_y - - (grid->glyph_y + grid->glyph_bbx.height); - grid->glyph_bbx.ascent = grid->base_y - grid->glyph_y; - grid->glyph_bbx.descent = - (grid->glyph_y + grid->glyph_bbx.height) - grid->base_y; - } - } - } - - if (flipped) { - /* - * Copy the scratch area back to the working area. - */ - if (sel) - (void) memcpy((char *) grid->sel.bitmap, (char *) scratch, bytes); - else - (void) memcpy((char *) grid->bitmap, (char *) scratch, bytes); - - if (sel) { - /* - * Check to see if flipping the selection caused the glyph metrics - * to change. - */ - if (_bdf_grid_ink_bounds(grid, &x, &y, &wd, &ht)) { - if (x < grid->glyph_x) { - delta = grid->glyph_x - x; - grid->glyph_bbx.width += delta; - grid->glyph_bbx.x_offset -= delta; - grid->glyph_x -= delta; - if (grid->spacing == BDF_PROPORTIONAL) - grid->dwidth += delta; - } else if (x >= grid->glyph_x + grid->glyph_bbx.width) { - delta = x - (grid->glyph_x + grid->glyph_bbx.width); - grid->glyph_bbx.width += delta; - if (grid->spacing == BDF_PROPORTIONAL) - grid->dwidth += delta; - } - - if (y < grid->glyph_y) { - delta = grid->glyph_y - y; - grid->glyph_bbx.height += delta; - grid->glyph_bbx.ascent += delta; - grid->glyph_y -= delta; - } else if (y >= grid->glyph_y + grid->glyph_bbx.height) { - delta = y - (grid->glyph_y + grid->glyph_bbx.height); - grid->glyph_bbx.height += delta; - grid->glyph_bbx.y_offset -= delta; - grid->glyph_bbx.descent += delta; - } - } - } - - /* - * Mark the grid as being modified. - */ - grid->modified = 1; - } - - return flipped; -} - -void -#ifdef __STDC__ -bdf_grid_origin(bdf_glyph_grid_t *grid, short *x, short *y) -#else -bdf_grid_origin(grid, x, y) -bdf_glyph_grid_t *grid; -short *x, *y; -#endif -{ - if (grid == 0) - return; - - *x = grid->base_x; - *y = grid->base_y; -} - -bdf_glyph_t * -#ifdef __STDC__ -bdf_grid_glyph(bdf_glyph_grid_t *grid) -#else -bdf_grid_glyph(grid) -bdf_glyph_grid_t *grid; -#endif -{ - int len; - short x, y, nx, ny, wd, ht, gx, gy; - unsigned short bpr, nbpr, si, di, col, byte; - bdf_glyph_t *glyph; - unsigned char *masks; - double ps, dw, rx; - - if (grid == 0) - return 0; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - di = 7; - break; - case 2: - masks = twobpp; - di = 3; - break; - case 4: - masks = fourbpp; - di = 1; - break; - } - - /* - * Create the new glyph. - */ - glyph = (bdf_glyph_t *) malloc(sizeof(bdf_glyph_t)); - (void) memset((char *) glyph, 0, sizeof(bdf_glyph_t)); - - gx = grid->glyph_x; - gy = grid->glyph_y; - - /* - * Copy the bounding box. - */ - (void) memcpy((char *) &glyph->bbx, (char *) &grid->glyph_bbx, - sizeof(bdf_bbx_t)); - - /* - * If the font has character-cell spacing, then make sure the bitmap is - * cropped to fit within the bounds of the font bbx. - */ - if (grid->spacing == BDF_CHARCELL) { - if (gx < grid->base_x) { - glyph->bbx.x_offset = 0; - glyph->bbx.width -= grid->base_x - gx; - gx += grid->base_x - gx; - } - if (glyph->bbx.width > grid->font_bbx.width) - glyph->bbx.width -= glyph->bbx.width - grid->font_bbx.width; - } - - /* - * Set up its bitmap. - */ - nbpr = ((glyph->bbx.width * grid->bpp) + 7) >> 3; - glyph->bytes = nbpr * glyph->bbx.height; - glyph->bitmap = (unsigned char *) malloc(glyph->bytes); - (void) memset((char *) glyph->bitmap, 0, glyph->bytes); - - /* - * Set the other values. - */ - if (grid->name != 0) { - len = strlen(grid->name) + 1; - glyph->name = (char *) malloc(len); - (void) memcpy(glyph->name, grid->name, len); - } - glyph->encoding = grid->encoding; - glyph->dwidth = grid->dwidth; - - /* - * Reset the glyph SWIDTH value. - */ - ps = (double) grid->point_size; - rx = (double) grid->resolution_x; - dw = (double) grid->dwidth; - glyph->swidth = (unsigned short)((dw * 72000.0) / (ps * rx)); - - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - wd = gx + glyph->bbx.width; - ht = gy + glyph->bbx.height; - - /* - * Copy the bitmap from the grid into the glyph. - */ - for (ny = 0, y = gy; y < ht; y++, ny++) { - col = gx * grid->bpp; - for (nx = 0, x = gx; x < wd; x++, nx += grid->bpp, col += grid->bpp) { - si = (col & 7) / grid->bpp; - byte = grid->bitmap[(y * bpr) + (col >> 3)] & masks[si]; - if (byte) { - di = (nx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - glyph->bitmap[(ny * nbpr) + (nx >> 3)] |= byte; - } - } - } - - /* - * Return the new glyph. - */ - return glyph; -} - -/* - * Create a bitmap with the glyph image as well as the selection. - */ -void -#ifdef __STDC__ -bdf_grid_image(bdf_glyph_grid_t *grid, bdf_bitmap_t *image) -#else -bdf_grid_image(grid, image) -bdf_glyph_grid_t *grid; -bdf_bitmap_t *image; -#endif -{ - short x, y, ix, iy; - unsigned short bpr, ibpr, si, di, col, colx, byte; - unsigned char *masks; - - if (grid == 0 || image == 0) - return; - - masks = 0; - switch (grid->bpp) { - case 1: - masks = onebpp; - di = 7; - break; - case 2: - masks = twobpp; - di = 3; - break; - case 4: - masks = fourbpp; - di = 1; - break; - } - - image->bpp = grid->bpp; - image->x = image->y = 0; - image->width = grid->grid_width; - image->height = grid->grid_height; - image->bytes = grid->bytes >> 1; - image->bitmap = (unsigned char *) malloc(image->bytes); - (void) memcpy((char *) image->bitmap, (char *) grid->bitmap, image->bytes); - - /* - * Add the selection to the bitmap if it exists. - */ - if (grid->sel.width != 0 && grid->sel.height != 0) { - ibpr = ((image->width * grid->bpp) + 7) >> 3; - bpr = ((grid->sel.width * grid->bpp) + 7) >> 3; - for (iy = grid->sel.y, y = 0; y < grid->sel.height; y++, iy++) { - for (ix = grid->sel.x, col = x = 0; x < grid->sel.width; - x++, ix++, col += grid->bpp) { - si = (col & 7) / grid->bpp; - byte = grid->sel.bitmap[(y * bpr) + (col >> 3)] & masks[si]; - if (byte) { - colx = ix * grid->bpp; - di = (colx & 7) / grid->bpp; - if (di < si) - byte <<= (si - di) * grid->bpp; - else if (di > si) - byte >>= (di - si) * grid->bpp; - image->bitmap[(iy * ibpr) + (colx >> 3)] |= byte; - } - } - } - } -} - -/* - * Routines for quick and dirty dithering. - */ -static void -#ifdef __STDC__ -_bdf_one_to_n(bdf_bitmap_t *bmap, int n) -#else -_bdf_one_to_n(bmap, n) -bdf_bitmap_t *bmap; -int n; -#endif -{ - unsigned short bpr, sbpr, bytes, col, sx, sy; - unsigned char *nbmap, *masks; - - if (bmap == 0 || bmap->width == 0 || bmap->height == 0) - return; - - masks = 0; - switch (n) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - sbpr = (bmap->width + 7) >> 3; - bpr = ((bmap->width * n) + 7) >> 3; - bytes = bpr * bmap->height; - nbmap = (unsigned char *) malloc(bytes); - (void) memset((char *) nbmap, 0, bytes); - - for (sy = 0; sy < bmap->height; sy++) { - for (col = sx = 0; sx < bmap->width; sx++, col += n) { - if (bmap->bitmap[(sy * sbpr) + (sx >> 3)] & (0x80 >> (sx & 7))) - nbmap[(sy * bpr) + (col >> 3)] |= masks[(col & 7) / n]; - } - } - free((char *) bmap->bitmap); - bmap->bpp = n; - bmap->bytes = bytes; - bmap->bitmap = nbmap; -} - -static void -#ifdef __STDC__ -_bdf_n_to_one(bdf_bitmap_t *bmap) -#else -_bdf_n_to_one(bmap) -bdf_bitmap_t *bmap; -#endif -{ - unsigned short bpr, sbpr, bytes, col, sx, sy; - unsigned char *nbmap, *masks; - - if (bmap == 0 || bmap->width == 0 || bmap->height == 0) - return; - - masks = 0; - switch (bmap->bpp) { - case 1: - masks = onebpp; - break; - case 2: - masks = twobpp; - break; - case 4: - masks = fourbpp; - break; - } - - sbpr = ((bmap->width * bmap->bpp) + 7) >> 3; - bpr = (bmap->width + 7) >> 3; - bytes = bpr * bmap->height; - nbmap = (unsigned char *) malloc(bytes); - (void) memset((char *) nbmap, 0, bytes); - - for (sy = 0; sy < bmap->height; sy++) { - for (col = sx = 0; sx < bmap->width; sx++, col += bmap->bpp) { - if (bmap->bitmap[(sy * sbpr) + (col >> 3)] & - masks[(col & 7) / bmap->bpp]) - nbmap[(sy * bpr) + (sx >> 3)] |= (0x80 >> (sx & 7)); - } - } - free((char *) bmap->bitmap); - bmap->bpp = 1; - bmap->bytes = bytes; - bmap->bitmap = nbmap; -} - -static void -#ifdef __STDC__ -_bdf_two_to_four(bdf_bitmap_t *bmap) -#else -_bdf_two_to_four(bmap) -bdf_bitmap_t *bmap; -#endif -{ - unsigned short bpr, sbpr, bytes, col, si, byte, sx, sy; - unsigned char *nbmap, *masks; - - if (bmap == 0 || bmap->width == 0 || bmap->height == 0) - return; - - masks = twobpp; - - sbpr = ((bmap->width << 1) + 7) >> 3; - bpr = ((bmap->width << 2) + 7) >> 3; - bytes = bpr * bmap->height; - nbmap = (unsigned char *) malloc(bytes); - (void) memset((char *) nbmap, 0, bytes); - - for (sy = 0; sy < bmap->height; sy++) { - for (col = sx = 0; sx < bmap->width; sx++, col += 2) { - si = (col & 7) >> 1; - byte = bmap->bitmap[(sy * sbpr) + (col >> 3)] & masks[si]; - if (byte) { - /* - * Shift the byte down to make an index. - */ - if (si < 3) - byte >>= (3 - si) << 1; - - /* - * Scale the index to four bits per pixel and shift it into - * place before adding it. - */ - byte = (byte << 2) + 3; - if ((sx & 1) == 0) - byte <<= 4; - nbmap[(sy * bpr) + ((sx << 2) >> 3)] |= byte; - } - } - } - free((char *) bmap->bitmap); - bmap->bpp = 4; - bmap->bytes = bytes; - bmap->bitmap = nbmap; -} - -static void -#ifdef __STDC__ -_bdf_four_to_two(bdf_bitmap_t *bmap) -#else -_bdf_four_to_two(bmap) -bdf_bitmap_t *bmap; -#endif -{ - unsigned short bpr, sbpr, bytes, col, si, byte, sx, sy; - unsigned char *nbmap, *masks; - - if (bmap == 0 || bmap->width == 0 || bmap->height == 0) - return; - - masks = fourbpp; - - sbpr = ((bmap->width << 2) + 7) >> 3; - bpr = ((bmap->width << 1) + 7) >> 3; - bytes = bpr * bmap->height; - nbmap = (unsigned char *) malloc(bytes); - (void) memset((char *) nbmap, 0, bytes); - - for (sy = 0; sy < bmap->height; sy++) { - for (col = sx = 0; sx < bmap->width; sx++, col += 4) { - si = (col & 7) >> 2; - byte = bmap->bitmap[(sy * sbpr) + (col >> 3)] & masks[si]; - if (byte) { - /* - * Shift the byte down to make an index. - */ - if (si == 0) - byte >>= 4; - - /* - * Scale the index to two bits per pixel and shift it into - * place if necessary. - */ - byte >>= 2; - - si = ((sx << 1) & 7) >> 1; - if (si < 3) - byte <<= (3 - si) << 1; - - nbmap[(sy * bpr) + ((sx << 1) >> 3)] |= byte; - } - } - } - free((char *) bmap->bitmap); - bmap->bpp = 2; - bmap->bytes = bytes; - bmap->bitmap = nbmap; -} - -/* - * Add a bitmap to a grid as a selection. - */ -void -#ifdef __STDC__ -bdf_add_selection(bdf_glyph_grid_t *grid, bdf_bitmap_t *sel) -#else -bdf_add_selection(grid, sel) -bdf_glyph_grid_t *grid; -bdf_bitmap_t *sel; -#endif -{ - unsigned short bytes, bpr; - - if (grid == 0 || sel == 0 || sel->width == 0 || sel->height == 0 || - sel->bytes == 0) - return; - - if (sel->bpp != grid->bpp) { - /* - * Dither the incoming bitmap to match the same bits per pixel as the - * grid it is being added to. - */ - if (sel->bpp == 1) - _bdf_one_to_n(sel, grid->bpp); - else if (grid->bpp == 1) - _bdf_n_to_one(sel); - else if (sel->bpp == 2) - _bdf_two_to_four(sel); - else - _bdf_four_to_two(sel); - } - - /* - * If the bitmap is too big then trim the right and/or the bottom to fit - * in the grid. - */ - if (sel->width > grid->grid_width) - sel->width = grid->grid_width; - if (sel->height > grid->grid_height) - sel->height = grid->grid_height; - - /* - * If the positioning puts the selection bitmap off one of the edges, - * adjust it so it is completely on the grid. - */ - if (sel->x + sel->width > grid->grid_width) - sel->x -= (sel->x + sel->width) - grid->grid_width; - if (sel->y + sel->height > grid->grid_height) - sel->y -= (sel->y + sel->height) - grid->grid_height; - - bpr = ((sel->width * grid->bpp) + 7) >> 3; - bytes = (bpr * sel->height) << 1; - - /* - * Resize the storage for the selection bitmap if necessary. - */ - if (bytes > grid->sel.bytes) { - if (grid->sel.bytes == 0) - grid->sel.bitmap = (unsigned char *) malloc(bytes); - else - grid->sel.bitmap = (unsigned char *) - realloc((char *) grid->sel.bitmap, bytes); - grid->sel.bytes = bytes; - } - - /* - * Copy the width and height values. - */ - grid->sel.x = sel->x; - grid->sel.y = sel->y; - grid->sel.width = sel->width; - grid->sel.height = sel->height; - - /* - * Copy the incoming bitmap to the new selection bitmap. - */ - (void) memcpy((char *) grid->sel.bitmap, (char *) sel->bitmap, - bytes >> 1); - - /* - * Crop the image to adjust the glyph bounding box. - */ - (void) bdf_grid_crop(grid, 1); -} - -int -#ifdef __STDC__ -bdf_grid_color_at(bdf_glyph_grid_t *grid, short x, short y) -#else -bdf_grid_color_at(grid, x, y) -bdf_glyph_grid_t *grid; -short x, y; -#endif -{ - unsigned short bpr, si, di, byte; - unsigned char *masks; - - if (grid->bpp == 1) - return -1; - - masks = twobpp; - di = 0; - switch (grid->bpp) { - case 2: - di = 3; - break; - case 4: - di = 1; - break; - } - - x *= grid->bpp; - - bpr = ((grid->grid_width * grid->bpp) + 7) >> 3; - si = (x & 7) / grid->bpp; - - byte = grid->bitmap[(y * bpr) + (x >> 3)] & masks[si]; - if (di > si) - byte >>= (di - si) * grid->bpp; - return (int) byte; -} |