mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-02-06 10:21:57 +08:00
implement new API: GetACharsExtentPointEx(); enhance GetTextExtentPoint() and GetTabbedTextExtentPoint() to support BIDI charsets
This commit is contained in:
@@ -12541,6 +12541,8 @@ typedef struct _ACHARMAPINFO {
|
||||
int char_len;
|
||||
/** The direction of the character; TRUE for RTL, FALSE for LTR. */
|
||||
BOOL is_rtol;
|
||||
/** The BIDI type */
|
||||
BidiType type;
|
||||
} ACHARMAPINFO;
|
||||
|
||||
/**
|
||||
@@ -12632,7 +12634,7 @@ MG_EXPORT int GUIAPI BIDIGetTextVisualAChars (LOGFONT* log_font,
|
||||
* Achar32* achars, int nr_achars, int pel,
|
||||
* void* extra, CB_REVERSE_ARRAY cb_reverse_extra)
|
||||
* \brief Reorder the specified logical glyph string in visual order and
|
||||
* reorder an extra array to reflect the visule order of the achars.
|
||||
* reorder an extra array to reflect the visual order of the achars.
|
||||
*
|
||||
* This function reorders the logical glyph string in place to visual order.
|
||||
* If \a extra and \a cb_reverse_extra are both not NULL, it also reorders
|
||||
@@ -12837,6 +12839,31 @@ MG_EXPORT int GUIAPI GetACharsExtent (HDC hdc, Achar32* achars, int nr_achars,
|
||||
MG_EXPORT int GUIAPI GetACharsExtentPoint (HDC hdc, Achar32* achars,
|
||||
int nr_achars, int max_extent, SIZE* size);
|
||||
|
||||
/**
|
||||
* \fn int GUIAPI GetACharsExtentPointEx (HDC hdc, Achar32* achars, \
|
||||
* int nr_achars, int max_extent, int* dx_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 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 GetACharsExtentPoint
|
||||
*
|
||||
* Since 5.0.12
|
||||
*/
|
||||
MG_EXPORT int GUIAPI GetACharsExtentPointEx (HDC hdc, Achar32* achars,
|
||||
int nr_achars, int max_extent, int* dx_achars, SIZE* size);
|
||||
|
||||
/**
|
||||
* \fn Glyph32 GUIAPI GetGlyphValue (LOGFONT* logfont, const char* mchar, \
|
||||
* int mchar_len, const char* pre_mchar, int pre_len)
|
||||
|
||||
@@ -738,6 +738,7 @@ Achar32* __mg_legacy_bidi_map_reorder (const CHARSETOPS* charset_ops,
|
||||
for (i=0; i<run_len; i++)
|
||||
{
|
||||
(map+run_pos+i)->is_rtol = (node_p)->level & 1;
|
||||
(map+run_pos+i)->type = (node_p)->type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -533,6 +533,97 @@ int GUIAPI TabbedTextOutEx (HDC hdc, int x, int y, const char* spText,
|
||||
return advance;
|
||||
}
|
||||
|
||||
static int get_tabbed_text_extent_point_for_bidi(HDC hdc,
|
||||
const char* text, int len, int max_extent,
|
||||
int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size)
|
||||
{
|
||||
PDC pdc = dc_HDC2PDC(hdc);
|
||||
LOGFONT *log_font = pdc->pLogFont;
|
||||
DEVFONT* sbc_devfont = log_font->devfonts[0];
|
||||
DEVFONT* mbc_devfont = log_font->devfonts[1];
|
||||
DEVFONT* devfont;
|
||||
Achar32 *achars = NULL;
|
||||
ACHARMAPINFO* achars_map = NULL;
|
||||
int *dx_achars = NULL;
|
||||
int nr_fit_achars = 0;
|
||||
|
||||
int nr_achars = BIDIGetTextLogicalAChars(log_font, text, len,
|
||||
&achars, &achars_map);
|
||||
if (nr_achars <= 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
_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->cy = line_height;
|
||||
|
||||
int left_achars = nr_achars;
|
||||
int last_line_width = 0;
|
||||
while (left_achars > 0) {
|
||||
if (pos_chars)
|
||||
pos_chars[nr_fit_achars] = achars_map[nr_fit_achars].byte_index;
|
||||
if (dx_chars)
|
||||
dx_chars[nr_fit_achars] = last_line_width;
|
||||
|
||||
Uint32 achar_type = GetACharBidiType(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:
|
||||
if (last_line_width > size->cx) {
|
||||
size->cx = last_line_width;
|
||||
adv_x = 0;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
|
||||
if (fit_chars)
|
||||
*fit_chars = nr_fit_achars;
|
||||
|
||||
done:
|
||||
if (achars)
|
||||
free(achars);
|
||||
if (achars_map)
|
||||
free(achars_map);
|
||||
return nr_fit_achars;
|
||||
}
|
||||
|
||||
int GUIAPI GetTabbedTextExtentPoint (HDC hdc, const char* text,
|
||||
int len, int max_extent,
|
||||
int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size)
|
||||
@@ -553,9 +644,11 @@ int GUIAPI GetTabbedTextExtentPoint (HDC hdc, const char* text,
|
||||
/* set size to zero first */
|
||||
size->cx = size->cy = 0;
|
||||
|
||||
/* This function does not support BIDI */
|
||||
if (mbc_devfont && pdc->bidi_flags && mbc_devfont->charset_ops->bidi_char_type)
|
||||
return -1;
|
||||
if (mbc_devfont && pdc->bidi_flags &&
|
||||
mbc_devfont->charset_ops->bidi_char_type) {
|
||||
return get_tabbed_text_extent_point_for_bidi(hdc, text, len,
|
||||
max_extent, fit_chars, pos_chars, dx_chars, size);
|
||||
}
|
||||
|
||||
_gdi_start_new_line (pdc);
|
||||
|
||||
|
||||
@@ -441,9 +441,61 @@ int GUIAPI TextOutOmitted (HDC hdc, int x, int y,
|
||||
|
||||
#undef STRDOT_LEN
|
||||
|
||||
int GUIAPI GetTextExtentPoint (HDC hdc, const char* text, int len,
|
||||
int max_extent,
|
||||
int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size)
|
||||
static int get_text_extent_point_for_bidi(HDC hdc,
|
||||
const char* text, int len, int max_extent,
|
||||
int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size)
|
||||
{
|
||||
PDC pdc = dc_HDC2PDC(hdc);
|
||||
LOGFONT *log_font = pdc->pLogFont;
|
||||
Achar32 *achars = NULL;
|
||||
ACHARMAPINFO* achars_map = NULL;
|
||||
int *dx_achars = NULL;
|
||||
int nr_fit_achars = 0;
|
||||
|
||||
int nr_achars = BIDIGetTextLogicalAChars(log_font, text, len,
|
||||
&achars, &achars_map);
|
||||
|
||||
if (nr_achars <= 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
dx_achars = malloc(sizeof(int) * nr_achars);
|
||||
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);
|
||||
|
||||
if (fit_chars) {
|
||||
*fit_chars = nr_fit_achars;
|
||||
}
|
||||
|
||||
if (pos_chars || dx_chars) {
|
||||
for (int i = 0; i < nr_fit_achars; i++) {
|
||||
if (pos_chars) {
|
||||
pos_chars[i] = achars_map[i].byte_index;
|
||||
}
|
||||
|
||||
if (dx_chars) {
|
||||
dx_chars[i] = dx_achars[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (achars)
|
||||
free(achars);
|
||||
if (achars_map)
|
||||
free(achars_map);
|
||||
if (dx_achars)
|
||||
free(dx_achars);
|
||||
return nr_fit_achars;
|
||||
}
|
||||
|
||||
int GUIAPI GetTextExtentPoint (HDC hdc,
|
||||
const char* text, int len, int max_extent,
|
||||
int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size)
|
||||
{
|
||||
PDC pdc = dc_HDC2PDC (hdc);
|
||||
LOGFONT* log_font = pdc->pLogFont;
|
||||
@@ -459,8 +511,12 @@ int GUIAPI GetTextExtentPoint (HDC hdc, const char* text, int len,
|
||||
size->cx = size->cy = 0;
|
||||
|
||||
/* This function does not support BIDI */
|
||||
if (mbc_devfont && pdc->bidi_flags && mbc_devfont->charset_ops->bidi_char_type)
|
||||
if (mbc_devfont && pdc->bidi_flags &&
|
||||
mbc_devfont->charset_ops->bidi_char_type) {
|
||||
get_text_extent_point_for_bidi(pdc, text, len, max_extent,
|
||||
fit_chars, pos_chars, dx_chars, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_gdi_start_new_line(pdc);
|
||||
|
||||
@@ -538,8 +594,8 @@ int GUIAPI DrawACharString (HDC hdc, int startx, int starty,
|
||||
return ctxt.advance;
|
||||
}
|
||||
|
||||
int GUIAPI GetACharsExtentPoint(HDC hdc, Achar32* achars, int nr_achars,
|
||||
int max_extent, SIZE* size)
|
||||
int GUIAPI GetACharsExtentPointEx (HDC hdc, Achar32* achars, int nr_achars,
|
||||
int max_extent, int *dx_achars, SIZE* size)
|
||||
{
|
||||
int i = 0;
|
||||
int advance = 0;
|
||||
@@ -552,7 +608,11 @@ int GUIAPI GetACharsExtentPoint(HDC hdc, Achar32* achars, int nr_achars,
|
||||
size->cx = 0;
|
||||
size->cy = 0;
|
||||
|
||||
while(i < nr_achars){
|
||||
while (i < nr_achars){
|
||||
if (dx_achars) {
|
||||
dx_achars[i] = advance;
|
||||
}
|
||||
|
||||
devfont = SELECT_DEVFONT_BY_ACHAR(log_font, achars[i]);
|
||||
char_type = devfont->charset_ops->char_type(achars[i]);
|
||||
|
||||
@@ -578,7 +638,7 @@ int GUIAPI GetACharsExtentPoint(HDC hdc, Achar32* achars, int nr_achars,
|
||||
|
||||
size->cx += adv_x;
|
||||
size->cy += adv_y;
|
||||
i ++;
|
||||
i++;
|
||||
}
|
||||
|
||||
_gdi_calc_glyphs_size_from_two_points (pdc, 0, 0,
|
||||
@@ -587,6 +647,13 @@ int GUIAPI GetACharsExtentPoint(HDC hdc, Achar32* achars, int nr_achars,
|
||||
return i;
|
||||
}
|
||||
|
||||
int GUIAPI GetACharsExtentPoint(HDC hdc, Achar32* achars, int nr_achars,
|
||||
int max_extent, SIZE* size)
|
||||
{
|
||||
return GetACharsExtentPointEx(hdc, achars, nr_achars, max_extent,
|
||||
NULL, size);
|
||||
}
|
||||
|
||||
int GUIAPI GetACharsExtent(HDC hdc, Achar32* achars, int nr_achars, SIZE* size)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
Reference in New Issue
Block a user