From 6e33602e7dfa1c36e050f5465444edd0d3f2f1ba Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Tue, 2 Apr 2019 17:27:15 +0800 Subject: [PATCH] debug for glyph orientation in vertical layout --- include/fixedmath.h | 122 ++++++++++++++++---------------- src/font/freetype2.c | 12 ++-- src/font/unicode-shape.c | 3 +- src/newgdi/drawtext.h | 6 +- src/newgdi/glyph-shaped.c | 12 +++- src/newgdi/glyph.c | 99 ++++++++++++-------------- src/newgdi/layout-utils.c | 3 +- src/newgdi/layoutinfo.c | 41 ++++++++++- src/newgdi/shape-glyphs-basic.c | 6 +- 9 files changed, 177 insertions(+), 127 deletions(-) diff --git a/include/fixedmath.h b/include/fixedmath.h index 49ece29c..6eaa83c6 100644 --- a/include/fixedmath.h +++ b/include/fixedmath.h @@ -2,12 +2,12 @@ * \file fixedmath.h * \author Wei Yongming * \date 2002/01/12 - * + * * \brief This file includes fixed point and three-dimension math routines. * \verbatim - This file is part of MiniGUI, a mature cross-platform windowing + This file is part of MiniGUI, a mature cross-platform windowing and Graphics User Interface (GUI) support system for embedded systems and smart IoT devices. @@ -45,7 +45,7 @@ /* * $Id: fixedmath.h 12154 2009-10-15 07:21:34Z weiym $ * - * MiniGUI for Linux/uClinux, eCos, uC/OS-II, VxWorks, + * MiniGUI for Linux/uClinux, eCos, uC/OS-II, VxWorks, * pSOS, ThreadX, NuCleus, OSE, and Win32. * * Fixed-point math routins come from Allegro (a gift software) @@ -79,21 +79,21 @@ extern "C" { /** * \defgroup fixed_math_fns Fixed point math functions - * + * * You know that the float point mathematics routines are very - * expensive. If you do not want precision mathematics result, + * expensive. If you do not want precision mathematics result, * you can use fixed point. MiniGUI uses a double word (32-bit) - * integer to represent a fixed point ranged from -32767.0 to - * 32767.0, and defines some fixed point mathematics routines for - * your application. Some GDI functions need fixed point + * integer to represent a fixed point ranged from -32767.0 to + * 32767.0, and defines some fixed point mathematics routines for + * your application. Some GDI functions need fixed point * math routines, like \a Arc. * * Example 1: - * + * * \include fixed_point.c * * Example 2: - * + * * \include fixedpoint.c * @{ */ @@ -112,9 +112,9 @@ MG_EXPORT fixed fixsqrt (fixed x); /** * \fn fixed fixhypot (fixed x, fixed y) * \brief Returns the Euclidean distance from the origin. - * - * The function returns the \a sqrt(x*x+y*y). This is the length of - * the hypotenuse of a right-angle triangle with sides of length \a x and \a y, + * + * The function returns the \a sqrt(x*x+y*y). This is the length of + * the hypotenuse of a right-angle triangle with sides of length \a x and \a y, * or the distance of the point \a (x,y) from the origin. * * \sa fixsqrt @@ -125,10 +125,10 @@ MG_EXPORT fixed fixhypot (fixed x, fixed y); * \fn fixed fixatan (fixed x) * \brief Calculates the arc tangent of a fixed point value. * - * This function calculates the arc tangent of \a x; that is the value + * This function calculates the arc tangent of \a x; that is the value * whose tangent is \a x. * - * \return Returns the arc tangent in radians and the value is + * \return Returns the arc tangent in radians and the value is * mathematically defined to be between -PI/2 and PI/2 (inclusive). * * \sa fixatan2 @@ -140,11 +140,11 @@ MG_EXPORT fixed fixatan (fixed x); * \brief Calculates the arc tangent of two fixed point variables. * * This function calculates the arc tangent of the two variables \a x and \a y. - * It is similar to calculating the arc tangent of \a y / \a x, except that - * the signs of both arguments are used to determine the quadrant of the + * It is similar to calculating the arc tangent of \a y / \a x, except that + * the signs of both arguments are used to determine the quadrant of the * result. * - * \return Returns the result in radians, which is between -PI and PI + * \return Returns the result in radians, which is between -PI and PI * (inclusive). * * \sa fixatan @@ -162,7 +162,7 @@ extern MG_EXPORT const fixed __mg_acos_tbl[]; * \fn fixed ftofix (double x) * \brief Converts a float point value to a fixed point value. * - * This function converts the specified float point value \a x to + * This function converts the specified float point value \a x to * a fixed point value. * * \note The float point should be ranged from -32767.0 to 32767.0. @@ -171,7 +171,7 @@ extern MG_EXPORT const fixed __mg_acos_tbl[]; * \sa fixtof */ static inline fixed ftofix (double x) -{ +{ if (x > 32767.0) { errno = ERANGE; return 0x7FFFFFFF; @@ -182,21 +182,21 @@ static inline fixed ftofix (double x) return -0x7FFFFFFF; } - return (long)(x * 65536.0 + (x < 0 ? -0.5 : 0.5)); + return (long)(x * 65536.0 + (x < 0 ? -0.5 : 0.5)); } /** * \fn double fixtof (fixed x) * \brief Converts a fixed point value to a float point value. * - * This function converts the specified fixed point value \a x to + * This function converts the specified fixed point value \a x to * a float point value. * * \sa ftofix */ static inline double fixtof (fixed x) -{ - return (double)x / 65536.0; +{ + return (double)x / 65536.0; } @@ -209,7 +209,7 @@ static inline double fixtof (fixed x) * * \param x x,y: Two addends. * \param y x,y: Two addends. - * \return The sum. If the result runs out of range of fixed point, + * \return The sum. If the result runs out of range of fixed point, * this function sets \a errno to \a ERANGE. * * \sa fixsub @@ -220,19 +220,19 @@ static inline fixed fixadd (fixed x, fixed y) if (result >= 0) { if ((x < 0) && (y < 0)) { - errno = ERANGE; - return -0x7FFFFFFF; + errno = ERANGE; + return -0x7FFFFFFF; } else - return result; + return result; } else { if ((x > 0) && (y > 0)) { - errno = ERANGE; - return 0x7FFFFFFF; + errno = ERANGE; + return 0x7FFFFFFF; } else - return result; + return result; } } @@ -240,13 +240,13 @@ static inline fixed fixadd (fixed x, fixed y) * \fn fixed fixsub (fixed x, fixed y) * \brief Subtract a fixed point value from another. * - * This function subtracts the fixed point values \a y from the fixed + * This function subtracts the fixed point values \a y from the fixed * point value \a x, and returns the difference. * * \param x The minuend. * \param y The subtrahend. * - * \return The difference. If the result runs out of range of fixed point, + * \return The difference. If the result runs out of range of fixed point, * this function sets \a errno to \a ERANGE. * * \sa fixadd @@ -257,33 +257,33 @@ static inline fixed fixsub (fixed x, fixed y) if (result >= 0) { if ((x < 0) && (y > 0)) { - errno = ERANGE; - return -0x7FFFFFFF; + errno = ERANGE; + return -0x7FFFFFFF; } else - return result; + return result; } else { if ((x > 0) && (y < 0)) { - errno = ERANGE; - return 0x7FFFFFFF; + errno = ERANGE; + return 0x7FFFFFFF; } else - return result; + return result; } } /** * \fn fixed fixmul (fixed x, fixed y) * \brief Returns the product of two fixed point values. - * + * * This function returns the product of two fixed point values \a x and \a y. * * \param x The faciend. * \param y The multiplicato. - * \return The prodcut. If the result runs out of range of fixed point, + * \return The prodcut. If the result runs out of range of fixed point, * this function sets \a errno to \a ERANGE. - * + * * \sa fixdiv */ MG_EXPORT fixed fixmul (fixed x, fixed y); @@ -291,14 +291,14 @@ MG_EXPORT fixed fixmul (fixed x, fixed y); /** * \fn fixed fixdiv (fixed x, fixed y) * \brief Returns the quotient of two fixed point values. - * + * * This function returns the quotient of two fixed point values \a x and \a y. * * \param x The dividend. * \param y The divisor. - * \return The quotient. If the result runs out of range of fixed point, + * \return The quotient. If the result runs out of range of fixed point, * this function sets \a errno to \a ERANGE. - * + * * \sa fixmul */ MG_EXPORT fixed fixdiv (fixed x, fixed y); @@ -336,7 +336,7 @@ static inline int fixceil (fixed x) * \sa fixtoi */ static inline fixed itofix (int x) -{ +{ return x << 16; } @@ -349,61 +349,61 @@ static inline fixed itofix (int x) * \sa itofix */ static inline int fixtoi (fixed x) -{ - return (x >> 16) + ((x & 0x8000) >> 15); +{ + return (x >> 16) + ((x & 0x8000) >> 15); } /** * \fn fixed fixcos (fixed x) * \brief Returns the cosine of a fixed point. * - * This function returns the cosine of the fixed point \a x, + * This function returns the cosine of the fixed point \a x, * where \a x is given in radians. * * \sa fixacos */ static inline fixed fixcos (fixed x) { - return __mg_cos_tbl[((x + 0x4000) >> 15) & 0x1FF]; + return __mg_cos_tbl[((x + 0x4000) >> 15) & 0x1FF]; } /** * \fn fixed fixsin (fixed x) * \brief Returns the sine of a fixed point. * - * This function returns the sine of the fixed point \a x, + * This function returns the sine of the fixed point \a x, * where \a x is given in radians. * * \sa fixasin */ static inline fixed fixsin (fixed x) -{ - return __mg_cos_tbl[((x - 0x400000 + 0x4000) >> 15) & 0x1FF]; +{ + return __mg_cos_tbl[((x - 0x400000 + 0x4000) >> 15) & 0x1FF]; } /** * \fn fixed fixtan (fixed x) * \brief Returns the tangent of a fixed point. * - * This function returns the tangent of the fixed point \a x, + * This function returns the tangent of the fixed point \a x, * where \a x is given in radians. * * \sa fixcos, fixsin */ static inline fixed fixtan (fixed x) -{ - return __mg_tan_tbl[((x + 0x4000) >> 15) & 0xFF]; +{ + return __mg_tan_tbl[((x + 0x4000) >> 15) & 0xFF]; } /** * \fn fixed fixacos (fixed x) * \brief Calculates and returns the arc cosine of a fixed point. * - * This function calculates the arc cosine of the fixed point \a x; + * This function calculates the arc cosine of the fixed point \a x; * that is the value whose cosine is \a x. If \a x falls outside * the range -1 to 1, this function fails and \a errno is set to EDOM. * - * \return Returns the arc cosine in radians and the value is mathematically + * \return Returns the arc cosine in radians and the value is mathematically * defined to be between 0 and PI (inclusive). * * \sa fixcos @@ -422,17 +422,17 @@ static inline fixed fixacos (fixed x) * \fn fixed fixasin (fixed x) * \brief Calculates and returns the arc sine of a fixed point. * - * This function calculates the arc sine of the fixed point \a x; + * This function calculates the arc sine of the fixed point \a x; * that is the value whose sine is \a x. If \a x falls outside * the range -1 to 1, this function fails and \a errno is set to EDOM. * - * \return Returns the arc sine in radians and the value is mathematically + * \return Returns the arc sine in radians and the value is mathematically * defined to be between -PI/2 and PI/2 (inclusive). * * \sa fixsin */ static inline fixed fixasin (fixed x) -{ +{ if ((x < -65536) || (x > 65536)) { errno = EDOM; return 0; diff --git a/src/font/freetype2.c b/src/font/freetype2.c index af92b450..205af235 100644 --- a/src/font/freetype2.c +++ b/src/font/freetype2.c @@ -758,10 +758,14 @@ get_glyph_advance (LOGFONT* logfont, DEVFONT* devfont, done: FT_UNLOCK(&ft_lock); - if (px) - *px += ((ft_inst_info->advance.x + 0x8000)>> 16); - if (py) - *py -= ((ft_inst_info->advance.y + 0x8000)>> 16); + if (px) { + //int old_x = *px; + *px += ((ft_inst_info->advance.x + 0x8000) >> 16); + } + if (py) { + //int old_y = *py; + *py -= ((ft_inst_info->advance.y + 0x8000) >> 16); + } advance = FT_Vector_Length (&ft_inst_info->advance); return (advance >> 16) + ((advance & 0x8000) >> 15); diff --git a/src/font/unicode-shape.c b/src/font/unicode-shape.c index f2b2fa79..070956b0 100644 --- a/src/font/unicode-shape.c +++ b/src/font/unicode-shape.c @@ -70,8 +70,9 @@ void GUIAPI UBidiShapeMirroring(const BidiLevel *embedding_levels, int len, if (BIDI_LEVEL_IS_RTL(embedding_levels[i])) { Uchar32 mirrored_ch; - if (UCharGetMirror(str[i], &mirrored_ch)) + if (UCharGetMirror(str[i], &mirrored_ch)) { str[i] = mirrored_ch; + } } } } diff --git a/src/newgdi/drawtext.h b/src/newgdi/drawtext.h index 74a2de43..9c2d4fd3 100644 --- a/src/newgdi/drawtext.h +++ b/src/newgdi/drawtext.h @@ -44,14 +44,16 @@ extern "C" { #endif /* __cplusplus */ +void _gdi_get_rotated_point(int *x, int *y, int rotation); + void _gdi_get_point_at_parallel(int x1, int y1, int x2, int y2, \ int advance, int* parallel_x1, int* parallel_y1, int* parallel_x2, \ - int* parallel_y2, PDC pdc); + int* parallel_y2, int rotation); void _gdi_get_baseline_point (PDC pdc, int* x, int* y); void _gdi_get_glyph_box_vertices (int x1, int y1, int x2, int y2, - POINT* pts, PDC pdc); + POINT* pts, PLOGFONT logfont); void _gdi_start_new_line (PDC pdc); diff --git a/src/newgdi/glyph-shaped.c b/src/newgdi/glyph-shaped.c index 2c39f454..191b87f4 100644 --- a/src/newgdi/glyph-shaped.c +++ b/src/newgdi/glyph-shaped.c @@ -72,6 +72,7 @@ BOOL DrawShapedGlyph(HDC hdc, Glyph32 gv, render_data->uc_index); if (glyph_pos->suppressed == 0 && glyph_pos->whitespace == 0) { + int x_off, y_off; gal_pixel fg_pixel, bg_pixel; SelectFont(hdc, render_data->logfont); @@ -91,8 +92,15 @@ BOOL DrawShapedGlyph(HDC hdc, Glyph32 gv, } SetTextAlign(hdc, render_data->ta); - DrawGlyph(hdc, glyph_pos->x + glyph_pos->x_off, - glyph_pos->y + glyph_pos->y_off, gv, NULL, NULL); + x_off = glyph_pos->x_off; + y_off = glyph_pos->y_off; + if (render_data->logfont->rotation) { + _gdi_get_rotated_point(&x_off, &y_off, + render_data->logfont->rotation); + } + + DrawGlyph(hdc, glyph_pos->x + x_off, + glyph_pos->y + y_off, gv, NULL, NULL); } else if (glyph_pos->whitespace && bg_color) { // TODO: draw background for whitespace. diff --git a/src/newgdi/glyph.c b/src/newgdi/glyph.c index 1e0750a1..1ff79457 100644 --- a/src/newgdi/glyph.c +++ b/src/newgdi/glyph.c @@ -2095,24 +2095,38 @@ static inline void _gdi_direct_fillglyph (PDC pdc, Glyph32 glyph_value, } } +void _gdi_get_rotated_point(int *x, int *y, int rotation) +{ + int advance = fixtoi(fixsqrt(fixadd(itofix(*x * *x), itofix(*y * *y)))); + + *x += CAL_VEC_X2(advance, ((rotation+900)%3600+3600)%3600 + *256/3600); + *y -= CAL_VEC_Y2(advance, ((rotation+900)%3600+3600)%3600 + *256/3600); +} + /* * the line direction is from (x1, y1) to (x2, y2), - * plus advance is the distance from (*parallel_x1,*parallel_y1) to (x1,y1),advance is along direction + * the advance is the distance from (*parallel_x1,*parallel_y1) to + * (x1,y1), advance is along direction * rotation 90 degree from line direction in counter-clockwise - * (*parallel_x1,*parallel_y1) is the point at the parallel line reponse to (x1,y1),the line from - * (*parallel_x1,*parallel_y1) to (x1,y1) is vertical relative to line from (x1,y1) to (x2,y2) - * (*parallel_x2,*parallel_y2) is the point at the parallel line reponse to (x2,y2) + * (*parallel_x1,*parallel_y1) is the point at the parallel line + * corresponding to (x1,y1). + * the line from (*parallel_x1,*parallel_y1) to (x1,y1) is vertical to + * to line from (x1,y1) to (x2,y2) + * (*parallel_x2,*parallel_y2) is the point at the parallel line + * corresponding to (x2,y2) */ void _gdi_get_point_at_parallel(int x1, int y1, int x2, int y2, int advance, int* parallel_x1, int* parallel_y1, - int* parallel_x2, int* parallel_y2, PDC pdc) + int* parallel_x2, int* parallel_y2, int rotation) { int adv_x, adv_y; - adv_x = CAL_VEC_X2(advance,((pdc->pLogFont->rotation +900)%3600+3600)%3600 + adv_x = CAL_VEC_X2(advance,((rotation+900)%3600+3600)%3600 + *256/3600); + adv_y = CAL_VEC_Y2(advance,((rotation+900)%3600+3600)%3600 *256/3600); - adv_y = CAL_VEC_Y2(advance,((pdc->pLogFont->rotation +900)%3600+3600)%3600 - *256 /3600); *parallel_x1 = x1 + adv_x; *parallel_y1 = y1 - adv_y; @@ -2121,14 +2135,15 @@ void _gdi_get_point_at_parallel(int x1, int y1, int x2, int y2, int advance, *parallel_y2 = y2 - adv_y; } -void _gdi_get_glyph_box_vertices (int x1, int y1, int x2, int y2, POINT* pts, PDC pdc) +void _gdi_get_glyph_box_vertices(int x1, int y1, int x2, int y2, + POINT* pts, PLOGFONT logfont) { int adv_x, adv_y; - adv_x = CAL_VEC_X2(pdc->pLogFont->ascent,((pdc->pLogFont->rotation +900)%3600 + adv_x = CAL_VEC_X2(logfont->ascent, ((logfont->rotation+900)%3600 + +3600)%3600*256/3600); + adv_y = CAL_VEC_Y2(logfont->ascent, ((logfont->rotation+900)%3600 +3600)%3600*256/3600); - adv_y = CAL_VEC_Y2(pdc->pLogFont->ascent,((pdc->pLogFont->rotation +900)%3600 - +3600)%3600 *256 /3600); pts[0].x = x1 + adv_x; pts[0].y = y1 - adv_y; @@ -2137,10 +2152,10 @@ void _gdi_get_glyph_box_vertices (int x1, int y1, int x2, int y2, POINT* pts, PD pts[1].y = y2 - adv_y; - adv_x = CAL_VEC_X2(pdc->pLogFont->descent,((pdc->pLogFont->rotation +2700)%3600 - +3600)%3600 * 256 / 3600); - adv_y = CAL_VEC_Y2(pdc->pLogFont->descent,((pdc->pLogFont->rotation +2700)%3600 - +3600)%3600 * 256 / 3600); + adv_x = CAL_VEC_X2(logfont->descent, ((logfont->rotation+2700)%3600 + +3600)%3600*256/3600); + adv_y = CAL_VEC_Y2(logfont->descent, ((logfont->rotation+2700)%3600 + +3600)%3600*256/3600); pts[3].x = x1 + adv_x; pts[3].y = y1 - adv_y; @@ -2163,8 +2178,7 @@ void _gdi_get_baseline_point (PDC pdc, int* x, int* y) } } else { - /* TODO: calculate a point on the baseline */ - + /* calculate a point on the baseline */ int adv_x, adv_y; if ((pdc->ta_flags & TA_Y_MASK) == TA_TOP) { @@ -2173,44 +2187,17 @@ void _gdi_get_baseline_point (PDC pdc, int* x, int* y) adv_y = CAL_VEC_Y2(pdc->pLogFont->ascent, ((pdc->pLogFont->rotation +2700)%3600+3600)%3600 * 256 / 3600); - if ((pdc->ta_flags & TA_X_MASK) == TA_LEFT) { - *x -= adv_x; - } - else if ((pdc->ta_flags & TA_X_MASK) == TA_RIGHT) { - *x += adv_x; - } - *y += adv_y; + *x += adv_x; + *y -= adv_y; } else if ((pdc->ta_flags & TA_Y_MASK) == TA_BOTTOM) { adv_x = CAL_VEC_X2(pdc->pLogFont->descent, ((pdc->pLogFont->rotation +900)%3600+3600)%3600 * 256 / 3600); adv_y = CAL_VEC_Y2(pdc->pLogFont->descent, ((pdc->pLogFont->rotation +900)%3600+3600)%3600 * 256 / 3600); - - if ((pdc->ta_flags & TA_X_MASK) == TA_LEFT) { - *x += adv_x; - } - else if ((pdc->ta_flags & TA_X_MASK) == TA_RIGHT) { - *x -= adv_x; - } - *y += adv_y; + *x += adv_x; + *y -= adv_y; } - - /* - int x1 = *x; - int y1 = *y; - int x2 = /x1 + 1000 * fixtoi(); - int y2; - - if ((pdc->ta_flags & TA_Y_MASK) == TA_TOP) { - _gdi_get_point_at_parallel (x1, y1, x2, y2, - -pdc->pLogFont->ascent, x1, x, y); - } - else if ((pdc->ta_flags & TA_Y_MASK) == TA_BOTTOM) { - _gdi_get_point_at_parallel (x1, y1, x2, y2, - pdc->pLogFont->descent, x1, x, y); - } - */ } } @@ -2485,7 +2472,7 @@ static void make_back_area(PDC pdc, int x0, int y0, int x1, int y1, case ROTATE_RECT: _gdi_get_glyph_box_vertices (x0, y0, x1, y1, - area, pdc); + area, pdc->pLogFont); break; } } @@ -2669,7 +2656,8 @@ static void draw_glyph_lines (PDC pdc, int x1, int y1, int x2, int y2) if (logfont->style & FS_DECORATE_UNDERLINE) { if (logfont->style & FS_FLIP_VERT) { _gdi_get_point_at_parallel(x1, y1, x2, y2, h-(descent<<1), \ - &draw_x1, &draw_y1, &draw_x2, &draw_y2, pdc); + &draw_x1, &draw_y1, &draw_x2, &draw_y2, + pdc->pLogFont->rotation); } else { @@ -2714,11 +2702,13 @@ static void draw_glyph_lines (PDC pdc, int x1, int y1, int x2, int y2) if (logfont->style & FS_DECORATE_STRUCKOUT) { if (logfont->style & FS_FLIP_VERT) { _gdi_get_point_at_parallel(x1, y1, x2, y2, (h >>1)-descent +1, \ - &draw_x1, &draw_y1, &draw_x2, &draw_y2, pdc); + &draw_x1, &draw_y1, &draw_x2, &draw_y2, + pdc->pLogFont->rotation); } else { _gdi_get_point_at_parallel(x1, y1, x2, y2, (h >>1) - descent, \ - &draw_x1, &draw_y1, &draw_x2, &draw_y2, pdc); + &draw_x1, &draw_y1, &draw_x2, &draw_y2, + pdc->pLogFont->rotation); } if (logfont->rotation == 0 && (logfont->style & FS_SLANT_ITALIC)) { @@ -2916,7 +2906,8 @@ int GUIAPI DrawGlyph (HDC hdc, int x, int y, Glyph32 glyph_value, _gdi_get_baseline_point (pdc, &x, &y); advance = _gdi_draw_one_glyph (pdc, glyph_value, - TRUE, x, y, &my_adv_x, &my_adv_y); + (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; diff --git a/src/newgdi/layout-utils.c b/src/newgdi/layout-utils.c index 79802089..5b83de86 100644 --- a/src/newgdi/layout-utils.c +++ b/src/newgdi/layout-utils.c @@ -175,7 +175,8 @@ static void resolve_layout_run_dir(const LAYOUTINFO* layout, if (layout->rf & GRF_WRITING_MODE_VERTICAL_FLAG) { lrun->dir = (lrun->el & 1) ? GLYPH_RUN_DIR_TTB : GLYPH_RUN_DIR_BTT; - if (lrun->ort == GLYPH_ORIENT_UPRIGHT) + if (lrun->ort == GLYPH_ORIENT_UPRIGHT || + lrun->ort == GLYPH_ORIENT_UPSIDE_DOWN) lrun->flags |= LAYOUTRUN_FLAG_CENTERED_BASELINE; } else { diff --git a/src/newgdi/layoutinfo.c b/src/newgdi/layoutinfo.c index 9461e700..6d66c1e4 100644 --- a/src/newgdi/layoutinfo.c +++ b/src/newgdi/layoutinfo.c @@ -1724,6 +1724,7 @@ static int traverse_line_glyphs(const LAYOUTINFO* layout, RENDERDATA extra; Uint32 def_ta; Uint32 up_ta; + int up_off_factor = 1; extra.truninfo = layout->truninfo; extra.layout = layout; @@ -1738,11 +1739,13 @@ static int traverse_line_glyphs(const LAYOUTINFO* layout, case GRF_WRITING_MODE_VERTICAL_RL: def_ta = TA_RIGHT | TA_TOP | TA_NOUPDATECP; up_ta = def_ta; + up_off_factor = -1; break; case GRF_WRITING_MODE_VERTICAL_LR: def_ta = TA_LEFT | TA_BOTTOM | TA_NOUPDATECP; up_ta = TA_LEFT | TA_TOP | TA_NOUPDATECP; + up_off_factor = 1; break; case GRF_WRITING_MODE_HORIZONTAL_TB: @@ -1774,20 +1777,52 @@ static int traverse_line_glyphs(const LAYOUTINFO* layout, if (layout->rf & GRF_WRITING_MODE_VERTICAL_FLAG) { pos.y = line_adv; pos.x = 0; + } else { pos.x = line_adv; pos.y = 0; } + // vertical layout if (run->lrun->flags & LAYOUTRUN_FLAG_CENTERED_BASELINE) { extra.ta = up_ta; - pos.x += (line->height - glyph_info->width) / 2; + if (run->lrun->ort == GLYPH_ORIENT_UPSIDE_DOWN) { + pos.y += run->gstr->glyphs[0].width; + pos.x_off = (line->height + glyph_info->height) / 2; + pos.x_off *= up_off_factor; + } + else if (run->lrun->ort == GLYPH_ORIENT_UPRIGHT) { + pos.x_off = (line->height - glyph_info->height) / 2; + pos.x_off *= up_off_factor; + } } else { extra.ta = def_ta; +#if 0 + if (run->lrun->ort == GLYPH_ORIENT_SIDEWAYS_LEFT) { + if ((layout->rf & GRF_WRITING_MODE_MASK) == + GRF_WRITING_MODE_VERTICAL_LR) + extra.ta = TA_RIGHT | TA_TOP | TA_NOUPDATECP; + else + extra.ta = TA_LEFT | TA_TOP | TA_NOUPDATECP; + } +#endif } + if (run->lrun->ort == GLYPH_ORIENT_SIDEWAYS_LEFT) { + pos.y += run->gstr->glyphs[0].width; + if ((layout->rf & GRF_WRITING_MODE_MASK) == + GRF_WRITING_MODE_VERTICAL_RL) + pos.x -= line->height; + else if ((layout->rf & GRF_WRITING_MODE_MASK) == + GRF_WRITING_MODE_VERTICAL_LR) + pos.x += line->height; + } + + pos.x_off += glyph_info->x_off; + pos.y_off += glyph_info->y_off; + pos.advance = glyph_info->width; pos.suppressed = 0; @@ -1809,6 +1844,10 @@ static int traverse_line_glyphs(const LAYOUTINFO* layout, } } + _DBG_PRINTF("%s: uc: %c, width: %d, pos (%d, %d), off (%d, %d)\n", + __FUNCTION__, extra.uc, glyph_info->width, + pos.x, pos.y, pos.x_off, pos.y_off); + if (!cb_laid_out(ctxt, glyph_info->gv, &pos, &extra)) return j; diff --git a/src/newgdi/shape-glyphs-basic.c b/src/newgdi/shape-glyphs-basic.c index a06c3bc3..adbd1e5c 100644 --- a/src/newgdi/shape-glyphs-basic.c +++ b/src/newgdi/shape-glyphs-basic.c @@ -141,9 +141,11 @@ static BOOL shape_layout_run(SEInstance* inst, bidi_ts = NULL; } } +#if 0 else if (BIDI_LEVEL_IS_RTL(run->el)) { UBidiShapeMirroring(els, nr_ucs, shaped_ucs); } +#endif if (els && els != local_els) { free (els); @@ -228,13 +230,15 @@ static BOOL shape_layout_run(SEInstance* inst, gs->glyphs[j].height = run->lf->size; } + _DBG_PRINTF("%s: shaped uchar: %c, width: %d\n", + __FUNCTION__, shaped_ucs[i], gs->glyphs[j].width); + gs->log_clusters[j] = i; j++; } } - gs->nr_glyphs = j; if (ar_props && ar_props != local_ar_props) {