From 0a5ace7f828ab1f7e5b11d564ba3cdf6ae5bca99 Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Wed, 9 Aug 2023 14:08:40 +0800 Subject: [PATCH] add a new method for DEVFONTOPS: get_feature(). currently used for check whether a devfont contains correct bounding box values for marks --- include/gdi.h | 2 ++ src/font/bitmapfont.c | 12 +++++++ src/font/freetype1.c | 12 +++++++ src/font/freetype2.c | 12 +++++++ src/font/nullfont.c | 12 +++++++ src/font/qpf.c | 12 +++++++ src/font/rawbitmap.c | 12 +++++++ src/font/scripteasy.c | 12 +++++++ src/font/upf.c | 12 +++++++ src/font/varbitmap.c | 12 +++++++ src/include/devfont.h | 10 +++++- src/newgdi/drawtext.c | 25 +++++++------- src/newgdi/drawtext.h | 2 ++ src/newgdi/glyph.c | 13 ++++++++ src/newgdi/tabbedtextout.c | 50 ++++++++++++++-------------- src/newgdi/textout.c | 68 ++++++++++++++++++++------------------ 16 files changed, 208 insertions(+), 70 deletions(-) diff --git a/include/gdi.h b/include/gdi.h index 760c6ed6..05cae2da 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -13003,6 +13003,8 @@ MG_EXPORT int GUIAPI DrawGlyph (HDC hdc, int x, int y, Glyph32 glyph_value, * \param last_adv The advance on the baseline of the last glyph. * * \return The advance on baseline of the vowel. + * + * Since 5.0.13 */ MG_EXPORT int GUIAPI DrawVowel (HDC hdc, int x, int y, Glyph32 glyph_value, int last_adv); diff --git a/src/font/bitmapfont.c b/src/font/bitmapfont.c index ea85bbf6..82b03a9b 100644 --- a/src/font/bitmapfont.c +++ b/src/font/bitmapfont.c @@ -202,6 +202,17 @@ static void destroy (GLYPHTREENODE *root) /*** device font ops ***/ +static DWORD get_feature (LOGFONT* logfont, DEVFONT* devfont, + enum devfont_feature feature) +{ + switch (feature) { + case DEVFONT_FEATURE_MARK_BBOX: + return 0; + } + + return 0; +} + static DWORD get_glyph_bmptype (LOGFONT* logfont, DEVFONT* devfont) { return DEVFONTGLYPHTYPE_PRERDRBMP; @@ -380,6 +391,7 @@ static int get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, /**************************** Global data ************************************/ FONTOPS __mg_bitmap_font_ops = { + get_feature, get_glyph_bmptype, get_ave_width, get_max_width, diff --git a/src/font/freetype1.c b/src/font/freetype1.c index c83a88ed..6b82e1a1 100644 --- a/src/font/freetype1.c +++ b/src/font/freetype1.c @@ -255,6 +255,17 @@ compute_kernval (TTFINSTANCEINFO* ttf_inst_info) return kernval; } +static DWORD get_feature (LOGFONT* logfont, DEVFONT* devfont, + enum devfont_feature feature) +{ + switch (feature) { + case DEVFONT_FEATURE_MARK_BBOX: + return 0; + } + + return 0; +} + static DWORD get_glyph_bmptype (LOGFONT* logfont, DEVFONT* devfont) { if (logfont->style & FS_WEIGHT_BOOK) @@ -792,6 +803,7 @@ static int is_rotatable (LOGFONT* logfont, DEVFONT* devfont, int rot_desired) } /**************************** Global data ************************************/ FONTOPS __mg_ttf_ops = { + get_feature, get_glyph_bmptype, get_ave_width, get_max_width, diff --git a/src/font/freetype2.c b/src/font/freetype2.c index eb7c7991..17781334 100644 --- a/src/font/freetype2.c +++ b/src/font/freetype2.c @@ -197,6 +197,17 @@ print_bitmap_grey (const BYTE* buffer, int width, int rows, int pitch) printf("*******************************************\n"); } +static DWORD get_feature (LOGFONT* logfont, DEVFONT* devfont, + enum devfont_feature feature) +{ + switch (feature) { + case DEVFONT_FEATURE_MARK_BBOX: + return 1; + } + + return 0; +} + static DWORD get_glyph_bmptype (LOGFONT* logfont, DEVFONT* devfont) { switch (logfont->style & FS_RENDER_MASK) { @@ -1265,6 +1276,7 @@ void font_TermFreetypeLibrary (void) /**************************** Global data ************************************/ FONTOPS __mg_ttf_ops = { + get_feature, get_glyph_bmptype, get_ave_width, get_max_width, diff --git a/src/font/nullfont.c b/src/font/nullfont.c index 13a02e16..31e5a3ef 100644 --- a/src/font/nullfont.c +++ b/src/font/nullfont.c @@ -66,6 +66,17 @@ #define NUF_WIDTH 8 #define NUF_HEIGHT 1 +static DWORD get_feature (LOGFONT* logfont, DEVFONT* devfont, + enum devfont_feature feature) +{ + switch (feature) { + case DEVFONT_FEATURE_MARK_BBOX: + return 0; + } + + return 0; +} + static DWORD get_glyph_bmptype (LOGFONT* logfont, DEVFONT* devfont) { return DEVFONTGLYPHTYPE_MONOBMP; @@ -171,6 +182,7 @@ static void unload_font_data (DEVFONT* devfont, void* data) } FONTOPS __mg_null_font_ops = { + get_feature, get_glyph_bmptype, get_ave_width, get_max_width, diff --git a/src/font/qpf.c b/src/font/qpf.c index 87acf83e..a24de7a2 100644 --- a/src/font/qpf.c +++ b/src/font/qpf.c @@ -287,6 +287,17 @@ static unsigned char def_smooth_bitmap [] = static QPF_GLYPH def_glyph = {&def_metrics, def_bitmap}; static QPF_GLYPH def_smooth_glyph = {&def_smooth_metrics, def_smooth_bitmap}; +static DWORD get_feature (LOGFONT* logfont, DEVFONT* devfont, + enum devfont_feature feature) +{ + switch (feature) { + case DEVFONT_FEATURE_MARK_BBOX: + return 0; + } + + return 0; +} + static DWORD get_glyph_bmptype (LOGFONT* logfont, DEVFONT* devfont) { if (QPFONT_INFO_P (devfont)->fm->flags & FLAG_MODE_SMOOTH) @@ -541,6 +552,7 @@ static int is_rotatable (LOGFONT* logfont, DEVFONT* devfont, int rot_desired) /**************************** Global data ************************************/ FONTOPS __mg_qpf_ops = { + get_feature, get_glyph_bmptype, get_ave_width, get_max_width, diff --git a/src/font/rawbitmap.c b/src/font/rawbitmap.c index 1f5742e6..c439b3ac 100644 --- a/src/font/rawbitmap.c +++ b/src/font/rawbitmap.c @@ -151,6 +151,17 @@ static void unload_font_data (DEVFONT* devfont, void* data) /*************** Raw bitmap font operations *********************************/ +static DWORD get_feature (LOGFONT* logfont, DEVFONT* devfont, + enum devfont_feature feature) +{ + switch (feature) { + case DEVFONT_FEATURE_MARK_BBOX: + return 0; + } + + return 0; +} + static DWORD get_glyph_bmptype (LOGFONT* logfont, DEVFONT* devfont) { return DEVFONTGLYPHTYPE_MONOBMP; @@ -280,6 +291,7 @@ static int is_rotatable (LOGFONT* logfont, DEVFONT* devfont, int rot_desired) /**************************** Global data ************************************/ FONTOPS __mg_rbf_ops = { + get_feature, get_glyph_bmptype, get_ave_width, get_ave_width, // max_width same as ave_width diff --git a/src/font/scripteasy.c b/src/font/scripteasy.c index 9942c0e8..811ef70c 100644 --- a/src/font/scripteasy.c +++ b/src/font/scripteasy.c @@ -377,6 +377,17 @@ static int get_max_width (LOGFONT* logfont, DEVFONT* devfont) return logfont->size; } +static DWORD get_feature (LOGFONT* logfont, DEVFONT* devfont, + enum devfont_feature feature) +{ + switch (feature) { + case DEVFONT_FEATURE_MARK_BBOX: + return 0; + } + + return 0; +} + static DWORD get_glyph_bmptype (LOGFONT* logfont, DEVFONT* devfont) { if (logfont->style & FS_WEIGHT_BOOK) @@ -598,6 +609,7 @@ static int is_rotatable (LOGFONT* logfont, DEVFONT* devfont, int rot_desired) /**************************** Global data ************************************/ static FONTOPS scripteasy_font_ops = { + get_feature, get_glyph_bmptype, get_ave_width, get_max_width, diff --git a/src/font/upf.c b/src/font/upf.c index dfcd6f7b..0f0e8999 100644 --- a/src/font/upf.c +++ b/src/font/upf.c @@ -148,6 +148,17 @@ static void unload_font_data (DEVFONT* devfont, void* data) free (((UPFINFO*) data)); } +static DWORD get_feature (LOGFONT* logfont, DEVFONT* devfont, + enum devfont_feature feature) +{ + switch (feature) { + case DEVFONT_FEATURE_MARK_BBOX: + return 0; + } + + return 0; +} + static DWORD get_glyph_bmptype (LOGFONT* logfont, DEVFONT* devfont) { Uint8* p_upf = (Uint8 *)UPFONT_INFO_P (devfont)->root_dir; @@ -525,6 +536,7 @@ static int is_rotatable (LOGFONT* logfont, DEVFONT* devfont, int rot_desired) } FONTOPS __mg_upf_ops = { + get_feature, get_glyph_bmptype, get_ave_width, get_max_width, diff --git a/src/font/varbitmap.c b/src/font/varbitmap.c index be58014a..97d6c72d 100644 --- a/src/font/varbitmap.c +++ b/src/font/varbitmap.c @@ -109,6 +109,17 @@ typedef struct _FONT_PROPT { int def_glyph; } FONT_PROPT; +static DWORD get_feature (LOGFONT* logfont, DEVFONT* devfont, + enum devfont_feature feature) +{ + switch (feature) { + case DEVFONT_FEATURE_MARK_BBOX: + return 0; + } + + return 0; +} + static DWORD get_glyph_bmptype (LOGFONT* logfont, DEVFONT* devfont) { return DEVFONTGLYPHTYPE_MONOBMP; @@ -477,6 +488,7 @@ static void unload_font_data (DEVFONT* devfont, void* data) } FONTOPS __mg_vbf_ops = { + get_feature, get_glyph_bmptype, get_ave_width, get_max_width, diff --git a/src/include/devfont.h b/src/include/devfont.h index a25d7001..fff71918 100644 --- a/src/include/devfont.h +++ b/src/include/devfont.h @@ -209,7 +209,7 @@ struct _CHARSETOPS /** Default character. */ Achar32 def_char_value; - /** Whether use legacy BIDI algorithm (Since 5.0.13). */ + /** Whether using legacy BIDI algorithm (Since 5.0.13). */ unsigned legacy_bidi:1; /** The method to get the length of the first character. */ @@ -266,9 +266,17 @@ struct _CHARSETOPS #define DEVFONTGLYPHTYPE_MASK_BMPTYPE 0x0F +enum devfont_feature { + DEVFONT_FEATURE_MARK_BBOX = 0, +}; + /** The font operation structure. */ struct _FONTOPS { + /** The method to get the feature value of the font (Since 5.0.13). */ + DWORD (*get_feature) (LOGFONT* logfont, DEVFONT* devfont, + enum devfont_feature feature); + /** The method to get the glyph bitmap type . */ DWORD (*get_glyph_bmptype) (LOGFONT* logfont, DEVFONT* devfont); diff --git a/src/newgdi/drawtext.c b/src/newgdi/drawtext.c index 0c707b5f..05df66ad 100644 --- a/src/newgdi/drawtext.c +++ b/src/newgdi/drawtext.c @@ -146,18 +146,19 @@ static BOOL cb_drawtextex2 (void* context, Glyph32 glyph_value, case ACHAR_BASIC_VOWEL: if (!ctxt->only_extent) { -#if 0 - int bkmode = ctxt->pdc->bkmode; - ctxt->pdc->bkmode = BM_TRANSPARENT; - _gdi_draw_one_glyph (ctxt->pdc, glyph_value, - (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, - ctxt->x, ctxt->y, &adv_x, &adv_y); - ctxt->pdc->bkmode = bkmode; -#else - _gdi_draw_one_vowel (ctxt->pdc, glyph_value, - (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, - ctxt->last_x, ctxt->last_y, ctxt->last_adv); -#endif + if (_gdi_if_mark_bbox_is_ok(ctxt->pdc, glyph_value)) { + int bkmode = ctxt->pdc->bkmode; + ctxt->pdc->bkmode = ctxt->pdc->bkmode_set; + _gdi_draw_one_glyph (ctxt->pdc, glyph_value, + (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + ctxt->x, ctxt->y, &adv_x, &adv_y); + ctxt->pdc->bkmode = bkmode; + } + else { + _gdi_draw_one_vowel (ctxt->pdc, glyph_value, + (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + ctxt->last_x, ctxt->last_y, ctxt->last_adv); + } adv_x = adv_y = 0; } break; diff --git a/src/newgdi/drawtext.h b/src/newgdi/drawtext.h index eb59a74a..b3acfe1c 100644 --- a/src/newgdi/drawtext.h +++ b/src/newgdi/drawtext.h @@ -82,6 +82,8 @@ static inline int _gdi_get_glyph_advance (PDC pdc, Glyph32 glyph_value, direction, pdc->cExtra, x, y, adv_x, adv_y, bbox); } +BOOL _gdi_if_mark_bbox_is_ok(PDC pdc, Glyph32 gv); + int _gdi_draw_one_vowel (PDC pdc, Glyph32 glyph_value, BOOL direction, int x, int y, int last_adv); diff --git a/src/newgdi/glyph.c b/src/newgdi/glyph.c index 45ab50d8..3b3a68b3 100644 --- a/src/newgdi/glyph.c +++ b/src/newgdi/glyph.c @@ -2806,6 +2806,18 @@ static void draw_glyph_lines (PDC pdc, int x1, int y1, int x2, int y2) } } +BOOL _gdi_if_mark_bbox_is_ok(PDC pdc, Glyph32 gv) +{ + LOGFONT* logfont; + DEVFONT* devfont; + + logfont = pdc->pLogFont; + devfont = SELECT_DEVFONT_BY_GLYPH (logfont, gv); + + return devfont->font_ops->get_feature(logfont, devfont, + DEVFONT_FEATURE_MARK_BBOX) != 0; +} + int _gdi_draw_one_glyph (PDC pdc, Glyph32 glyph_value, BOOL direction, int x, int y, int* adv_x, int* adv_y) { @@ -3091,6 +3103,7 @@ int GUIAPI DrawGlyph (HDC hdc, int x, int y, Glyph32 glyph_value, return advance; } +/* XXX: an experimental API */ int GUIAPI DrawVowel (HDC hdc, int x, int y, Glyph32 glyph_value, int last_adv) { diff --git a/src/newgdi/tabbedtextout.c b/src/newgdi/tabbedtextout.c index 9cdc8c6c..e3229142 100644 --- a/src/newgdi/tabbedtextout.c +++ b/src/newgdi/tabbedtextout.c @@ -161,18 +161,19 @@ static BOOL cb_tabbedtextout (void* context, Glyph32 glyph_value, case ACHAR_BASIC_VOWEL: if (!ctxt->only_extent) { -#if 0 - int bkmode = ctxt->pdc->bkmode; - ctxt->pdc->bkmode = BM_TRANSPARENT; - _gdi_draw_one_glyph (ctxt->pdc, glyph_value, - (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, - ctxt->x, ctxt->y, &adv_x, &adv_y); - ctxt->pdc->bkmode = bkmode; -#else - _gdi_draw_one_vowel (ctxt->pdc, glyph_value, - (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, - ctxt->last_x, ctxt->last_y, ctxt->last_adv); -#endif + if (_gdi_if_mark_bbox_is_ok(ctxt->pdc, glyph_value)) { + int bkmode = ctxt->pdc->bkmode; + ctxt->pdc->bkmode = ctxt->pdc->bkmode_set; + _gdi_draw_one_glyph (ctxt->pdc, glyph_value, + (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + ctxt->x, ctxt->y, &adv_x, &adv_y); + ctxt->pdc->bkmode = bkmode; + } + else { + _gdi_draw_one_vowel (ctxt->pdc, glyph_value, + (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + ctxt->last_x, ctxt->last_y, ctxt->last_adv); + } } adv_x = adv_y = 0; break; @@ -261,18 +262,19 @@ static BOOL cb_tabbedtextoutex (void* context, Glyph32 glyph_value, break; case ACHAR_BASIC_VOWEL: { -#if 0 - int bkmode = ctxt->pdc->bkmode; - ctxt->pdc->bkmode = BM_TRANSPARENT; - _gdi_draw_one_glyph (ctxt->pdc, glyph_value, - (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, - ctxt->x, ctxt->y, &adv_x, &adv_y); - ctxt->pdc->bkmode = bkmode; -#else - _gdi_draw_one_vowel (ctxt->pdc, glyph_value, - (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, - ctxt->last_x, ctxt->last_y, ctxt->last_adv); -#endif + if (_gdi_if_mark_bbox_is_ok(ctxt->pdc, glyph_value)) { + int bkmode = ctxt->pdc->bkmode; + ctxt->pdc->bkmode = ctxt->pdc->bkmode_set; + _gdi_draw_one_glyph (ctxt->pdc, glyph_value, + (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + ctxt->x, ctxt->y, &adv_x, &adv_y); + ctxt->pdc->bkmode = bkmode; + } + else { + _gdi_draw_one_vowel (ctxt->pdc, glyph_value, + (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + ctxt->last_x, ctxt->last_y, ctxt->last_adv); + } adv_x = adv_y = 0; break; } diff --git a/src/newgdi/textout.c b/src/newgdi/textout.c index 4a4a8349..9252e9ce 100644 --- a/src/newgdi/textout.c +++ b/src/newgdi/textout.c @@ -128,15 +128,15 @@ static BOOL cb_draw_glyph (void* context, Glyph32 glyph_value, unsigned int char adv_x = adv_y = 0; } else if (check_vowel(char_type)) { - int bkmode = GetBkMode (ctxt->hdc); - SetBkMode (ctxt->hdc, BM_TRANSPARENT); -#if 0 - DrawGlyph (ctxt->hdc, ctxt->x, ctxt->y, glyph_value, &adv_x, &adv_y); -#else - DrawVowel (ctxt->hdc, ctxt->last_x, ctxt->last_y, glyph_value, - ctxt->last_adv); -#endif - SetBkMode (ctxt->hdc, bkmode); + PDC pdc = dc_HDC2PDC(ctxt->hdc); + if (_gdi_if_mark_bbox_is_ok(pdc, glyph_value)) { + DrawGlyph (ctxt->hdc, ctxt->x, ctxt->y, glyph_value, + &adv_x, &adv_y); + } + else { + DrawVowel (ctxt->hdc, ctxt->last_x, ctxt->last_y, + glyph_value, ctxt->last_adv); + } adv_x = 0; adv_y = 0; } @@ -175,18 +175,19 @@ static BOOL cb_textout (void* context, Glyph32 glyph_value, } else if (check_vowel(char_type)) { if (!ctxt->only_extent) { -#if 0 - int bkmode = ctxt->pdc->bkmode; - ctxt->pdc->bkmode = BM_TRANSPARENT; - _gdi_draw_one_glyph (ctxt->pdc, glyph_value, - (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, - ctxt->x, ctxt->y, &adv_x, &adv_y); - ctxt->pdc->bkmode = bkmode; -#else - _gdi_draw_one_vowel (ctxt->pdc, glyph_value, - (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, - ctxt->last_x, ctxt->last_y, ctxt->last_adv); -#endif + if (_gdi_if_mark_bbox_is_ok(ctxt->pdc, glyph_value)) { + int bkmode = ctxt->pdc->bkmode; + ctxt->pdc->bkmode = ctxt->pdc->bkmode_set; + _gdi_draw_one_glyph (ctxt->pdc, glyph_value, + (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + ctxt->x, ctxt->y, &adv_x, &adv_y); + ctxt->pdc->bkmode = bkmode; + } + else { + _gdi_draw_one_vowel (ctxt->pdc, glyph_value, + (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + ctxt->last_x, ctxt->last_y, ctxt->last_adv); + } } adv_x = adv_y = 0; } @@ -356,18 +357,19 @@ cb_textout_omitted (void* context, Glyph32 glyph_value, unsigned int char_type) adv_x = adv_y = 0; } else if (check_vowel(char_type)) { -#if 0 - int bkmode = ctxt->pdc->bkmode; - ctxt->pdc->bkmode = BM_TRANSPARENT; - _gdi_draw_one_glyph (ctxt->pdc, glyph_value, - (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, - ctxt->x, ctxt->y, &adv_x, &adv_y); - ctxt->pdc->bkmode = bkmode; -#else - _gdi_draw_one_vowel (ctxt->pdc, glyph_value, - (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, - ctxt->last_x, ctxt->last_y, ctxt->last_adv); -#endif + if (_gdi_if_mark_bbox_is_ok(ctxt->pdc, glyph_value)) { + int bkmode = ctxt->pdc->bkmode; + ctxt->pdc->bkmode = ctxt->pdc->bkmode_set; + _gdi_draw_one_glyph (ctxt->pdc, glyph_value, + (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + ctxt->x, ctxt->y, &adv_x, &adv_y); + ctxt->pdc->bkmode = bkmode; + } + else { + _gdi_draw_one_vowel (ctxt->pdc, glyph_value, + (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + ctxt->last_x, ctxt->last_y, ctxt->last_adv); + } adv_x = adv_y = 0; } else {