From 537b659fc75fd5192ca1181516576894fd62523d Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Wed, 13 Mar 2019 17:25:48 +0800 Subject: [PATCH] tune implementation of GetShapedGlyphsBasic --- include/gdi.h | 259 +++++++++++++++++++++----------------- src/newgdi/shaped-glyph.c | 164 ++++++++++++------------ 2 files changed, 228 insertions(+), 195 deletions(-) diff --git a/include/gdi.h b/include/gdi.h index 43435f1c..854f9d67 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -7883,6 +7883,9 @@ typedef Uint8 BidiArabicProp; #define BIDI_PGDIR_LTR BIDI_TYPE_LTR #define BIDI_PGDIR_RTL BIDI_TYPE_RTL +#define BIDI_PGDIR_WLRT BIDI_TYPE_WLTR +#define BIDI_PGDIR_WRTL BIDI_TYPE_WRTL + #define BIDI_PGDIR_ON BIDI_TYPE_ON /* @@ -12208,156 +12211,182 @@ typedef enum _GlyphPosition { } GlyphPosition; /** - * The shaped glyph. + * The glyph shaping information. */ -typedef struct _SHAPEDGLYPH { - /** The glyph value */ - Glyph32 gv; - /** The glyph breaking opportunities */ - Uint16 bos; +typedef struct _GLYPHSHAPINGINFO { /** The glyph type */ Uint8 gt; /** The glyph position */ Uint8 gp; -} SHAPEDGLYPH; +} GLYPHSHAPINGINFO; /** * \fn int GUIAPI GetShapedGlyphsBasic(LOGFONT* logfont, - * LanguageCode content_language, UCharScriptType writing_system, + * UCharScriptType writing_system, + * Uint8 ctr, Uint8 wbr, Uint8 lbp, * const Uchar32* logical_ucs, int nr_ucs, - * Uint16* break_oppos, SHAPEDGLYPH* visual_glyphs, - * BidiType *paragraph_dir, int* pos_l2v, int* nr_glyphs) - * \brief Analyse and generate a shaped glyph string of a Unicode string under - * specific content language and script. + * BidiType* paragraph_dir, + * Glyph32* visual_glyphs, GLYPHSHAPINGINFO* shaping_info, + * Uint16* break_oppos, int* map_v2l, int* nr_glyphs) + * \brief Analyse and generate a shaped glyph string of a Unicode string + * under specific script. * - * This function analyses and generates a shaped glyph string (including + * This function analyses and generates a shaped glyph string, as long as * the breaking opportunities of the glyphs, the glyph types, and the position - * information of them) from a Unicode string and the breaking opportunities - * of all Unicode characters under the specified content language - * \a content_language, and the writing system \a writing_system. + * information of them, from a Unicode string under the specified + * writing system \a writing_system. * - * This function also performs the basic shaping process according to the - * Unicode character properties if the content language is Arabic. - * The shaping process includes: + * This function perform the complex shaping process based on the data + * of Unicode character properties. The shaping process includes: * * - Shaping (substituting) glyphs. - * - Tailoring and assigning the breaking opportunities to glyphs. * - Re-ordering glyphs. + * - Caculating and tailoring the breaking opportunities of the glyphs. * - Positioning glyphs. * + * This function also performs the basic shaping process according to the + * Unicode character properties if the script type (writing system) is Arabic. + * This function also apply the UBA (Unicode Bidirectional Algorithm) to + * reorder the glyphs if the script type is Arabic or Hebrew. + * * You can also call \a GetShapedGlyphsComplex to perform the shaping process * based on the data contained in the OpenType Layout tables of the font. * - * Note that you are responsible for allocating the buffer for the shaped glyph - * string. Generally, the length of the allocated buffer should be same as - * \a nr_ucs. + * Note that you are responsible for allocating the buffers for the shaped + * visual glyphs, the glyph shaping information, as well as the buffers + * of the breaking opportunities and the indics map from glyphs to characters + * if you need them. Generally, the length of the allocated buffer should + * be same as \a nr_ucs, however, the buffer length of the breaking + * opportunities should be longer one than \a nr_ucs. * * \param logfont The logfont used to parse the string. * Note that the charset/encoding of this logfont should be Unicode, * such as UTF-8, UTF-16LE, and UTF-16BE. - * \param content_language The content lanuage identifier. * \param writing_system The writing system (script) identifier. * \param logical_ucs The pointer to the Uchar32 array, which is the logical * Unicode character string. * \param nr_ucs The number of the Unicode characters. - * \param break_oppos The pointer to a Uint16 array which contains - * the break opportunities of the Unicode characters. Note that - * the values may be changed under certain content languags and/or - * writing systems. - * \param visual_glyphs The pointer to the buffer to store the generated + * \param paragraph_dir The specified paragraph base direction, and the + * resolved paragraph base direction will be returned if the specified + * is a weak direction. + * \param visual_glyphs The pointer to a Glyph32 array to store the generated * shaped visual glyph array. - * \param paragraph_dir The specified and resolved paragraph base direction. - * \param pos_l2v The pointer to an int array which will store the map from - * the positions in the logical Uchar32 string to the positions in - * the visual shaped glyphs; can be NULL. - * \param nr_glyphs The buffer to store the number of the generated glyphs. + * \param glyph_shaping_info The pointer to a GLYPHSHAPINGINFO array to store + * the shaping information of all visual glyphs. + * \param break_oppos The pointer to a Uint16 array which stores + * the break opportunities of the visual glyphs. Note that + * the values may be changed under certain content languags and/or + * writing systems. You can pass NULL for this parameter. + * \param map_v2l The pointer to an int array which will store the map from + * the positions in the visual glyph string to the positions in + * the logical Uchar32 string; can be NULL. + * \param nr_glyphs The buffer to store the number of the generated glyphs; + * cannot be NULL. * * \return The number of the Unicode characters processed; zero on error. * * \note Only available when support for UNICODE is enabled. * * \note This function assumes that you passed one line (one paragraph) of - * the logical Unicode string. Therefore, you need to call this function - * after calling GetUCharsUntilParagraphBoundary. + * the logical Unicode string. Therefore, you'd better to call this + * function after calling GetUCharsUntilParagraphBoundary. * - * \sa GetUCharsUntilParagraphBoundary, GetShapedGlyphsComplex, SHAPEDGLYPH, + * \sa GetUCharsUntilParagraphBoundary, GetShapedGlyphsComplex, * UBidiReorderLine, bidi_types, * GetGlyphsExtentInfo, GetGlyphsPositionInfo, DrawShapedGlyphString */ MG_EXPORT int GUIAPI GetShapedGlyphsBasic(LOGFONT* logfont, - LanguageCode content_language, UCharScriptType writing_system, + UCharScriptType writing_system, + Uint8 ctr, Uint8 wbr, Uint8 lbp, const Uchar32* logical_ucs, int nr_ucs, - Uint16* break_oppos, SHAPEDGLYPH* visual_glyphs, - BidiType *paragraph_dir, int* pos_l2v, int* nr_glyphs); + BidiType* paragraph_dir, + Glyph32* visual_glyphs, GLYPHSHAPINGINFO* glyph_shaping_info, + Uint16* break_oppos, int* map_v2l, int* nr_glyphs); /** * \fn int GUIAPI GetShapedGlyphsComplex(LOGFONT* logfont, - * LanguageCode content_language, UCharScriptType writing_system, + * UCharScriptType writing_system, + * Uint8 ctr, Uint8 wbr, Uint8 lbp, * const Uchar32* logical_ucs, int nr_ucs, - * Uint16* break_oppos, SHAPEDGLYPH* visual_glyphs, - * BidiType *paragraph_dir, int* pos_l2v, int* nr_glyphs); - * \brief Analyse and generate a shaped glyph string of a Unicode string under - * specific content language and script. + * BidiType* paragraph_dir, + * Glyph32* visual_glyphs, GLYPHSHAPINGINFO* shaping_info, + * Uint16* break_oppos, int* map_v2l, int* nr_glyphs); + * \brief Analyse and generate a shaped glyph string of a Unicode string + * under specific script. * - * This function analyses and generates a shaped glyph string (including - * the breaking opportunities of the glyphs, and the type and the position - * information of them) from a Unicode string and the breaking opportunities - * of all Unicode characters under the specified content language - * \a content_language, and the writing system \a writing_system. + * This function analyses and generates a shaped glyph string, as long as + * the breaking opportunities of the glyphs, the glyph types, and the position + * information of them, from a Unicode string under the specified + * writing system \a writing_system. * * This function perform the complex shaping process according to the data * contained in the OpenType Layout tables (GSUB, GPOS, and so on). * The shaping process includes: * + * The shaping process includes: + * * - Shaping (substituting) glyphs. - * - Assigning the breaking opportunities. - * - Re-ordering. + * - Re-ordering glyphs. + * - Caculating and tailoring the breaking opportunities of the glyphs. * - Positioning glyphs. * - * You can also call \a GetShapedGlyphsBasic to perform the basic shaping - * process based on the Unicode character properties. + * This function also performs the basic shaping process according to the + * Unicode character properties if the script type (writing system) is Arabic. + * This function also apply the UBA (Unicode Bidirectional Algorithm) to + * reorder the glyphs if the script type is Arabic or Hebrew. * - * Note that you are responsible for allocating the buffer for the shaped glyph - * string. Generally, the length of the allocated buffer should be same as - * \a nr_ucs. + * You can call \a GetShapedGlyphsBasic to perform the basic shaping + * process based on the Unicode character properties instead. + * + * Note that you are responsible for allocating the buffers for the shaped + * visual glyphs, the glyph shaping information, as well as the buffers + * of the breaking opportunities and the indics map from glyphs to characters + * if you need them. Generally, the length of the allocated buffer should + * be same as \a nr_ucs, however, the buffer length of the breaking + * opportunities should be longer one than \a nr_ucs. * * \param logfont The logfont used to parse the string. * Note that the charset/encoding of this logfont should be Unicode, * such as UTF-8, UTF-16LE, and UTF-16BE. - * \param content_language The content lanuage identifier. * \param writing_system The writing system (script) identifier. * \param logical_ucs The pointer to the Uchar32 array, which is the logical * Unicode character string. * \param nr_ucs The number of the Unicode characters. - * \param break_oppos The pointer to a Uint16 array which contains - * the break opportunities of the Unicode characters. Note that - * the values may be changed under certain content languags and/or - * writing systems. - * \param visual_glyphs The pointer to the buffer to store the generated + * \param paragraph_dir The specified paragraph base direction, and the + * resolved paragraph base direction will be returned if the specified + * is a weak direction. + * \param visual_glyphs The pointer to a Glyph32 array to store the generated * shaped visual glyph array. - * \param paragraph_dir The specified and resolved paragraph base direction. - * \param pos_l2v The pointer to an int array which will store the map from - * the positions in the logical Uchar32 string to the positions in - * the visual shaped glyphs; can be NULL. - * \param nr_glyphs The buffer to store the number of the generated glyphs. + * \param glyph_shaping_info The pointer to a GLYPHSHAPINGINFO array to store + * the shaping information of all visual glyphs. + * \param break_oppos The pointer to a Uint16 array which stores + * the break opportunities of the visual glyphs. Note that + * the values may be changed under certain content languags and/or + * writing systems. You can pass NULL for this parameter. + * \param map_v2l The pointer to an int array which will store the map from + * the positions in the visual glyph string to the positions in + * the logical Uchar32 string; can be NULL. + * \param nr_glyphs The buffer to store the number of the generated glyphs; + * cannot be NULL. * * \return The number of the Unicode characters processed; zero on error. * * \note Only available when support for UNICODE is enabled. * * \note This function assumes that you passed one line (one paragraph) of - * the logical Unicode string. Therefore, you need to call this function - * after calling GetUCharsUntilParagraphBoundary. + * the logical Unicode string. Therefore, you'd better to call this + * function after calling GetUCharsUntilParagraphBoundary. * - * \sa GetUCharsUntilParagraphBoundary, GetShapedGlyphsBasic, SHAPEDGLYPH, - * UBidiReorderLine, bidi_types, + * \sa GetUCharsUntilParagraphBoundary, GetShapedGlyphsComplex, * GetGlyphsExtentInfo, GetGlyphsPositionInfo, DrawShapedGlyphString */ MG_EXPORT int GUIAPI GetShapedGlyphsComplex(LOGFONT* logfont, - LanguageCode content_language, UCharScriptType writing_system, + UCharScriptType writing_system, + Uint8 ctr, Uint8 wbr, Uint8 lbp, const Uchar32* logical_ucs, int nr_ucs, - Uint16* break_oppos, SHAPEDGLYPH* visual_glyphs, - BidiType *paragraph_dir, int* pos_l2v, int* nr_glyphs); + BidiType* paragraph_dir, + Glyph32* visual_glyphs, GLYPHSHAPINGINFO* glyph_shaping_info, + Uint16* break_oppos, int* map_v2l, int* nr_glyphs); #define GLYPH_ORIENTATION_UPRIGHT 0 #define GLYPH_ORIENTATION_SIDEWAYS 1 @@ -12398,23 +12427,25 @@ typedef struct _GLYPHEXTINFO { /** * \fn int GUIAPI GetGlyphsExtentInfo(LOGFONT* logfont, - * const SHAPEDGLYPH* glyphs, int nr_glyphs, - * Uint32 render_flags, - * GLYPHEXTINFO* glyph_ext_info, - * LOGFONT** logfont_sideways); + * const Glyph32* glyphs, const GLYPHSHAPINGINFO* glyph_shaping_info, + * int nr_glyphs, Uint32 render_flags, + * GLYPHEXTINFO* glyph_ext_info, LOGFONT** logfont_sideways); * * \brief Get the extent information of all shaped glyphs. * - * This function gets the position information of a SHAPEDGLYPH string which can - * fit a line with the specified maximal extent. + * This function gets the extent information of all glyphs in + * a shaped glyph string. * * \param logfont_upright The logfont used to render the upright glyphs. * Note that the charset/encoding of this logfont should be Unicode, * such as UTF-8, UTF-16LE, and UTF-16BE. - * \param glyphs The pointer to the SHAPEDGLYPH string. + * \param glyphs The glyph string. + * \param glyph_shaping_info The pointer to the GLYPHSHAPINGINFO array, which + * contains the shaping information of all glyphs. * \param nr_glyphs The number of the glyphs. * \param render_flags The render flags; see \a glyph_render_flags. - * \param glyph_ext_info The GLYPHEXTINFO array storing the extent info of all glyphs. + * \param glyph_ext_info The pointer to a GLYPHEXTINFO array storing the + * extent information of all glyphs. * \param logfont_sideways The buffer to store the LOGFONT object created * by this function for sideways glyphs if text orientation specified * in \a render_flags is mixed (GRF_TEXT_ORIENTATION_MIXED) or @@ -12422,12 +12453,7 @@ typedef struct _GLYPHEXTINFO { * not NULL, this function will try to use this LOGFONT object for * sideways glyphs. * - * \return The number of shaped glyphs which are fit to the maximal extent. - * The extra_x and extra_y fields of the glyph extent info of every glyph - * may be changed due to the spacing value and justification. - * 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. + * \return The number of glyphs; zero for failure. * * \note Only available when support for UNICODE is enabled. * @@ -12439,10 +12465,9 @@ typedef struct _GLYPHEXTINFO { * GetGlyphsPositionInfo, DrawShapedGlyphString, GLYPHEXTINFO, glyph_render_flags */ MG_EXPORT int GUIAPI GetGlyphsExtentInfo(LOGFONT* logfont, - const SHAPEDGLYPH* glyphs, int nr_glyphs, - Uint32 render_flags, - GLYPHEXTINFO* glyph_ext_info, - LOGFONT** logfont_sideways); + const Glyph32* glyphs, const GLYPHSHAPINGINFO* glyph_shaping_info, + int nr_glyphs, Uint32 render_flags, + GLYPHEXTINFO* glyph_ext_info, LOGFONT** logfont_sideways); /** * The glyph position information. @@ -12487,23 +12512,30 @@ typedef struct _GLYPHPOS { /** * \fn int GUIAPI GetGlyphsPositionInfo( * LOGFONT* logfont_upright, LOGFONT* logfont_sideways, - * const SHAPEDGLYPH* glyphs, GLYPHEXTINFO* glyph_ext_info, int nr_glyphs, + * const Glyph32* glyphs, const GLYPHSHAPINGINFO* glyph_shaping_info, + * const Uint16* break_oppos, 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); + * GLYPHEXTINFO* glyph_ext_info, SIZE* line_size, GLYPHPOS* glyph_pos); * * \brief Get the position info of all shaped glyphs fitting in the specified * maximal output extent. * - * This function gets the position information of a SHAPEDGLYPH string which can - * fit a line with the specified maximal extent. + * This function gets the position information of a shaped glyph string which + * can fit a line with the specified maximal extent. * * \param logfont_upright The logfont used to render the upright glyphs. * Note that the charset/encoding of this logfont should be Unicode, * such as UTF-8, UTF-16LE, and UTF-16BE. * \param logfont_sideways The LOGFONT object used to render the sideways glyphs. - * \param glyphs The pointer to the SHAPEDGLYPH string. - * \param glyph_ext_info The GLYPHEXTINFO array storing the extent info of all glyphs. + * \param glyphs The glyph string. + * \param glyph_shaping_info The pointer to the GLYPHSHAPINGINFO array which + * returned by GetShapedGlyphsBasic() or GetShapedGlyphsComplex(). + * \param break_oppos The pointer to the break opportunities array of the glyphs. + * It should be returned by \a UStrGetBreaks, GetShapedGlyphsBasic, + * or GetShapedGlyphsComplex. However, the caller should skip the first + * unit (the break opportunity before the first glyph) when passing + * the pointer to this function. * \param nr_glyphs The number of the glyphs. * \param render_flags The render flags; see \a glyph_render_flags. * \param x The x-position of first glyph. @@ -12514,6 +12546,7 @@ typedef struct _GLYPHPOS { * words. * \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 glyph_ext_info The GLYPHEXTINFO array storing the extent info of all glyphs. * \param line_size The buffer to store the line extent info; can be NULL. * \param glyph_pos The buffer to store the positions and orientations of * all glyphs which can fit in the max extent; cannot be NULL. @@ -12544,10 +12577,11 @@ typedef struct _GLYPHPOS { */ MG_EXPORT int GUIAPI GetGlyphsPositionInfo( LOGFONT* logfont_upright, LOGFONT* logfont_sideways, - const SHAPEDGLYPH* glyphs, GLYPHEXTINFO* glyph_ext_info, int nr_glyphs, + const Glyph32* glyphs, const GLYPHSHAPINGINFO* glyph_shaping_info, + const Uint16* break_oppos, 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); + GLYPHEXTINFO* glyph_ext_info, SIZE* line_size, GLYPHPOS* glyph_pos); /** * \fn int GUIAPI GetGlyphsExtentFromUChars(LOGFONT* logfont_upright, @@ -12637,22 +12671,20 @@ MG_EXPORT int GUIAPI GetGlyphsExtentFromUChars(LOGFONT* logfont_upright, /* * \fn int GUIAPI DrawShapedGlyphString (HDC hdc, * LOGFONT* logfont_upright, LOGFONT* logfont_sideways, - * const SHAPEDGLYPH* glyphs, const GLYPHPOS* glyph_pos, - * int nr_glyphs) - * \brief Draw a glyph string at the specified positions and text orientations. + * const Glyph32* glyphs, const GLYPHSHAPINGINFO* glyph_shaping_info, + * const GLYPHPOS* glyph_pos, int nr_glyphs) + * \brief Draw a shaped glyph string at the specified positions and text orientations. * - * This function draws a glyph string to the specific positions and + * This function draws a shaped glyph string to the specific positions and * orientations on a DC \a hdc with the logfonts specified by * \a logfont_upright and \a logfont_sideways. * * \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; either a Glyph32 array - * or a SHAPEDGLYPH array. You should specify the unit size of the array - * via \a glyph_unit_size. - * \param glyph_unit_size The size of one glyph unit item in bytes. If - * it is zero, then sizeof (Glyph32) will be used. + * \param glyphs The pointer to the glyph string. + * \param glyph_shaping_info The pointer to the GLYPHSHAPINGINFO array which + * returned by GetShapedGlyphsBasic() or GetShapedGlyphsComplex(). * \param glyph_pos The buffer holds the position information * of every glyph. * \param nr_glyphs The number of the glyphs should be drawn. @@ -12666,16 +12698,15 @@ MG_EXPORT int GUIAPI GetGlyphsExtentFromUChars(LOGFONT* logfont_upright, */ MG_EXPORT int GUIAPI DrawShapedGlyphString (HDC hdc, LOGFONT* logfont_upright, LOGFONT* logfont_sideways, - const SHAPEDGLYPH* glyphs, const GLYPHPOS* glyph_pos, - int nr_glyphs); + const Glyph32* glyphs, const GLYPHSHAPINGINFO* glyph_shaping_info, + const GLYPHPOS* glyph_pos, int nr_glyphs); #endif /* _MGCHARSET_UNICODE */ /* * \fn int GUIAPI DrawGlyphStringEx (HDC hdc, * LOGFONT* logfont_upright, LOGFONT* logfont_sideways, - * const Glyph32* glyphs, const GLYPHPOS* glyph_pos, - * int nr_glyphs) + * const Glyph32* glyphs, const GLYPHPOS* glyph_pos, int nr_glyphs) * \brief Draw a glyph string at the specified positions and text orientations. * * This function draws a glyph string to the specific positions and diff --git a/src/newgdi/shaped-glyph.c b/src/newgdi/shaped-glyph.c index 4c3fe273..5c4c181b 100644 --- a/src/newgdi/shaped-glyph.c +++ b/src/newgdi/shaped-glyph.c @@ -70,15 +70,23 @@ static void bidi_reverse_shaped_glyphs (void* context, int len, int pos) #endif /* Local array size, used for stack-based local arrays */ -#define LOCAL_ARRAY_SIZE 128 + +#if SIZEOF_PTR == 8 +# define LOCAL_ARRAY_SIZE 256 +#else +# define LOCAL_ARRAY_SIZE 128 +#endif int GUIAPI GetShapedGlyphsBasic(LOGFONT* logfont, - LanguageCode content_language, UCharScriptType writing_system, + UCharScriptType writing_system, + Uint8 ctr, Uint8 wbr, Uint8 lbp, const Uchar32* logical_ucs, int nr_ucs, - Uint16* break_oppos, SHAPEDGLYPH* visual_glyphs, - BidiType *paragraph_dir, int* pos_l2v, int* nr_glyphs) + BidiType* paragraph_dir, + Glyph32* visual_glyphs, GLYPHSHAPINGINFO* glyph_shaping_info, + Uint16* break_oppos, int* map_v2l, int* nr_glyphs) { - int i, j; + int ret_value = 0; + int i, j, nr_reordered; BidiLevel max_level = 0; Uchar32 local_visual_ucs[LOCAL_ARRAY_SIZE]; @@ -96,20 +104,15 @@ int GUIAPI GetShapedGlyphsBasic(LOGFONT* logfont, BidiLevel local_els[LOCAL_ARRAY_SIZE]; BidiLevel* els = NULL; - int local_pos_v2l[LOCAL_ARRAY_SIZE]; - int* pos_v2l = NULL; + int local_indics_map[LOCAL_ARRAY_SIZE]; + int* indics_map = NULL; if (nr_ucs == 0 || logical_ucs == NULL || break_oppos == NULL || visual_glyphs == NULL || nr_glyphs == NULL) { return 0; } - writing_system = _unicode_normalize_script(content_language, writing_system); - - /* - * TODO: tailor break opportunties according to the content languages. - */ - + /* TODO: we may re-use visual_glyphs for visual ucs */ if (nr_ucs < LOCAL_ARRAY_SIZE) visual_ucs = local_visual_ucs; else @@ -118,6 +121,14 @@ int GUIAPI GetShapedGlyphsBasic(LOGFONT* logfont, if (!visual_ucs) goto out; + if (nr_ucs < LOCAL_ARRAY_SIZE) + indics_map = local_indics_map; + else + indics_map = malloc (nr_ucs * sizeof(int)); + + if (!indics_map) + goto out; + /* TODO: compose logical character here */ memcpy(visual_ucs, logical_ucs, sizeof(Uchar32) * nr_ucs); @@ -154,23 +165,9 @@ int GUIAPI GetShapedGlyphsBasic(LOGFONT* logfont, if (max_level < 0) goto out; - /* If l2v is to be calculated we must have to - make a private instance of it. */ - if (pos_l2v) { - if (nr_ucs < LOCAL_ARRAY_SIZE) - pos_v2l = local_pos_v2l; - else - pos_v2l = (int*)malloc(sizeof(int) * nr_ucs); - - if (!pos_v2l) - goto out; - } - /* Set up the ordering array to identity order */ - if (pos_v2l) { - for (i = 0; i < nr_ucs; i++) - pos_v2l[i] = i; - } + for (i = 0; i < nr_ucs; i++) + indics_map[i] = i; if (writing_system == UCHAR_SCRIPT_ARABIC) { /* Arabic joining */ @@ -190,63 +187,66 @@ int GUIAPI GetShapedGlyphsBasic(LOGFONT* logfont, } if (UBidiReorderLine(BIDI_FLAGS_DEFAULT, bidi_ts, nr_ucs, 0, - *paragraph_dir, els, visual_ucs, pos_v2l, NULL, NULL) == 0) + *paragraph_dir, els, visual_ucs, indics_map, NULL, NULL) == 0) goto out; - /* get shaped glyphs */ + // remove the unused characters and get the real length of the visual ucs. j = 0; for (i = 0; i < nr_ucs; i++) { - if (pos_v2l[i] >= 0) { - visual_glyphs[j].gv = GetGlyphValue(logfont, - UCHAR2ACHAR(visual_ucs[i])); - visual_glyphs[j].bos = break_oppos[pos_v2l[i]]; - - if (ar_props) { - BidiArabicProp ar_prop = ar_props[pos_v2l[i]]; - if (ar_prop & BIDI_MASK_LIGATURED) { - visual_glyphs[j].gt = GLYPH_TYPE_STDLIGATURE; - visual_glyphs[j].gp = GLYPH_POS_BASELINE; - } - else if (UCharIsArabicVowel(visual_ucs[i])) { - visual_glyphs[j].gt = GLYPH_TYPE_STDMARK; - visual_glyphs[j].gp = GLYPH_POS_STDMARK_ABOVE; - } - else { - visual_glyphs[j].gt = GLYPH_TYPE_STANDALONE; - visual_glyphs[j].gp = GLYPH_POS_BASELINE; - } - } - else { - visual_glyphs[j].gt = GLYPH_TYPE_STANDALONE; - visual_glyphs[j].gp = GLYPH_POS_BASELINE; - } - + if (!BIDI_IS_EXPLICIT_OR_BN (bidi_ts[indics_map[i]])) { + visual_ucs[j] = visual_ucs[i]; j++; } + } + nr_reordered = j; + + if (break_oppos) { + // The breaking opportunities + if (UStrGetBreaks(writing_system, ctr, wbr, lbp, visual_ucs, nr_reordered, + &break_oppos) == 0) + goto out; + } + + // get shaped glyphs + for (i = 0; i < nr_reordered; i++) { + visual_glyphs[i] = GetGlyphValue(logfont, UCHAR2ACHAR(visual_ucs[i])); + + if (ar_props) { + BidiArabicProp ar_prop = ar_props[indics_map[i]]; + if (ar_prop & BIDI_MASK_LIGATURED) { + glyph_shaping_info[i].gt = GLYPH_TYPE_STDLIGATURE; + glyph_shaping_info[i].gp = GLYPH_POS_BASELINE; + } + else if (UCharIsArabicVowel(visual_ucs[i])) { + glyph_shaping_info[i].gt = GLYPH_TYPE_STDMARK; + glyph_shaping_info[i].gp = GLYPH_POS_STDMARK_ABOVE; + } + else { + glyph_shaping_info[i].gt = GLYPH_TYPE_STANDALONE; + glyph_shaping_info[i].gp = GLYPH_POS_BASELINE; + } + } else { - _DBG_PRINTF("%s: A character skipped\n", __FUNCTION__); + glyph_shaping_info[i].gt = GLYPH_TYPE_STANDALONE; + glyph_shaping_info[i].gp = GLYPH_POS_BASELINE; } } - *nr_glyphs = j; + *nr_glyphs = nr_reordered; - /* Convert the v2l list to l2v */ - if (pos_l2v) { - for (i = 0; i < nr_ucs; i++) - pos_l2v[i] = -1; - for (i = 0; i < nr_ucs; i++) - pos_l2v[pos_v2l[i]] = i; + if (map_v2l) { + memcpy(map_v2l, indics_map, sizeof(int) * nr_reordered); } - return nr_ucs; + ret_value = nr_ucs; out: + if (indics_map && indics_map != local_indics_map) + free (indics_map); + if (visual_ucs && visual_ucs != local_visual_ucs) free (visual_ucs); - if (pos_v2l && pos_v2l != local_pos_v2l) - free (pos_v2l); - if (els && els != local_els) free (els); @@ -259,41 +259,43 @@ out: if (brk_ts && brk_ts != local_brk_ts) free (brk_ts); - return 0; + return ret_value; } int GUIAPI GetShapedGlyphsComplex(LOGFONT* logfont, - LanguageCode content_language, UCharScriptType writing_system, + UCharScriptType writing_system, + Uint8 ctr, Uint8 wbr, Uint8 lbp, const Uchar32* logical_ucs, int nr_ucs, - Uint16* break_oppos, SHAPEDGLYPH* visual_glyphs, - BidiType *paragraph_dir, int* pos_l2v, int* nr_glyphs) + BidiType* paragraph_dir, + Glyph32* visual_glyphs, GLYPHSHAPINGINFO* glyph_shaping_info, + Uint16* break_oppos, int* map_v2l, int* nr_glyphs) { return 0; } int GUIAPI GetGlyphsExtentInfo(LOGFONT* logfont, - const SHAPEDGLYPH* glyphs, int nr_glyphs, - Uint32 render_flags, - GLYPHEXTINFO* glyph_extent_info, - LOGFONT** logfont_sideways) + const Glyph32* glyphs, const GLYPHSHAPINGINFO* glyph_shaping_info, + int nr_glyphs, Uint32 render_flags, + GLYPHEXTINFO* glyph_ext_info, LOGFONT** logfont_sideways) { return 0; } int GUIAPI GetGlyphsPositionInfo( LOGFONT* logfont_upright, LOGFONT* logfont_sideways, - const SHAPEDGLYPH* glyphs, GLYPHEXTINFO* glyph_ext_info, int nr_glyphs, + const Glyph32* glyphs, const GLYPHSHAPINGINFO* glyph_shaping_info, + const Uint16* break_oppos, 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) + GLYPHEXTINFO* glyph_ext_info, SIZE* line_size, GLYPHPOS* glyph_pos) { return 0; } int GUIAPI DrawShapedGlyphString(HDC hdc, LOGFONT* logfont_upright, LOGFONT* logfont_sideways, - const SHAPEDGLYPH* glyphs, const GLYPHPOS* glyph_pos, - int nr_glyphs) + const Glyph32* glyphs, const GLYPHSHAPINGINFO* glyph_shaping_info, + const GLYPHPOS* glyph_pos, int nr_glyphs) { int i; int n = 0; @@ -321,7 +323,7 @@ int GUIAPI DrawShapedGlyphString(HDC hdc, goto error; } - DrawGlyph(hdc, glyph_pos[i].x, glyph_pos[i].y, glyphs[i].gv, + DrawGlyph(hdc, glyph_pos[i].x, glyph_pos[i].y, glyphs[i], NULL, NULL); n++;