From e575e7c69d458938e80fd35cdcc008f3e08520b9 Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Mon, 24 Apr 2023 11:38:02 +0800 Subject: [PATCH] add new APIs: GetTabbedACharsExtentXXX --- RELEASE-NOTES.md | 6 +++ include/gdi.h | 74 +++++++++++++++++++++++++++ src/newgdi/legacy-bidi.c | 3 +- src/newgdi/tabbedtextout.c | 102 +++++++++++++++++++++++++++++++++++-- src/newgdi/textout.c | 8 +-- 5 files changed, 183 insertions(+), 10 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 72830e58..4a0e648f 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,5 +1,7 @@ # Release Notes +- [Version 5.0.12](#version-5012) + + [What's new in version 5.0.12](#whats-new-in-version-5012) - [Version 5.0.11](#version-5011) + [What's new in version 5.0.11](#whats-new-in-version-5011) - [Version 5.0.10](#version-5010) @@ -40,8 +42,12 @@ In this version, we made some enhancements: * ENHANCEMENTS: - Add new API `GetACharsExtentPointEx()`. + - Add new APIs `GetTabbedACharsExtent()`, `GetTabbedACharsExtentPoint()`, + and `GetTabbedACharsExtentPointEx()`. - Enhance two APIs `GetTextExtentPoint()` and `GetTabbedTextExtentPoint()` to support BIDI charsets. +* BUGFIXING: + - Fix a typo: `Achar2UChar()` to `AChar2UChar()`. ## Version 5.0.11 diff --git a/include/gdi.h b/include/gdi.h index c25c6b8d..9104262c 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -12862,6 +12862,80 @@ MG_EXPORT int GUIAPI GetACharsExtentPoint (HDC hdc, Achar32* achars, MG_EXPORT int GUIAPI GetACharsExtentPointEx (HDC hdc, Achar32* achars, int nr_achars, int max_extent, int* dx_achars, SIZE* size); +/** + * \fn int GUIAPI GetTabbedACharsExtent (HDC hdc, Achar32* achars, + * int nr_achars, SIZE* size) + * \brief Get visual extent value of an achar string. + * + * This function gets the extent value of an achar string on a DC. Note that + * this function will ignore all breaks in the achar string. + * + * \param hdc The device context. + * \param achars The pointer to the achar string. + * \param nr_achars The length of the achar string. + * \param size The buffer restoring the extents of the achar strings. + * + * \return The extent of the achar string. + * + * \sa GetTabbedACharsExtentPoint + * + * Since 5.0.12 + */ +MG_EXPORT int GUIAPI GetTabbedACharsExtent (HDC hdc, Achar32* achars, + int nr_achars, SIZE* size); + +/** + * \fn int GUIAPI GetTabbedACharsExtentPoint (HDC hdc, Achar32* achars, + * int nr_achars, int max_extent, SIZE* size) + * \brief Get the visual extent value of an achar string. + * + * This function gets the visual extent value of a glpyh string. + * Note that this function ignore all breaks in the achar string. + * + * \param hdc The device context. + * \param achars The pointer to the achar string. + * \param nr_achars The length of the achar string len. + * \param max_extent The maximal output extent value. + * \param size The real extent of all visual achars in the achar string. + * + * \return The the index of the last achar which can be fit to the extent. + * + * \sa GetTabbedACharsExtentPointEx + * + * Since 5.0.12 + */ +MG_EXPORT int GUIAPI GetTabbedACharsExtentPoint (HDC hdc, Achar32* achars, + int nr_achars, int max_extent, SIZE* size); + +/** + * \fn int GUIAPI GetTabbedACharsExtentPointEx (HDC hdc, + * Achar32* achars, int nr_achars, int max_extent, + * int* dx_chars, int* dy_chars, SIZE* size) + * \brief Get the visual extent value of an achar string. + * + * This function gets the visual extent value of a glpyh string. + * Note that this function ignore all breaks in the achar string. + * + * \param hdc The device context. + * \param achars The pointer to the achar string. + * \param nr_achars The length of the achar string len. + * \param max_extent The maximal output extent value. + * \param dx_achars The output x-positions of each character in the text + * will be returned through this pointer. It can be NULL. + * \param dy_achars The output y-positions of each character in the text + * will be returned through this pointer. It can be NULL. + * \param size The real extent of all visual achars in the achar string. + * + * \return The index of the last achar which can be fit to the extent. + * + * \sa GetTabbedACharsExtentPoint + * + * Since 5.0.12 + */ +MG_EXPORT int GUIAPI GetTabbedACharsExtentPointEx (HDC hdc, + Achar32* achars, int nr_achars, int max_extent, + int* dx_achars, int* dy_achars, SIZE* size); + /** * \fn Glyph32 GUIAPI GetGlyphValue (LOGFONT* logfont, const char* mchar, \ * int mchar_len, const char* pre_mchar, int pre_len) diff --git a/src/newgdi/legacy-bidi.c b/src/newgdi/legacy-bidi.c index a63ac628..37fad788 100644 --- a/src/newgdi/legacy-bidi.c +++ b/src/newgdi/legacy-bidi.c @@ -612,8 +612,7 @@ int _gdi_reorder_text (PDC pdc, const unsigned char* text, int text_len, (NULL, 0, text + i, 1))) return (text_len-i-1); - char_type = sbc_devfont->charset_ops->char_type - (chv); + char_type = sbc_devfont->charset_ops->char_type (chv); gv = GetGlyphValueAlt (pdc->pLogFont, chv); if (gv == INV_GLYPH_VALUE) diff --git a/src/newgdi/tabbedtextout.c b/src/newgdi/tabbedtextout.c index e6e43c6b..813e0223 100644 --- a/src/newgdi/tabbedtextout.c +++ b/src/newgdi/tabbedtextout.c @@ -544,7 +544,7 @@ static int get_tabbed_text_extent_point_for_bidi(HDC hdc, ACHARMAPINFO* achars_map = NULL; int nr_fit_achars = 0; - int nr_achars = BIDIGetTextLogicalAChars(log_font, text, len, + int nr_achars = BIDIGetTextVisualAChars(log_font, text, len, &achars, &achars_map); if (nr_achars <= 0) { goto done; @@ -555,6 +555,8 @@ static int get_tabbed_text_extent_point_for_bidi(HDC hdc, int tab_width = sbc_devfont->font_ops->get_ave_width(log_font, sbc_devfont) * pdc->tabstop; int line_height = log_font->size + pdc->alExtra + pdc->blExtra; + + size->cx = 0; size->cy = line_height; int left_achars = nr_achars; @@ -564,8 +566,9 @@ static int get_tabbed_text_extent_point_for_bidi(HDC hdc, pos_chars[nr_fit_achars] = achars_map[nr_fit_achars].byte_index; if (dx_chars) dx_chars[nr_fit_achars] = last_line_width; + size->cx = last_line_width; - Uint32 achar_type = GetACharBidiType(log_font, achars[nr_fit_achars]); + Uint32 achar_type = GetACharType(log_font, achars[nr_fit_achars]); Glyph32 gv = GetGlyphValueAlt(log_font, achars[nr_fit_achars]); int adv_x = 0, adv_y = 0; @@ -576,9 +579,9 @@ static int get_tabbed_text_extent_point_for_bidi(HDC hdc, case ACHAR_BASIC_LF: adv_y = line_height; case ACHAR_BASIC_CR: + adv_x = 0; if (last_line_width > size->cx) { size->cx = last_line_width; - adv_x = 0; } last_line_width = 0; _gdi_start_new_line(pdc); @@ -659,6 +662,7 @@ int GUIAPI GetTabbedTextExtentPoint (HDC hdc, const char* text, pos_chars [char_count] = len - left_bytes; if (dx_chars) dx_chars [char_count] = last_line_width; + size->cx = last_line_width; devfont = NULL; len_cur_char = 0; @@ -689,7 +693,6 @@ int GUIAPI GetTabbedTextExtentPoint (HDC hdc, const char* text, switch (char_type & ACHARTYPE_BASIC_MASK) { case ACHAR_BASIC_ZEROWIDTH: - case ACHAR_BASIC_VOWEL: break; case ACHAR_BASIC_LF: size->cy += line_height; @@ -732,3 +735,94 @@ ret: return len - left_bytes; } +int GUIAPI GetTabbedACharsExtentPointEx(HDC hdc, + Achar32* achars, int nr_achars, int max_extent, + int* dx_achars, int* dy_achars, SIZE* size) +{ + PDC pdc = dc_HDC2PDC(hdc); + LOGFONT *log_font = pdc->pLogFont; + DEVFONT* sbc_devfont = log_font->devfonts[0]; + int nr_fit_achars = 0; + + _gdi_start_new_line(pdc); + + int tab_width = sbc_devfont->font_ops->get_ave_width(log_font, sbc_devfont) + * pdc->tabstop; + int line_height = log_font->size + pdc->alExtra + pdc->blExtra; + + size->cx = 0; + size->cy = 0; + + int left_achars = nr_achars; + int last_line_width = 0; + while (left_achars > 0) { + if (dx_achars) + dx_achars[nr_fit_achars] = last_line_width; + if (dy_achars) + dy_achars[nr_fit_achars] = size->cy; + size->cx = last_line_width; + + Uint32 achar_type = GetACharType(log_font, achars[nr_fit_achars]); + Glyph32 gv = GetGlyphValueAlt(log_font, achars[nr_fit_achars]); + + int adv_x = 0, adv_y = 0; + switch (achar_type & ACHARTYPE_BASIC_MASK) { + case ACHAR_BASIC_ZEROWIDTH: + adv_x = adv_y = 0; + break; + case ACHAR_BASIC_LF: + adv_y = line_height; + case ACHAR_BASIC_CR: + adv_x = 0; + if (last_line_width > size->cx) { + size->cx = last_line_width; + } + last_line_width = 0; + _gdi_start_new_line(pdc); + break; + + case ACHAR_BASIC_HT: + adv_x = tab_width; + last_line_width += tab_width; + _gdi_start_new_line(pdc); + break; + + default: + last_line_width += _gdi_get_glyph_advance (pdc, gv, + (pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + 0, 0, &adv_x, &adv_y, NULL); + last_line_width += pdc->cExtra; + break; + } + + if (max_extent > 0 && last_line_width > max_extent) { + break; + } + + size->cx += adv_x; + size->cy += adv_y; + if (last_line_width > size->cx) + size->cx = last_line_width; + left_achars--; + nr_fit_achars++; + } + + size->cy += line_height; + return nr_fit_achars; +} + +int GUIAPI GetTabbedACharsExtentPoint(HDC hdc, Achar32* achars, + int nr_achars, int max_extent, SIZE* size) +{ + return GetTabbedACharsExtentPointEx(hdc, + achars, nr_achars, max_extent, NULL, NULL, size); +} + +int GUIAPI GetTabbedACharsExtent(HDC hdc, Achar32* achars, + int nr_achars, SIZE* size) +{ + GetTabbedACharsExtentPointEx(hdc, + achars, nr_achars, -1, NULL, NULL, size); + return size->cx; +} + diff --git a/src/newgdi/textout.c b/src/newgdi/textout.c index f84a1f28..de28a255 100644 --- a/src/newgdi/textout.c +++ b/src/newgdi/textout.c @@ -319,7 +319,8 @@ typedef struct _TEXTOUTOMITTED_CTXT Uint32 max_extent; } TEXTOUTOMITTED_CTXT; -static BOOL cb_textout_omitted (void* context, Glyph32 glyph_value, unsigned int char_type) +static BOOL +cb_textout_omitted (void* context, Glyph32 glyph_value, unsigned int char_type) { TEXTOUTOMITTED_CTXT* ctxt = (TEXTOUTOMITTED_CTXT*)context; int adv_x, adv_y; @@ -452,7 +453,7 @@ static int get_text_extent_point_for_bidi(HDC hdc, int *dx_achars = NULL; int nr_fit_achars = 0; - int nr_achars = BIDIGetTextLogicalAChars(log_font, text, len, + int nr_achars = BIDIGetTextVisualAChars(log_font, text, len, &achars, &achars_map); if (nr_achars <= 0) { @@ -463,7 +464,6 @@ static int get_text_extent_point_for_bidi(HDC hdc, if (dx_chars == NULL || achars == NULL || achars_map == NULL) goto done; - BIDILogAChars2VisAChars(log_font, achars, nr_achars, achars_map); nr_fit_achars = GetACharsExtentPointEx(hdc, achars, nr_achars, max_extent, dx_achars, size); @@ -616,7 +616,7 @@ int GUIAPI GetACharsExtentPointEx (HDC hdc, Achar32* achars, int nr_achars, devfont = SELECT_DEVFONT_BY_ACHAR(log_font, achars[i]); char_type = devfont->charset_ops->char_type(achars[i]); - if (check_zero_width (char_type)) { + if (check_zero_width(char_type)) { adv_x = adv_y = 0; } else {