| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <assert.h>
- #include "bdf_glyph.h"
- bg_t *bg_Open(void)
- {
- bg_t *bg;
-
- bg = (bg_t *)malloc(sizeof(bg_t));
- if ( bg != NULL )
- {
- bg->encoding = 0;
- bg->map_to = -1;
- bg->bitmap_data = NULL;
- bg->target_data = NULL;
- bg->target_max = 0;
- bg->target_cnt = 0;
- bg->shift_x = 0;
- bg->is_excluded_from_kerning = 0;
-
- return bg;
- }
- return NULL;
- }
- void bg_Close(bg_t *bg)
- {
- if ( bg->bitmap_data != NULL )
- free(bg->bitmap_data);
- if ( bg->target_data != NULL )
- free(bg->target_data);
- bg->bitmap_data = NULL;
- bg->target_data =NULL;
- bg->target_max = 0;
- bg->target_cnt = 0;
- bg->target_bit_pos = 0;
- bg->encoding = 0;
- free(bg);
- }
- static int bg_extend_target_data(bg_t *bg)
- {
- int extend = 16;
- int i;
- void *ptr;
- if ( bg->target_data == NULL )
- {
- ptr = malloc(extend*sizeof(uint8_t));
- bg->target_max = 0;
- }
- else
- {
- ptr = realloc(bg->target_data, (bg->target_max + extend)*sizeof(uint8_t));
- }
- if ( ptr == NULL )
- return 0;
- bg->target_data = (uint8_t *)ptr;
- for( i = bg->target_max; i < bg->target_max + extend; i++ )
- bg->target_data[i] = 0;
- bg->target_max += extend;
- return 1;
- }
- int bg_AddTargetData(bg_t *bg, uint8_t data)
- {
- while( bg->target_max <= bg->target_cnt )
- if ( bg_extend_target_data(bg) == 0 )
- return -1;
- bg->target_data[bg->target_cnt] = data;
- bg->target_cnt++;
- return bg->target_cnt-1;
- }
- void bg_ClearTargetData(bg_t *bg)
- {
- int i;
- for( i = 0; i < bg->target_max; i++ )
- bg->target_data[i] = 0;
- bg->target_cnt = 0;
- bg->target_bit_pos = 0;
- }
- /*
- Desc:
- Output a field to the target bitstream. The field size in bits is given by "cnt" and
- the value of the field is "val".
- Args:
- cnt: Fieldsize in bits, must be lower or equal to 8
- val: The value (content) of the field. Side condition: val < (1<<cnt) && val >= 0
- */
- int bg_AddTargetBits(bg_t *bg, unsigned cnt, unsigned val)
- {
-
- assert( val < (1<<cnt) );
-
- while( bg->target_max <= bg->target_cnt+1 )
- if ( bg_extend_target_data(bg) == 0 )
- return 0;
-
- bg->target_data[bg->target_cnt] |= (val << bg->target_bit_pos);
-
- if ( bg->target_bit_pos+cnt >= 8 )
- {
- bg->target_cnt++;
-
- val >>= 8-bg->target_bit_pos;
- bg->target_data[bg->target_cnt] = val;
-
- bg->target_bit_pos+=cnt;
- bg->target_bit_pos-=8;
- }
- else
- {
- bg->target_bit_pos+=cnt;
- }
-
- return 1;
- }
- int bg_FlushTargetBits(bg_t *bg)
- {
- while( bg->target_bit_pos != 0 )
- if ( bg_AddTargetBits(bg, 1, 0) == 0 )
- return 0;
- return 1;
- }
- int bg_SetBitmapSizeInBytes(bg_t *bg, size_t bytes)
- {
- if ( bg->bitmap_data != NULL )
- free(bg->bitmap_data);
- bg->bitmap_data = (uint8_t *)malloc(bytes);
- if ( bg->bitmap_data == NULL )
- return 0;
- memset(bg->bitmap_data, 0, bytes);
- return 1;
- }
- int bg_SetBitmapSize(bg_t *bg, int w, int h)
- {
- return bg_SetBitmapSizeInBytes(bg, w*h);
- }
- void bg_SetBitmapPixel(bg_t *bg, int x, int y, int value)
- {
- static long last_encoding = 0xffffffff;
- static long biggest_x = -1;
-
- if ( x >= bg->bitmap_width || y >= bg->bitmap_height )
- {
- if ( last_encoding != bg->encoding )
- {
- biggest_x = x;
- printf("Glyph size problem: ");
- printf("encoding=%ld/0x%lx, ", bg->encoding, bg->encoding);
- printf("width=%d, height=%d, ", bg->bitmap_width, bg->bitmap_height);
- printf("requested position x=%d, y=%d (use BBX %d ...?)\n", x, y, x+1);
- last_encoding = bg->encoding;
- }
- else if ( biggest_x < x )
- {
- biggest_x = x;
- printf("Glyph size problem: ");
- printf("encoding=%ld/0x%lx, ", bg->encoding, bg->encoding);
- printf("width=%d, height=%d, ", bg->bitmap_width, bg->bitmap_height);
- printf("requested position x=%d, y=%d (use BBX %d ...?)\n", x, y, x+1);
- }
- }
-
- assert( x < ((bg->bitmap_width+7)/8)*8 );
- assert( y < bg->bitmap_height );
- assert( x >= 0 );
- assert( y >= 0 );
- bg->bitmap_data[y*bg->bitmap_width + x] = value;
- }
- int bg_GetBitmapPixel(bg_t *bg, int x, int y)
- {
- if ( x >= bg->bitmap_width )
- return 0;
-
- if ( y >= bg->bitmap_height )
- return 0;
- if ( x < 0 )
- return 0;
- if ( y < 0 )
- return 0;
-
- return bg->bitmap_data[y*bg->bitmap_width + x];
- }
- /*
- Return a pixel with the provided bbx
- Coordinates are within the bbx.
- */
- int bg_GetBBXPixel(bg_t *bg, int x, int y)
- {
- /* glyph rectangle */
- long glyph_x0, glyph_x1, glyph_y0, glyph_y1;
-
- /* local bitmap coordinates */
- long bitmap_x, bitmap_y;
-
- /* perform x offset alignment (used in BDF_BBX_MODE_HEIGHT mode only)*/
- x += bg->shift_x;
-
- /* calculate the rectangle for the glyph */
- glyph_x0 = bg->bbx.x;
- glyph_y0 = bg->bbx.y;
- glyph_x1 = bg->bbx.x+bg->bbx.w;
- glyph_y1 = bg->bbx.y+bg->bbx.h;
- if ( x < glyph_x0 )
- return 0;
- if ( x >= glyph_x1 )
- return 0;
-
- if ( y < glyph_y0 )
- return 0;
- if ( y >= glyph_y1 )
- return 0;
-
- bitmap_x = x - glyph_x0;
- bitmap_y = bg->bbx.h - 1 - ( y - glyph_y0);
-
- return bg_GetBitmapPixel( bg, bitmap_x, bitmap_y );
-
- }
- void bg_ShowBitmap(bg_t *bg, bbx_t *bbx)
- {
- int x, y;
-
- if ( bbx == NULL )
- bbx = &(bg->bbx);
-
- printf("Encoding %ld, mapped to %ld, w=%ld, h=%ld, x=%ld, y=%ld\n", bg->encoding, bg->map_to, bg->bbx.w, bg->bbx.h, bg->bbx.x, bg->bbx.y);
- for( y = bbx->y+bbx->h-1; y >= bbx->y; y--)
- {
- printf("%03d ", y);
- for( x = bbx->x; x < bbx->x + bbx->w; x++)
- {
- if ( bg_GetBBXPixel(bg, x, y) == 0 )
- {
- printf(" .");
- }
- else
- {
- printf(" #");
- }
- }
-
- printf("\n");
- }
- }
- int bg_IsColZero(bg_t *bg, int x)
- {
- int y;
- for( y = 0; y < bg->bitmap_height; y++ )
- {
- if ( bg_GetBitmapPixel(bg, x, y) != 0 )
- return 0;
- }
- return 1;
- }
- int bg_IsRowZero(bg_t *bg, int y)
- {
- int x;
- for( x = 0; x < bg->bitmap_width; x++ )
- {
- if ( bg_GetBitmapPixel(bg, x, y) != 0 )
- return 0;
- }
- return 1;
- }
- void bg_DeleteFirstCol(bg_t *bg)
- {
- int x,y;
- for( y = 0; y < bg->bitmap_height; y++ )
- for( x = 0; x+1 < bg->bitmap_width; x++ )
- {
- bg_SetBitmapPixel(bg, x, y, bg_GetBitmapPixel(bg, x+1, y));
- }
- }
- void bg_DeleteFirstRow(bg_t *bg)
- {
- int x,y;
- for( y = 0; y+1 < bg->bitmap_height; y++ )
- for( x = 0; x < bg->bitmap_width; x++ )
- {
- bg_SetBitmapPixel(bg, x, y, bg_GetBitmapPixel(bg, x, y+1));
- }
- }
- void bg_ReduceGlyph(bg_t *bg)
- {
- //long w;
- /* assign bitmap dimension (should be done already) */
-
- //bg->bbx.w = bg->bitmap_width;
- //bg->bbx.h = bg->bitmap_height;
-
- /* do not assign x,y because they are already set correctly */
-
- //w = bg->bbx.w;
-
- while( bg->bbx.w > 0 )
- {
- if ( bg_IsColZero(bg, bg->bbx.w-1) == 0 )
- break;
- bg->bbx.w--;
- }
- while( bg->bbx.h > 0 )
- {
- if ( bg_IsRowZero(bg, bg->bbx.h-1) == 0 )
- break;
- bg->bbx.y++;
- bg->bbx.h--;
- }
-
- while( bg->bbx.w > 0)
- {
- if ( bg_IsColZero(bg, 0) == 0 )
- break;
- bg_DeleteFirstCol(bg);
- bg->bbx.x++;
- bg->bbx.w--;
- }
-
- while( bg->bbx.h > 0 )
- {
- if ( bg_IsRowZero(bg, 0) == 0 )
- break;
- bg_DeleteFirstRow(bg);
- bg->bbx.h--;
- }
-
- /*
- problem: pixel width calculation failes, because a blank at
- the end is not calculated correctly.
- analysis:
- - bbx.w is reduced to 0
- - original bbx.w is sometimes identical to dwidth_x (6x10.bdf)
- or is 1 (helvR10.bdf)
- -the bdf file for helvR10.bdf does not contain any other information then
- delta x, so this should be used as bbx.w
- solution:
- Nothing done on the converter side, but handle this as a special case in the
- pixel width calculation
-
- */
- //if ( bg->bbx.w == 0 && bg->bbx.h == 0 )
- //{
- //printf("enc=%ld, new bbx,w=%ld, original width=%ld, dx=%ld\n", bg->encoding, bg->bbx.w, w, bg->dwidth_x);
- //printf("enc=%ld, new bbx.w=%ld, original width=%ld, dx=%ld\n", bg->encoding, bg->bbx.w, w, bg->dwidth_x);
- //}
-
- }
- /*
- maximize the provided bbx so that the bbxof the glyph completly is covered by the max bbx
- */
- int bg_Max(bg_t *bg, bbx_t *max)
- {
- int r = 0;
-
- /* glyph rectangle */
- long glyph_x0, glyph_x1, glyph_y0, glyph_y1;
-
- /* max rectangle */
- long max_x0, max_x1, max_y0, max_y1;
- // printf("Encoding %ld, mapped to %ld, w=%ld, h=%ld, x=%ld, y=%ld\n", bg->encoding, bg->map_to, bg->bbx.w, bg->bbx.h, bg->bbx.x, bg->bbx.y);
-
- /* calculate the rectangle for the glyph */
- glyph_x0 = bg->bbx.x;
- glyph_y0 = bg->bbx.y;
- glyph_x1 = bg->bbx.x+bg->bbx.w;
- glyph_y1 = bg->bbx.y+bg->bbx.h;
- /* calculate the rectangle for the max bbx */
- max_x0 = max->x;
- max_y0 = max->y;
- max_x1 = max->x+max->w;
- max_y1 = max->y+max->h;
- /* maximize the max rectrangle so that the glyph rectangle full fits inside */
- if ( max_x0 > glyph_x0 )
- {
- max_x0 = glyph_x0;
- r = 3;
- }
- /* 28 Mar dwidth_x and x0???? */
- if ( max_x0 > bg->dwidth_x ) /* include dwidth_x into the box */
- {
- max_x0 = bg->dwidth_x; /* is this correct??? */
- r = 3;
- }
-
-
- if ( max_x1 < glyph_x1 )
- {
- r = 1;
- max_x1 = glyph_x1;
- }
-
- if ( max_y0 > glyph_y0 )
- {
- r = 4;
- max_y0 = glyph_y0;
- }
- if ( max_y1 < glyph_y1 )
- {
- r = 2;
- max_y1 = glyph_y1;
- }
-
- /* reconstruct the max bbx from the max rectangle */
- max->x = max_x0;
- max->y = max_y0;
- max->w = max_x1 - max->x;
- max->h = max_y1 - max->y;
- return r;
- }
|