diff --git a/include/gdi.h b/include/gdi.h index eca73f52..d26c68c0 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -9571,8 +9571,8 @@ MG_EXPORT void GUIAPI DestroyBMPFont (DEVFONT* dev_font); * @{ */ -typedef Uint32 Achar32; -typedef Uint32 Glyph32; +typedef unsigned int Achar32; +typedef unsigned long Glyph32; /** * \def INV_ACHAR_VALUE @@ -9915,7 +9915,7 @@ MG_EXPORT Uint32 GUIAPI GetACharType (LOGFONT* logfont, Achar32 chv); /** * \fn Uint32 GUIAPI GetACharBIDIType (LOGFONT* logfont, Achar32 chv) - * \brief Retriev the BIDI type of an abstract character. + * \brief Retrieve the BIDI type of an abstract character. * * This function retrieves the BIDI type of an abstract character. * @@ -10119,6 +10119,70 @@ static inline void BIDIGetVisualEmbeddLevels (LOGFONT* log_font, BIDIGetVisualEmbedLevelsEx (log_font, achars, nr_achars, -1, embed_levels); } +/* + * \fn int GUIAPI DrawACharString (HDC hdc, int x, int y, + * Achar32* achars, int nr_achars, int* adv_x, int* adv_y); + * + * \brief Draw an abstract character string. + * + * This function draws an abstract character string to the specific + * postion of a DC. Note that this function will ignore all breaks + * in the Achar32 string. + * + * \param hdc The device context. + * \param x The output start x position. + * \param y The output start y position. + * \param achars The pointer to the glyph string. + * \param nr_achars The number of achars which will be draw. + * \param adv_x The pointer used to return the advance in x-coordinate of + * the glyph string, can be NULL. + * \param adv_y The pointer used to return the advance in y-coordinate of + * the glyph string, can be NULL. + * + * \return The advance on baseline. + */ +MG_EXPORT int GUIAPI DrawACharString (HDC hdc, int x, int y, Achar32* achars, + int nr_achars, int* adv_x, int* adv_y); + +/** + * \fn int GUIAPI GetACharsExtent(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. + */ +MG_EXPORT int GUIAPI GetACharsExtent (HDC hdc, Achar32* achars, int nr_achars, + SIZE* size); + +/** + * \fn int GUIAPI GetACharsExtentPoint (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 GetACharsExtentPointEx + */ +MG_EXPORT int GUIAPI GetACharsExtentPoint (HDC hdc, Achar32* achars, + int nr_achars, int max_extent, SIZE* size); + /** * \fn void GUIAPI GetGlyphValue (LOGFONT* logfont, Achar32 chv) * \brief Get the LOGFONT glyph value of an abstract character. @@ -10153,28 +10217,67 @@ MG_EXPORT int GUIAPI DrawGlyph (HDC hdc, int x, int y, Glyph32 glyph_value, int* adv_x, int* adv_y); /* - * \fn int GUIAPI DrawGlyphString (HDC hdc, int x, int y, \ - * Glyph32* glyphs, int nr_glyphs, int* adv_x, int* adv_y); + * \fn int GUIAPI DrawGlyphString (HDC hdc, Glyph32* glyphs, int nr_glyphs, + * const POINT* pts); * - * \brief Draw a glyph string. + * \brief Draw a glyph string at specified positions. * - * This function draws a glyph string to the specific postion of a DC. - * Note that this function will ignore all breaks in the glyph string. + * This function draws a glyph string to the specific postions of a DC. + * Note that this function will ignore all special type (such as zero-width) + * in the glyph string. * * \param hdc The device context. - * \param x The output start x position. - * \param y The output start y position. * \param glyphs The pointer to the glyph string. * \param nr_glyphs The number of glyphs which will be draw. - * \param adv_x The pointer used to return the advance in x-coordinate of - * the glyph string, can be NULL. - * \param adv_y The pointer used to return the advance in y-coordinate of - * the glyph string, can be NULL. + * \param pts The positions of every glyphs. * - * \return The advance on baseline. + * \return The number of glyphs drawn. + * + * \sa DrawGlyphStringEx */ -MG_EXPORT int GUIAPI DrawGlyphString (HDC hdc, int x, int y, Glyph32* glyphs, - int nr_glyphs, int* adv_x, int* adv_y); +MG_EXPORT int GUIAPI DrawGlyphString (HDC hdc, Glyph32* glyphs, int nr_glyphs, + const POINT* pts); + +/** + * \fn int GUIAPI GetGlyphsExtent(HDC hdc, Glyph32* glyphs, int nr_glyphs, \ + * SIZE* size) + * \brief Get visual extent value of a glyph string. + * + * This function gets the extent value of a glyph string on a DC. Note that + * this function will ignore all special types in the glyph string. + * + * \param hdc The device context. + * \param glyphs The pointer to the glyph string. + * \param nr_glyphs The length of the glyph string. + * \param size The buffer restoring the extents of the glyph string. + * + * \return The extent of the glyph string. + * + * \sa GetGlyphsExtentFromUChars + */ +MG_EXPORT int GUIAPI GetGlyphsExtent (HDC hdc, Glyph32* glyphs, int nr_glyphs, + SIZE* size); + +/** + * \fn int GUIAPI GetGlyphsExtentPoint (HDC hdc, Glyph32* glyphs, \ + * int nr_glyphs, int max_extent, SIZE* size) + * \brief Get the visual extent value of an glyph string. + * + * This function gets the visual extent value of a glpyh string. + * Note that this function ignore all special types in the glyph string. + * + * \param hdc The device context. + * \param glyphs The pointer to the glyph string. + * \param nr_glyphs The length of the glyph string len. + * \param max_extent The maximal output extent value. + * \param size The real extent of all visual glyphs in the glyph string. + * + * \return The the index of the last glyph which can be fit to the extent. + * + * \sa GetGlyphsExtentFromUChars + */ +MG_EXPORT int GUIAPI GetGlyphsExtentPoint (HDC hdc, Glyph32* glyphs, + int nr_glyphs, int max_extent, SIZE* size); #define GLYPH_INFO_METRICS 0x01 #define GLYPH_INFO_BMP 0x02 @@ -10237,7 +10340,7 @@ typedef struct _GLYPHINFO { /** * \fn int GUIAPI GetGlyphInfo (LOGFONT* logfont, Glyph32 glyph_value, \ * GLYPHINFO* glyph_info) - * \brief Retriev the information of a glyph. + * \brief Retrieve the information of a glyph. * * This function retrieves the information of a glyph. * @@ -10254,45 +10357,6 @@ typedef struct _GLYPHINFO { MG_EXPORT int GUIAPI GetGlyphInfo (LOGFONT* logfont, Glyph32 glyph_value, GLYPHINFO* glyph_info); -/** - * \fn int GUIAPI GetGlyphsExtent(HDC hdc, Glyph32* glyphs, int nr_glyphs, \ - * SIZE* size) - * \brief Get visual extent value of a glyph string. - * - * This function gets the extent value of a glyph string on a DC. Note that - * this function will ignore all breaks in the glyph string. - * - * \param hdc The device context. - * \param glyphs The pointer to the glyph string. - * \param nr_glyphs The length of the glyph string. - * \param size The buffer restoring the extents of the glyph strings. - * - * \return The extent of the glyph string. - */ -MG_EXPORT int GUIAPI GetGlyphsExtent (HDC hdc, Glyph32* glyphs, int nr_glyphs, - SIZE* size); - -/** - * \fn int GUIAPI GetGlyphsExtentPoint (HDC hdc, Glyph32* glyphs, \ - * int nr_glyphs, int max_extent, SIZE* size) - * \brief Get the visual extent value of a glyph string. - * - * This function gets the visual extent value of a glpyh string. - * Note that this function ignore all breaks in the glyph string. - * - * \param hdc The device context. - * \param glyphs The pointer to the glyph string. - * \param nr_glyphs The length of the glyph string len. - * \param max_extent The maximal output extent value. - * \param size The real extent of all visual glyphs in the glyph string. - * - * \return The the index of the last glyph which can be fit to the extent. - * - * \sa GetGlyphsExtentPointEx - */ -MG_EXPORT int GUIAPI GetGlyphsExtentPoint (HDC hdc, Glyph32* glyphs, - int nr_glyphs, int max_extent, SIZE* size); - #ifdef _MGCHARSET_UNICODE /** @@ -11054,7 +11118,7 @@ MG_EXPORT int GUIAPI AChars2UChars(LOGFONT* logfont, const Achar32* chs, /** * \defgroup glyph_render_flags Glyph Rendering Flags * - * The glyph rendering flags indicates \a GetGlyphsExtentPointEx + * The glyph rendering flags indicates \a GetGlyphsExtentFromUChars * - Whether and how to break if the glyph string overflows the max extent; * - The direction of the glyphs; * - The writing mode (horizontal or vertical) and text orientation; @@ -11240,57 +11304,42 @@ MG_EXPORT int GUIAPI AChars2UChars(LOGFONT* logfont, const Achar32* chs, #define GLYPH_ORIENTATION_UPRIGHT 0 #define GLYPH_ORIENTATION_SIDEWAYS 1 -typedef struct _SHAPEDGLYPHS { - int nr_glyphs; - /** The shaped glyphs */ - Glyph32* glyphs; - /** The break opportunities */ - Uint8* break_oppos; - /** The Unicode general categories. */ - Uint8* ugc; - /** The Unicode Indic syllabic categories. */ - Uint8* uics; - /** The Unicode Indic positional categories. */ - Uint8* uipc; -} SHAPEDGLYPHS; +typedef enum _GlyphType { + GLYPH_TYPE_STANDALONE, + GLYPH_TYPE_STDBASE, + GLYPH_TYPE_STDMARK, + GLYPH_TYPE_STDLIGATURE, +} GlyphType; -MG_EXPORT int GUIAPI GetShapedGlyphs(LOGFONT* logfont, +typedef enum _GlyphPosition { + GLYPH_POS_BASELINE, + GLYPH_POS_STDMARK_ABOVE, + GLYPH_POS_STDMARK_BELOW, + GLYPH_POS_STDMKMK, + GLYPH_POS_STDKERNING, + GLYPH_POS_CMPCURSIVE, +} GlyphPosition; + +typedef struct _SHAPEDGLYPH { + /** The glyph value */ + Glyph32 gv; + /** The glyph breaking opportunities */ + Uint16 bos; + /** The glyph type */ + Uint8 gt; + /** The glyph position */ + Uint8 gp; +} SHAPEDGLYPH; + +MG_EXPORT int GUIAPI GetShapedGlyphsStandard(LOGFONT* logfont, LanguageCode content_language, UCharScriptType writing_system, - const Uchar32 ucs, int nr_chars, - SHAPEDGLYPHS* shaped_glyphs); + const Uchar32* ucs, const Uint8* break_oppos, int nr_chars, + SHAPEDGLYPH* glyphs, int* nr_glyphs); -/** - * The glyph extent information. - */ -typedef struct _GLYPHEXTENT { - /** The bounding box of the glyph. */ - int bbox_x, bbox_y, bbox_w, bbox_h; - /** The advance values of the glyph. */ - int adv_x, adv_y; - /** The advance value of the glyph along the line direction. */ - int line_adv; - /** - * The orientation of the glyph; can be one of the following values: - * - GLYPH_ORIENTATION_UPRIGHT\n - * the glyph is in the standard horizontal orientation. - * - GLYPH_ORIENTATION_SIDEWAYS\n - * the glyph rotates 90° clockwise from horizontal. - */ - Uint8 orientation:2; - /** - * Whether is a whitespace glyph. - */ - Uint8 whitespace:1; - /** - * Whether suppress the glyph. - */ - Uint8 suppressed:1; -} GLYPHEXTENT; - -MG_EXPORT int GUIAPI GetGlyphsExtentInfo(LOGFONT* logfont, - const SHAPEDGLYPHS* shaped_glyphs, Uint32 render_flags, - GLYPHEXTENT** glyph_extents, - LOGFONT** logfont_sideways); +MG_EXPORT int GUIAPI GetShapedGlyphsComplex(LOGFONT* logfont, + LanguageCode content_language, UCharScriptType writing_system, + const Uchar32* ucs, const Uint8* break_oppos, int nr_chars, + SHAPEDGLYPH* glyphs, int* nr_glyphs); /** * The glyph extent information. @@ -11304,8 +11353,29 @@ typedef struct _GLYPHEXTINFO { int extra_x, extra_y; /** The advance value of the glyph along the line direction. */ int line_adv; + /** + * Whether suppress the glyph. + */ + Uint8 suppressed:1; + /** + * Whether is a whitespace glyph. + */ + Uint8 whitespace:1; + /** + * The orientation of the glyph; can be one of the following values: + * - GLYPH_ORIENTATION_UPRIGHT\n + * the glyph is in the standard horizontal orientation. + * - GLYPH_ORIENTATION_SIDEWAYS\n + * the glyph rotates 90° clockwise from horizontal. + */ + Uint8 orientation:2; } GLYPHEXTINFO; +MG_EXPORT int GUIAPI GetGlyphsExtentInfo(LOGFONT* logfont, + const SHAPEDGLYPH* glyphs, Uint32 render_flags, + GLYPHEXTINFO** glyph_extent_info, + LOGFONT** logfont_sideways); + /** * The glyph position information. */ @@ -11318,6 +11388,14 @@ typedef struct _GLYPHPOS { * The y coordinate of the glyph position. */ int y; + /** + * Whether suppress the glyph. + */ + Uint8 suppressed:1; + /** + * Whether is a whitespace glyph. + */ + Uint8 whitespace:1; /** * The orientation of the glyph; can be one of the following values: * - GLYPH_ORIENTATION_UPRIGHT\n @@ -11326,14 +11404,6 @@ typedef struct _GLYPHPOS { * the glyph rotates 90° clockwise from horizontal. */ Uint8 orientation:2; - /** - * Whether is a whitespace glyph. - */ - Uint8 whitespace:1; - /** - * Whether suppress the glyph. - */ - Uint8 suppressed:1; /** * Whether hanged the glyph; can be one of the following values: * - GLYPH_HANGED_NONE\n @@ -11347,18 +11417,18 @@ typedef struct _GLYPHPOS { } GLYPHPOS; MG_EXPORT int GUIAPI GetGlyphsPositionInfo(LOGFONT* logfont_upright, - const Glyph32* glyphs, const Uint16* break_oppos, - const GLYPHEXTINFO* glyph_ext_info, int nr_glyphs, + const SHAPEDGLYPH* glyphs, GLYPHEXTINFO* glyph_ext_info, int nr_glyphs, Uint32 render_flags, int x, int y, int letter_spacing, int word_spacing, int tab_size, int max_extent, SIZE* line_size, GLYPHPOS* glyph_pos, LOGFONT** logfont_sideways); + /** - * \fn int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, - * const Glyph32* glyphs, int nr_glyphs, const Uint16* break_oppos, + * \fn int GUIAPI GetGlyphsExtentFromUChars(LOGFONT* logfont_upright, + * const Uchar32* uchars, int nr_uchars, const Uint16* break_oppos, * Uint32 render_flags, int x, int y, * int letter_spacing, int word_spacing, int tab_size, int max_extent, - * SIZE* line_size, GLYPHEXTINFO* glyph_ext_info, GLYPHPOS* glyph_pos, - * LOGFONT** logfont_sideways) + * SIZE* line_size, Glyph32* glyphs, GLYPHEXTINFO* glyph_ext_info, + * GLYPHPOS* glyph_pos, LOGFONT** logfont_sideways) * \brief Get the visual extent info of all glyphs fitting in the specified * maximal output extent. * @@ -11366,9 +11436,8 @@ MG_EXPORT int GUIAPI GetGlyphsPositionInfo(LOGFONT* logfont_upright, * fit a line with the specified maximal extent. * * \param logfont The logfont used to parse the glyph string. - * \param glyphs The pointer to the glyph string. The glyphs should be reordered - * as visual ones by calling BIDI functions. - * \param nr_glyphs The number of the glyphs. + * \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) @@ -11383,6 +11452,8 @@ MG_EXPORT int GUIAPI GetGlyphsPositionInfo(LOGFONT* logfont_upright, * \param tab_size The tab size used to render preserved tab characters. * \param max_extent The maximal output extent value. No limit when it is < 0. * \param line_size The buffer to store the line extent info; can be NULL. + * \param glyphs The buffer to store the glyphs, which can fit in + * the max extent; cannot be NULL. * \param glyph_ext_info The buffer to store the extent info of all glyphs * which can fit in the max extent; can be NULL. * \param glyph_pos The buffer to store the positions and orientations of @@ -11394,9 +11465,10 @@ MG_EXPORT int GUIAPI GetGlyphsPositionInfo(LOGFONT* logfont_upright, * not NULL, this function will try to use this LOGFONT object for * sideways glyphs. * - * \return The number of glyphs which can be fit to the maximal extent. - * The extent info of every glyphs which are fit in the maximal extent - * will be returned through \a glyph_ext_info if it was not NULL, and the + * \return The number of achars which can be fit to the maximal extent. + * The glyphs and the extent info of every glyphs which are fit in + * the maximal extent will be returned through \a glyphs and + * \a glyph_ext_info (if it was not NULL), and the * line extent info will be returned through \a line_size * if it was not NULL. Note the function will return immediately if * it encounters a mandatory breaking. @@ -11420,19 +11492,20 @@ MG_EXPORT int GUIAPI GetGlyphsPositionInfo(LOGFONT* logfont_upright, * * \sa GetUCharsAndBreaks, DrawGlyphStringEx, GLYPHEXTINFO, glyph_render_flags */ -MG_EXPORT int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, - const Glyph32* glyphs, int nr_glyphs, const Uint16* break_oppos, +MG_EXPORT int GUIAPI GetGlyphsExtentFromUChars(LOGFONT* logfont_upright, + const Achar32* uchars, int nr_uchars, const Uint16* break_oppos, Uint32 render_flags, int x, int y, int letter_spacing, int word_spacing, int tab_size, int max_extent, - SIZE* line_size, GLYPHEXTINFO* glyph_ext_info, GLYPHPOS* glyph_pos, - LOGFONT** logfont_sideways); + SIZE* line_size, Glyph32* glyphs, GLYPHEXTINFO* glyph_ext_info, + GLYPHPOS* glyph_pos, LOGFONT** logfont_sideways); #endif /* _MGCHARSET_UNICODE */ /* - * \fn int GUIAPI DrawGlyphStringEx (HDC hdc,, + * \fn int GUIAPI DrawGlyphStringEx (HDC hdc, * LOGFONT* logfont_upright, LOGFONT* logfont_sideways, - * const Glyph32* glyphs, int nr_glyphs, const GLYPHPOS* glyph_pos) + * const Glyph32* glyphs, size_t glyph_unit_size, int nr_glyphs, + * const GLYPHPOS* glyph_pos) * \brief Draw a glyph string at the specified positions and text orientations. * * This function draws a glyph string to the specific positions and @@ -11442,21 +11515,26 @@ MG_EXPORT int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, * \param hdc The device context. * \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. - * \param nr_glyphs The number of the glyphs should be drawn. + * \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. + * \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 - * of every glyph. + * of every glyph. + * \param nr_glyphs The number of the glyphs should be drawn. * * \return The number of glyphs really drawn. * * \note The positions contained in \a glyph_pos are always aligned to * the top-left corner of the output rectangle. * - * \sa GetGlyphsExtentPointEx + * \sa GetGlyphsExtentFromUChars */ MG_EXPORT int GUIAPI DrawGlyphStringEx (HDC hdc, LOGFONT* logfont_upright, LOGFONT* logfont_sideways, - const Glyph32* glyphs, int nr_glyphs, const GLYPHPOS* glyph_pos); + const Glyph32* glyphs, size_t glyph_unit_size, + const GLYPHPOS* glyph_pos, int nr_glyphs); /** @} end of glyph */ /* diff --git a/src/control/bidiedit.c b/src/control/bidiedit.c index 008a1080..2c28c8ea 100644 --- a/src/control/bidiedit.c +++ b/src/control/bidiedit.c @@ -537,11 +537,11 @@ static void slePaint (HWND hWnd, HDC hdc, PBIDISLEDITDATA sled) /* draw normal string. */ setup_dc (hWnd, sled, hdc, FALSE); - outw += DrawGlyphString (hdc, startx + outw, starty, + outw += DrawACharString (hdc, startx + outw, starty, achar_string, len, NULL, NULL); /* draw selected string.*/ setup_dc (hWnd, sled, hdc, TRUE); - outw += DrawGlyphString (hdc, startx + outw, starty, + outw += DrawACharString (hdc, startx + outw, starty, achar_string + len, *(p + 1) - *p, NULL, NULL); achar_string = ACHARS + *(p + 1); @@ -553,28 +553,28 @@ static void slePaint (HWND hWnd, HDC hdc, PBIDISLEDITDATA sled) /* draw the last rest normal string if necessary.*/ if (p && ACHARSLEN > *(p-1)) { setup_dc (hWnd, sled, hdc, FALSE); - outw += DrawGlyphString (hdc, startx + outw, starty, + outw += DrawACharString (hdc, startx + outw, starty, achar_string, ACHARSLEN - *(p - 1), NULL, NULL); } else if(!p || nr_ranges == 0){ /* draw first normal chars */ if (sled->selStart > 0) { setup_dc (hWnd, sled, hdc, FALSE); - outw += DrawGlyphString (hdc, startx + outw, starty, + outw += DrawACharString (hdc, startx + outw, starty, achar_string, sled->selStart, NULL, NULL); achar_string += sled->selStart; } /* draw selected chars */ setup_dc (hWnd, sled, hdc, TRUE); - outw += DrawGlyphString (hdc, startx + outw, starty, + outw += DrawACharString (hdc, startx + outw, starty, achar_string, sled->selEnd - sled->selStart, NULL, NULL); achar_string += sled->selEnd - sled->selStart; /* draw others */ if (sled->selEnd < ACHARSLEN) { setup_dc (hWnd, sled, hdc, FALSE); - outw += DrawGlyphString (hdc, startx + outw, starty, + outw += DrawACharString (hdc, startx + outw, starty, achar_string, ACHARSLEN - sled->selEnd, NULL, NULL); } @@ -587,7 +587,7 @@ static void slePaint (HWND hWnd, HDC hdc, PBIDISLEDITDATA sled) setup_dc (hWnd, sled, hdc, FALSE); startx = sled->startx; sleContentToWindow (sled, &startx); - DrawGlyphString (hdc, startx, starty, achar_string, ACHARSLEN, NULL, NULL); + DrawACharString (hdc, startx, starty, achar_string, ACHARSLEN, NULL, NULL); } if (dwStyle & ES_PASSWORD) @@ -638,7 +638,7 @@ static void set_caret_pos (HWND hWnd, PBIDISLEDITDATA sled, int x, BOOL bSel) txtsize.cx = 0; } else { - out_achars = GetGlyphsExtentPoint (hdc, ACHARS, ACHARSLEN, + out_achars = GetACharsExtentPoint (hdc, ACHARS, ACHARSLEN, x - sled->startx, &txtsize); #ifdef _DEBUG if(out_achars <= ACHARSLEN){ @@ -694,7 +694,7 @@ make_charpos_visible (HWND hWnd, PBIDISLEDITDATA sled, int achar_pos, int *cx) achar_pos = ACHARSLEN; hdc = GetClientDC (hWnd); - GetGlyphsExtent (hdc, ACHARS, achar_pos, &achars_size); + GetACharsExtent (hdc, ACHARS, achar_pos, &achars_size); ReleaseDC (hdc); } if (cx) @@ -799,7 +799,7 @@ static int sleMouseMove (HWND hWnd, PBIDISLEDITDATA sled, LPARAM lParam) sled->selEnd = ACHARSLEN; //sled->nContX = sled->nContW - (sled->rcVis.right - sled->rcVis.left); hdc = GetClientDC (hWnd); - sled->nContX = GetGlyphsExtent (hdc, ACHARS, ACHARSLEN, &size) - (sled->rcVis.right - sled->rcVis.left); + sled->nContX = GetACharsExtent (hdc, ACHARS, ACHARSLEN, &size) - (sled->rcVis.right - sled->rcVis.left); ReleaseDC (hdc); printf ("nContX = %d. nContW = %d, rcVis.right = %d, rcVis.left = %d.\n", sled->nContX, sled->nContW, sled->rcVis.right, sled->rcVis.left); @@ -849,7 +849,7 @@ static void set_line_width (HWND hWnd, PBIDISLEDITDATA sled) SelectFont (hdc, GetWindowFont(hWnd)); update_achar_info(hWnd, sled); - GetGlyphsExtent (hdc, ACHARS, ACHARSLEN, &achars_size); + GetACharsExtent (hdc, ACHARS, ACHARSLEN, &achars_size); ReleaseDC (hdc); if (achars_size.cx > sled->nVisW) @@ -2281,7 +2281,7 @@ static void sledit_refresh_caret (HWND hWnd, PBIDISLEDITDATA sled, BOOL bInited) return; hdc = GetClientDC (hWnd); - outchar = GetGlyphsExtentPoint (hdc, ACHARS, ACHARSLEN, 0, &achars_size); + outchar = GetACharsExtentPoint (hdc, ACHARS, ACHARSLEN, 0, &achars_size); ReleaseDC (hdc); if (bInited) { diff --git a/src/font/bitmapfont.c b/src/font/bitmapfont.c index f4f0457e..d2e0e3dd 100644 --- a/src/font/bitmapfont.c +++ b/src/font/bitmapfont.c @@ -274,7 +274,7 @@ get_glyph_prbitmap (LOGFONT* logfont, DEVFONT* devfont, bmp->bmHeight = 0; bmp->bmPitch = 0; - _MG_PRINTF ("FONT>Bitmap: " + _DBG_PRINTF ("FONT>Bitmap: " "Glyph %d does not exist and is replaced with default glyph. \n", glyph_value); return 1; diff --git a/src/font/charset-arabic.c b/src/font/charset-arabic.c index 7001ddc2..e6cb0a42 100644 --- a/src/font/charset-arabic.c +++ b/src/font/charset-arabic.c @@ -176,6 +176,8 @@ static unsigned short iso8859_68x_unicode_map [] = static Uchar32 iso8859_6_conv_to_uc32 (Achar32 chv) { + chv = REAL_ACHAR(chv); + if (chv < 0x81) return (Achar32) (chv); else if (chv <= MAX_GLYPH_VALUE ) @@ -588,7 +590,7 @@ static Uint32 __mg_iso8859_68x_type[] = { static unsigned int iso8859_6_bidi_char_type (Achar32 chv) { - return __mg_iso8859_68x_type [chv]; + return __mg_iso8859_68x_type[REAL_ACHAR(chv)]; } static int get_table_index(Uint8 c) diff --git a/src/font/charset.c b/src/font/charset.c index 58561b5c..2ddad4ef 100644 --- a/src/font/charset.c +++ b/src/font/charset.c @@ -735,13 +735,18 @@ static CHARSETOPS CharsetOps_iso8859_5 = { #include "bidi.h" -static BOOL get_mirror_char (const BIDICHAR_MIRROR_MAP* map, int n, Achar32 chv, Achar32* mirrored) +static BOOL get_mirror_char (const BIDICHAR_MIRROR_MAP* map, int n, + Achar32 chv, Achar32* mirrored) { int pos, step; BOOL found = FALSE; + Achar32 mbc_mask; pos = step = (n / 2) + 1; + mbc_mask = chv & ACHAR_MBC_FLAG; + chv = REAL_ACHAR(chv); + while (step > 1) { Achar32 cmp_char = map[pos].chv; step = (step + 1) / 2; @@ -764,6 +769,7 @@ static BOOL get_mirror_char (const BIDICHAR_MIRROR_MAP* map, int n, Achar32 chv, if (mirrored){ *mirrored = found ? map[pos].mirrored : chv; + *mirrored |= mbc_mask; } return found; @@ -1042,7 +1048,7 @@ static Uint32 __mg_iso8859_8_type[] = { static unsigned int iso8859_8_bidi_char_type (Achar32 chv) { - return __mg_iso8859_8_type [chv]; + return __mg_iso8859_8_type [REAL_ACHAR(chv)]; } static const BIDICHAR_MIRROR_MAP __mg_iso8859_8_mirror_table [] = @@ -1068,6 +1074,8 @@ static BOOL iso8859_8_bidi_mirror_char (Achar32 chv, Achar32* mirrored) #ifdef _MGCHARSET_UNICODE static Uchar32 iso8859_8_conv_to_uc32 (Achar32 chv) { + chv = REAL_ACHAR(chv); + if (chv >= 0xE0 && chv <= 0xFA) { return chv - 0xE0 + 0x05D0; } @@ -1122,7 +1130,7 @@ static int iso8859_8_conv_from_uc32 (Uchar32 wc, unsigned char* mchar) static CHARSETOPS CharsetOps_iso8859_8 = { 256, - 1, + 2, // This is a trick for bidi reorder only implemented for MBC. FONT_CHARSET_ISO8859_8, 0, sb_len_first_char, @@ -2104,7 +2112,7 @@ static int gb2312_0_pos_first_char (const unsigned char* mstr, int mstrlen) #ifdef _MGCHARSET_UNICODE static Uchar32 gb2312_0_conv_to_uc32 (Achar32 chv) { - return (Uchar32)__mg_gbunicode_map [chv]; + return (Uchar32)__mg_gbunicode_map [REAL_ACHAR(chv)]; } const unsigned char* __mg_map_uc16_to_gb (unsigned short uc16); @@ -2262,7 +2270,7 @@ static int gbk_pos_first_char (const unsigned char* mstr, int mstrlen) #ifdef _MGCHARSET_UNICODE static Uchar32 gbk_conv_to_uc32 (Achar32 chv) { - return (Uchar32)__mg_gbkunicode_map[chv]; + return (Uchar32)__mg_gbkunicode_map[REAL_ACHAR(chv)]; } const unsigned char* __mg_map_uc16_to_gbk (unsigned short uc16); @@ -2506,6 +2514,8 @@ static const unsigned char* gb18030_0_get_next_word (const unsigned char* mstr, #ifdef _MGCHARSET_UNICODE static Uchar32 gb18030_0_conv_to_uc32 (Achar32 chv) { + chv = REAL_ACHAR(chv); + /* from 0x90308130 to 0xE3329A35 */ if (chv > 63611) { int m1, n1, m2, n2, m3, n3; @@ -2680,7 +2690,7 @@ static int big5_pos_first_char (const unsigned char* mstr, int mstrlen) #ifdef _MGCHARSET_UNICODE static Uchar32 big5_conv_to_uc32 (Achar32 chv) { - unsigned short ucs_code = __mg_big5_unicode_map [chv]; + unsigned short ucs_code = __mg_big5_unicode_map[REAL_ACHAR(chv)]; if (ucs_code == 0) return '?'; @@ -2839,7 +2849,7 @@ static int ksc5601_0_pos_first_char (const unsigned char* mstr, int mstrlen) #ifdef _MGCHARSET_UNICODE static Uchar32 ksc5601_0_conv_to_uc32 (Achar32 chv) { - unsigned short ucs_code = __mg_ksc5601_0_unicode_map [chv]; + unsigned short ucs_code = __mg_ksc5601_0_unicode_map[REAL_ACHAR(chv)]; if (ucs_code == 0) return '?'; @@ -3106,7 +3116,7 @@ static Uchar32 jisx0208_0_conv_to_uc32 (Achar32 chv) { unsigned short ucs_code; - ucs_code = __mg_jisx0208_0_unicode_map [chv]; + ucs_code = __mg_jisx0208_0_unicode_map[REAL_ACHAR(chv)]; if (ucs_code == 0) return '?'; @@ -3362,7 +3372,7 @@ static Uchar32 jisx0208_1_conv_to_uc32 (Achar32 chv) { unsigned short ucs_code; - ucs_code = __mg_jisx0208_1_unicode_map [chv]; + ucs_code = __mg_jisx0208_1_unicode_map[REAL_ACHAR(chv)]; if (ucs_code == 0) return '?'; @@ -3533,6 +3543,7 @@ static unsigned int unicode_char_type (Achar32 chv) unsigned int mchar_type = MCHAR_TYPE_UNKNOWN; unsigned int basic_type = 0, break_type = 0; + chv = REAL_ACHAR(chv); basic_type = TYPE(chv); break_type = PROP(chv); diff --git a/src/include/devfont.h b/src/include/devfont.h index e99af013..076baf56 100644 --- a/src/include/devfont.h +++ b/src/include/devfont.h @@ -80,7 +80,7 @@ * * \param glyph The logfont glyph value */ -#define IS_MBC_GLYPH(glyph) ((glyph) & GLYPH_DEVFONT_INDEX_MASK) +//#define IS_MBC_GLYPH(glyph) ((glyph) & GLYPH_DEVFONT_INDEX_MASK) #define SET_GLYPH_DFI(glyph, dfi) \ (((glyph) & ~GLYPH_DEVFONT_INDEX_MASK) | \ diff --git a/src/newgdi/achar.c b/src/newgdi/achar.c index 3ca9bf4f..e8edeba9 100644 --- a/src/newgdi/achar.c +++ b/src/newgdi/achar.c @@ -138,7 +138,7 @@ Uint32 GUIAPI GetACharType (LOGFONT* logfont, Achar32 chv) return devfont->charset_ops->char_type (REAL_ACHAR (chv)); } -Uint32 GetGlyphBIDIType (LOGFONT* log_font, Achar32 chv) +Uint32 GUIAPI GetACharBIDIType (LOGFONT* log_font, Achar32 chv) { DEVFONT* devfont = SELECT_DEVFONT_BY_ACHAR(log_font, chv); diff --git a/src/newgdi/bidi.c b/src/newgdi/bidi.c index 58836b3c..433cb6c7 100644 --- a/src/newgdi/bidi.c +++ b/src/newgdi/bidi.c @@ -119,35 +119,43 @@ static Achar32* _gdi_get_achars_string(PDC pdc, const unsigned char* text, static unsigned int inline get_char_type(LOGFONT* logfont, Achar32 chv) { - if (IS_MBC_GLYPH (chv)) + if (IS_MBCHV (chv)) return logfont->devfonts[1]->charset_ops->char_type(chv); else return logfont->devfonts[0]->charset_ops->char_type(chv); } -static int inline get_glyph_advance_in_dc (PDC pdc, Achar32 chv) +static int inline get_glyph_advance_in_dc (PDC pdc, Glyph32 gv) { - return _gdi_get_glyph_advance(pdc, chv, TRUE, 0, 0, NULL, NULL, NULL); + return _gdi_get_glyph_advance(pdc, gv, TRUE, 0, 0, NULL, NULL, NULL); } - -static int jump_vowels_ltr (PDC pdc, Achar32* achs, int glyph_num, Glyph32* biggest_vowel) +static int jump_vowels_ltr (PDC pdc, Achar32* achs, int nr_achs, + Achar32* biggest_vowel) { int i = 0; int max_advance = 0; int cur_advance = 0; - for (i=0; ipLogFont, achs[i]))) return i; - cur_advance = get_glyph_advance_in_dc (pdc, achs[i]); - if (cur_advance > max_advance) - { + + if ((gv = GetGlyphValue(pdc->pLogFont, achs[i])) == INV_GLYPH_VALUE) { + _DBG_PRINTF("%s: got a bad glyph value from achar: %x\n", + __FUNCTION__, achs[i]); + return i; + } + cur_advance = get_glyph_advance_in_dc (pdc, gv); + if (cur_advance > max_advance) { max_advance = cur_advance; *biggest_vowel = achs [i]; } } - return glyph_num; + + return nr_achs; } static int output_visual_achars_ltr (PDC pdc, Achar32* visual_achars, @@ -158,6 +166,7 @@ static int output_visual_achars_ltr (PDC pdc, Achar32* visual_achars, unsigned int char_type; Achar32 chv; Achar32 biggest_vowel = 0; + Glyph32 gv; int vowel_num; int outed_num = 0; @@ -175,13 +184,20 @@ static int output_visual_achars_ltr (PDC pdc, Achar32* visual_achars, /*output the letter after vowels, * the letter is the owner of jumped vowels * if there is a letter on the vowel's right*/ - if (vowel_num < nr_achars - i) - { + if (vowel_num < nr_achars - i) { + chv = *(visual_achars); char_type = get_char_type (pdc->pLogFont, chv); - if (!cb_one_glyph (context, chv, char_type)){ + if ((gv = GetGlyphValue(pdc->pLogFont, chv)) == INV_GLYPH_VALUE) { + _DBG_PRINTF("%s: got a bad glyph value from achar: %x\n", + __FUNCTION__, chv); + goto end ; + } + + if (!cb_one_glyph (context, gv, char_type)) { goto end; } + outed_num++; /*set vowel aligns width letter's right*/ @@ -190,25 +206,40 @@ static int output_visual_achars_ltr (PDC pdc, Achar32* visual_achars, } /*first output the biggest vowel*/ - if (vowel_num) - { + if (vowel_num) { + char_type = get_char_type (pdc->pLogFont, biggest_vowel); - if (!cb_one_glyph (context, biggest_vowel, char_type)){ + gv = GetGlyphValue(pdc->pLogFont, biggest_vowel); + if ((gv = GetGlyphValue(pdc->pLogFont, biggest_vowel)) == + INV_GLYPH_VALUE) { + _DBG_PRINTF("%s: got a bad glyph value from achar: %x\n", + __FUNCTION__, biggest_vowel); + goto end ; + } + + if (!cb_one_glyph (context, gv, char_type)){ goto end; } + outed_num++; /*transparent from other vowels*/ pdc->bkmode = BM_TRANSPARENT; } /*output other vowels from visual_achars[i]*/ - for (j = 1; j<=vowel_num; j++) - { + for (j = 1; j <= vowel_num; j++) { + chv = *(visual_achars - j); - if (chv != biggest_vowel) - { + if (chv != biggest_vowel) { char_type = get_char_type (pdc->pLogFont, chv); - if (!cb_one_glyph (context, chv, char_type)){ + if ((gv = GetGlyphValue(pdc->pLogFont, chv)) == + INV_GLYPH_VALUE) { + _DBG_PRINTF("%s: got a bad glyph value from achar: %x\n", + __FUNCTION__, chv); + goto end ; + } + + if (!cb_one_glyph (context, gv, char_type)){ goto end; } outed_num++; @@ -239,16 +270,27 @@ static int output_vowels_rtl (PDC pdc, Achar32* end_achar, int left_num, pdc->ta_flags = (old_text_align & ~TA_RIGHT) | TA_LEFT; pdc->bkmode = BM_TRANSPARENT; *outed_num = 0; - for (i=0; ipLogFont, chv); if (check_vowel(char_type)) { - if (cb_one_glyph(context, chv, char_type)) { + Glyph32 gv; + + if ((gv = GetGlyphValue(pdc->pLogFont, chv)) == INV_GLYPH_VALUE) { + _DBG_PRINTF("%s: got a bad glyph value from achar: %x\n", + __FUNCTION__, chv); + break; + } + + if (cb_one_glyph(context, gv, char_type)) { (*outed_num) ++; } + else + break; } - else break; + else + break; } pdc->ta_flags = old_text_align; @@ -260,13 +302,14 @@ static int output_unowned_vowels_rtl (PDC pdc, Achar32* end_achar, int left_num, CB_ONE_GLYPH cb_one_glyph, void* context, int* outed_num) { int i = 0; - Achar32 chv = INV_GLYPH_VALUE; - Achar32 biggest_vowel = INV_GLYPH_VALUE; + Achar32 chv = INV_ACHAR_VALUE; + Achar32 biggest_vowel = INV_ACHAR_VALUE; unsigned int char_type; int cur_advance = 0; int max_advance = 0; int bkmode = pdc->bkmode; int old_text_align = pdc->ta_flags; + Glyph32 gv; *outed_num = 0; if (!check_vowel(get_char_type (pdc->pLogFont, *end_achar))) @@ -280,18 +323,29 @@ static int output_unowned_vowels_rtl (PDC pdc, Achar32* end_achar, int left_num, if (!check_vowel(char_type)) break; - cur_advance = get_glyph_advance_in_dc (pdc, chv); - if (cur_advance > max_advance) - { + if ((gv = GetGlyphValue(pdc->pLogFont, chv)) == + INV_GLYPH_VALUE) { + _DBG_PRINTF("%s: got a bad glyph value from achar: %x\n", + __FUNCTION__, chv); + break; + } + + cur_advance = get_glyph_advance_in_dc (pdc, gv); + if (cur_advance > max_advance) { max_advance = cur_advance; biggest_vowel = chv; } } /*output the biggest_vowel*/ - if(max_advance){ + if (max_advance) { char_type = get_char_type (pdc->pLogFont, biggest_vowel); - if (cb_one_glyph(context, biggest_vowel, char_type)){ + if ((gv = GetGlyphValue(pdc->pLogFont, biggest_vowel)) == + INV_GLYPH_VALUE) { + _DBG_PRINTF("%s: got a bad glyph value from achar: %x\n", + __FUNCTION__, biggest_vowel); + } + else if (cb_one_glyph(context, gv, char_type)) { (*outed_num) ++; } } @@ -299,18 +353,23 @@ static int output_unowned_vowels_rtl (PDC pdc, Achar32* end_achar, int left_num, pdc->bkmode = BM_TRANSPARENT; left_num = i; - for (i=0; ipLogFont, chv); - if (cb_one_glyph(context, chv, char_type)) - { + if ((gv = GetGlyphValue(pdc->pLogFont, chv)) == INV_GLYPH_VALUE) { + _DBG_PRINTF("%s: got a bad glyph value from achar: %x\n", + __FUNCTION__, chv); + break; + } + if (cb_one_glyph(context, gv, char_type)) { (*outed_num) ++; } } } + pdc->bkmode = bkmode; pdc->ta_flags = old_text_align; return left_num; @@ -339,8 +398,12 @@ static int output_visual_achars_rtl (PDC pdc, Achar32* visual_achars, Glyph32 gv; chv = visual_achars[cur]; - char_type = get_char_type (pdc->pLogFont, REAL_ACHAR(chv)); - gv = GetGlyphValue(pdc->pLogFont, chv); + char_type = get_char_type (pdc->pLogFont, chv); + if ((gv = GetGlyphValue(pdc->pLogFont, chv)) == INV_GLYPH_VALUE) { + _DBG_PRINTF("%s: got a bad glyph value from achar: %x\n", + __FUNCTION__, chv); + return outed_glyph_num; + } /*output the letter*/ if (!cb_one_glyph(context, gv, char_type)){ @@ -423,7 +486,7 @@ static int _gdi_output_achars_direct(PDC pdc, const unsigned char* text, else break; do_glyph: - if (IS_MBC_GLYPH (chv)) + if (IS_MBCHV (chv)) char_type = mbc_devfont->charset_ops->char_type (chv); else char_type = sbc_devfont->charset_ops->char_type (chv); @@ -942,7 +1005,7 @@ int GUIAPI BIDIGetTextLogicalAChars( int nr_chars; int prev_len = 0, len_cur_char = 0; const char* prev_mchar = NULL; - Achar32 chv = INV_GLYPH_VALUE; + Achar32 chv = INV_ACHAR_VALUE; Achar32* achar_str = NULL; ACHARMAPINFO* map = NULL; diff --git a/src/newgdi/drawtext.h b/src/newgdi/drawtext.h index a02f518d..5e4fbf56 100644 --- a/src/newgdi/drawtext.h +++ b/src/newgdi/drawtext.h @@ -91,7 +91,7 @@ void _gdi_calc_glyphs_size_from_two_points (PDC pdc, int x0, int y0, typedef BOOL (*CB_ONE_GLYPH) (void* context, Glyph32 glyph_value, unsigned int char_type); -int _gdi_output_visual_achars(PDC pdc, Glyph32* visual_glyphs, int nr_glyphs, +int _gdi_output_visual_achars(PDC pdc, Achar32* visual_achars, int nr_achars, BOOL direction, CB_ONE_GLYPH cb_one_glyph, void* context); int _gdi_reorder_text (PDC pdc, const unsigned char* text, int text_len, diff --git a/src/newgdi/glyph-unicode.c b/src/newgdi/glyph-unicode.c index 47ae577b..0689f23d 100644 --- a/src/newgdi/glyph-unicode.c +++ b/src/newgdi/glyph-unicode.c @@ -3170,10 +3170,10 @@ error: typedef struct _MYGLYPHINFO { Uchar32 uc; Uint8 gc; + Uint8 suppressed:1; Uint8 whitespace:1; - Uint8 ignored:1; + Uint8 orientation:2; Uint8 hanged:2; - Uint8 ort:2; Uint8 justify_word:1; Uint8 justify_char:1; } MYGLYPHINFO; @@ -3181,10 +3181,11 @@ typedef struct _MYGLYPHINFO { typedef struct _MYGLYPHARGS { PLOGFONT lfur; PLOGFONT lfsw; - const Glyph32* gvs; + const Uchar32* ucs; const Uint16* bos; + Glyph32* gvs; + int nr_ucs; Uint32 rf; - int nr_gvs; int lw; int hanged_start; @@ -3436,7 +3437,7 @@ static void justify_glyphs_inter_word(MYGLYPHARGS* args, int left; for (i = 0; i < n; i++) { - if (gis[i].ignored == 0 && gis[i].hanged == 0 && + if (gis[i].suppressed == 0 && gis[i].hanged == 0 && is_word_separator(args, gis, i)) { nr_words++; gis[i].justify_word = 1; @@ -3487,7 +3488,7 @@ static void justify_glyphs_inter_char(MYGLYPHARGS* args, int left; for (i = 0; i < n; i++) { - if (gis[i].ignored == 0 && gis[i].hanged == 0 && + if (gis[i].suppressed == 0 && gis[i].hanged == 0 && !is_word_separator(args, gis, i) && is_typographic_char(args, gis, i)) { nr_chars++; @@ -3547,7 +3548,7 @@ static void justify_glyphs_auto(MYGLYPHARGS* args, for (i = 0; i < n; i++) { gis[i].justify_word = 0; gis[i].justify_char = 0; - if (gis[i].ignored == 0 && gis[i].hanged == 0) { + if (gis[i].suppressed == 0 && gis[i].hanged == 0) { if ((is_word_separator(args, gis, i) && i != 0) || IsUCharWideCJK(gis[i].uc)) { nr_words++; @@ -3634,14 +3635,14 @@ static void adjust_glyph_position(MYGLYPHARGS* args, { switch (args->rf & GRF_WRITING_MODE_MASK) { case GRF_WRITING_MODE_VERTICAL_RL: - if (gi->ort == GLYPH_ORIENTATION_UPRIGHT) { + if (gi->orientation == GLYPH_ORIENTATION_UPRIGHT) { x -= (args->lw + ge->bbox_w) / 2; x -= ge->bbox_x; } break; case GRF_WRITING_MODE_VERTICAL_LR: - if (gi->ort == GLYPH_ORIENTATION_SIDEWAYS) { + if (gi->orientation == GLYPH_ORIENTATION_SIDEWAYS) { x += args->lfsw->size; } else { @@ -3660,7 +3661,7 @@ static void adjust_glyph_position(MYGLYPHARGS* args, } static void calc_unhanged_glyph_positions(MYGLYPHARGS* args, - const MYGLYPHINFO* gis, const GLYPHEXTINFO* ges, int n, + const MYGLYPHINFO* gis, GLYPHEXTINFO* ges, int n, int x, int y, GLYPHPOS* pos) { int i; @@ -3687,10 +3688,14 @@ static void calc_unhanged_glyph_positions(MYGLYPHARGS* args, for (i = first; i < stop; i++) { adjust_glyph_position(args, x, y, gis + i, ges + i, pos + i); + ges[i].suppressed = gis[i].suppressed; + ges[i].whitespace = gis[i].whitespace; + ges[i].orientation = gis[i].orientation; + + pos[i].suppressed = gis[i].suppressed; pos[i].whitespace = gis[i].whitespace; - pos[i].suppressed = gis[i].ignored; + pos[i].orientation = gis[i].orientation; pos[i].hanged = gis[i].hanged; - pos[i].orientation = gis[i].ort; } } @@ -3719,7 +3724,7 @@ static int calc_hanged_glyphs_extent(MYGLYPHARGS* args, } static int calc_hanged_glyphs_start(MYGLYPHARGS* args, - const MYGLYPHINFO* gis, const GLYPHEXTINFO* ges, + const MYGLYPHINFO* gis, GLYPHEXTINFO* ges, GLYPHPOS* pos, int n, int x, int y) { int i; @@ -3770,17 +3775,21 @@ static int calc_hanged_glyphs_start(MYGLYPHARGS* args, for (i = 0; i <= args->hanged_start; i++) { adjust_glyph_position(args, x, y, gis + i, ges + i, pos + i); + ges[i].suppressed = gis[i].suppressed; + ges[i].whitespace = gis[i].whitespace; + ges[i].orientation = gis[i].orientation; + + pos[i].suppressed = gis[i].suppressed; pos[i].whitespace = gis[i].whitespace; - pos[i].suppressed = gis[i].ignored; + pos[i].orientation = gis[i].orientation; pos[i].hanged = gis[i].hanged; - pos[i].orientation = gis[i].ort; } return hanged_extent; } static int calc_hanged_glyphs_end(MYGLYPHARGS* args, - const MYGLYPHINFO* gis, const GLYPHEXTINFO* ges, + const MYGLYPHINFO* gis, GLYPHEXTINFO* ges, GLYPHPOS* pos, int n, int x, int y, int extent) { int i; @@ -3827,10 +3836,14 @@ static int calc_hanged_glyphs_end(MYGLYPHARGS* args, for (i = args->hanged_end; i < n; i++) { adjust_glyph_position(args, x, y, gis + i, ges + i, pos + i); + ges[i].suppressed = gis[i].suppressed; + ges[i].whitespace = gis[i].whitespace; + ges[i].orientation = gis[i].orientation; + + pos[i].suppressed = gis[i].suppressed; pos[i].whitespace = gis[i].whitespace; - pos[i].suppressed = gis[i].ignored; + pos[i].orientation = gis[i].orientation; pos[i].hanged = gis[i].hanged; - pos[i].orientation = gis[i].ort; } _DBG_PRINTF("%s: hanged_start(%d) hanged_end(%d) n(%d) hanged_extent(%d)\n", @@ -3937,16 +3950,14 @@ static inline BOOL is_stop_or_common(const MYGLYPHINFO* gi) static void init_glyph_info(MYGLYPHARGS* args, int i, MYGLYPHINFO* gi) { - DEVFONT* devfont = SELECT_DEVFONT_BY_GLYPH(args->lfur, args->gvs[i]); - if (devfont->charset_ops->conv_to_uc32) - gi->uc = devfont->charset_ops->conv_to_uc32(args->gvs[i]); - else - gi->uc = REAL_GLYPH(args->gvs[i]); + args->gvs[i] = GetGlyphValue(args->lfur, SET_MBCHV(args->ucs[i])); + + gi->uc = args->ucs[i]; gi->gc = UCharGetCategory(gi->uc); gi->whitespace = 0; - gi->ignored = 0; + gi->suppressed = 0; gi->hanged = GLYPH_HANGED_NONE; - gi->ort = GLYPH_ORIENTATION_UPRIGHT; + gi->orientation = GLYPH_ORIENTATION_UPRIGHT; } static inline int shrink_total_extent(MYGLYPHARGS* args, int total_extent, @@ -3987,13 +3998,13 @@ static int get_glyph_extent_info(MYGLYPHARGS* args, Glyph32 gv, == GRF_TEXT_ORIENTATION_MIXED) { if (is_horizontal_only_script(gi->uc)) { logfont = args->lfsw; - gi->ort = GLYPH_ORIENTATION_SIDEWAYS; + gi->orientation = GLYPH_ORIENTATION_SIDEWAYS; } } else if ((args->rf & GRF_TEXT_ORIENTATION_MASK) == GRF_TEXT_ORIENTATION_SIDEWAYS) { logfont = args->lfsw; - gi->ort = GLYPH_ORIENTATION_SIDEWAYS; + gi->orientation = GLYPH_ORIENTATION_SIDEWAYS; } } @@ -4016,7 +4027,7 @@ static int get_first_normal_glyph(const MYGLYPHARGS* args, { int i; for (i = 0; i < n; i++) { - if (gis[i].ignored == 0 && gis[i].hanged == 0 + if (gis[i].suppressed == 0 && gis[i].hanged == 0 && (args->bos[i - 1] & BOV_GB_CHAR_BREAK)) return i; } @@ -4029,7 +4040,7 @@ static int get_last_normal_glyph(const MYGLYPHARGS* args, { int i; for (i = n - 1; i >= 0; i--) { - if (gis[i].ignored == 0 && gis[i].hanged == 0 + if (gis[i].suppressed == 0 && gis[i].hanged == 0 && (args->bos[i - 1] & BOV_GB_CHAR_BREAK)) return i; } @@ -4037,13 +4048,22 @@ static int get_last_normal_glyph(const MYGLYPHARGS* args, return -1; } -int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, - const Glyph32* glyphs, int nr_glyphs, +static inline BOOL is_logfont_unicode(LOGFONT* lf) +{ + DEVFONT* df = lf->devfonts[1]; + if (df && df->charset_ops->conv_to_uc32 == NULL) + return TRUE; + + return FALSE; +} + +int GUIAPI GetGlyphsExtentFromUChars(LOGFONT* logfont_upright, + const Uchar32* ucs, int nr_ucs, const Uint16* break_oppos, Uint32 render_flags, int x, int y, int letter_spacing, int word_spacing, int tab_size, int max_extent, - SIZE* line_size, GLYPHEXTINFO* glyph_ext_info, GLYPHPOS* glyph_pos, - LOGFONT** logfont_sideways) + SIZE* line_size, Glyph32* glyphs, GLYPHEXTINFO* glyph_ext_info, + GLYPHPOS* glyph_pos, LOGFONT** logfont_sideways) { int n = 0; int total_extent = 0; @@ -4060,6 +4080,14 @@ int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, if (logfont_upright == NULL || logfont_upright->rotation != 0) return 0; + if (!is_logfont_unicode(logfont_upright) || + (*logfont_sideways != NULL && + !is_logfont_unicode(*logfont_sideways))) { + _ERR_PRINTF("%s: the logfonts are not in Unicode charset.\n", + __FUNCTION__); + return 0; + } + if (*logfont_sideways == NULL) { if ((render_flags & GRF_WRITING_MODE_MASK) != GRF_WRITING_MODE_HORIZONTAL_TB) { @@ -4086,31 +4114,32 @@ int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, } if (glyph_ext_info == NULL) { - ges = (GLYPHEXTINFO*)calloc(sizeof(GLYPHEXTINFO), nr_glyphs); + ges = (GLYPHEXTINFO*)calloc(sizeof(GLYPHEXTINFO), nr_ucs); if (ges == NULL) goto error; } else { ges = glyph_ext_info; - memset(ges, 0, sizeof(GLYPHEXTINFO) * nr_glyphs); + memset(ges, 0, sizeof(GLYPHEXTINFO) * nr_ucs); } - gis = (MYGLYPHINFO*)calloc(sizeof(MYGLYPHINFO), nr_glyphs); + gis = (MYGLYPHINFO*)calloc(sizeof(MYGLYPHINFO), nr_ucs); if (gis == NULL) goto error; args.lfur = logfont_upright; args.lfsw = *logfont_sideways; + args.ucs = ucs; args.gvs = glyphs; args.bos = break_oppos; + args.nr_ucs = nr_ucs; args.rf = render_flags; - args.nr_gvs = nr_glyphs; args.lw = args.lfur->size; if (args.lfsw) { args.lw = MAX(args.lw, args.lfsw->size); } - while (n < nr_glyphs) { + while (n < nr_ucs) { int extra_spacing; init_glyph_info(&args, n, gis + n); @@ -4144,7 +4173,7 @@ int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, gis[n].whitespace = 1; } else { - gis[n].ignored = 1; + gis[n].suppressed = 1; ges[n].line_adv = 0; } } @@ -4163,7 +4192,7 @@ int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, } } else if (is_zero_width_glyph(&args, gis, n)) { - gis[n].ignored = 1; + gis[n].suppressed = 1; ges[n].line_adv = 0; } else { @@ -4173,10 +4202,10 @@ int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, // extra space for word and letter extra_spacing = 0; - if (gis[n].ignored == 0 && is_word_separator(&args, gis, n)) { + if (gis[n].suppressed == 0 && is_word_separator(&args, gis, n)) { extra_spacing = word_spacing; } - else if (gis[n].ignored == 0 && is_typographic_char(&args, gis, n)) { + else if (gis[n].suppressed == 0 && is_typographic_char(&args, gis, n)) { extra_spacing = letter_spacing; } @@ -4247,7 +4276,7 @@ int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, while (i < n && gis[i].uc == UCHAR_SPACE) { total_extent -= ges[i].line_adv; memset(ges + i, 0, sizeof(GLYPHEXTINFO)); - gis[i].ignored = 1; + gis[i].suppressed = 1; i++; } } @@ -4259,7 +4288,7 @@ int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, (gis[i].uc == UCHAR_SPACE || gis[i].uc == UCHAR_IDSPACE)) { total_extent -= ges[i].line_adv; memset(ges + i, 0, sizeof(GLYPHEXTINFO)); - gis[i].ignored = 1; + gis[i].suppressed = 1; i--; } } @@ -4274,7 +4303,7 @@ int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, } } - if (n < nr_glyphs) { + if (n < nr_ucs) { init_glyph_info(&args, n, gis + n); } @@ -4293,7 +4322,7 @@ int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, if (last < args.hanged_end) args.hanged_end = last; } #if 0 - else if (n < nr_glyphs && is_closing_punctation(gis + n)) { + else if (n < nr_ucs && is_closing_punctation(gis + n)) { gis[n].hanged = GLYPH_HANGED_END; if (n < args.hanged_end) args.hanged_end = n; ges[n].line_adv = get_glyph_extent_info(&args, glyphs[n], gis + n, @@ -4312,7 +4341,7 @@ int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, if (last < args.hanged_end) args.hanged_end = last; } #if 0 - else if (n < nr_glyphs && is_stop_or_common(gis + n)) { + else if (n < nr_ucs && is_stop_or_common(gis + n)) { gis[n].hanged = GLYPH_HANGED_END; if (n < args.hanged_end) args.hanged_end = n; ges[n].line_adv = get_glyph_extent_info(&args, glyphs[n], gis + n, @@ -4325,7 +4354,7 @@ int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright, else if (render_flags & GRF_HANGING_PUNC_ALLOW_END) { // A stop or comma at the end of a line hangs // if it does not otherwise fit prior to justification. - if (n < nr_glyphs && is_stop_or_common(gis + n)) { + if (n < nr_ucs && is_stop_or_common(gis + n)) { gis[n].hanged = GLYPH_HANGED_END; if (n < args.hanged_end) args.hanged_end = n; ges[n].line_adv = get_glyph_extent_info(&args, glyphs[n], gis + n, @@ -4414,21 +4443,26 @@ error: int GUIAPI DrawGlyphStringEx(HDC hdc, LOGFONT* logfont_upright, LOGFONT* logfont_sideways, - const Glyph32* glyphs, int nr_glyphs, - const GLYPHPOS* glyph_pos) + const Glyph32* glyphs, size_t gsize, + const GLYPHPOS* glyph_pos, int nr_glyphs) { int i; int n = 0; Uint32 old_ta; + const BYTE* glyph_item = (const BYTE*)glyphs; PLOGFONT old_lf; - if (glyph_pos == NULL || nr_glyphs <= 0) + if (glyphs == NULL || glyph_pos == NULL || nr_glyphs <= 0) return 0; + if (gsize < sizeof(Glyph32)) + gsize = sizeof(Glyph32); + old_ta = SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_UPDATECP); old_lf = GetCurFont(hdc); for (i = 0; i < nr_glyphs; i++) { + Glyph32 gv = *(const Glyph32*)glyph_item; if (glyph_pos[i].suppressed == 0 && glyph_pos[i].whitespace == 0) { if (glyph_pos[i].orientation == GLYPH_ORIENTATION_UPRIGHT) { if (logfont_upright) @@ -4443,11 +4477,13 @@ int GUIAPI DrawGlyphStringEx(HDC hdc, goto error; } - DrawGlyph(hdc, glyph_pos[i].x, glyph_pos[i].y, glyphs[i], + DrawGlyph(hdc, glyph_pos[i].x, glyph_pos[i].y, gv, NULL, NULL); n++; } + + glyph_item += gsize; } error: diff --git a/src/newgdi/glyph.c b/src/newgdi/glyph.c index 9d0ccc5e..402bd035 100644 --- a/src/newgdi/glyph.c +++ b/src/newgdi/glyph.c @@ -80,7 +80,7 @@ Glyph32 GetGlyphValue(LOGFONT* lf, Achar32 chv) if (IS_MBCHV(chv)) { chv = REAL_ACHAR(chv); for (i = 1; i < MAXNR_DEVFONTS; i++) { - if ((df = lf->devfonts[i])) { + if ((df = lf->devfonts[i]) != NULL) { if (df->font_ops->get_glyph_value) gv = df->font_ops->get_glyph_value(lf, df, chv); else @@ -94,7 +94,7 @@ Glyph32 GetGlyphValue(LOGFONT* lf, Achar32 chv) } if (dfi == 0) { - if ((df = lf->devfonts[1])) { + if ((df = lf->devfonts[1]) != NULL) { dfi = 1; if (df->font_ops->get_glyph_value) gv = df->font_ops->get_glyph_value(lf, df, chv); @@ -182,41 +182,6 @@ int GUIAPI GetGlyphInfo (LOGFONT* logfont, Glyph32 glyph_value, return 0; } -int GUIAPI DrawGlyph (HDC hdc, int x, int y, Glyph32 glyph_value, - int* adv_x, int* adv_y) -{ - int advance; - int char_type; - - PDC pdc = dc_HDC2PDC(hdc); - DEVFONT* devfont = SELECT_DEVFONT_BY_GLYPH(pdc->pLogFont, glyph_value); - - /* Transfer logical to device to screen here. */ - coor_LP2SP (pdc, &x, &y); - pdc->rc_output = pdc->DevRC; - - char_type = devfont->charset_ops->char_type (glyph_value); - if (check_zero_width(char_type)) { - if (adv_x) *adv_x = 0; - if (adv_y) *adv_y = 0; - advance = 0; - } - else { - int my_adv_x, my_adv_y; - /* convert to the start point on baseline. */ - _gdi_get_baseline_point (pdc, &x, &y); - - advance = _gdi_draw_one_glyph (pdc, glyph_value, - (pdc->ta_flags & TA_X_MASK) != TA_RIGHT, - x, y, &my_adv_x, &my_adv_y); - - if (adv_x) *adv_x = my_adv_x; - if (adv_y) *adv_y = my_adv_y; - } - - return advance; -} - static int mult (fixed op1, fixed op2) { long s = op2; @@ -2827,6 +2792,69 @@ void _gdi_start_new_line (PDC pdc) } } +int GUIAPI DrawGlyph (HDC hdc, int x, int y, Glyph32 glyph_value, + int* adv_x, int* adv_y) +{ + int my_adv_x, my_adv_y; + int advance; + PDC pdc; + + if (glyph_value == INV_GLYPH_VALUE) + return 0; + + pdc = dc_HDC2PDC(hdc); + /* Transfer logical to device to screen here. */ + coor_LP2SP (pdc, &x, &y); + pdc->rc_output = pdc->DevRC; + + /* convert to the start point on baseline. */ + _gdi_get_baseline_point (pdc, &x, &y); + + advance = _gdi_draw_one_glyph (pdc, glyph_value, + (pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + x, y, &my_adv_x, &my_adv_y); + + if (adv_x) *adv_x = my_adv_x; + if (adv_y) *adv_y = my_adv_y; + + return advance; +} + +int GUIAPI DrawGlyphStrings(HDC hdc, Glyph32* glyphs, int nr_glyphs, + const POINT* pts) +{ + int count = 0; + int i; + PDC pdc = dc_HDC2PDC(hdc); + + for (i = 0; i < nr_glyphs; i++) { + int x, y; + int my_adv_x, my_adv_y; + Glyph32 gv = glyphs[i]; + + if (gv == INV_GLYPH_VALUE) + break; + + count++; + + /* Transfer logical to device to screen here. */ + x = pts[i].x; + y = pts[i].y; + + coor_LP2SP (pdc, &x, &y); + pdc->rc_output = pdc->DevRC; + + /* convert to the start point on baseline. */ + _gdi_get_baseline_point (pdc, &x, &y); + + _gdi_draw_one_glyph (pdc, gv, + (pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + x, y, &my_adv_x, &my_adv_y); + } + + return count; +} + int GUIAPI GetGlyphsExtentPoint(HDC hdc, Glyph32* glyphs, int nr_glyphs, int max_extent, SIZE* size) { @@ -2834,22 +2862,18 @@ int GUIAPI GetGlyphsExtentPoint(HDC hdc, Glyph32* glyphs, int nr_glyphs, int advance = 0; int adv_x, adv_y; PDC pdc = dc_HDC2PDC(hdc); - PLOGFONT log_font = pdc->pLogFont; - DEVFONT* devfont = NULL; - unsigned int char_type = 0; size->cx = 0; size->cy = 0; - while(i < nr_glyphs){ - devfont = SELECT_DEVFONT_BY_GLYPH(log_font, glyphs[i]); - char_type = devfont->charset_ops->char_type(glyphs[i]); + while (i < nr_glyphs) { + Glyph32 gv = glyphs[i]; - if (check_zero_width (char_type)) { + if (gv == INV_GLYPH_VALUE) { adv_x = adv_y = 0; } else { - advance += _gdi_get_glyph_advance (pdc, glyphs[i], + advance += _gdi_get_glyph_advance (pdc, gv, (pdc->ta_flags & TA_X_MASK) != TA_RIGHT, 0, 0, &adv_x, &adv_y, NULL); } @@ -2859,7 +2883,7 @@ int GUIAPI GetGlyphsExtentPoint(HDC hdc, Glyph32* glyphs, int nr_glyphs, size->cx += adv_x; size->cy += adv_y; - i ++; + i++; } _gdi_calc_glyphs_size_from_two_points (pdc, 0, 0, @@ -2873,23 +2897,18 @@ int GUIAPI GetGlyphsExtent(HDC hdc, Glyph32* glyphs, int nr_glyphs, SIZE* size) int i = 0; int advance = 0; int adv_x, adv_y; - unsigned int char_type; - Glyph32 glyph_value = INV_GLYPH_VALUE; PDC pdc = dc_HDC2PDC(hdc); - PLOGFONT log_font = pdc->pLogFont; - DEVFONT* devfont = SELECT_DEVFONT_BY_GLYPH(log_font, glyph_value); size->cx = 0; size->cy = 0; while (i < nr_glyphs) { - devfont = SELECT_DEVFONT_BY_GLYPH(log_font, glyphs[i]); - char_type = devfont->charset_ops->char_type(glyphs[i]); + Glyph32 gv = glyphs[i]; - if (check_zero_width (char_type)) { + if (gv == INV_GLYPH_VALUE) { adv_x = adv_y = 0; } else { - advance += _gdi_get_glyph_advance (pdc, glyphs[i], + advance += _gdi_get_glyph_advance (pdc, gv, (pdc->ta_flags & TA_X_MASK) != TA_RIGHT, 0, 0, &adv_x, &adv_y, NULL); } diff --git a/src/newgdi/textout.c b/src/newgdi/textout.c index 66b53558..2f2328cd 100644 --- a/src/newgdi/textout.c +++ b/src/newgdi/textout.c @@ -124,7 +124,8 @@ static BOOL cb_draw_glyph (void* context, Glyph32 glyph_value, unsigned int char adv_y = 0; } else { - ctxt->advance += DrawGlyph (ctxt->hdc, ctxt->x, ctxt->y, glyph_value, &adv_x, &adv_y); + ctxt->advance += DrawGlyph (ctxt->hdc, ctxt->x, ctxt->y, + glyph_value, &adv_x, &adv_y); } ctxt->x += adv_x; @@ -133,26 +134,6 @@ static BOOL cb_draw_glyph (void* context, Glyph32 glyph_value, unsigned int char return TRUE; } -int DrawGlyphString (HDC hdc, int startx, int starty, Glyph32* glyph_string, int len, int* adv_x, int* adv_y) -{ - DRAW_GLYPHS_CTXT ctxt = {hdc, startx, starty, 0}; - - if ((((PDC)hdc)->ta_flags & TA_X_MASK) == TA_LEFT) - _gdi_output_visual_achars((PDC)hdc, glyph_string, - len, TRUE, cb_draw_glyph, &ctxt); - else - _gdi_output_visual_achars((PDC)hdc, glyph_string, - len, FALSE, cb_draw_glyph, &ctxt); - - if (adv_x) - *adv_x = ctxt.x - startx; - - if (adv_y) - *adv_y = ctxt.y - starty; - - return ctxt.advance; -} - typedef struct _TEXTOUT_CTXT { PDC pdc; @@ -457,7 +438,8 @@ int GUIAPI GetTextExtentPoint (HDC hdc, const char* text, int len, int len_cur_char, advance_cur_char; int left_bytes = len; int char_count = 0; - Glyph32 glyph_value; + Achar32 chv; + Glyph32 gv; /* set size to zero first */ size->cx = size->cy = 0; @@ -479,25 +461,12 @@ int GUIAPI GetTextExtentPoint (HDC hdc, const char* text, int len, if (mbc_devfont && (len_cur_char = mbc_devfont->charset_ops->len_first_char ((const unsigned char*)text, left_bytes)) > 0) { - int i, dfi; - DEVFONT* df; - glyph_value = (*mbc_devfont->charset_ops->get_char_value)(NULL, + chv = (*mbc_devfont->charset_ops->get_char_value)(NULL, 0, (const unsigned char*)text, 0); - dfi = 1; - for (i = 1; i < MAXNR_DEVFONTS; i++) { - if ((df = log_font->devfonts[i])) { - if (df->font_ops->is_glyph_existed(log_font, df, - glyph_value)) { - dfi = i; - break; - } - } - } - glyph_value = SET_GLYPH_DFI(glyph_value, dfi); - - advance_cur_char = _gdi_get_glyph_advance (pdc, glyph_value, + gv = GetGlyphValue(pdc->pLogFont, chv); + advance_cur_char = _gdi_get_glyph_advance (pdc, gv, (pdc->ta_flags & TA_X_MASK) == TA_LEFT, 0, 0, NULL, NULL, NULL); } @@ -505,9 +474,10 @@ int GUIAPI GetTextExtentPoint (HDC hdc, const char* text, int len, if ((len_cur_char = sbc_devfont->charset_ops->len_first_char ((const unsigned char*)text, left_bytes)) > 0) { - glyph_value = (*sbc_devfont->charset_ops->get_char_value)( + chv = (*sbc_devfont->charset_ops->get_char_value)( NULL, 0, (const unsigned char*)text, 0); - advance_cur_char = _gdi_get_glyph_advance (pdc, glyph_value, + gv = GetGlyphValue(pdc->pLogFont, chv); + advance_cur_char = _gdi_get_glyph_advance (pdc, gv, (pdc->ta_flags & TA_X_MASK) == TA_LEFT, 0, 0, NULL, NULL, NULL); } @@ -532,3 +502,116 @@ ret: return len - left_bytes; } +int GUIAPI DrawACharString (HDC hdc, int startx, int starty, + Achar32* achars, int len, int* adv_x, int* adv_y) +{ + DRAW_GLYPHS_CTXT ctxt = {hdc, startx, starty, 0}; + + if ((((PDC)hdc)->ta_flags & TA_X_MASK) == TA_LEFT) + _gdi_output_visual_achars((PDC)hdc, achars, + len, TRUE, cb_draw_glyph, &ctxt); + else + _gdi_output_visual_achars((PDC)hdc, achars, + len, FALSE, cb_draw_glyph, &ctxt); + + if (adv_x) + *adv_x = ctxt.x - startx; + + if (adv_y) + *adv_y = ctxt.y - starty; + + return ctxt.advance; +} + +int GUIAPI GetACharsExtentPoint(HDC hdc, Achar32* achars, int nr_achars, + int max_extent, SIZE* size) +{ + int i = 0; + int advance = 0; + int adv_x, adv_y; + PDC pdc = dc_HDC2PDC(hdc); + PLOGFONT log_font = pdc->pLogFont; + DEVFONT* devfont = NULL; + unsigned int char_type = 0; + + size->cx = 0; + size->cy = 0; + + while(i < 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)) { + adv_x = adv_y = 0; + } + else { + Glyph32 gv; + + if ((gv = GetGlyphValue(log_font, achars[i])) == INV_GLYPH_VALUE) { + _DBG_PRINTF("%s: got a bad glyph value from achar: %x\n", + __FUNCTION__, achars[i]); + break; + } + + advance += _gdi_get_glyph_advance (pdc, gv, + (pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + 0, 0, &adv_x, &adv_y, NULL); + } + + if (max_extent > 0 && advance > max_extent) + break; + + size->cx += adv_x; + size->cy += adv_y; + i ++; + } + + _gdi_calc_glyphs_size_from_two_points (pdc, 0, 0, + size->cx, size->cy, size); + + return i; +} + +int GUIAPI GetACharsExtent(HDC hdc, Achar32* achars, int nr_achars, SIZE* size) +{ + int i = 0; + int advance = 0; + int adv_x, adv_y; + unsigned int char_type; + PDC pdc = dc_HDC2PDC(hdc); + PLOGFONT log_font = pdc->pLogFont; + DEVFONT* devfont; + + size->cx = 0; + size->cy = 0; + while (i < nr_achars) { + devfont = SELECT_DEVFONT_BY_GLYPH(log_font, achars[i]); + char_type = devfont->charset_ops->char_type(achars[i]); + + if (check_zero_width (char_type)) { + adv_x = adv_y = 0; + } + else { + Glyph32 gv; + + if ((gv = GetGlyphValue(log_font, achars[i])) == INV_GLYPH_VALUE) { + _DBG_PRINTF("%s: got a bad glyph value from achar: %x\n", + __FUNCTION__, achars[i]); + break; + } + + advance += _gdi_get_glyph_advance (pdc, gv, + (pdc->ta_flags & TA_X_MASK) != TA_RIGHT, + 0, 0, &adv_x, &adv_y, NULL); + } + size->cx += adv_x; + size->cy += adv_y; + i ++; + } + + _gdi_calc_glyphs_size_from_two_points (pdc, 0, 0, + size->cx, size->cy, size); + + return advance; +} +