diff --git a/include/gdi.h b/include/gdi.h index d26c68c0..9381c009 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -11435,13 +11435,15 @@ MG_EXPORT int GUIAPI GetGlyphsPositionInfo(LOGFONT* logfont_upright, * This function gets the visual extent information of a glyph string which can * fit a line with the specified maximal extent. * - * \param logfont The logfont used to parse the glyph string. + * \param logfont_upright The logfont used to render the uchar string. Note + * that the charset/encoding of this logfont should be Unicode, such as + * UTF-8, UTF-16LE, and UTF-16BE. * \param uchars The pointer to the achar string. * \param nr_uchars The number of the glyphs. * \param break_oppos The pointer to the break opportunities array of the glyphs. * It should be returned by \a GetUCharsAndBreaks. However, the caller * should skip the first unit (the break opportunity before the first glyph) - * before passing the pointer to this function. + * when passing the pointer to this function. * \param render_flags The render flags; see \a glyph_render_flags. * \param x The x-position of first glyph. * \param y The y-position of first glyph. @@ -11475,6 +11477,12 @@ MG_EXPORT int GUIAPI GetGlyphsPositionInfo(LOGFONT* logfont_upright, * * \note Only available when support for UNICODE is enabled. * + * \note This function ignore the special types (such as diacritic mark, + * vowel, contextual form, ligature, and so on) of the Unicode characters. + * Please see \a GetShapedGlyphsStandard and \a GetShapedGlyphsComplex + * for the purpose of shaping glyphs according to the language, script + * (writing system), and the contextual shape features. + * * \note Any invisible format character including SOFT HYPHEN (U+00AD) * will be ignored (suppressed). * @@ -11516,8 +11524,8 @@ MG_EXPORT int GUIAPI GetGlyphsExtentFromUChars(LOGFONT* logfont_upright, * \param logfont_upright The LOGFONT object used for upright glyphs. * \param logfont_sideways The LOGFONT object used for sideways glyphs. * \param glyphs The pointer to the glyph string; either a Glyph32 array - * or a SHAPEDGLYPH array. You should specify the element size via - * \a glyph_unit_size. + * or a SHAPEDGLYPH array. You should specify the unit size of the array + * via \a glyph_unit_size. * \param glyph_unit_size The size of one glyph unit item in bytes. If * it is zero, then sizeof (Glyph32) will be used. * \param glyph_pos The buffer holds the position information diff --git a/src/font/charset-arabic.c b/src/font/charset-arabic.c index e6cb0a42..2c6a1735 100644 --- a/src/font/charset-arabic.c +++ b/src/font/charset-arabic.c @@ -849,7 +849,7 @@ static BOOL iso8859_6_bidi_mirror_char (Achar32 chv, Achar32* mirrored) static CHARSETOPS CharsetOps_iso8859_6 = { 256, - 1, + 3, FONT_CHARSET_ISO8859_6, 0, iso8859_6_len_first_char, diff --git a/src/font/fontcache.c b/src/font/fontcache.c index 7355872b..e74304f8 100644 --- a/src/font/fontcache.c +++ b/src/font/fontcache.c @@ -378,7 +378,7 @@ AppendBlk(FontCache *cache, MemBlk *blk, int key) *size : if found the data, how long is the data(return val) reutrn = pointer to the data */ TTFCACHEINFO * -__mg_ttc_search(HCACHE hCache, Uchar32 unicode, int *size) +__mg_ttc_search(HCACHE hCache, Glyph32 gv, int *size) { int key; CacheQueueNode *ca; @@ -388,7 +388,7 @@ __mg_ttc_search(HCACHE hCache, Uchar32 unicode, int *size) return NULL; } ca = (CacheQueueNode *)(hCache); - key = ca->cache.makeHashKeyFunc(unicode); + key = ca->cache.makeHashKeyFunc(gv); if (key > (ca->cache.nDir - 1)) { return NULL; } @@ -397,7 +397,7 @@ __mg_ttc_search(HCACHE hCache, Uchar32 unicode, int *size) for ( ; blk != &(ca->cache.hashDir[key].hashHead); blk = blk->hashNext) { TTFCACHEINFO* tci = (TTFCACHEINFO*)blk->data; - if (tci->unicode == unicode) { + if (tci->glyph_code == gv) { /* If found the blk, we should pick off it and link it at the end of LRU-q */ *size = blk->len; @@ -433,7 +433,7 @@ __mg_ttc_write(HCACHE hCache, TTFCACHEINFO *data, int size) if (ca->cache.blkSize < size) { return -1; } - key = ca->cache.makeHashKeyFunc(data->unicode); + key = ca->cache.makeHashKeyFunc(data->glyph_code); /* pick off a block from lru queue */ if ((blk = PickOffBlk(&ca->cache)) == NULL) { @@ -695,7 +695,6 @@ void __mg_ttc_dump_cacheinfo(TTFCACHEINFO *ca) { DP(("Dump TTFCACHEINFO %p...\n", ca)); - DP(("cacheInfo->unicode = %d\n", ca->unicode)); DP(("cacheInfo->glyph_code = %d\n", ca->glyph_code)); DP(("cacheInfo->cur_xmin = %d, cacheInfo->cur_ymin = %d\n", @@ -714,7 +713,6 @@ void __mg_ttc_dump_instance(TTFINSTANCEINFO *in) { DP(("Dump TTFINSTANCEINFO %p...\n", in)); - DP(("Instance->cur_unicode = %d\n", in->cur_unicode)); DP(("Instance->cur_glyph_code = %d\n", in->cur_glyph_code)); DP(("Instance->outline(addr) = %p\n", &in->cur_outline)); DP(("Instance->cur_xmin = %d, Instance->cur_ymin = %d\n", diff --git a/src/font/freetype2.c b/src/font/freetype2.c index 705594df..87c6eb5f 100644 --- a/src/font/freetype2.c +++ b/src/font/freetype2.c @@ -272,10 +272,9 @@ get_font_descent (LOGFONT* logfont, DEVFONT* devfont) static int load_or_search_glyph (FTINSTANCEINFO* ft_inst_info, FT_Face* face, - FT_ULong uni_char, int char_type) + Glyph32 gv, int char_type) { /* no need to lock/unlock in this function */ - #ifndef _MGFONT_TTF_CACHE FTFACEINFO* ft_face_info = ft_inst_info->ft_face_info; int ft_load_flags = FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; @@ -294,8 +293,7 @@ load_or_search_glyph (FTINSTANCEINFO* ft_inst_info, FT_Face* face, FT_Activate_Size (ft_inst_info->size); *face = ft_face_info->face; - ft_inst_info->cur_index = FT_Get_Char_Index (*face, uni_char); - + ft_inst_info->cur_index = gv; if (FT_Load_Glyph (*face, ft_inst_info->cur_index, ft_load_flags)) { _MG_PRINTF ("FONT>FT2: FT_Load_Glyph error\n"); return -1; @@ -315,16 +313,9 @@ load_or_search_glyph (FTINSTANCEINFO* ft_inst_info, FT_Face* face, return 0; } - ft_inst_info->cur_index = FTC_CMapCache_Lookup (ft_cmap_cache, - (FTC_FaceID) (ft_inst_info->image_type.face_id), - ft_inst_info->ft_face_info->cmap_index, - uni_char); - - if (FTC_ImageCache_Lookup (ft_image_cache, - &ft_inst_info->image_type, - ft_inst_info->cur_index, - &ft_glyph_tmp, - NULL)) { + ft_inst_info->cur_index = gv; + if (FTC_ImageCache_Lookup (ft_image_cache, &ft_inst_info->image_type, + ft_inst_info->cur_index, &ft_glyph_tmp, NULL)) { _MG_PRINTF ("FONT>FT2: can't access image cache.\n"); return -1; } @@ -345,24 +336,17 @@ load_or_search_glyph (FTINSTANCEINFO* ft_inst_info, FT_Face* face, /* call this function before getting the bitmap/pixmap of the char * to get the bbox of the char */ static int -get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, - Glyph32 glyph_value, +get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, Glyph32 gv, int* px, int* py, int* pwidth, int* pheight) { - FT_BBox bbox; FT_Face face; - FT_UInt uni_char; FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); bbox.xMin = bbox.yMin = 32000; bbox.xMax = bbox.yMax = -32000; - glyph_value = REAL_GLYPH(glyph_value); - if (devfont->charset_ops->conv_to_uc32) - uni_char = (*devfont->charset_ops->conv_to_uc32) (glyph_value); - else - uni_char = glyph_value; + gv = REAL_GLYPH(gv); FT_LOCK(&ft_lock); @@ -371,8 +355,7 @@ get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, if (ft_inst_info->cache) { TTFCACHEINFO *cache_info; int datasize; - cache_info = __mg_ttc_search(ft_inst_info->cache, - uni_char, &datasize); + cache_info = __mg_ttc_search(ft_inst_info->cache, gv, &datasize); if (cache_info != NULL) { DP(("%s: BBOX Hit!! %d\n", __FUNCTION__, bbox_hit++)); @@ -390,12 +373,11 @@ get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, FT_UNLOCK(&ft_lock); return (int)(cache_info->bbox.xMax - cache_info->bbox.xMin); } - DP(("%s: BBOX Non - Hit! %d, %d\n", - __FUNCTION__, bbox_nohit++, uni_char)); + DP(("%s: BBOX Non - Hit! %d, %d\n", __FUNCTION__, bbox_nohit++, gv)); } #endif /* _MGFONT_TTF_CACHE */ - if (load_or_search_glyph (ft_inst_info, &face, uni_char, + if (load_or_search_glyph (ft_inst_info, &face, gv, get_glyph_bmptype(logfont, devfont))) { _ERR_PRINTF ("FONT>FT2: load_or_search_glyph error in freetype2\n"); goto error; @@ -451,12 +433,10 @@ get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, int datasize; int size = 0; - pcache = __mg_ttc_search(ft_inst_info->cache, - uni_char, &datasize); + pcache = __mg_ttc_search(ft_inst_info->cache, gv, &datasize); if (pcache == NULL) { cache_info.glyph_code = ft_inst_info->cur_index; - cache_info.unicode = uni_char; cache_info.bbox = ft_inst_info->bbox; cache_info.advance = ft_inst_info->advance; cache_info.delta = ft_inst_info->delta; @@ -490,34 +470,27 @@ error: /* call this function to get the bitmap/pixmap of the char */ static const void* char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, - Glyph32 glyph_value, SIZE* sz, int* pitch, BOOL is_grey) + Glyph32 gv, SIZE* sz, int* pitch, BOOL is_grey) { FT_BitmapGlyph glyph_bitmap; FT_Bitmap* source; - FT_UInt uni_char; FT_Face face; BYTE* buffer = NULL; FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); - glyph_value = REAL_GLYPH(glyph_value); + gv = REAL_GLYPH(gv); FT_LOCK(&ft_lock); if (IS_SUBPIXEL(logfont)) FT_Library_SetLcdFilter(ft_library, ft_inst_info->ft_lcdfilter); - if (devfont->charset_ops->conv_to_uc32) - uni_char = (*devfont->charset_ops->conv_to_uc32) (glyph_value); - else - uni_char = glyph_value; - #ifdef _MGFONT_TTF_CACHE if (ft_inst_info->cache) { TTFCACHEINFO *cacheinfo; int datasize; - cacheinfo = __mg_ttc_search(ft_inst_info->cache, - uni_char, &datasize); + cacheinfo = __mg_ttc_search(ft_inst_info->cache, gv, &datasize); if (cacheinfo != NULL && cacheinfo->flag == TRUE) { DP(("%s: Bitmap Hit!! %d\n", __FUNCTION__, bitmap_hit++)); @@ -534,11 +507,11 @@ char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, return cacheinfo->bitmap; } - DP(("%s: Bitmap Non hit %d, %d\n", __FUNCTION__, bitmap_nohit++, uni_char)); + DP(("%s: Bitmap Non hit %d, %d\n", __FUNCTION__, bitmap_nohit++, gv)); } #endif /* _MGFONT_TTF_CACHE */ - if (load_or_search_glyph (ft_inst_info, &face, uni_char, + if (load_or_search_glyph (ft_inst_info, &face, gv, get_glyph_bmptype(logfont, devfont))) { _ERR_PRINTF ("FONT>FT2: load_or_search_glyph failed in freetype2\n"); goto error; @@ -577,13 +550,11 @@ char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, int datasize; int size = source->rows * source->pitch; - pcache = __mg_ttc_search(ft_inst_info->cache, - uni_char, &datasize); + pcache = __mg_ttc_search(ft_inst_info->cache, gv, &datasize); if (pcache == NULL) { TTFCACHEINFO cache_info; cache_info.glyph_code = ft_inst_info->cur_index; - cache_info.unicode = uni_char; cache_info.bbox = ft_inst_info->bbox; cache_info.advance = ft_inst_info->advance; cache_info.delta = ft_inst_info->delta; @@ -609,7 +580,7 @@ char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, pcache->flag = TRUE; DP(("%s: Write bitmap data for 0x%x to cache, bitmap (%d X %d, %d), cache = %p\n", - __FUNCTION__, uni_char, source->width, source->rows, + __FUNCTION__, gv, source->width, source->rows, source->pitch, ft_inst_info->cache)); } @@ -661,21 +632,21 @@ error: static const void* get_glyph_monobitmap (LOGFONT* logfont, DEVFONT* devfont, - Glyph32 glyph_value, SIZE* sz, int* pitch, unsigned short* scale) + Glyph32 gv, SIZE* sz, int* pitch, unsigned short* scale) { - glyph_value = REAL_GLYPH(glyph_value); + gv = REAL_GLYPH(gv); if (scale) *scale = 1; - return char_bitmap_pixmap (logfont, devfont, glyph_value, sz, pitch, FALSE); + return char_bitmap_pixmap (logfont, devfont, gv, sz, pitch, FALSE); } static const void* get_glyph_greybitmap (LOGFONT* logfont, DEVFONT* devfont, - Glyph32 glyph_value, SIZE* sz, int* pitch, + Glyph32 gv, SIZE* sz, int* pitch, unsigned short* scale) { - glyph_value = REAL_GLYPH(glyph_value); + gv = REAL_GLYPH(gv); if (scale) *scale = 1; - return char_bitmap_pixmap (logfont, devfont, glyph_value, sz, pitch, TRUE); + return char_bitmap_pixmap (logfont, devfont, gv, sz, pitch, TRUE); } /* call this function before output a string */ @@ -696,12 +667,12 @@ start_str_output (LOGFONT* logfont, DEVFONT* devfont) * to get the advance of the char */ static int get_glyph_advance (LOGFONT* logfont, DEVFONT* devfont, - Glyph32 glyph_value, int* px, int* py) + Glyph32 gv, int* px, int* py) { FT_Fixed advance; FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); - glyph_value = REAL_GLYPH(glyph_value); + gv = REAL_GLYPH(gv); if (ft_inst_info->use_kerning && ft_inst_info->prev_index && ft_inst_info->cur_index) { if (ft_inst_info->is_index_old) { @@ -722,7 +693,7 @@ get_glyph_advance (LOGFONT* logfont, DEVFONT* devfont, } #ifdef _MGFONT_TTF_CACHE -static inline int make_hash_key(Uchar32 data) +static int make_hash_key(Glyph32 data) { return ((int)data % 37); } @@ -928,50 +899,44 @@ delete_instance (DEVFONT* devfont) free (devfont); } -static BOOL is_glyph_existed (LOGFONT* logfont, DEVFONT* devfont, Glyph32 glyph_value) +static Glyph32 get_glyph_value (LOGFONT* logfont, DEVFONT* devfont, Achar32 ac) { - FT_Face face; - FT_UInt uni_char; + FT_Face face; + FT_UInt uc; + Glyph32 gv = INV_GLYPH_VALUE; FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); - glyph_value = REAL_GLYPH(glyph_value); if (devfont->charset_ops->conv_to_uc32) - uni_char = (*devfont->charset_ops->conv_to_uc32) (glyph_value); + uc = (*devfont->charset_ops->conv_to_uc32) (ac); else - uni_char = glyph_value; + uc = REAL_ACHAR(ac); FT_LOCK(&ft_lock); #ifndef _MGFONT_TTF_CACHE face = ft_inst_info->ft_face_info->face; - if (0 == FT_Get_Char_Index (face, uni_char)) - goto error; - else { - FT_UNLOCK(&ft_lock); - return TRUE; - } - + gv = FT_Get_Char_Index (face, uc); #else /* !_MGFONT_TTF_CACHE */ - if (get_cached_face (ft_inst_info, &face)) { _MG_PRINTF ("FONT>FT2: can't access cached face %p\n", ft_inst_info->ft_face_info); goto error; } - if (0 == FTC_CMapCache_Lookup (ft_cmap_cache, - (FTC_FaceID) (ft_inst_info->image_type.face_id), - ft_inst_info->ft_face_info->cmap_index, uni_char)) { - goto error; - } - else { - FT_UNLOCK(&ft_lock); - return TRUE; - } - + gv = FTC_CMapCache_Lookup (ft_cmap_cache, + (FTC_FaceID) (ft_inst_info->image_type.face_id), + ft_inst_info->ft_face_info->cmap_index, uc); #endif /* _MGFONT_TTF_CACHE */ error: FT_UNLOCK(&ft_lock); + return gv; +} + +static BOOL is_glyph_existed (LOGFONT* logfont, DEVFONT* devfont, Glyph32 gv) +{ + if (REAL_GLYPH(gv)) + return TRUE; + return FALSE; } @@ -1231,7 +1196,8 @@ FONTOPS __mg_ttf_ops = { delete_instance, is_rotatable, load_font_data, - unload_font_data + unload_font_data, + get_glyph_value }; BOOL diff --git a/src/font/freetype2.h b/src/font/freetype2.h index 30c79d8f..a3d23256 100644 --- a/src/font/freetype2.h +++ b/src/font/freetype2.h @@ -72,7 +72,7 @@ extern "C" { #ifdef _MGFONT_TTF_CACHE typedef void* HCACHE; -typedef int (* MakeHashKeyFunc)(Uchar32 unicode); +typedef int (* MakeHashKeyFunc)(Glyph32 gv); #endif typedef struct tagFTFACEINFO { @@ -122,7 +122,6 @@ typedef struct tagFTINSTANCEINFO { #define _TTF_HASH_NDIR 37 typedef struct tagTTFCACHEINFO { - Uchar32 unicode; FT_UInt glyph_code; FT_Vector advance; FT_BBox bbox; @@ -144,8 +143,7 @@ extern int __mg_ttc_write(HCACHE hCache, TTFCACHEINFO *data, int size); extern void __mg_ttc_release(HCACHE hCache); extern int __mg_ttc_sys_init(int maxCache, int cacheSize); extern void __mg_ttc_sys_deinit(void); -extern TTFCACHEINFO *__mg_ttc_search(HCACHE hCache, - Uchar32 unicode, int *size); +extern TTFCACHEINFO *__mg_ttc_search(HCACHE hCache, Glyph32 gv, int *size); extern void __mg_ttc_refer(HCACHE hCache); #endif diff --git a/src/font/rawbitmap.c b/src/font/rawbitmap.c index 021c4d2a..ffe327b9 100644 --- a/src/font/rawbitmap.c +++ b/src/font/rawbitmap.c @@ -162,8 +162,9 @@ static int get_font_size (LOGFONT* logfont, DEVFONT* devfont, int expect, int df if (logfont->style & FS_OTHER_AUTOSCALE) scale = font_GetBestScaleFactor (height, expect); - if (df_slot >= 0 && df_slot < MAXNR_DEVFONTS) + if (df_slot >= 0 && df_slot < MAXNR_DEVFONTS) { SET_DEVFONT_SCALE (logfont, df_slot, scale); + } return height * scale; }