/* * Modified Alfont 2.0.9 * * The original AllegroFont v2.0.9 has a few problems. * This modification solves them. * * Modification by: Alexandre Martins (thanks to http://allegro.cc forums) * Modification date: 2010-10-30 * * Original Alfont website: http://chernsha.sitesled.com/ * AllegroFont (c) 2001, 2002 Javier Gonzalez * Enhanced by Chernsha since 2004 year */ #if defined(__GNUC__) && !defined(__MINGW32__) #define _msize malloc_usable_size #endif /* AllegroFont - a wrapper for FreeType 2 */ /* to render TTF and other font formats with Allegro */ /* FreeType 2 is copyright (c) 1996-2000 */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* AllegroFont is copyright (c) 2001, 2002 Javier Gonz lez */ /* Enhanced by Chernsha since 2004 year */ /* See FTL.txt (FreeType License) for license */ // todo (char map null check) #include #include #include #include #include #ifdef ALFONT_DOS //run in DOS #include #else //run in Other #include #endif #ifdef ALFONT_LINUX //run in LINUX #include #endif #include FT_FREETYPE_H #include FT_GLYPH_H /* structs */ struct ALFONT_FONT { FT_Face face; /* face */ int face_h; /* face height */ int real_face_h; /* real face height */ int face_ascender; /* face ascender */ char *data; /* if loaded from memory, the data chunk */ int data_size; /* and its size */ int ch_spacing; /* extra spacing */ int num_fixed_sizes; /* -1 if scalable, >=0 if fixed */ struct _ALFONT_CACHED_GLYPH { char is_cached; int width, height, aawidth, aaheight; int left, top, aaleft, aatop; int advancex, advancey; int mono_available, aa_available; unsigned char *bmp; unsigned char *aabmp; } *cached_glyphs; /* array to know which glyphs have been cached */ int *fixed_sizes; /* array with the fixed sizes */ char *language; /* language */ int type; /* Code Convert(Please Use TYPE_WIDECHAR for ASCII to UNICODE) */ int outline_top; /* Font top outline width */ int outline_bottom; /* Font bottom outline width */ int outline_right; /* Font right outline width */ int outline_left; /* Font left outline width */ int outline_color; /* Font outline color */ int outline_hollow; /* Font hollow(TRUE/FALSE) */ int style; /* Font Style(STYLE_STANDARD/STYLE_ITALIC/STYLE_BOLD/STYLE_BOLDITALIC) */ int underline; /* Font underline(TRUE/FALSE) */ int underline_right; /* Extend right underline(TRUE/FALSE) */ int underline_left; /* Extend left underline(TRUE/FALSE) */ int background; /* Font Background Color(TRUE/FALSE) */ int transparency; /* Font transparency(0-255) */ int autofix; /* Font autofix(TRUE/FALSE) */ int precedingchar; /* preceding character for autofix*/ int fixed_width; /* Font fixed width(TRUE/FALSE) */ }; /* global vars */ BITMAP *default_bmp; //Draw Font on default BITMAP; static FT_Library ft_library; static int alfont_textmode = 0; static int alfont_inited = 0; /* helpers */ static void _alfont_reget_fixed_sizes(ALFONT_FONT *f) { if (f->num_fixed_sizes < 0) { /* scalable font */ f->fixed_sizes[0] = -1; } else { /* fixed */ int i; for (i = 0; i < f->num_fixed_sizes; i++) { f->fixed_sizes[i] = f->face->available_sizes[i].height; } /* set last one to -1 */ f->fixed_sizes[f->num_fixed_sizes] = -1; } } static void _alfont_uncache_glyphs(ALFONT_FONT *f) { if (f->cached_glyphs) { int i; for (i = 0; i < f->face->num_glyphs; i++) { if (f->cached_glyphs[i].is_cached) { f->cached_glyphs[i].is_cached = 0; if (f->cached_glyphs[i].bmp) { free(f->cached_glyphs[i].bmp); f->cached_glyphs[i].bmp = NULL; } if (f->cached_glyphs[i].aabmp) { free(f->cached_glyphs[i].aabmp); f->cached_glyphs[i].aabmp = NULL; } } } } } static void _alfont_uncache_glyph_number(ALFONT_FONT *f, int glyph_number) { if (f->cached_glyphs) { if (f->cached_glyphs[glyph_number].is_cached) { f->cached_glyphs[glyph_number].is_cached = 0; if (f->cached_glyphs[glyph_number].bmp) { free(f->cached_glyphs[glyph_number].bmp); f->cached_glyphs[glyph_number].bmp = NULL; } if (f->cached_glyphs[glyph_number].aabmp) { free(f->cached_glyphs[glyph_number].aabmp); f->cached_glyphs[glyph_number].aabmp = NULL; } } } } static void _alfont_delete_glyphs(ALFONT_FONT *f) { _alfont_uncache_glyphs(f); if (f->cached_glyphs) { free(f->cached_glyphs); f->cached_glyphs = NULL; } } static void _alfont_cache_glyph(ALFONT_FONT *f, int glyph_number) { /* if glyph not cached yet */ if (!f->cached_glyphs[glyph_number].is_cached) { FT_Glyph new_glyph; /* load the font glyph */ FT_Load_Glyph(f->face, glyph_number, FT_LOAD_DEFAULT); FT_Get_Glyph(f->face->glyph, &new_glyph); /* ok, this glyph is now cached */ f->cached_glyphs[glyph_number].is_cached = 1; f->cached_glyphs[glyph_number].mono_available = 0; f->cached_glyphs[glyph_number].aa_available = 0; /* render the mono bmp */ { FT_Bitmap *ft_bmp; FT_Glyph glyph; FT_BitmapGlyph bmp_glyph; FT_Glyph_Copy(new_glyph, &glyph); /* only render glyph if it is not already a bitmap */ if (glyph->format != ft_glyph_format_bitmap) FT_Glyph_To_Bitmap(&glyph, ft_render_mode_mono, NULL, 1); /* the FT rendered bitmap */ bmp_glyph = (FT_BitmapGlyph)glyph; ft_bmp = &bmp_glyph->bitmap; /* save only if the bitmap is really 1 bit */ if (ft_bmp->pixel_mode == ft_pixel_mode_mono) { int memsize; f->cached_glyphs[glyph_number].mono_available = 1; /* set width, height, left, top */ f->cached_glyphs[glyph_number].width = ft_bmp->width; f->cached_glyphs[glyph_number].height = ft_bmp->rows; f->cached_glyphs[glyph_number].left = bmp_glyph->left; f->cached_glyphs[glyph_number].top = bmp_glyph->top; /* allocate bitmap */ memsize = ft_bmp->width * ft_bmp->rows * sizeof(unsigned char); if (memsize > 0) f->cached_glyphs[glyph_number].bmp = malloc(memsize); else f->cached_glyphs[glyph_number].bmp = NULL; /* monochrome drawing */ if (memsize > 0) { unsigned char *outbmp_p = f->cached_glyphs[glyph_number].bmp; unsigned char *bmp_p; int bmp_x, bmp_y, bit; /* copy the FT character bitmap to ours */ bmp_p = ft_bmp->buffer; for (bmp_y = 0; bmp_y < ft_bmp->rows; bmp_y++) { unsigned char *next_bmp_p; next_bmp_p = bmp_p + ft_bmp->pitch; bit = 7; for (bmp_x = 0; bmp_x < ft_bmp->width; bmp_x++) { *outbmp_p = *bmp_p & (1 << bit); outbmp_p++; if (bit == 0) { bit = 7; bmp_p++; } else bit--; } bmp_p = next_bmp_p; } } } FT_Done_Glyph(glyph); } /* render the aa bmp */ { FT_Bitmap *ft_bmp; FT_Glyph glyph; FT_BitmapGlyph bmp_glyph; FT_Glyph_Copy(new_glyph, &glyph); /* only render glyph if it is not already a bitmap */ if (glyph->format != ft_glyph_format_bitmap) FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, NULL, 1); /* the FT rendered bitmap */ bmp_glyph = (FT_BitmapGlyph)glyph; ft_bmp = &bmp_glyph->bitmap; /* save only if the bitmap is really 8 bit */ if (ft_bmp->pixel_mode == ft_pixel_mode_grays) { int memsize; f->cached_glyphs[glyph_number].aa_available = 1; /* set width, height, left, top */ f->cached_glyphs[glyph_number].aawidth = ft_bmp->width; f->cached_glyphs[glyph_number].aaheight = ft_bmp->rows; f->cached_glyphs[glyph_number].aaleft = bmp_glyph->left; f->cached_glyphs[glyph_number].aatop = bmp_glyph->top; /* allocate bitmap */ memsize = ft_bmp->width * ft_bmp->rows * sizeof(unsigned char); if (memsize > 0) f->cached_glyphs[glyph_number].aabmp = malloc(memsize); else f->cached_glyphs[glyph_number].aabmp = NULL; /* aa drawing */ if (memsize > 0) { unsigned char *outbmp_p = f->cached_glyphs[glyph_number].aabmp; unsigned char *bmp_p; int bmp_y; unsigned char mul = 256 / ft_bmp->num_grays; /* we set it to 0 because it is faster to test for false */ if (mul == 1) mul = 0; /* copy the FT character bitmap to ours */ bmp_p = ft_bmp->buffer; for (bmp_y = 0; bmp_y < ft_bmp->rows; bmp_y++) { unsigned char *next_bmp_p; next_bmp_p = bmp_p + ft_bmp->pitch; memcpy(outbmp_p, bmp_p, ft_bmp->width * sizeof(unsigned char)); /* we have to change our pixels if the numgrays is not 256 */ if (mul) { unsigned char *p = outbmp_p; unsigned char *p_end = p + ft_bmp->width; for (; p < p_end; p++) *p *= mul; } outbmp_p += ft_bmp->width; bmp_p = next_bmp_p; } } } FT_Done_Glyph(glyph); } f->cached_glyphs[glyph_number].advancex = f->face->glyph->advance.x >> 6; f->cached_glyphs[glyph_number].advancey = f->face->glyph->advance.y >> 6; /* delete the glyph */ FT_Done_Glyph(new_glyph); } } static void _alfont_new_cache_glyph(ALFONT_FONT *f) { int i; if (!f->cached_glyphs) f->cached_glyphs = malloc(f->face->num_glyphs * sizeof(struct _ALFONT_CACHED_GLYPH)); for (i = 0; i < f->face->num_glyphs; i++) { f->cached_glyphs[i].is_cached = 0; f->cached_glyphs[i].bmp = NULL; f->cached_glyphs[i].aabmp = NULL; } } /* API */ int alfont_set_font_size(ALFONT_FONT *f, int h) { int error, test_h, direction; /* check the font doesn't already use that w and h */ if (h == f->face_h) return ALFONT_OK; else if (h <= 0) return ALFONT_ERROR; /* keep changing the size until the real size is not the one */ /* we want */ test_h = h; direction = 0; while (1) { int real_height; error = FT_Set_Pixel_Sizes(f->face, 0, test_h); if (error) break; /* compare real height with asked height */ real_height = abs(f->face->size->metrics.ascender >> 6) + abs(f->face->size->metrics.descender >> 6); if (real_height == h) { /* we found the wanted height */ break; } /* check the direction */ if (direction == 0) { /* direction still not set */ if (real_height > h) direction = -1; else direction = 1; } /* check we didn't overpass it */ else if ((direction > 0) && (real_height > h)) { /* decrease one and found */ test_h--; FT_Set_Pixel_Sizes(f->face, 0, test_h); break; } /* check we didn't surpass it */ else if ((direction < 0) && (real_height < h)) { break; } test_h += direction; /* check we arent at 0 */ if (test_h <= 0) { error = TRUE; break; } } if (!error) { _alfont_uncache_glyphs(f); f->face_h = h; f->real_face_h = test_h; f->face_ascender = f->face->size->metrics.ascender >> 6; return ALFONT_OK; } else { FT_Set_Pixel_Sizes(f->face, 0, f->real_face_h); return ALFONT_ERROR; } } int alfont_get_font_height(ALFONT_FONT *f) { return f->face_h; } void alfont_exit(void) { if (alfont_inited) { alfont_inited = 0; FT_Done_FreeType(ft_library); memset(&ft_library, 0, sizeof(ft_library)); } } int alfont_init(void) { if (alfont_inited) return 0; else { int error; memset(&ft_library, 0, sizeof(ft_library)); error = FT_Init_FreeType(&ft_library); if (!error) alfont_inited = 1; return error; } } ALFONT_FONT *alfont_load_font(const char *filepathname) { int error; /* try to allocate the memory */ ALFONT_FONT *font = malloc(sizeof(ALFONT_FONT)); if (font == NULL) return NULL; /* clear the struct */ memset(font, 0, sizeof(ALFONT_FONT)); font->cached_glyphs = NULL; /* we are loading from file, no mem buffer needed */ font->data = NULL; font->data_size = 0; /* load the font */ error = FT_New_Face(ft_library, filepathname, 0, &font->face); if (error) { free(font); return NULL; } /* get if the font contains only fixed sizes */ if (!(font->face->face_flags & FT_FACE_FLAG_SCALABLE)) font->num_fixed_sizes = font->face->num_fixed_sizes; else font->num_fixed_sizes = -1; _alfont_new_cache_glyph(font); if (font->num_fixed_sizes < 0) { font->fixed_sizes = malloc(sizeof(int)); _alfont_reget_fixed_sizes(font); alfont_set_font_size(font, 8); } else { font->fixed_sizes = malloc(sizeof(int) * (font->num_fixed_sizes + 1)); _alfont_reget_fixed_sizes(font); /* set as current size the first found fixed size */ alfont_set_font_size(font, font->fixed_sizes[0]); } alfont_set_char_extra_spacing(font, 0); //Initial Font attribute font->language=NULL; /* Initial Language */ font->type=0; /* Initial Code Convert */ font->outline_top=0; /* Initial Font top outline width */ font->outline_bottom=0; /* Initial Font bottom outline width */ font->outline_left=0; /* Initial Font left outline width */ font->outline_right=0; /* Initial Font right outline width */ font->outline_color=0; /* Initial Font outline color */ font->outline_hollow=FALSE; /* Initial Font hollow(TRUE/FALSE) */ font->style=0; /* Initial Font Style */ font->underline=FALSE; /* Initial Font underline(TRUE/FALSE) */ font->underline_right=FALSE; /* Initial Extend right underline(TRUE/FALSE) */ font->underline_left=FALSE; /* Initial Extend left underline(TRUE/FALSE) */ font->background=FALSE; /* Initial Font Background Color(TRUE/FALSE) */ font->transparency=255; /* Initial Font transparency(0-255) */ font->autofix=FALSE; /* Initial Font autofix(TRUE/FALSE) */ font->precedingchar=0; /* Initial preceding character */ return font; } ALFONT_FONT *alfont_load_font_from_mem(const char *data, int data_len) { int error; char *new_data; /* try to allocate the memory */ ALFONT_FONT *font = malloc(sizeof(ALFONT_FONT)); new_data = malloc(data_len); if ((font == NULL) || (new_data == NULL)) { if (font) free(font); if (new_data) free(new_data); return NULL; } /* clear the struct */ memset(font, 0, sizeof(ALFONT_FONT)); font->cached_glyphs = NULL; /* copy user data to internal buffer */ font->data = new_data; font->data_size = data_len; memcpy((void *)font->data, (void *)data, data_len); /* load the font */ error = FT_New_Memory_Face(ft_library, font->data, font->data_size, 0, &font->face); if (error) { free(font->data); free(font); return NULL; } /* get if the font contains only fixed sizes */ if (!(font->face->face_flags & FT_FACE_FLAG_SCALABLE)) font->num_fixed_sizes = font->face->num_fixed_sizes; else font->num_fixed_sizes = -1; _alfont_new_cache_glyph(font); if (font->num_fixed_sizes < 0) { font->fixed_sizes = malloc(sizeof(int)); _alfont_reget_fixed_sizes(font); alfont_set_font_size(font, 8); } else { font->fixed_sizes = malloc(sizeof(int) * (font->num_fixed_sizes + 1)); _alfont_reget_fixed_sizes(font); /* set as current size the first found fixed size */ alfont_set_font_size(font, font->fixed_sizes[0]); } alfont_set_char_extra_spacing(font, 0); //Initial Font attribute font->language=NULL; /* Initial Language */ font->type=0; /* Initial Code Convert */ font->outline_top=0; /* Initial Font top outline width */ font->outline_bottom=0; /* Initial Font bottom outline width */ font->outline_left=0; /* Initial Font left outline width */ font->outline_right=0; /* Initial Font right outline width */ font->outline_color=0; /* Initial Font outline color */ font->outline_hollow=FALSE; /* Initial Font hollow(TRUE/FALSE) */ font->style=0; /* Initial Font Style */ font->underline=FALSE; /* Initial Font underline(TRUE/FALSE) */ font->underline_right=FALSE; /* Initial Extend right underline(TRUE/FALSE) */ font->underline_left=FALSE; /* Initial Extend left underline(TRUE/FALSE) */ font->background=FALSE; /* Initial Font Background Color(TRUE/FALSE) */ font->transparency=255; /* Initial Font transparency(0-255) */ font->autofix=FALSE; /* Initial Font autofix(TRUE/FALSE) */ font->precedingchar=0; /* Initial preceding character */ return font; } int alfont_text_mode(int mode) { int old_mode = alfont_textmode; alfont_textmode = mode; return old_mode; } void alfont_destroy_font(ALFONT_FONT *f) { if (f == NULL) return; /* delete old glyphs */ _alfont_delete_glyphs(f); /* delete the face */ FT_Done_Face(f->face); if (f->fixed_sizes) free(f->fixed_sizes); /* deallocate the data */ if (f->data) free(f->data); /* deallocate the language string*/ if (f->language) free(f->language); free(f); } void alfont_textout_aa(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color) { alfont_textout_aa_ex(bmp, f, s, x, y, color, alfont_textmode); } void alfont_textout_aa_ex(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color, int backg) { char *lpszW; char *lpszW_tmp; int x_tmp; int max_advancex; char *lpszW_pointer=NULL; //used for freeing string char *s_pointer=NULL; //used for original string fixed by autofix char *s_pointer_temp=NULL; //temporary used for autofix string char *precedingchar_pointer=NULL; //used for precedingchar character int nLen; int ret; //decide that if the ASCII Code convert to Unicode Code is all OK when used for autofix string or used for general convert. int character; int alpha_table[256]; int last_glyph_index; int first_x=0, final_x=0, final_y=0; int curr_uformat; int first_flag=TRUE; //First Char flag BITMAP *masked_bmp; //the masked bmp used by Font hollow #ifdef ALFONT_DOS iconv_t c_pt; size_t fromlen, tolen; char *sin, *sout; #endif if (s == NULL) { return; } nLen = strlen(s) + 1; s_pointer = (char *)malloc(nLen*sizeof(char)); memset(s_pointer, 0, nLen); strcpy(s_pointer, s); //Auto Fix for cutted string //For ASCII convert to unicode //Add the previous character to the s string //If find the cutted character, store it from the converted s string and remove it from the original s string if (f->autofix==TRUE) { if (f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) != (iconv_t)-1) { fromlen = strlen(s) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); //add the previous character to the s string if (f->precedingchar != 0) { free(s_pointer); fromlen = strlen(s) + 1 + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); s_pointer = (char *)malloc(tolen*sizeof(char)); memset(s_pointer, 0, tolen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(s_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(s_pointer, s); f->precedingchar = 0; } iconv(c_pt, NULL, NULL, NULL, NULL); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = s; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); s_pointer_temp = s_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*s_pointer_temp != '\0') { f->precedingchar = *s_pointer_temp; s_pointer_temp++; } //remove the final character s_pointer_temp--; *s_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } } #else #ifdef ALFONT_LINUX nLen = strlen(s_pointer) * 5 + 1; #else nLen = strlen(s_pointer) + 1; #endif //add the previous character to the s string if (f->precedingchar != 0) { free(s_pointer); nLen = strlen(s) + 1 + 1; s_pointer = (char *)malloc(nLen*sizeof(char)); memset(s_pointer, 0, nLen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(s_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(s_pointer, s); f->precedingchar = 0; } setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); ret = mbstowcs((wchar_t *)lpszW, s_pointer, nLen); s_pointer_temp = s_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*s_pointer_temp != '\0') { f->precedingchar = *s_pointer_temp; s_pointer_temp++; } //remove the final character s_pointer_temp--; *s_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } #endif //recover to original codepage set_uformat(curr_uformat); } } //Font Code Convert if (f->type==1) { #ifdef ALFONT_DOS if ((c_pt = iconv_open(f->language, "UTF-16LE")) == (iconv_t)-1) { lpszW = (char *)s_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(s_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); lpszW_pointer = lpszW; sin = s_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)s_pointer; } } #else setlocale(LC_CTYPE,f->language); nLen= MB_CUR_MAX * wcslen((const wchar_t*)s_pointer) + 1; lpszW = (char *)malloc(nLen*sizeof(char)); memset(lpszW, 0, nLen); lpszW_pointer = lpszW; wcstombs(lpszW, (const wchar_t *)s_pointer, nLen); #endif } else if(f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) == (iconv_t)-1) { lpszW = (char *)s_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(s_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); lpszW_pointer = lpszW; sin = s_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)s_pointer; } else { set_uformat(U_UNICODE); } } #else setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); #ifdef ALFONT_LINUX nLen = strlen(s_pointer) * 5 + 1; #else nLen= strlen(s_pointer) + 1; #endif lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); lpszW_pointer = lpszW; mbstowcs((wchar_t *)lpszW, s_pointer, nLen); #endif } else { #ifdef ALFONT_LINUX set_uformat(U_UTF8); nLen= ustrlen(s_pointer) + 1; #endif lpszW = (char *)s_pointer; } /* is it under or over or too far to the right of the clipping rect then we can assume the string is clipped */ if ((y + f->face_h < bmp->ct) || (y > bmp->cb) || (x > bmp->cr)) return; //build transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); set_trans_blender(0,0,0,f->transparency); } } else { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } /* if we are doing opaque mode, draw a rect and init our table*/ if (backg >= 0) { int i, r, g, b, br, bg, bb, ir, ig, ib; int blendr, blendg, blendb; if(f->background==TRUE) { rectfill(bmp, x, y, x + alfont_text_length(f, s_pointer) - 1, y + f->face_h - 1, backg); } /* get the color rgb */ r = getr(color); g = getg(color); b = getb(color); /* get the background rgb */ br = getr(backg); bg = getg(backg); bb = getb(backg); /* get increments */ ir = (r == br) ? 0 : (r + 1) - br; ig = (g == bg) ? 0 : (g + 1) - bg; ib = (b == bb) ? 0 : (b + 1) - bb; blendr = br << 8; blendg = bg << 8; blendb = bb << 8; /* blend both values and make our alpha table */ for (i = 0; i < 256; i++) { alpha_table[i] = makecol(blendr >> 8, blendg >> 8, blendb >> 8); blendr += ir; blendg += ig; blendb += ib; } } /* draw char by char (using allegro unicode funcs) */ acquire_bitmap(bmp); last_glyph_index = 0; if (f->fixed_width == TRUE) { lpszW_tmp = lpszW; x_tmp = x; max_advancex = 0; _alfont_uncache_glyphs(f); #ifdef ALFONT_LINUX //Fix for Linux Unicode System(be converted) for (character = ugetxc((const char**)&lpszW_tmp); character != 0; character = ugetxc((const char**)&lpszW_tmp),character = ugetxc((const char**)&lpszW_tmp)) { #else for (character = ugetxc((const char**)&lpszW_tmp); character != 0; character = ugetxc((const char**)&lpszW_tmp)) { #endif int glyph_index_tmp; struct _ALFONT_CACHED_GLYPH cglyph_tmp; #ifdef ALFONT_LINUX //Recover for Linux Unicode System Fixed if(f->type!=2) { lpszW_tmp--; } #endif /* if left side of char farther than right side of clipping, we are done */ if (x_tmp > bmp->cr) break; /* get the character out of the font */ if (f->face->charmap) glyph_index_tmp = FT_Get_Char_Index(f->face, character); else glyph_index_tmp = character; /* cache the glyph */ _alfont_cache_glyph(f, glyph_index_tmp); cglyph_tmp = f->cached_glyphs[glyph_index_tmp]; if (max_advancex < f->cached_glyphs[glyph_index_tmp].advancex) max_advancex = f->cached_glyphs[glyph_index_tmp].advancex; /* advance */ if (cglyph_tmp.advancex) x_tmp += cglyph_tmp.advancex + f->ch_spacing; } } #ifdef ALFONT_LINUX //Fix for Linux Unicode System(be converted) for (character = ugetxc((const char**)&lpszW); character != 0; character = ugetxc((const char**)&lpszW),character = ugetxc((const char**)&lpszW)) { #else for (character = ugetxc((const char**)&lpszW); character != 0; character = ugetxc((const char**)&lpszW)) { #endif int real_x, real_y, glyph_index; struct _ALFONT_CACHED_GLYPH cglyph; #ifdef ALFONT_LINUX //Recover for Linux Unicode System Fixed if(f->type!=2) { lpszW--; } #endif /* if left side of char farther than right side of clipping, we are done */ if (x > bmp->cr) break; /* get the character out of the font */ if (f->face->charmap) glyph_index = FT_Get_Char_Index(f->face, character); else glyph_index = character; /* cache the glyph */ _alfont_cache_glyph(f, glyph_index); if (f->fixed_width == TRUE) f->cached_glyphs[glyph_index].advancex = max_advancex; cglyph = f->cached_glyphs[glyph_index]; /* calculate drawing coords */ real_x = x + cglyph.aaleft; real_y = (y - cglyph.aatop) + f->face_ascender; /* apply kerning */ /*if (last_glyph_index) { FT_Vector v; FT_Get_Kerning(f->face, last_glyph_index, glyph_index, ft_kerning_default, &v); real_x += v.x >> 6; real_y += v.y >> 6; }*/ last_glyph_index = glyph_index; /* draw only if exists */ if ((cglyph.aa_available) && (cglyph.aabmp)) { int bmp_x, bmp_y,outline_w; unsigned char *bmp_p = cglyph.aabmp; const int max_bmp_x = cglyph.aawidth + real_x; const int max_bmp_y = cglyph.aaheight + real_y; if (first_flag==TRUE) { first_x= max_bmp_x; } /* if in opaque mode */ if (backg >= 0) { if(f->outline_hollow==TRUE) { //Set masked region //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if (f->style==1) { masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),max_bmp_x+((max_bmp_y-real_y)/2)-real_x, max_bmp_y-real_y); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); } else if(f->style==2) { masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),max_bmp_x+1-real_x, max_bmp_y-real_y); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); } else if(f->style==3) { masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),max_bmp_x+((max_bmp_y-real_y)/2)+1-real_x, max_bmp_y-real_y); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); } else { masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),max_bmp_x-real_x, max_bmp_y-real_y); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); } for (bmp_y = real_y; bmp_y < max_bmp_y; bmp_y++) { for (bmp_x = real_x; bmp_x < max_bmp_x; bmp_x++) { if (*bmp_p++) { if(first_x>bmp_x) first_x=bmp_x; if(final_xstyle==1) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+((max_bmp_y-bmp_y)/2); } if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2))) first_x=bmp_x+((max_bmp_y-bmp_y)/2); } putpixel(masked_bmp, bmp_x+((max_bmp_y-bmp_y)/2)-real_x, bmp_y-real_y, getpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y)); } else if(f->style==2) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+1)) final_x=bmp_x+1; if(final_x<(bmp_x)) final_x=bmp_x; } if(f->underline_left==TRUE) { if(first_x>(bmp_x+1)) first_x=bmp_x+1; if(first_x>(bmp_x)) first_x=bmp_x; } putpixel(masked_bmp, bmp_x+1-real_x, bmp_y-real_y, getpixel(bmp, bmp_x+1, bmp_y)); putpixel(masked_bmp, bmp_x-real_x, bmp_y-real_y, getpixel(bmp, bmp_x, bmp_y)); } else if(f->style==3) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2)+1)) final_x=bmp_x+((max_bmp_y-bmp_y)/2)+1; if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+((max_bmp_y-bmp_y)/2); } if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2)+1)) first_x=bmp_x+((max_bmp_y-bmp_y)/2)+1; if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2))) first_x=bmp_x+((max_bmp_y-bmp_y)/2); } putpixel(masked_bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1-real_x, bmp_y-real_y, getpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1, bmp_y)); putpixel(masked_bmp, bmp_x+((max_bmp_y-bmp_y)/2)-real_x, bmp_y-real_y, getpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y)); } else { putpixel(masked_bmp, bmp_x-real_x, bmp_y-real_y, getpixel(bmp, bmp_x, bmp_y)); } } } } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } bmp_p = cglyph.aabmp; //repointer to Font bmp pointer and draw outline } if ((f->outline_top>0) || (f->outline_bottom>0) || (f->outline_left>0) || (f->outline_right>0)) { for (bmp_y = real_y; bmp_y < max_bmp_y; bmp_y++) { for (bmp_x = real_x; bmp_x < max_bmp_x; bmp_x++) { const int alpha = *bmp_p++; if (alpha) { if (f->outline_right>0) { for (outline_w = 0; outline_w < f->outline_right; outline_w++) { if (bmp_x+(outline_w+1)<=max_bmp_x) { if (f->style==1) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2); } putpixel(bmp, bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2), bmp_y, f->outline_color); } else if(f->style==2) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+(outline_w+1)+1)) final_x=bmp_x+(outline_w+1)+1; } putpixel(bmp, bmp_x+(outline_w+1)+1, bmp_y, f->outline_color); } else if(f->style==3) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2)+1)) final_x=bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2)+1; } putpixel(bmp, bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2)+1, bmp_y, f->outline_color); } else { if(f->underline_right==TRUE) { if(final_x<(bmp_x+(outline_w+1))) final_x=bmp_x+(outline_w+1); } putpixel(bmp, bmp_x+(outline_w+1), bmp_y, f->outline_color); } } } } if (f->outline_bottom>0) { for (outline_w = 0; outline_w < f->outline_bottom; outline_w++) { if (bmp_y+(outline_w+1)<=max_bmp_y) { if (f->style==1) { putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y+(outline_w+1), f->outline_color); } else if(f->style==2) { putpixel(bmp, bmp_x+1, bmp_y+(outline_w+1), f->outline_color); putpixel(bmp, bmp_x, bmp_y+(outline_w+1), f->outline_color); } else if(f->style==3) { putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1, bmp_y+(outline_w+1), f->outline_color); putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y+(outline_w+1), f->outline_color); } else { putpixel(bmp, bmp_x, bmp_y+(outline_w+1), f->outline_color); } } } } if (f->outline_left>0) { for (outline_w = 0; outline_w < f->outline_left; outline_w++) { if (bmp_x-(outline_w+1)>=real_x-1) { if (f->style==1) { if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1))) first_x=bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1); } putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1), bmp_y, f->outline_color); } else if(f->style==2) { if(f->underline_left==TRUE) { if(first_x>(bmp_x-(outline_w+1))) first_x=bmp_x-(outline_w+1); } putpixel(bmp, bmp_x-(outline_w+1), bmp_y, f->outline_color); } else if(f->style==3) { if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1))) first_x=bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1); } putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1), bmp_y, f->outline_color); } else { if(f->underline_left==TRUE) { if(first_x>(bmp_x-(outline_w+1))) first_x=bmp_x-(outline_w+1); } putpixel(bmp, bmp_x-(outline_w+1), bmp_y, f->outline_color); } } } } if (f->outline_top>0) { for (outline_w = 0; outline_w < f->outline_top; outline_w++) { if (bmp_y-(outline_w+1)>=real_y-1) { if (f->style==1) { putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y-(outline_w+1), f->outline_color); } else if(f->style==2) { putpixel(bmp, bmp_x+1, bmp_y-(outline_w+1), f->outline_color); putpixel(bmp, bmp_x, bmp_y-(outline_w+1), f->outline_color); } else if(f->style==3) { putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1, bmp_y-(outline_w+1), f->outline_color); putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y-(outline_w+1), f->outline_color); } else { putpixel(bmp, bmp_x, bmp_y-(outline_w+1), f->outline_color); } } } } } } } } if(f->outline_hollow==FALSE) { //check if it will restore the masked region bmp_p = cglyph.aabmp; //repointer to Font bmp pointer for (bmp_y = real_y; bmp_y < max_bmp_y; bmp_y++) { for (bmp_x = real_x; bmp_x < max_bmp_x; bmp_x++) { const int alpha = *bmp_p++; if (alpha) { if(first_x>bmp_x) first_x=bmp_x; if(final_xstyle==1) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+((max_bmp_y-bmp_y)/2); } if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2))) first_x=bmp_x+((max_bmp_y-bmp_y)/2); } putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y, alpha_table[alpha]); } else if(f->style==2) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+1)) final_x=bmp_x+1; if(final_x<(bmp_x)) final_x=bmp_x; } if(f->underline_left==TRUE) { if(first_x>(bmp_x+1)) first_x=bmp_x+1; if(first_x>(bmp_x)) first_x=bmp_x; } putpixel(bmp, bmp_x+1, bmp_y, alpha_table[alpha]); putpixel(bmp, bmp_x, bmp_y, alpha_table[alpha]); } else if(f->style==3) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2)+1)) final_x=bmp_x+((max_bmp_y-bmp_y)/2)+1; if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+((max_bmp_y-bmp_y)/2); } if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2)+1)) first_x=bmp_x+((max_bmp_y-bmp_y)/2)+1; if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2))) first_x=bmp_x+((max_bmp_y-bmp_y)/2); } putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1, bmp_y, alpha_table[alpha]); putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y, alpha_table[alpha]); } else { putpixel(bmp, bmp_x, bmp_y, alpha_table[alpha]); } } } } } else { //restore original pic //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if (f->style==1) { masked_blit(masked_bmp, bmp, 0, 0, real_x, real_y, max_bmp_x+((max_bmp_y-real_y)/2)-real_x, max_bmp_y-real_y); destroy_bitmap(masked_bmp); } else if(f->style==2) { masked_blit(masked_bmp, bmp, 0, 0, real_x, real_y, max_bmp_x+1-real_x, max_bmp_y-real_y); destroy_bitmap(masked_bmp); } else if(f->style==3) { masked_blit(masked_bmp, bmp, 0, 0, real_x, real_y, max_bmp_x+((max_bmp_y-real_y)/2)+1-real_x, max_bmp_y-real_y); destroy_bitmap(masked_bmp); } else { masked_blit(masked_bmp, bmp, 0, 0, real_x, real_y, max_bmp_x-real_x, max_bmp_y-real_y); destroy_bitmap(masked_bmp); } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } } } /* if in transparent mode */ else { if(f->outline_hollow==TRUE) { //set the masked region //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if (f->style==1) { masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),max_bmp_x+((max_bmp_y-real_y)/2)-real_x, max_bmp_y-real_y); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); } else if(f->style==2) { masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),max_bmp_x+1-real_x, max_bmp_y-real_y); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); } else if(f->style==3) { masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),max_bmp_x+((max_bmp_y-real_y)/2)+1-real_x, max_bmp_y-real_y); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); } else { masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),max_bmp_x-real_x, max_bmp_y-real_y); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); } for (bmp_y = real_y; bmp_y < max_bmp_y; bmp_y++) { for (bmp_x = real_x; bmp_x < max_bmp_x; bmp_x++) { if (*bmp_p++) { if(first_x>bmp_x) first_x=bmp_x; if(final_xstyle==1) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+((max_bmp_y-bmp_y)/2); } if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2))) first_x=bmp_x+((max_bmp_y-bmp_y)/2); } putpixel(masked_bmp, bmp_x+((max_bmp_y-bmp_y)/2)-real_x, bmp_y-real_y, getpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y)); } else if(f->style==2) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+1)) final_x=bmp_x+1; if(final_x<(bmp_x)) final_x=bmp_x; } if(f->underline_left==TRUE) { if(first_x>(bmp_x+1)) first_x=bmp_x+1; if(first_x>(bmp_x)) first_x=bmp_x; } putpixel(masked_bmp, bmp_x+1-real_x, bmp_y-real_y, getpixel(bmp, bmp_x+1, bmp_y)); putpixel(masked_bmp, bmp_x-real_x, bmp_y-real_y, getpixel(bmp, bmp_x, bmp_y)); } else if(f->style==3) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2)+1)) final_x=bmp_x+((max_bmp_y-bmp_y)/2)+1; if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+((max_bmp_y-bmp_y)/2); } if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2)+1)) first_x=bmp_x+((max_bmp_y-bmp_y)/2)+1; if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2))) first_x=bmp_x+((max_bmp_y-bmp_y)/2); } putpixel(masked_bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1-real_x, bmp_y-real_y, getpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1, bmp_y)); putpixel(masked_bmp, bmp_x+((max_bmp_y-bmp_y)/2)-real_x, bmp_y-real_y, getpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y)); } else { putpixel(masked_bmp, bmp_x-real_x, bmp_y-real_y, getpixel(bmp, bmp_x, bmp_y)); } } } } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } bmp_p = cglyph.aabmp; //repointer to Font bmp pointer and draw outline } if ((f->outline_top>0) || (f->outline_bottom>0) || (f->outline_left>0) || (f->outline_right>0)) { for (bmp_y = real_y; bmp_y < max_bmp_y; bmp_y++) { for (bmp_x = real_x; bmp_x < max_bmp_x; bmp_x++) { const int alpha = *bmp_p++; if (alpha) { if (f->outline_right>0) { for (outline_w = 0; outline_w < f->outline_right; outline_w++) { if (bmp_x+(outline_w+1)<=max_bmp_x) { if (f->style==1) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2); } putpixel(bmp, bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2), bmp_y, f->outline_color); } else if(f->style==2) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+(outline_w+1)+1)) final_x=bmp_x+(outline_w+1)+1; } putpixel(bmp, bmp_x+(outline_w+1)+1, bmp_y, f->outline_color); } else if(f->style==3) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2)+1)) final_x=bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2)+1; } putpixel(bmp, bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2)+1, bmp_y, f->outline_color); } else { if(f->underline_right==TRUE) { if(final_x<(bmp_x+(outline_w+1))) final_x=bmp_x+(outline_w+1); } putpixel(bmp, bmp_x+(outline_w+1), bmp_y, f->outline_color); } } } } if (f->outline_bottom>0) { for (outline_w = 0; outline_w < f->outline_bottom; outline_w++) { if (bmp_y+(outline_w+1)<=max_bmp_y) { if (f->style==1) { putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y+(outline_w+1), f->outline_color); } else if(f->style==2) { putpixel(bmp, bmp_x+1, bmp_y+(outline_w+1), f->outline_color); putpixel(bmp, bmp_x, bmp_y+(outline_w+1), f->outline_color); } else if(f->style==3) { putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1, bmp_y+(outline_w+1), f->outline_color); putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y+(outline_w+1), f->outline_color); } else { putpixel(bmp, bmp_x, bmp_y+(outline_w+1), f->outline_color); } } } } if (f->outline_left>0) { for (outline_w = 0; outline_w < f->outline_left; outline_w++) { if (bmp_x-(outline_w+1)>=real_x-1) { if (f->style==1) { if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1))) first_x=bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1); } putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1), bmp_y, f->outline_color); } else if(f->style==2) { if(f->underline_left==TRUE) { if(first_x>(bmp_x-(outline_w+1))) first_x=bmp_x-(outline_w+1); } putpixel(bmp, bmp_x-(outline_w+1), bmp_y, f->outline_color); } else if(f->style==3) { if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1))) first_x=bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1); } putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1), bmp_y, f->outline_color); } else { if(f->underline_left==TRUE) { if(first_x>(bmp_x-(outline_w+1))) first_x=bmp_x-(outline_w+1); } putpixel(bmp, bmp_x-(outline_w+1), bmp_y, f->outline_color); } } } } if (f->outline_top>0) { for (outline_w = 0; outline_w < f->outline_top; outline_w++) { if (bmp_y-(outline_w+1)>=real_y-1) { if (f->style==1) { putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y-(outline_w+1), f->outline_color); } else if(f->style==2) { putpixel(bmp, bmp_x+1, bmp_y-(outline_w+1), f->outline_color); putpixel(bmp, bmp_x, bmp_y-(outline_w+1), f->outline_color); } else if(f->style==3) { putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1, bmp_y-(outline_w+1), f->outline_color); putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y-(outline_w+1), f->outline_color); } else { putpixel(bmp, bmp_x, bmp_y-(outline_w+1), f->outline_color); } } } } } } } } if(f->outline_hollow==FALSE) { //check if it will restore the masked region bmp_p = cglyph.aabmp; //repointer to Font bmp pointer for (bmp_y = real_y; bmp_y < max_bmp_y; bmp_y++) { for (bmp_x = real_x; bmp_x < max_bmp_x; bmp_x++) { const int alpha = *bmp_p++; if (alpha) { if (alpha >= 255) solid_mode(); else { drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0); set_trans_blender(0, 0, 0, alpha); } if(first_x>bmp_x) first_x=bmp_x; if(final_xstyle==1) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+((max_bmp_y-bmp_y)/2); } if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2))) first_x=bmp_x+((max_bmp_y-bmp_y)/2); } putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y, color); } else if(f->style==2) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+1)) final_x=bmp_x+1; if(final_x<(bmp_x)) final_x=bmp_x; } if(f->underline_left==TRUE) { if(first_x>(bmp_x+1)) first_x=bmp_x+1; if(first_x>(bmp_x)) first_x=bmp_x; } putpixel(bmp, bmp_x+1, bmp_y, color); putpixel(bmp, bmp_x, bmp_y, color); } else if(f->style==3) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2)+1)) final_x=bmp_x+((max_bmp_y-bmp_y)/2)+1; if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+((max_bmp_y-bmp_y)/2); } if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2)+1)) first_x=bmp_x+((max_bmp_y-bmp_y)/2)+1; if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2))) first_x=bmp_x+((max_bmp_y-bmp_y)/2); } putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1, bmp_y, color); putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y, color); } else { putpixel(bmp, bmp_x, bmp_y, color); } } } } } else { //restore original pic //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if (f->style==1) { masked_blit(masked_bmp, bmp, 0, 0, real_x, real_y, max_bmp_x+((max_bmp_y-real_y)/2)-real_x, max_bmp_y-real_y); destroy_bitmap(masked_bmp); } else if(f->style==2) { masked_blit(masked_bmp, bmp, 0, 0, real_x, real_y, max_bmp_x+1-real_x, max_bmp_y-real_y); destroy_bitmap(masked_bmp); } else if(f->style==3) { masked_blit(masked_bmp, bmp, 0, 0, real_x, real_y, max_bmp_x+((max_bmp_y-real_y)/2)+1-real_x, max_bmp_y-real_y); destroy_bitmap(masked_bmp); } else { masked_blit(masked_bmp, bmp, 0, 0, real_x, real_y, max_bmp_x-real_x, max_bmp_y-real_y); destroy_bitmap(masked_bmp); } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } } } } /* advance */ if (cglyph.advancex) x += cglyph.advancex + f->ch_spacing; if (cglyph.advancey) y += cglyph.advancey + f->ch_spacing; first_flag=FALSE; //set first char flag is FALSE } //draw underline if ((f->underline)==TRUE) { if ((final_y+((f->real_face_h)>>5))>5) { if(f->outline_hollow==TRUE) { //set the masked region for underline int bmp_x, bmp_y; //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if(f->underline_right==TRUE) { //If the underline_right is TRUE,extend right underline masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),final_x+f->ch_spacing-first_x+1, final_y+((f->real_face_h)>>5)-final_y+1); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); for (bmp_y = final_y; bmp_y <= final_y+((f->real_face_h)>>5); bmp_y++) { for (bmp_x = first_x; bmp_x <= final_x+f->ch_spacing; bmp_x++) { putpixel(masked_bmp, bmp_x-first_x, bmp_y-final_y, getpixel(bmp, bmp_x, bmp_y)); } } } else { //If the underline_right is not TRUE,just draw underline masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),final_x-first_x+1, final_y+((f->real_face_h)>>5)-final_y+1); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); for (bmp_y = final_y; bmp_y <= final_y+((f->real_face_h)>>5); bmp_y++) { for (bmp_x = first_x; bmp_x <= final_x; bmp_x++) { putpixel(masked_bmp, bmp_x-first_x, bmp_y-final_y, getpixel(bmp, bmp_x, bmp_y)); } } } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } } //Draw outline if ((f->outline_top>0) || (f->outline_bottom>0) || (f->outline_left>0) || (f->outline_right>0)) { if(f->outline_top>0) { if(f->underline_right==TRUE) { //If the underline_right is TRUE rectfill(bmp, first_x, final_y-1, final_x+f->ch_spacing, final_y+((f->real_face_h)>>5), f->outline_color); } else { //If the underline_right is FALSE rectfill(bmp, first_x, final_y-1, final_x, final_y+((f->real_face_h)>>5), f->outline_color); } } if(f->outline_bottom>0) { if(f->underline_right==TRUE) { //If the underline_right is TRUE rectfill(bmp, first_x, final_y, final_x+f->ch_spacing, final_y+((f->real_face_h)>>5)+1, f->outline_color); } else { //If the underline_right is FALSE rectfill(bmp, first_x, final_y, final_x, final_y+((f->real_face_h)>>5)+1, f->outline_color); } } if(f->outline_left>0) { if(f->underline_left==FALSE) { rectfill(bmp, first_x-1, final_y, final_x, final_y+((f->real_face_h)>>5), f->outline_color); } } if(f->outline_right>0) { if(f->underline_right==FALSE) { rectfill(bmp, first_x, final_y, final_x+1, final_y+((f->real_face_h)>>5), f->outline_color); } } } if(f->outline_hollow==FALSE) { //check if it is the masked region for outline if(f->underline_right==TRUE) { //If the underline_right is TRUE rectfill(bmp, first_x, final_y, final_x+f->ch_spacing, final_y+((f->real_face_h)>>5), color); } else { //If the underline_right is FALSE rectfill(bmp, first_x, final_y, final_x, final_y+((f->real_face_h)>>5), color); } } else { //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if(f->underline_right==TRUE) { //If the underline_right is TRUE masked_blit(masked_bmp, bmp, 0, 0, first_x, final_y, final_x+f->ch_spacing-first_x+1, final_y+((f->real_face_h)>>5)-final_y+1); destroy_bitmap(masked_bmp); } else { //If the underline_right is FALSE masked_blit(masked_bmp, bmp, 0, 0, first_x, final_y, final_x-first_x+1, final_y+((f->real_face_h)>>5)-final_y+1); destroy_bitmap(masked_bmp); } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } } } else { if(f->outline_hollow==TRUE) { //set the masked region for underline int bmp_x, bmp_y; //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if(f->underline_right==TRUE) { //If the underline_right is TRUE masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),final_x+f->ch_spacing-first_x+1, final_y+5-final_y+1); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); for (bmp_y = final_y; bmp_y <= final_y+5; bmp_y++) { for (bmp_x = first_x; bmp_x <= final_x+f->ch_spacing; bmp_x++) { putpixel(masked_bmp, bmp_x-first_x, bmp_y-final_y, getpixel(bmp, bmp_x, bmp_y)); } } } else { //If the underline_right is FALSE masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),final_x-first_x+1, final_y+5-final_y+1); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); for (bmp_y = final_y; bmp_y <= final_y+5; bmp_y++) { for (bmp_x = first_x; bmp_x <= final_x; bmp_x++) { putpixel(masked_bmp, bmp_x-first_x, bmp_y-final_y, getpixel(bmp, bmp_x, bmp_y)); } } } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } } //Draw outline if ((f->outline_top>0) || (f->outline_bottom>0) || (f->outline_left>0) || (f->outline_right>0)) { if(f->outline_top>0) { if(f->underline_right==TRUE) { //If the underline_right is TRUE rectfill(bmp, first_x, final_y-1, final_x+f->ch_spacing, final_y+5, f->outline_color); } else { //If the underline_right is FALSE rectfill(bmp, first_x, final_y-1, final_x, final_y+5, f->outline_color); } } if(f->outline_bottom>0) { if(f->underline_right==TRUE) { //If the underline_right is TRUE rectfill(bmp, first_x, final_y, final_x+f->ch_spacing, final_y+5, f->outline_color); } else { //If the underline_right is FALSE rectfill(bmp, first_x, final_y, final_x, final_y+5, f->outline_color); } } if(f->outline_left>0) { if(f->underline_left==FALSE) { rectfill(bmp, first_x-1, final_y, final_x, final_y+5, f->outline_color); } } if(f->outline_right>0) { if(f->underline_right==FALSE) { rectfill(bmp, first_x, final_y, final_x+1, final_y+5, f->outline_color); } } } if(f->outline_hollow==FALSE) { //check if it is the masked region for outline if(f->underline_right==TRUE) { //If the underline_right is TRUE rectfill(bmp, first_x, final_y, final_x+f->ch_spacing, final_y+5, color); } else { //If the underline_right is FALSE rectfill(bmp, first_x, final_y, final_x, final_y+5, color); } } else { //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if(f->underline_right==TRUE) { //If the underline_right is TRUE masked_blit(masked_bmp, bmp, 0, 0, first_x, final_y, final_x+f->ch_spacing-first_x+1, final_y+5-final_y+1); destroy_bitmap(masked_bmp); } else { //If the underline_right is FALSE masked_blit(masked_bmp, bmp, 0, 0, first_x, final_y, final_x-first_x+1, final_y+5-final_y+1); destroy_bitmap(masked_bmp); } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } } } } release_bitmap(bmp); /* reset blender */ if (backg < 0) solid_mode(); if ((f->type==1)||(f->type==2)) { if (lpszW_pointer) free(lpszW_pointer); } if (s_pointer) { free(s_pointer); } #ifndef ALFONT_DOS setlocale(LC_CTYPE,""); #endif if (f->type==2) { set_uformat(curr_uformat); } } void alfont_textout(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color) { alfont_textout_ex(bmp, f, s, x, y, color, alfont_textmode); } void alfont_textout_ex(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color, int backg) { char *lpszW; char *lpszW_tmp; int x_tmp; int max_advancex; char *lpszW_pointer=NULL; //used for freeing string char *s_pointer=NULL; //used for original string fixed by autofix char *s_pointer_temp=NULL; //temporary used for autofix string char *precedingchar_pointer=NULL; //used for precedingchar character int nLen; int ret; //decide that if the ASCII Code convert to Unicode Code is all OK when used for autofix string or used for general convert. int character, last_glyph_index; int first_x=0, final_x=0, final_y=0; int curr_uformat; int first_flag=TRUE; //First Char flag BITMAP *masked_bmp; //the masked bmp used by Font hollow #ifdef ALFONT_DOS iconv_t c_pt; size_t fromlen, tolen; char *sin, *sout; #endif if (s == NULL) { return; } nLen = strlen(s) + 1; s_pointer = (char *)malloc(nLen*sizeof(char)); memset(s_pointer, 0, nLen); strcpy(s_pointer, s); //Auto Fix for cutted string //For ASCII convert to unicode //Add the previous character to the s string //If find the cutted character, store it from the converted s string and remove it from the original s string if (f->autofix==TRUE) { if (f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) != (iconv_t)-1) { fromlen = strlen(s) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); //add the previous character to the s string if (f->precedingchar != 0) { free(s_pointer); fromlen = strlen(s) + 1 + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); s_pointer = (char *)malloc(tolen*sizeof(char)); memset(s_pointer, 0, tolen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(s_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(s_pointer, s); f->precedingchar = 0; } iconv(c_pt, NULL, NULL, NULL, NULL); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = s; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); s_pointer_temp = s_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*s_pointer_temp != '\0') { f->precedingchar = *s_pointer_temp; s_pointer_temp++; } //remove the final character s_pointer_temp--; *s_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } } #else #ifdef ALFONT_LINUX nLen = strlen(s_pointer) * 5 + 1; #else nLen = strlen(s_pointer) + 1; #endif //add the previous character to the s string if (f->precedingchar != 0) { free(s_pointer); nLen = strlen(s) + 1 + 1; s_pointer = (char *)malloc(nLen*sizeof(char)); memset(s_pointer, 0, nLen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(s_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(s_pointer, s); f->precedingchar = 0; } setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); ret = mbstowcs((wchar_t *)lpszW, s_pointer, nLen); s_pointer_temp = s_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*s_pointer_temp != '\0') { f->precedingchar = *s_pointer_temp; s_pointer_temp++; } //remove the final character s_pointer_temp--; *s_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } #endif //recover to original codepage set_uformat(curr_uformat); } } //Font Code Convert if (f->type==1) { #ifdef ALFONT_DOS if ((c_pt = iconv_open(f->language, "UTF-16LE")) == (iconv_t)-1) { lpszW = (char *)s_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(s_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); lpszW_pointer = lpszW; sin = s_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)s_pointer; } } #else setlocale(LC_CTYPE,f->language); nLen= MB_CUR_MAX * wcslen((const wchar_t*)s_pointer) + 1; lpszW = (char *)malloc(nLen*sizeof(char)); memset(lpszW, 0, nLen); lpszW_pointer = lpszW; wcstombs(lpszW, (const wchar_t *)s_pointer, nLen); #endif } else if(f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) == (iconv_t)-1) { lpszW = (char *)s_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(s_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); lpszW_pointer = lpszW; sin = s_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)s_pointer; } else { set_uformat(U_UNICODE); } } #else setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); #ifdef ALFONT_LINUX nLen = strlen(s_pointer) * 5 + 1; #else nLen= strlen(s_pointer) + 1; #endif lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); lpszW_pointer = lpszW; mbstowcs((wchar_t *)lpszW, s_pointer, nLen); #endif } else { #ifdef ALFONT_LINUX set_uformat(U_UTF8); nLen= ustrlen(s_pointer) + 1; #endif lpszW = (char *)s_pointer; } /* is it under or over or too far to the right of the clipping rect then we can assume the string is clipped */ if ((y + f->face_h < bmp->ct) || (y > bmp->cb) || (x > bmp->cr)) return; //build transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); set_trans_blender(0,0,0,f->transparency); } } else { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } /* if we are doing opaque mode, draw a rect */ if (backg >= 0) { if(f->background==TRUE) { rectfill(bmp, x, y, x + alfont_text_length(f, s_pointer) - 1, y + f->face_h - 1, backg); } } /* draw char by char (using allegro unicode funcs) */ acquire_bitmap(bmp); last_glyph_index = 0; if (f->fixed_width == TRUE) { lpszW_tmp = lpszW; x_tmp = x; max_advancex = 0; _alfont_uncache_glyphs(f); #ifdef ALFONT_LINUX //Fix for Linux Unicode System(be converted) for (character = ugetxc((const char**)&lpszW_tmp); character != 0; character = ugetxc((const char**)&lpszW_tmp),character = ugetxc((const char**)&lpszW_tmp)) { #else for (character = ugetxc((const char**)&lpszW_tmp); character != 0; character = ugetxc((const char**)&lpszW_tmp)) { #endif int glyph_index_tmp; struct _ALFONT_CACHED_GLYPH cglyph_tmp; #ifdef ALFONT_LINUX //Recover for Linux Unicode System Fixed if(f->type!=2) { lpszW_tmp--; } #endif /* if left side of char farther than right side of clipping, we are done */ if (x_tmp > bmp->cr) break; /* get the character out of the font */ if (f->face->charmap) glyph_index_tmp = FT_Get_Char_Index(f->face, character); else glyph_index_tmp = character; /* cache the glyph */ _alfont_cache_glyph(f, glyph_index_tmp); cglyph_tmp = f->cached_glyphs[glyph_index_tmp]; if (max_advancex < f->cached_glyphs[glyph_index_tmp].advancex) max_advancex = f->cached_glyphs[glyph_index_tmp].advancex; /* advance */ if (cglyph_tmp.advancex) x_tmp += cglyph_tmp.advancex + f->ch_spacing; } } #ifdef ALFONT_LINUX //Fix for Linux Unicode System(be converted) for (character = ugetxc((const char**)&lpszW); character != 0; character = ugetxc((const char**)&lpszW),character = ugetxc((const char**)&lpszW)) { #else for (character = ugetxc((const char**)&lpszW); character != 0; character = ugetxc((const char**)&lpszW)) { #endif int real_x, real_y, glyph_index; struct _ALFONT_CACHED_GLYPH cglyph; #ifdef ALFONT_LINUX //Recover for Linux Unicode System Fixed if(f->type!=2) { lpszW--; } #endif /* if left side of char farther than right side of clipping, we are done */ if (x > bmp->cr) break; /* get the character out of the font */ if (f->face->charmap) glyph_index = FT_Get_Char_Index(f->face, character); else glyph_index = character; /* cache the glyph */ _alfont_cache_glyph(f, glyph_index); if (f->fixed_width == TRUE) f->cached_glyphs[glyph_index].advancex = max_advancex; cglyph = f->cached_glyphs[glyph_index]; /* calculate drawing coords */ real_x = x + cglyph.left; real_y = (y - cglyph.top) + f->face_ascender; /* apply kerning */ /*if (last_glyph_index) { FT_Vector v; FT_Get_Kerning(f->face, last_glyph_index, glyph_index, ft_kerning_default, &v); real_x += v.x >> 6; real_y += v.y >> 6; }*/ last_glyph_index = glyph_index; /* draw only if exists */ if ((cglyph.mono_available) && (cglyph.bmp)) { unsigned char *bmp_p = cglyph.bmp; /* monochrome drawing */ int bmp_x, bmp_y,outline_w; /* copy the character bitmap to our allegro one */ const int max_bmp_x = cglyph.width + real_x; const int max_bmp_y = cglyph.height + real_y; if (first_flag==TRUE) { first_x= max_bmp_x; } if(f->outline_hollow==TRUE) { //Set masked region //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if (f->style==1) { masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),max_bmp_x+((max_bmp_y-real_y)/2)-real_x, max_bmp_y-real_y); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); } else if(f->style==2) { masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),max_bmp_x+1-real_x, max_bmp_y-real_y); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); } else if(f->style==3) { masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),max_bmp_x+((max_bmp_y-real_y)/2)+1-real_x, max_bmp_y-real_y); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); } else { masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),max_bmp_x-real_x, max_bmp_y-real_y); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); } for (bmp_y = real_y; bmp_y < max_bmp_y; bmp_y++) { for (bmp_x = real_x; bmp_x < max_bmp_x; bmp_x++) { if (*bmp_p++) { if(first_x>bmp_x) first_x=bmp_x; if(final_xstyle==1) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+((max_bmp_y-bmp_y)/2); } if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2))) first_x=bmp_x+((max_bmp_y-bmp_y)/2); } putpixel(masked_bmp, bmp_x+((max_bmp_y-bmp_y)/2)-real_x, bmp_y-real_y, getpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y)); } else if(f->style==2) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+1)) final_x=bmp_x+1; if(final_x<(bmp_x)) final_x=bmp_x; } if(f->underline_left==TRUE) { if(first_x>(bmp_x+1)) first_x=bmp_x+1; if(first_x>(bmp_x)) first_x=bmp_x; } putpixel(masked_bmp, bmp_x+1-real_x, bmp_y-real_y, getpixel(bmp, bmp_x+1, bmp_y)); putpixel(masked_bmp, bmp_x-real_x, bmp_y-real_y, getpixel(bmp, bmp_x, bmp_y)); } else if(f->style==3) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2)+1)) final_x=bmp_x+((max_bmp_y-bmp_y)/2)+1; if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+((max_bmp_y-bmp_y)/2); } if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2)+1)) first_x=bmp_x+((max_bmp_y-bmp_y)/2)+1; if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2))) first_x=bmp_x+((max_bmp_y-bmp_y)/2); } putpixel(masked_bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1-real_x, bmp_y-real_y, getpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1, bmp_y)); putpixel(masked_bmp, bmp_x+((max_bmp_y-bmp_y)/2)-real_x, bmp_y-real_y, getpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y)); } else { putpixel(masked_bmp, bmp_x-real_x, bmp_y-real_y, getpixel(bmp, bmp_x, bmp_y)); } } } } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } bmp_p = cglyph.bmp; //repointer to Font bmp pointer and draw outline } if ((f->outline_top>0) || (f->outline_bottom>0) || (f->outline_left>0) || (f->outline_right>0)) { for (bmp_y = real_y; bmp_y < max_bmp_y; bmp_y++) { for (bmp_x = real_x; bmp_x < max_bmp_x; bmp_x++) { if (*bmp_p++) { if (f->outline_right>0) { for (outline_w = 0; outline_w < f->outline_right; outline_w++) { if (bmp_x+(outline_w+1)<=max_bmp_x) { if (f->style==1) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2); } putpixel(bmp, bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2), bmp_y, f->outline_color); } else if(f->style==2) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+(outline_w+1)+1)) final_x=bmp_x+(outline_w+1)+1; } putpixel(bmp, bmp_x+(outline_w+1)+1, bmp_y, f->outline_color); } else if(f->style==3) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2)+1)) final_x=bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2)+1; } putpixel(bmp, bmp_x+(outline_w+1)+((max_bmp_y-bmp_y)/2)+1, bmp_y, f->outline_color); } else { if(f->underline_right==TRUE) { if(final_x<(bmp_x+(outline_w+1))) final_x=bmp_x+(outline_w+1); } putpixel(bmp, bmp_x+(outline_w+1), bmp_y, f->outline_color); } } } } if (f->outline_bottom>0) { for (outline_w = 0; outline_w < f->outline_bottom; outline_w++) { if (bmp_y+(outline_w+1)<=max_bmp_y) { if (f->style==1) { putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y+(outline_w+1), f->outline_color); } else if(f->style==2) { putpixel(bmp, bmp_x+1, bmp_y+(outline_w+1), f->outline_color); putpixel(bmp, bmp_x, bmp_y+(outline_w+1), f->outline_color); } else if(f->style==3) { putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1, bmp_y+(outline_w+1), f->outline_color); putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y+(outline_w+1), f->outline_color); } else { putpixel(bmp, bmp_x, bmp_y+(outline_w+1), f->outline_color); } } } } if (f->outline_left>0) { for (outline_w = 0; outline_w < f->outline_left; outline_w++) { if (bmp_x-(outline_w+1)>=real_x-1) { if (f->style==1) { if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1))) first_x=bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1); } putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1), bmp_y, f->outline_color); } else if(f->style==2) { if(f->underline_left==TRUE) { if(first_x>(bmp_x-(outline_w+1))) first_x=bmp_x-(outline_w+1); } putpixel(bmp, bmp_x-(outline_w+1), bmp_y, f->outline_color); } else if(f->style==3) { if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1))) first_x=bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1); } putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)-(outline_w+1), bmp_y, f->outline_color); } else { if(f->underline_left==TRUE) { if(first_x>(bmp_x-(outline_w+1))) first_x=bmp_x-(outline_w+1); } putpixel(bmp, bmp_x-(outline_w+1), bmp_y, f->outline_color); } } } } if (f->outline_top>0) { for (outline_w = 0; outline_w < f->outline_top; outline_w++) { if (bmp_y-(outline_w+1)>=real_y-1) { if (f->style==1) { putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y-(outline_w+1), f->outline_color); } else if(f->style==2) { putpixel(bmp, bmp_x+1, bmp_y-(outline_w+1), f->outline_color); putpixel(bmp, bmp_x, bmp_y-(outline_w+1), f->outline_color); } else if(f->style==3) { putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1, bmp_y-(outline_w+1), f->outline_color); putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y-(outline_w+1), f->outline_color); } else { putpixel(bmp, bmp_x, bmp_y-(outline_w+1), f->outline_color); } } } } } } } } if(f->outline_hollow==FALSE) { //check if it will restore the masked region bmp_p = cglyph.bmp; //repointer to Font bmp pointer for (bmp_y = real_y; bmp_y < max_bmp_y; bmp_y++) { for (bmp_x = real_x; bmp_x < max_bmp_x; bmp_x++) { if (*bmp_p++) { if(first_x>bmp_x) first_x=bmp_x; if(final_xstyle==1) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+((max_bmp_y-bmp_y)/2); } if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2))) first_x=bmp_x+((max_bmp_y-bmp_y)/2); } putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y, color); } else if(f->style==2) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+1)) final_x=bmp_x+1; if(final_x<(bmp_x)) final_x=bmp_x; } if(f->underline_left==TRUE) { if(first_x>(bmp_x+1)) first_x=bmp_x+1; if(first_x>(bmp_x)) first_x=bmp_x; } putpixel(bmp, bmp_x+1, bmp_y, color); putpixel(bmp, bmp_x, bmp_y, color); } else if(f->style==3) { if(f->underline_right==TRUE) { if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2)+1)) final_x=bmp_x+((max_bmp_y-bmp_y)/2)+1; if(final_x<(bmp_x+((max_bmp_y-bmp_y)/2))) final_x=bmp_x+((max_bmp_y-bmp_y)/2); } if(f->underline_left==TRUE) { if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2)+1)) first_x=bmp_x+((max_bmp_y-bmp_y)/2)+1; if(first_x>(bmp_x+((max_bmp_y-bmp_y)/2))) first_x=bmp_x+((max_bmp_y-bmp_y)/2); } putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2)+1, bmp_y, color); putpixel(bmp, bmp_x+((max_bmp_y-bmp_y)/2), bmp_y, color); } else { putpixel(bmp, bmp_x, bmp_y, color); } } } } } else { //restore original pic //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if (f->style==1) { masked_blit(masked_bmp, bmp, 0, 0, real_x, real_y, max_bmp_x+((max_bmp_y-real_y)/2)-real_x, max_bmp_y-real_y); destroy_bitmap(masked_bmp); } else if(f->style==2) { masked_blit(masked_bmp, bmp, 0, 0, real_x, real_y, max_bmp_x+1-real_x, max_bmp_y-real_y); destroy_bitmap(masked_bmp); } else if(f->style==3) { masked_blit(masked_bmp, bmp, 0, 0, real_x, real_y, max_bmp_x+((max_bmp_y-real_y)/2)+1-real_x, max_bmp_y-real_y); destroy_bitmap(masked_bmp); } else { masked_blit(masked_bmp, bmp, 0, 0, real_x, real_y, max_bmp_x-real_x, max_bmp_y-real_y); destroy_bitmap(masked_bmp); } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } } } /* advance */ if (cglyph.advancex) x += cglyph.advancex + f->ch_spacing; if (cglyph.advancey) y += cglyph.advancey + f->ch_spacing; first_flag=FALSE; //set first char flag is FALSE } //draw underline if ((f->underline)==TRUE) { if ((final_y+((f->real_face_h)>>5))>5) { if(f->outline_hollow==TRUE) { //set the masked region for underline int bmp_x, bmp_y; //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if(f->underline_right==TRUE) { //If the underline_right is TRUE masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),final_x+f->ch_spacing-first_x+1, final_y+((f->real_face_h)>>5)-final_y+1); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); for (bmp_y = final_y; bmp_y <= final_y+((f->real_face_h)>>5); bmp_y++) { for (bmp_x = first_x; bmp_x <= final_x+f->ch_spacing; bmp_x++) { putpixel(masked_bmp, bmp_x-first_x, bmp_y-final_y, getpixel(bmp, bmp_x, bmp_y)); } } } else { //If the underline_right is FALSE masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),final_x-first_x+1, final_y+((f->real_face_h)>>5)-final_y+1); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); for (bmp_y = final_y; bmp_y <= final_y+((f->real_face_h)>>5); bmp_y++) { for (bmp_x = first_x; bmp_x <= final_x; bmp_x++) { putpixel(masked_bmp, bmp_x-first_x, bmp_y-final_y, getpixel(bmp, bmp_x, bmp_y)); } } } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } } //Draw outline if ((f->outline_top>0) || (f->outline_bottom>0) || (f->outline_left>0) || (f->outline_right>0)) { if(f->outline_top>0) { if(f->underline_right==TRUE) { //If the underline_right is TRUE rectfill(bmp, first_x, final_y-1, final_x+f->ch_spacing, final_y+((f->real_face_h)>>5), f->outline_color); } else { //If the underline_right is FALSE rectfill(bmp, first_x, final_y-1, final_x, final_y+((f->real_face_h)>>5), f->outline_color); } } if(f->outline_bottom>0) { if(f->underline_right==TRUE) { //If the underline_right is TRUE rectfill(bmp, first_x, final_y, final_x+f->ch_spacing, final_y+((f->real_face_h)>>5)+1, f->outline_color); } else { //If the underline_right is FALSE rectfill(bmp, first_x, final_y, final_x, final_y+((f->real_face_h)>>5)+1, f->outline_color); } } if(f->outline_left>0) { if(f->underline_left==FALSE) { rectfill(bmp, first_x-1, final_y, final_x, final_y+((f->real_face_h)>>5), f->outline_color); } } if(f->outline_right>0) { if(f->underline_right==FALSE) { rectfill(bmp, first_x, final_y, final_x+1, final_y+((f->real_face_h)>>5), f->outline_color); } } } if(f->outline_hollow==FALSE) { //check if it is the masked region for outline if(f->underline_right==TRUE) { //If the underline_right is TRUE rectfill(bmp, first_x, final_y, final_x+f->ch_spacing, final_y+((f->real_face_h)>>5), color); } else { //If the underline_right is FALSE rectfill(bmp, first_x, final_y, final_x, final_y+((f->real_face_h)>>5), color); } } else { //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if(f->underline_right==TRUE) { //If the underline_right is TRUE masked_blit(masked_bmp, bmp, 0, 0, first_x, final_y, final_x+f->ch_spacing-first_x+1, final_y+((f->real_face_h)>>5)-final_y+1); destroy_bitmap(masked_bmp); } else { //If the underline_right is FALSE masked_blit(masked_bmp, bmp, 0, 0, first_x, final_y, final_x-first_x+1, final_y+((f->real_face_h)>>5)-final_y+1); destroy_bitmap(masked_bmp); } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } } } else { if(f->outline_hollow==TRUE) { //set the masked region for underline int bmp_x, bmp_y; //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if(f->underline_right==TRUE) { //If the underline_right is TRUE masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),final_x+f->ch_spacing-first_x+1, final_y+5-final_y+1); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); for (bmp_y = final_y; bmp_y <= final_y+5; bmp_y++) { for (bmp_x = first_x; bmp_x <= final_x+f->ch_spacing; bmp_x++) { putpixel(masked_bmp, bmp_x-first_x, bmp_y-final_y, getpixel(bmp, bmp_x, bmp_y)); } } } else { //If the underline_right is FALSE masked_bmp= create_bitmap_ex(bitmap_color_depth(bmp),final_x-first_x+1, final_y+5-final_y+1); clear_to_color(masked_bmp,bitmap_mask_color(bmp)); for (bmp_y = final_y; bmp_y <= final_y+5; bmp_y++) { for (bmp_x = first_x; bmp_x <= final_x; bmp_x++) { putpixel(masked_bmp, bmp_x-first_x, bmp_y-final_y, getpixel(bmp, bmp_x, bmp_y)); } } } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } } //Draw outline if ((f->outline_top>0) || (f->outline_bottom>0) || (f->outline_left>0) || (f->outline_right>0)) { if(f->outline_top>0) { if(f->underline_right==TRUE) { //If the underline_right is TRUE rectfill(bmp, first_x, final_y-1, final_x+f->ch_spacing, final_y+5, f->outline_color); } else { //If the underline_right is FALSE rectfill(bmp, first_x, final_y-1, final_x, final_y+5, f->outline_color); } } if(f->outline_bottom>0) { if(f->underline_right==TRUE) { //If the underline_right is TRUE rectfill(bmp, first_x, final_y, final_x+f->ch_spacing, final_y+5, f->outline_color); } else { //If the underline_right is FALSE rectfill(bmp, first_x, final_y, final_x, final_y+5, f->outline_color); } } if(f->outline_left>0) { if(f->underline_left==FALSE) { rectfill(bmp, first_x-1, final_y, final_x, final_y+5, f->outline_color); } } if(f->outline_right>0) { if(f->underline_right==FALSE) { rectfill(bmp, first_x, final_y, final_x+1, final_y+5, f->outline_color); } } } if(f->outline_hollow==FALSE) { //check if it is the masked region for outline if(f->underline_right==TRUE) { //If the underline_right is TRUE rectfill(bmp, first_x, final_y, final_x+f->ch_spacing, final_y+5, color); } else { //If the underline_right is FALSE rectfill(bmp, first_x, final_y, final_x, final_y+5, color); } } else { //cancel transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_SOLID,NULL,0,0); } } if(f->underline_right==TRUE) { //If the underline_right is TRUE masked_blit(masked_bmp, bmp, 0, 0, first_x, final_y, final_x+f->ch_spacing-first_x+1, final_y+5-final_y+1); destroy_bitmap(masked_bmp); } else { //If the underline_right is FALSE masked_blit(masked_bmp, bmp, 0, 0, first_x, final_y, final_x-first_x+1, final_y+5-final_y+1); destroy_bitmap(masked_bmp); } //restore transparency if (f->transparency!=255) { if (bitmap_color_depth(bmp)>8) { drawing_mode(DRAW_MODE_TRANS,NULL,0,0); } } } } } release_bitmap(bmp); if ((f->type==1)||(f->type==2)) { if (lpszW_pointer) free(lpszW_pointer); } if(s_pointer) { free(s_pointer); } #ifndef ALFONT_DOS setlocale(LC_CTYPE,""); #endif if (f->type==2) { set_uformat(curr_uformat); } } int alfont_text_height(ALFONT_FONT *f) { return f->face_h; } int alfont_text_length(ALFONT_FONT *f, const char *str) { char *lpszW; char *lpszW_tmp; int max_advancex; char *lpszW_pointer=NULL; //used for freeing string char *str_pointer=NULL; //used for original string fixed by autofix char *str_pointer_temp=NULL; //temporary used for autofix string char *precedingchar_pointer=NULL; //used for precedingchar character int nLen; int ret; //decide that if the ASCII Code convert to Unicode Code is all OK when used for autofix string or used for general convert. int curr_uformat; int total_length = 0, character, last_glyph_index; int glyph_index; int glyph_index_tmp; #ifdef ALFONT_DOS iconv_t c_pt; size_t fromlen, tolen; char *sin, *sout; #endif if (str == NULL) { return 0; } nLen = strlen(str) + 1; str_pointer = (char *)malloc(nLen*sizeof(char)); memset(str_pointer, 0, nLen); strcpy(str_pointer, str); //Auto Fix for cutted string //For ASCII convert to unicode //Add the previous character to the str string //If find the cutted character, store it from the converted str string and remove it from the original str string if (f->autofix==TRUE) { if (f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) != (iconv_t)-1) { fromlen = strlen(str) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); //add the previous character to the str string if (f->precedingchar != 0) { free(str_pointer); fromlen = strlen(str) + 1 + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); str_pointer = (char *)malloc(tolen*sizeof(char)); memset(str_pointer, 0, tolen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(str_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(str_pointer, str); f->precedingchar = 0; } iconv(c_pt, NULL, NULL, NULL, NULL); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = str; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); str_pointer_temp = str_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*str_pointer_temp != '\0') { f->precedingchar = *str_pointer_temp; str_pointer_temp++; } //remove the final character str_pointer_temp--; *str_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } } #else #ifdef ALFONT_LINUX nLen = strlen(str_pointer) * 5 + 1; #else nLen = strlen(str_pointer) + 1; #endif //add the previous character to the str string if (f->precedingchar != 0) { free(str_pointer); nLen = strlen(str) + 1 + 1; str_pointer = (char *)malloc(nLen*sizeof(char)); memset(str_pointer, 0, nLen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(str_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(str_pointer, str); f->precedingchar = 0; } setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); ret = mbstowcs((wchar_t *)lpszW, str_pointer, nLen); str_pointer_temp = str_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*str_pointer_temp != '\0') { f->precedingchar = *str_pointer_temp; str_pointer_temp++; } //remove the final character str_pointer_temp--; *str_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } #endif //recover to original codepage set_uformat(curr_uformat); } } //Font Code Convert if (f->type==1) { #ifdef ALFONT_DOS if ((c_pt = iconv_open(f->language, "UTF-16LE")) == (iconv_t)-1) { lpszW = (char *)str_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(str_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); lpszW_pointer = lpszW; sin = str_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)str_pointer; } } #else setlocale(LC_CTYPE,f->language); nLen= MB_CUR_MAX * wcslen((const wchar_t*)str_pointer) + 1; lpszW = (char *)malloc(nLen*sizeof(char)); memset(lpszW, 0, nLen); lpszW_pointer = lpszW; wcstombs(lpszW, (const wchar_t *)str_pointer, nLen); #endif } else if(f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) == (iconv_t)-1) { lpszW = (char *)str_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(str_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); lpszW_pointer = lpszW; sin = str_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)str_pointer; } else { set_uformat(U_UNICODE); } } #else setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); #ifdef ALFONT_LINUX nLen = strlen(str_pointer) * 5 + 1; #else nLen= strlen(str_pointer) + 1; #endif lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); lpszW_pointer = lpszW; mbstowcs((wchar_t *)lpszW, str_pointer, nLen); #endif } else { #ifdef ALFONT_LINUX set_uformat(U_UTF8); nLen= ustrlen(str_pointer) + 1; #endif lpszW = (char *)str_pointer; } /* virtually draw char by char */ last_glyph_index = 0; if (f->fixed_width == TRUE) { lpszW_tmp = lpszW; max_advancex = 0; _alfont_uncache_glyphs(f); #ifdef ALFONT_LINUX //Fix for Linux Unicode System(be converted) for (character = ugetxc((const char**)&lpszW_tmp); character != 0; character = ugetxc((const char**)&lpszW_tmp),character = ugetxc((const char**)&lpszW_tmp)) { #else for (character = ugetxc((const char**)&lpszW_tmp); character != 0; character = ugetxc((const char**)&lpszW_tmp)) { #endif /* get the character out of the font */ #ifdef ALFONT_LINUX //Recover for Linux Unicode System Fixed if(f->type!=2) { lpszW_tmp--; } #endif /* get the character out of the font */ if (f->face->charmap) glyph_index_tmp = FT_Get_Char_Index(f->face, character); else glyph_index_tmp = character; /* cache the glyph */ _alfont_cache_glyph(f, glyph_index_tmp); if (max_advancex < f->cached_glyphs[glyph_index_tmp].advancex) max_advancex = f->cached_glyphs[glyph_index_tmp].advancex; } } #ifdef ALFONT_LINUX //Fix for Linux Unicode System(be converted) for (character = ugetxc((const char**)&lpszW); character != 0; character = ugetxc((const char**)&lpszW),character = ugetxc((const char**)&lpszW)) { #else for (character = ugetxc((const char**)&lpszW); character != 0; character = ugetxc((const char**)&lpszW)) { #endif /* get the character out of the font */ #ifdef ALFONT_LINUX //Recover for Linux Unicode System Fixed if(f->type!=2) { lpszW--; } #endif if (f->face->charmap) glyph_index = FT_Get_Char_Index(f->face, character); else glyph_index = character; /* apply kerning */ /*if (last_glyph_index) { FT_Vector v; FT_Get_Kerning(f->face, last_glyph_index, glyph_index, ft_kerning_default, &v); total_length += v.x >> 6; }*/ last_glyph_index = glyph_index; /* cache */ _alfont_cache_glyph(f, glyph_index); if (f->fixed_width == TRUE) f->cached_glyphs[glyph_index].advancex = max_advancex; /* advance */ if (f->cached_glyphs[glyph_index].advancex) total_length += f->cached_glyphs[glyph_index].advancex + f->ch_spacing; } if ((f->style==1)||(f->style==3)) { if (f->cached_glyphs[last_glyph_index].advancex) total_length += (f->outline_right+1) + (f->cached_glyphs[last_glyph_index].advancex/2); } if ((f->type==1)||(f->type==2)) { if (lpszW_pointer) free(lpszW_pointer); } if(str_pointer) { free(str_pointer); } #ifndef ALFONT_DOS setlocale(LC_CTYPE,""); #endif if (f->type==2) { set_uformat(curr_uformat); } return total_length; } int alfont_char_length(ALFONT_FONT *f, int character) { int curr_uformat; int total_length = 0, last_glyph_index; int glyph_index; if (character == 0) { return 0; } //Font Code Convert if (f->type==1) { setlocale(LC_CTYPE,f->language); } else if(f->type==2) { curr_uformat=get_uformat(); setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); } else { #ifdef ALFONT_LINUX set_uformat(U_UTF8); #endif } /* virtually draw char by char */ last_glyph_index = 0; /* get the character out of the font */ if (f->face->charmap) glyph_index = FT_Get_Char_Index(f->face, character); else glyph_index = character; /* apply kerning */ /*if (last_glyph_index) { FT_Vector v; FT_Get_Kerning(f->face, last_glyph_index, glyph_index, ft_kerning_default, &v); total_length += v.x >> 6; }*/ last_glyph_index = glyph_index; if (f->fixed_width == TRUE) { _alfont_uncache_glyph_number(f, glyph_index); } /* cache */ _alfont_cache_glyph(f, glyph_index); /* advance */ if (f->cached_glyphs[glyph_index].advancex) total_length += f->cached_glyphs[glyph_index].advancex + f->ch_spacing; if ((f->style==1)||(f->style==3)) { if (f->cached_glyphs[last_glyph_index].advancex) total_length += (f->outline_right+1) + (f->cached_glyphs[last_glyph_index].advancex/2); } #ifndef ALFONT_DOS setlocale(LC_CTYPE,""); #endif if (f->type==2) { set_uformat(curr_uformat); } return total_length; } int alfont_text_count(ALFONT_FONT *f, const char *str) { char *lpszW; char *lpszW_pointer=NULL; //used for freeing string char *str_pointer=NULL; //used for original string fixed by autofix char *str_pointer_temp=NULL; //temporary used for autofix string char *precedingchar_pointer=NULL; //used for precedingchar character int nLen; int ret; //decide that if the ASCII Code convert to Unicode Code is all OK when used for autofix string or used for general convert. int curr_uformat; int string_count=0; #ifdef ALFONT_DOS iconv_t c_pt; size_t fromlen, tolen; char *sin, *sout; #endif if (str == NULL) { return 0; } nLen = strlen(str) + 1; str_pointer = (char *)malloc(nLen*sizeof(char)); memset(str_pointer, 0, nLen); strcpy(str_pointer, str); //Auto Fix for cutted string //For ASCII convert to unicode //Add the previous character to the str string //If find the cutted character, store it from the converted str string and remove it from the original str string if (f->autofix==TRUE) { if (f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) != (iconv_t)-1) { fromlen = strlen(str) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); //add the previous character to the str string if (f->precedingchar != 0) { free(str_pointer); fromlen = strlen(str) + 1 + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); str_pointer = (char *)malloc(tolen*sizeof(char)); memset(str_pointer, 0, tolen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(str_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(str_pointer, str); f->precedingchar = 0; } iconv(c_pt, NULL, NULL, NULL, NULL); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = str; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); str_pointer_temp = str_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*str_pointer_temp != '\0') { f->precedingchar = *str_pointer_temp; str_pointer_temp++; } //remove the final character str_pointer_temp--; *str_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } } #else #ifdef ALFONT_LINUX nLen = strlen(str_pointer) * 5 + 1; #else nLen = strlen(str_pointer) + 1; #endif //add the previous character to the str string if (f->precedingchar != 0) { free(str_pointer); nLen = strlen(str) + 1 + 1; str_pointer = (char *)malloc(nLen*sizeof(char)); memset(str_pointer, 0, nLen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(str_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(str_pointer, str); f->precedingchar = 0; } setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); ret = mbstowcs((wchar_t *)lpszW, str_pointer, nLen); str_pointer_temp = str_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*str_pointer_temp != '\0') { f->precedingchar = *str_pointer_temp; str_pointer_temp++; } //remove the final character str_pointer_temp--; *str_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } #endif //recover to original codepage set_uformat(curr_uformat); } } //Font Code Convert if (f->type==1) { #ifdef ALFONT_DOS if ((c_pt = iconv_open(f->language, "UTF-16LE")) == (iconv_t)-1) { lpszW = (char *)str_pointer; string_count = strlen(lpszW); } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(str_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); lpszW_pointer = lpszW; sin = str_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)str_pointer; } string_count = strlen(lpszW); } #else setlocale(LC_CTYPE,f->language); nLen= MB_CUR_MAX * wcslen((const wchar_t*)str_pointer) + 1; lpszW = (char *)malloc(nLen*sizeof(char)); memset(lpszW, 0, nLen); lpszW_pointer = lpszW; string_count = wcstombs(lpszW, (const wchar_t *)str_pointer, nLen); #endif } else if(f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) == (iconv_t)-1) { lpszW = (char *)str_pointer; string_count = strlen(lpszW); } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(str_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); lpszW_pointer = lpszW; sin = str_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)str_pointer; string_count = strlen(lpszW); } else { set_uformat(U_UNICODE); string_count = ustrlen(lpszW); } } #else setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); #ifdef ALFONT_LINUX nLen = strlen(str_pointer) * 5 + 1; #else nLen= strlen(str_pointer) + 1; #endif lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); lpszW_pointer = lpszW; string_count = mbstowcs((wchar_t *)lpszW, str_pointer, nLen); #endif } else { #ifdef ALFONT_LINUX set_uformat(U_UTF8); nLen= ustrlen(str_pointer) + 1; string_count = ustrlen(str_pointer); #else string_count = strlen(str_pointer); #endif lpszW = (char *)str_pointer; } if ((f->type==1)||(f->type==2)) { if (lpszW_pointer) free(lpszW_pointer); } if(str_pointer) { free(str_pointer); } #ifndef ALFONT_DOS setlocale(LC_CTYPE,""); #endif if (f->type==2) { set_uformat(curr_uformat); } return string_count; } int alfont_ugetc(ALFONT_FONT *f, const char *s) { char *lpszW; char *lpszW_pointer=NULL; //used for freeing string char *s_pointer=NULL; //used for original string fixed by autofix char *s_pointer_temp=NULL; //temporary used for autofix string char *precedingchar_pointer=NULL; //used for precedingchar character int nLen; int ret; //decide that if the ASCII Code convert to Unicode Code is all OK when used for autofix string or used for general convert. int character; int curr_uformat; #ifdef ALFONT_DOS iconv_t c_pt; size_t fromlen, tolen; char *sin, *sout; #endif if (s == NULL) { return 0; } nLen = strlen(s) + 1; s_pointer = (char *)malloc(nLen*sizeof(char)); memset(s_pointer, 0, nLen); strcpy(s_pointer, s); //Auto Fix for cutted string //For ASCII convert to unicode //Add the previous character to the s string //If find the cutted character, store it from the converted s string and remove it from the original s string if (f->autofix==TRUE) { if (f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) != (iconv_t)-1) { fromlen = strlen(s) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); //add the previous character to the s string if (f->precedingchar != 0) { free(s_pointer); fromlen = strlen(s) + 1 + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); s_pointer = (char *)malloc(tolen*sizeof(char)); memset(s_pointer, 0, tolen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(s_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(s_pointer, s); f->precedingchar = 0; } iconv(c_pt, NULL, NULL, NULL, NULL); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = s; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); s_pointer_temp = s_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*s_pointer_temp != '\0') { f->precedingchar = *s_pointer_temp; s_pointer_temp++; } //remove the final character s_pointer_temp--; *s_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } } #else #ifdef ALFONT_LINUX nLen = strlen(s_pointer) * 5 + 1; #else nLen = strlen(s_pointer) + 1; #endif //add the previous character to the s string if (f->precedingchar != 0) { free(s_pointer); nLen = strlen(s) + 1 + 1; s_pointer = (char *)malloc(nLen*sizeof(char)); memset(s_pointer, 0, nLen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(s_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(s_pointer, s); f->precedingchar = 0; } setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); ret = mbstowcs((wchar_t *)lpszW, s_pointer, nLen); s_pointer_temp = s_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*s_pointer_temp != '\0') { f->precedingchar = *s_pointer_temp; s_pointer_temp++; } //remove the final character s_pointer_temp--; *s_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } #endif //recover to original codepage set_uformat(curr_uformat); } } //Font Code Convert if (f->type==1) { #ifdef ALFONT_DOS if ((c_pt = iconv_open(f->language, "UTF-16LE")) == (iconv_t)-1) { lpszW = (char *)s_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(s_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = s_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)s_pointer; } } #else setlocale(LC_CTYPE,f->language); nLen= MB_CUR_MAX * wcslen((const wchar_t*)s_pointer) + 1; lpszW = (char *)malloc(nLen*sizeof(char)); memset(lpszW, 0, nLen); wcstombs(lpszW, (const wchar_t *)s_pointer, nLen); #endif } else if(f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) == (iconv_t)-1) { lpszW = (char *)s_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(s_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = s_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)s_pointer; } else { set_uformat(U_UNICODE); } } #else setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); #ifdef ALFONT_LINUX nLen = strlen(s_pointer) * 5 + 1; #else nLen= strlen(s_pointer) + 1; #endif lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); mbstowcs((wchar_t *)lpszW, s_pointer, nLen); #endif } else { #ifdef ALFONT_LINUX set_uformat(U_UTF8); nLen= ustrlen(s_pointer) + 1; #endif lpszW = (char *)s_pointer; } character = ugetc((const char*)lpszW); if ((f->type==1)||(f->type==2)) { if (lpszW) free(lpszW); } if(s_pointer) { free(s_pointer); } #ifndef ALFONT_DOS setlocale(LC_CTYPE,""); #endif if (f->type==2) { set_uformat(curr_uformat); } return character; } int alfont_ugetx(ALFONT_FONT *f, char **s) { char *lpszW; char *lpszW_pointer=NULL; //used for freeing string char *s_pointer=NULL; //used for original string fixed by autofix char *s_pointer_temp=NULL; //temporary used for autofix string char *precedingchar_pointer=NULL; //used for precedingchar character int nLen; int ret; //decide that if the ASCII Code convert to Unicode Code is all OK when used for autofix string or used for general convert. int character; int curr_uformat; char *lpszWS; char *lpszWA; int sLen; //length before advances the *s pointer to the next character int aLen; //length after advances the *s pointer to the next character int lIndex; #ifdef ALFONT_DOS iconv_t c_pt; size_t fromlen, tolen; char *sin, *sout; #endif if (*s == NULL) { return 0; } sLen = strlen(*s); nLen = strlen(*s) + 1; s_pointer = (char *)malloc(nLen*sizeof(char)); memset(s_pointer, 0, nLen); strcpy(s_pointer, *s); //Auto Fix for cutted string //For ASCII convert to unicode //Add the previous character to the *s string //If find the cutted character, store it from the converted *s string and remove it from the original *s string if (f->autofix==TRUE) { if (f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) != (iconv_t)-1) { fromlen = strlen(*s) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); //add the previous character to the *s string if (f->precedingchar != 0) { free(s_pointer); fromlen = strlen(*s) + 1 + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); s_pointer = (char *)malloc(tolen*sizeof(char)); memset(s_pointer, 0, tolen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(s_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(s_pointer, *s); f->precedingchar = 0; } iconv(c_pt, NULL, NULL, NULL, NULL); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = *s; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); s_pointer_temp = s_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*s_pointer_temp != '\0') { f->precedingchar = *s_pointer_temp; s_pointer_temp++; } //remove the final character s_pointer_temp--; *s_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } } #else #ifdef ALFONT_LINUX nLen = strlen(s_pointer) * 5 + 1; #else nLen = strlen(s_pointer) + 1; #endif //add the previous character to the *s string if (f->precedingchar != 0) { free(s_pointer); nLen = strlen(*s) + 1 + 1; s_pointer = (char *)malloc(nLen*sizeof(char)); memset(s_pointer, 0, nLen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(s_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(s_pointer, *s); f->precedingchar = 0; } setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); ret = mbstowcs((wchar_t *)lpszW, s_pointer, nLen); s_pointer_temp = s_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*s_pointer_temp != '\0') { f->precedingchar = *s_pointer_temp; s_pointer_temp++; } //remove the final character s_pointer_temp--; *s_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } #endif //recover to original codepage set_uformat(curr_uformat); } } //Font Code Convert if (f->type==1) { #ifdef ALFONT_DOS if ((c_pt = iconv_open(f->language, "UTF-16LE")) == (iconv_t)-1) { lpszW = (char *)s_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(s_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = s_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)s_pointer; } } #else setlocale(LC_CTYPE,f->language); nLen= MB_CUR_MAX * wcslen((const wchar_t*)s_pointer) + 1; lpszW = (char *)malloc(nLen*sizeof(char)); memset(lpszW, 0, nLen); wcstombs(lpszW, (const wchar_t *)s_pointer, nLen); #endif } else if(f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) == (iconv_t)-1) { lpszW = (char *)s_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(s_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = s_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)s_pointer; } else { set_uformat(U_UNICODE); } } #else setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); #ifdef ALFONT_LINUX nLen = strlen(s_pointer) * 5 + 1; #else nLen= strlen(s_pointer) + 1; #endif lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); mbstowcs((wchar_t *)lpszW, s_pointer, nLen); #endif } else { #ifdef ALFONT_LINUX set_uformat(U_UTF8); nLen= ustrlen(s_pointer) + 1; #endif lpszW = (char *)s_pointer; } lpszWS = lpszW; character = ugetc((const char*)lpszW); //advances the *s pointer to the next character if (f->type==1) { ugetxc((char**)s); #ifdef ALFONT_LINUX ugetxc((char**)s); #endif } else if(f->type==2) { ugetxc(&lpszWS); #ifdef ALFONT_LINUX ugetxc(&lpszWS); #endif #ifdef ALFONT_DOS if ((c_pt = iconv_open(f->language, "UTF-16LE")) == (iconv_t)-1) { aLen = strlen(lpszWS); } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(lpszWS) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszWA = (char *)malloc(tolen*sizeof(char)); memset(lpszWA, 0, tolen); sin = lpszWS; sout = lpszWA; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { if (lpszWA) free(lpszWA); lpszWA = lpszWS } aLen = strlen(lpszWA); } #else setlocale(LC_CTYPE,f->language); nLen= MB_CUR_MAX * wcslen((const wchar_t*)lpszWS) + 1; lpszWA = (char *)malloc(nLen*sizeof(char)); memset(lpszWA, 0, nLen); wcstombs(lpszWA, (const wchar_t *)lpszWS, nLen); aLen = strlen(lpszWA); #endif for (lIndex = 0; lIndex < sLen - aLen; lIndex++) { (*(*s)++); } if (lpszWA) { free(lpszWA); } } else { #ifdef ALFONT_LINUX set_uformat(U_UTF8); #endif ugetxc((char**)s); #ifdef ALFONT_LINUX ugetxc((char**)s); #endif } if ((f->type==1)||(f->type==2)) { if (lpszW) free(lpszW); } if(s_pointer) { free(s_pointer); } #ifndef ALFONT_DOS setlocale(LC_CTYPE,""); #endif if (f->type==2) { set_uformat(curr_uformat); } return character; } int alfont_ugetxc(ALFONT_FONT *f, const char **s) { char *lpszW; char *lpszW_pointer=NULL; //used for freeing string char *s_pointer=NULL; //used for original string fixed by autofix char *s_pointer_temp=NULL; //temporary used for autofix string char *precedingchar_pointer=NULL; //used for precedingchar character int nLen; int ret; //decide that if the ASCII Code convert to Unicode Code is all OK when used for autofix string or used for general convert. int character; int curr_uformat; char *lpszWS; char *lpszWA; int sLen; //length before advances the *s pointer to the next character int aLen; //length after advances the *s pointer to the next character int lIndex; #ifdef ALFONT_DOS iconv_t c_pt; size_t fromlen, tolen; char *sin, *sout; #endif if (*s == NULL) { return 0; } sLen = strlen(*s); nLen = strlen(*s) + 1; s_pointer = (char *)malloc(nLen*sizeof(char)); memset(s_pointer, 0, nLen); strcpy(s_pointer, *s); //Auto Fix for cutted string //For ASCII convert to unicode //Add the previous character to the *s string //If find the cutted character, store it from the converted *s string and remove it from the original *s string if (f->autofix==TRUE) { if (f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) != (iconv_t)-1) { fromlen = strlen(*s) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); //add the previous character to the *s string if (f->precedingchar != 0) { free(s_pointer); fromlen = strlen(*s) + 1 + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); s_pointer = (char *)malloc(tolen*sizeof(char)); memset(s_pointer, 0, tolen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(s_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(s_pointer, *s); f->precedingchar = 0; } iconv(c_pt, NULL, NULL, NULL, NULL); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = *s; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); s_pointer_temp = s_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*s_pointer_temp != '\0') { f->precedingchar = *s_pointer_temp; s_pointer_temp++; } //remove the final character s_pointer_temp--; *s_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } } #else #ifdef ALFONT_LINUX nLen = strlen(s_pointer) * 5 + 1; #else nLen = strlen(s_pointer) + 1; #endif //add the previous character to the *s string if (f->precedingchar != 0) { free(s_pointer); nLen = strlen(*s) + 1 + 1; s_pointer = (char *)malloc(nLen*sizeof(char)); memset(s_pointer, 0, nLen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(s_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(s_pointer, *s); f->precedingchar = 0; } setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); ret = mbstowcs((wchar_t *)lpszW, s_pointer, nLen); s_pointer_temp = s_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*s_pointer_temp != '\0') { f->precedingchar = *s_pointer_temp; s_pointer_temp++; } //remove the final character s_pointer_temp--; *s_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } #endif //recover to original codepage set_uformat(curr_uformat); } } //Font Code Convert if (f->type==1) { #ifdef ALFONT_DOS if ((c_pt = iconv_open(f->language, "UTF-16LE")) == (iconv_t)-1) { lpszW = (char *)s_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(s_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = s_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)s_pointer; } } #else setlocale(LC_CTYPE,f->language); nLen= MB_CUR_MAX * wcslen((const wchar_t*)s_pointer) + 1; lpszW = (char *)malloc(nLen*sizeof(char)); memset(lpszW, 0, nLen); wcstombs(lpszW, (const wchar_t *)s_pointer, nLen); #endif } else if(f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) == (iconv_t)-1) { lpszW = (char *)s_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(s_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = s_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)s_pointer; } else { set_uformat(U_UNICODE); } } #else setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); #ifdef ALFONT_LINUX nLen = strlen(s_pointer) * 5 + 1; #else nLen= strlen(s_pointer) + 1; #endif lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); mbstowcs((wchar_t *)lpszW, s_pointer, nLen); #endif } else { #ifdef ALFONT_LINUX set_uformat(U_UTF8); nLen= ustrlen(s_pointer) + 1; #endif lpszW = (char *)s_pointer; } lpszWS = lpszW; character = ugetc((const char*)lpszW); //advances the *s pointer to the next character if (f->type==1) { ugetxc((const char**)s); #ifdef ALFONT_LINUX ugetxc((const char**)s); #endif } else if(f->type==2) { ugetxc(&lpszWS); #ifdef ALFONT_LINUX ugetxc(&lpszWS); #endif #ifdef ALFONT_DOS if ((c_pt = iconv_open(f->language, "UTF-16LE")) == (iconv_t)-1) { aLen = strlen(lpszWS); } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(lpszWS) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszWA = (char *)malloc(tolen*sizeof(char)); memset(lpszWA, 0, tolen); sin = lpszWS; sout = lpszWA; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { if (lpszWA) free(lpszWA); lpszWA = lpszWS } aLen = strlen(lpszWA); } #else setlocale(LC_CTYPE,f->language); nLen= MB_CUR_MAX * wcslen((const wchar_t*)lpszWS) + 1; lpszWA = (char *)malloc(nLen*sizeof(char)); memset(lpszWA, 0, nLen); wcstombs(lpszWA, (const wchar_t *)lpszWS, nLen); aLen = strlen(lpszWA); #endif for (lIndex = 0; lIndex < sLen - aLen; lIndex++) { (*(*s)++); } if (lpszWA) { free(lpszWA); } } else { #ifdef ALFONT_LINUX set_uformat(U_UTF8); #endif ugetxc((const char**)s); #ifdef ALFONT_LINUX ugetxc((const char**)s); #endif } if ((f->type==1)||(f->type==2)) { if (lpszW) free(lpszW); } if(s_pointer) { free(s_pointer); } #ifndef ALFONT_DOS setlocale(LC_CTYPE,""); #endif if (f->type==2) { set_uformat(curr_uformat); } return character; } void alfont_get_string(ALFONT_FONT *f, const char *s , char **out){ char *lpszW; char *lpszW_pointer=NULL; //used for freeing string char *s_pointer=NULL; //used for original string fixed by autofix char *s_pointer_temp=NULL; //temporary used for autofix string char *precedingchar_pointer=NULL; //used for precedingchar character int nLen; int ret; //decide that if the ASCII Code convert to Unicode Code is all OK when used for autofix string or used for general convert. int curr_uformat; #ifdef ALFONT_DOS iconv_t c_pt; size_t fromlen, tolen; char *sin, *sout; #endif if (s == NULL) { return; } nLen = strlen(s) + 1; s_pointer = (char *)malloc(nLen*sizeof(char)); memset(s_pointer, 0, nLen); strcpy(s_pointer, s); //Auto Fix for cutted string //For ASCII convert to unicode //Add the previous character to the s string //If find the cutted character, store it from the converted s string and remove it from the original s string if (f->autofix==TRUE) { if (f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) != (iconv_t)-1) { fromlen = strlen(s) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); //add the previous character to the s string if (f->precedingchar != 0) { free(s_pointer); fromlen = strlen(s) + 1 + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); s_pointer = (char *)malloc(tolen*sizeof(char)); memset(s_pointer, 0, tolen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(s_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(s_pointer, s); f->precedingchar = 0; } iconv(c_pt, NULL, NULL, NULL, NULL); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = s; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); s_pointer_temp = s_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*s_pointer_temp != '\0') { f->precedingchar = *s_pointer_temp; s_pointer_temp++; } //remove the final character s_pointer_temp--; *s_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } } #else #ifdef ALFONT_LINUX nLen = strlen(s_pointer) * 5 + 1; #else nLen = strlen(s_pointer) + 1; #endif //add the previous character to the s string if (f->precedingchar != 0) { free(s_pointer); nLen = strlen(s) + 1 + 1; s_pointer = (char *)malloc(nLen*sizeof(char)); memset(s_pointer, 0, nLen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(s_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(s_pointer, s); f->precedingchar = 0; } setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); ret = mbstowcs((wchar_t *)lpszW, s_pointer, nLen); s_pointer_temp = s_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*s_pointer_temp != '\0') { f->precedingchar = *s_pointer_temp; s_pointer_temp++; } //remove the final character s_pointer_temp--; *s_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } #endif //recover to original codepage set_uformat(curr_uformat); } } //Font Code Convert if (f->type==1) { #ifdef ALFONT_DOS if ((c_pt = iconv_open(f->language, "UTF-16LE")) == (iconv_t)-1) { lpszW = (char *)s_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(s_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = s_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)s_pointer; } } #else setlocale(LC_CTYPE,f->language); nLen= MB_CUR_MAX * wcslen((const wchar_t*)s_pointer) + 1; lpszW = (char *)malloc(nLen*sizeof(char)); memset(lpszW, 0, nLen); wcstombs(lpszW, (const wchar_t *)s_pointer, nLen); #endif } else if(f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) == (iconv_t)-1) { lpszW = (char *)s_pointer; } else { iconv(c_pt, NULL, NULL, NULL, NULL); fromlen = strlen(s_pointer) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = s_pointer; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); if (ret == -1) { lpszW = (char *)s_pointer; } else { set_uformat(U_UNICODE); } } #else setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); #ifdef ALFONT_LINUX nLen = strlen(s_pointer) * 5 + 1; #else nLen= strlen(s_pointer) + 1; #endif lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); mbstowcs((wchar_t *)lpszW, s_pointer, nLen); #endif } else { #ifdef ALFONT_LINUX set_uformat(U_UTF8); nLen= ustrlen(s_pointer) + 1; #endif lpszW = (char *)s_pointer; } memset(*out, 0, _msize(*out)); if (_msize(*out) > 0 && _msize(lpszW) >= _msize(*out)) { memcpy(*out, lpszW, _msize(*out)); } else if (_msize(*out) > 0 && _msize(*out) > _msize(lpszW)) { memcpy(*out, lpszW, _msize(lpszW)); } if ((f->type==1)||(f->type==2)) { if (lpszW) free(lpszW); } if(s_pointer) { free(s_pointer); } #ifndef ALFONT_DOS setlocale(LC_CTYPE,""); #endif if (f->type==2) { set_uformat(curr_uformat); } } int alfont_need_uconvert(ALFONT_FONT *f, const char *str) { char *lpszW; char *str_pointer=NULL; //used for original string fixed by autofix char *str_pointer_temp=NULL; //temporary used for autofix string char *precedingchar_pointer=NULL; //used for precedingchar character int need_unicode_convert=TRUE; int nLen; int ret; //decide that if the ASCII Code convert to Unicode Code is all OK when used for autofix string or used for general convert. int curr_uformat; #ifdef ALFONT_DOS iconv_t c_pt; size_t fromlen, tolen; char *sin, *sout; #endif if (str == NULL) { return FALSE; } nLen = strlen(str) + 1; str_pointer = (char *)malloc(nLen*sizeof(char)); memset(str_pointer, 0, nLen); strcpy(str_pointer, str); //Auto Fix for cutted string //For ASCII convert to unicode //Add the previous character to the str string //If find the cutted character, store it from the converted str string and remove it from the original str string if (f->autofix==TRUE) { if (f->type==2) { curr_uformat=get_uformat(); #ifdef ALFONT_DOS if ((c_pt = iconv_open("UTF-16LE", f->language)) != (iconv_t)-1) { fromlen = strlen(str) + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); //add the previous character to the str string if (f->precedingchar != 0) { free(str_pointer); fromlen = strlen(str) + 1 + 1; tolen = MB_CUR_MAX * fromlen * (sizeof(wchar_t) + 1); str_pointer = (char *)malloc(tolen*sizeof(char)); memset(str_pointer, 0, tolen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(str_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(str_pointer, str); f->precedingchar = 0; } iconv(c_pt, NULL, NULL, NULL, NULL); lpszW = (char *)malloc(tolen*sizeof(char)); memset(lpszW, 0, tolen); sin = str; sout = lpszW; ret = iconv(c_pt, &sin, &fromlen, &sout, &tolen); iconv_close(c_pt); str_pointer_temp = str_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*str_pointer_temp != '\0') { f->precedingchar = *str_pointer_temp; str_pointer_temp++; } //remove the final character str_pointer_temp--; *str_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } } #else #ifdef ALFONT_LINUX nLen = strlen(str_pointer) * 5 + 1; #else nLen = strlen(str_pointer) + 1; #endif //add the previous character to the str string if (f->precedingchar != 0) { free(str_pointer); nLen = strlen(str) + 1 + 1; str_pointer = (char *)malloc(nLen*sizeof(char)); memset(str_pointer, 0, nLen); precedingchar_pointer=(char *)malloc(2*sizeof(char)); memset(precedingchar_pointer, 0, 2); sprintf(precedingchar_pointer, "%c", f->precedingchar); strcpy(str_pointer,precedingchar_pointer); if (precedingchar_pointer) { free(precedingchar_pointer); precedingchar_pointer = NULL; } strcat(str_pointer, str); f->precedingchar = 0; } setlocale(LC_CTYPE,f->language); set_uformat(U_UNICODE); lpszW = (char *)malloc(nLen*sizeof(wchar_t)); memset(lpszW, 0, nLen); ret = mbstowcs((wchar_t *)lpszW, str_pointer, nLen); str_pointer_temp = str_pointer; if (ret == -1) { //If the ret is -1, the final one will can be a shortcutted character. //store the last character to precedingchar character //get the final character set_uformat(curr_uformat); while (*str_pointer_temp != '\0') { f->precedingchar = *str_pointer_temp; str_pointer_temp++; } //remove the final character str_pointer_temp--; *str_pointer_temp = '\0'; } if (lpszW) { free(lpszW); lpszW = NULL; } #endif //recover to original codepage set_uformat(curr_uformat); } } if (f->type==1) { need_unicode_convert=FALSE; } else if(f->type==2) { curr_uformat=get_uformat(); if (!need_uconvert(str_pointer, U_ASCII, U_UTF8)) { need_unicode_convert=FALSE; } } else { need_unicode_convert=FALSE; } if(str_pointer) { free(str_pointer); } #ifndef ALFONT_DOS setlocale(LC_CTYPE,""); #endif if (f->type==2) { set_uformat(curr_uformat); } return need_unicode_convert; } void alfont_textout_centre_aa(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color) { alfont_textout_centre_aa_ex(bmp, f, s, x, y, color, alfont_textmode); } void alfont_textout_centre_aa_ex(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color, int backg) { x -= alfont_text_length(f, s) / 2; alfont_textout_aa_ex(bmp, f, s, x, y, color, backg); } void alfont_textout_centre(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color) { alfont_textout_centre_ex(bmp, f, s, x, y, color, alfont_textmode); } void alfont_textout_centre_ex(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color, int backg) { x -= alfont_text_length(f, s) / 2; alfont_textout_ex(bmp, f, s, x, y, color, backg); } void alfont_textout_right_aa(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color) { alfont_textout_right_aa_ex(bmp, f, s, x, y, color, alfont_textmode); } void alfont_textout_right_aa_ex(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color, int backg) { x -= alfont_text_length(f, s); alfont_textout_aa_ex(bmp, f, s, x, y, color, backg); } void alfont_textout_right(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color) { alfont_textout_right_ex(bmp, f, s, x, y, color, alfont_textmode); } void alfont_textout_right_ex(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color, int backg) { x -= alfont_text_length(f, s); alfont_textout_ex(bmp, f, s, x, y, color, backg); } void alfont_textprintf(BITMAP *bmp, ALFONT_FONT *f, int x, int y, int color, const char *format, ...) { char buf[512]; va_list ap; set_uformat(U_ASCII); va_start(ap, format); uvszprintf(buf, sizeof(buf), format, ap); va_end(ap); alfont_textout(bmp, f, buf, x, y, color); } void alfont_textprintf_ex(BITMAP *bmp, ALFONT_FONT *f, int x, int y, int color, int backg, const char *format, ...) { char buf[512]; va_list ap; set_uformat(U_ASCII); va_start(ap, format); uvszprintf(buf, sizeof(buf), format, ap); va_end(ap); alfont_textout_ex(bmp, f, buf, x, y, color, backg); } void alfont_textprintf_aa(BITMAP *bmp, ALFONT_FONT *f, int x, int y, int color, const char *format, ...) { char buf[512]; va_list ap; set_uformat(U_ASCII); va_start(ap, format); uvszprintf(buf, sizeof(buf), format, ap); va_end(ap); alfont_textout_aa(bmp, f, buf, x, y, color); } void alfont_textprintf_aa_ex(BITMAP *bmp, ALFONT_FONT *f, int x, int y, int color, int backg, const char *format, ...) { char buf[512]; va_list ap; set_uformat(U_ASCII); va_start(ap, format); uvszprintf(buf, sizeof(buf), format, ap); va_end(ap); alfont_textout_aa_ex(bmp, f, buf, x, y, color, backg); } void alfont_textprintf_centre(BITMAP *bmp, ALFONT_FONT *f, int x, int y, int color, const char *format, ...) { char buf[512]; va_list ap; set_uformat(U_ASCII); va_start(ap, format); uvszprintf(buf, sizeof(buf), format, ap); va_end(ap); alfont_textout_centre(bmp, f, buf, x, y, color); } void alfont_textprintf_centre_ex(BITMAP *bmp, ALFONT_FONT *f, int x, int y, int color, int backg, const char *format, ...) { char buf[512]; va_list ap; set_uformat(U_ASCII); va_start(ap, format); uvszprintf(buf, sizeof(buf), format, ap); va_end(ap); alfont_textout_centre_ex(bmp, f, buf, x, y, color, backg); } void alfont_textprintf_centre_aa(BITMAP *bmp, ALFONT_FONT *f, int x, int y, int color, const char *format, ...) { char buf[512]; va_list ap; set_uformat(U_ASCII); va_start(ap, format); uvszprintf(buf, sizeof(buf), format, ap); va_end(ap); alfont_textout_centre_aa(bmp, f, buf, x, y, color); } void alfont_textprintf_centre_aa_ex(BITMAP *bmp, ALFONT_FONT *f, int x, int y, int color, int backg, const char *format, ...) { char buf[512]; va_list ap; set_uformat(U_ASCII); va_start(ap, format); uvszprintf(buf, sizeof(buf), format, ap); va_end(ap); alfont_textout_centre_aa_ex(bmp, f, buf, x, y, color, backg); } void alfont_textprintf_right(BITMAP *bmp, ALFONT_FONT *f, int x, int y, int color, const char *format, ...) { char buf[512]; va_list ap; set_uformat(U_ASCII); va_start(ap, format); uvszprintf(buf, sizeof(buf), format, ap); va_end(ap); alfont_textout_right(bmp, f, buf, x, y, color); } void alfont_textprintf_right_ex(BITMAP *bmp, ALFONT_FONT *f, int x, int y, int color, int backg, const char *format, ...) { char buf[512]; va_list ap; set_uformat(U_ASCII); va_start(ap, format); uvszprintf(buf, sizeof(buf), format, ap); va_end(ap); alfont_textout_right_ex(bmp, f, buf, x, y, color, backg); } void alfont_textprintf_right_aa(BITMAP *bmp, ALFONT_FONT *f, int x, int y, int color, const char *format, ...) { char buf[512]; va_list ap; set_uformat(U_ASCII); va_start(ap, format); uvszprintf(buf, sizeof(buf), format, ap); va_end(ap); alfont_textout_right_aa(bmp, f, buf, x, y, color); } void alfont_textprintf_right_aa_ex(BITMAP *bmp, ALFONT_FONT *f, int x, int y, int color, int backg, const char *format, ...) { char buf[512]; va_list ap; set_uformat(U_ASCII); va_start(ap, format); uvszprintf(buf, sizeof(buf), format, ap); va_end(ap); alfont_textout_right_aa_ex(bmp, f, buf, x, y, color, backg); } int alfont_is_fixed_font(ALFONT_FONT *f) { if (f->num_fixed_sizes < 0) return FALSE; else return TRUE; } int alfont_is_scalable_font(ALFONT_FONT *f) { if (f->num_fixed_sizes < 0) return TRUE; else return FALSE; } const int *alfont_get_available_fixed_sizes(ALFONT_FONT *f) { /* we reget them just to make sure the contents where not changed */ _alfont_reget_fixed_sizes(f); return f->fixed_sizes; } int alfont_get_nof_available_fixed_sizes(ALFONT_FONT *f) { return f->num_fixed_sizes; } int alfont_get_char_extra_spacing(ALFONT_FONT *f) { return f->ch_spacing; } void alfont_set_char_extra_spacing(ALFONT_FONT *f, int spacing) { if (spacing < 0) f->ch_spacing = 0; else if (spacing > 4096) f->ch_spacing = 4096; else f->ch_spacing = spacing; } void alfont_set_language(ALFONT_FONT *f, const char *language) { if (language == NULL) { f->language = NULL; } else { f->language=(char *)malloc((strlen(language)+1)*sizeof(char)); strcpy(f->language,language); } } char *alfont_get_language(ALFONT_FONT *f) { return f->language; } void alfont_set_convert(ALFONT_FONT *f, int type) { if (type < 0) f->type = 0; else if (type > 2) f->type = 2; else f->type = type; } int alfont_get_convert(ALFONT_FONT *f) { return f->type; } void alfont_set_font_outline_top(ALFONT_FONT *f, int w) { if (w < 0) f->outline_top = 0; else f->outline_top = w; } int alfont_get_font_outline_top(ALFONT_FONT *f) { return f->outline_top; } void alfont_set_font_outline_bottom(ALFONT_FONT *f, int w) { if (w < 0) f->outline_bottom = 0; else f->outline_bottom = w; } int alfont_get_font_outline_bottom(ALFONT_FONT *f) { return f->outline_bottom; } void alfont_set_font_outline_right(ALFONT_FONT *f, int w) { if (w < 0) f->outline_right = 0; else f->outline_right = w; } int alfont_get_font_outline_right(ALFONT_FONT *f) { return f->outline_right; } void alfont_set_font_outline_left(ALFONT_FONT *f, int w) { if (w < 0) f->outline_left = 0; else f->outline_left = w; } int alfont_get_font_outline_left(ALFONT_FONT *f) { return f->outline_left; } void alfont_set_font_outline_color(ALFONT_FONT *f, int c) { if (c < 0) f->outline_color = 0; else f->outline_color = c; } int alfont_get_font_outline_color(ALFONT_FONT *f) { return f->outline_color; } void alfont_set_font_outline_hollow(ALFONT_FONT *f, int hollow) { if (hollow == FALSE) f->outline_hollow = FALSE; else f->outline_hollow = TRUE; } int alfont_get_font_outline_hollow(ALFONT_FONT *f) { return f->outline_hollow; } void alfont_set_font_style(ALFONT_FONT *f, int style) { if (style < 0) f->style = 0; else if (style > 3) f->style = 3; else f->style = style; } int alfont_get_font_style(ALFONT_FONT *f) { return f->style; } void alfont_set_font_underline(ALFONT_FONT *f, int underline) { if (underline == FALSE) f->underline = FALSE; else f->underline = TRUE; } int alfont_get_font_underline(ALFONT_FONT *f) { return f->underline; } void alfont_set_font_underline_right(ALFONT_FONT *f, int underline_right) { if (underline_right == FALSE) f->underline_right = FALSE; else f->underline_right = TRUE; } int alfont_get_font_underline_right(ALFONT_FONT *f) { return f->underline_right; } void alfont_set_font_underline_left(ALFONT_FONT *f, int underline_left) { if (underline_left == FALSE) f->underline_left = FALSE; else f->underline_left = TRUE; } int alfont_get_font_underline_left(ALFONT_FONT *f) { return f->underline_left; } void alfont_set_font_background(ALFONT_FONT *f, int background) { if (background == FALSE) f->background = FALSE; else f->background = TRUE; } int alfont_get_font_background(ALFONT_FONT *f) { return f->background; } void alfont_set_font_transparency(ALFONT_FONT *f, int transparency) { f->transparency = transparency; } int alfont_get_font_transparency(ALFONT_FONT *f) { return f->transparency; } void alfont_set_autofix(ALFONT_FONT *f, int autofix) { if (autofix == FALSE) f->autofix = FALSE; else f->autofix = TRUE; } int alfont_get_autofix(ALFONT_FONT *f) { return f->autofix; } void alfont_set_precedingchar(ALFONT_FONT *f, int precedingchar) { f->precedingchar = precedingchar; } int alfont_get_precedingchar(ALFONT_FONT *f) { return f->precedingchar; } ALFONT_DLL_DECLSPEC void alfont_set_font_fixed_width(ALFONT_FONT *f, int fixed_width) { if (fixed_width == FALSE) f->fixed_width = FALSE; else f->fixed_width = TRUE; _alfont_uncache_glyphs(f); }