implementation of DrawLayoutLine

This commit is contained in:
Vincent Wei
2019-04-02 18:46:34 +08:00
parent 6e33602e7d
commit 49421e1f88
2 changed files with 107 additions and 94 deletions
+84 -74
View File
@@ -111,11 +111,11 @@ BOOL DrawShapedGlyph(HDC hdc, Glyph32 gv,
int DrawLayoutLine(HDC hdc, const LAYOUTLINE* line, int x, int y)
{
int n, log_x = 0, log_y = 0;
int n, line_adv = 0;
struct list_head* i;
const TEXTRUNSINFO* truninfo;
const LAYOUTINFO* layout;
Uint32 old_ta;
Uint32 def_ta, up_ta;
PLOGFONT old_lf = NULL;
if (line == NULL)
@@ -124,23 +124,39 @@ int DrawLayoutLine(HDC hdc, const LAYOUTLINE* line, int x, int y)
layout = line->layout;
truninfo = layout->truninfo;
if ((layout->rf & GRF_WRITING_MODE_MASK) ==
GRF_WRITING_MODE_HORIZONTAL_BT)
old_ta = SetTextAlign(hdc, TA_LEFT | TA_BOTTOM | TA_NOUPDATECP);
else if ((layout->rf & GRF_WRITING_MODE_MASK) ==
GRF_WRITING_MODE_VERTICAL_RL)
old_ta = SetTextAlign(hdc, TA_RIGHT | TA_TOP | TA_NOUPDATECP);
else
old_ta = SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
old_lf = GetCurFont(hdc);
switch (layout->rf & GRF_WRITING_MODE_MASK) {
case GRF_WRITING_MODE_HORIZONTAL_BT:
def_ta = TA_LEFT | TA_BOTTOM | TA_NOUPDATECP;
up_ta = def_ta;
break;
case GRF_WRITING_MODE_VERTICAL_RL:
def_ta = TA_RIGHT | TA_TOP | TA_NOUPDATECP;
up_ta = def_ta;
break;
case GRF_WRITING_MODE_VERTICAL_LR:
def_ta = TA_LEFT | TA_BOTTOM | TA_NOUPDATECP;
up_ta = TA_LEFT | TA_TOP | TA_NOUPDATECP;
break;
case GRF_WRITING_MODE_HORIZONTAL_TB:
default:
def_ta = TA_LEFT | TA_TOP | TA_NOUPDATECP;
up_ta = def_ta;
break;
}
old_lf = GetCurFont(hdc);
list_for_each(i, &line->gruns) {
GlyphRun* run = (GlyphRun*)i;
int j;
int log_x, log_y;
SelectFont(hdc, run->lrun->lf);
for (j = 0; j < run->gstr->nr_glyphs; j++) {
int dev_x, dev_y;
int x_off, y_off;
Uint32 ta;
ShapedGlyph* gi = run->gstr->glyphs + j;
int log_index = run->lrun->si + run->gstr->log_clusters[j];
@@ -158,82 +174,76 @@ int DrawLayoutLine(HDC hdc, const LAYOUTLINE* line, int x, int y)
SetBkMode(hdc, BM_TRANSPARENT);
}
if (run->lrun->dir == GLYPH_RUN_DIR_TTB ||
run->lrun->dir == GLYPH_RUN_DIR_BTT) {
dev_y = log_x + gi->x_off;
dev_x = log_y + gi->y_off;
if (layout->rf & GRF_WRITING_MODE_VERTICAL_FLAG) {
log_y = line_adv;
log_x = 0;
}
else {
dev_x = log_x + gi->x_off;
dev_y = log_y + gi->y_off;
log_x = line_adv;
log_y = 0;
}
if ((run->lrun->flags & LAYOUTRUN_FLAG_NO_SHAPING) &&
gi->width > 0 && bg_color) {
// FIXME: draw background here
// vertical layout
if (run->lrun->flags & LAYOUTRUN_FLAG_CENTERED_BASELINE) {
ta = up_ta;
if (run->lrun->ort == GLYPH_ORIENT_UPSIDE_DOWN) {
log_y += run->gstr->glyphs[0].width;
if ((layout->rf & GRF_WRITING_MODE_MASK) ==
GRF_WRITING_MODE_VERTICAL_RL)
log_x -= (line->height - gi->height) / 2;
else if ((layout->rf & GRF_WRITING_MODE_MASK) ==
GRF_WRITING_MODE_VERTICAL_LR)
log_x += (line->height + gi->height) / 2;
}
else if (run->lrun->ort == GLYPH_ORIENT_UPRIGHT) {
if ((layout->rf & GRF_WRITING_MODE_MASK) ==
GRF_WRITING_MODE_VERTICAL_RL)
log_x -= (line->height - gi->height) / 2;
else if ((layout->rf & GRF_WRITING_MODE_MASK) ==
GRF_WRITING_MODE_VERTICAL_LR)
log_x += (line->height - gi->height) / 2;
}
}
else {
DrawGlyph(hdc, x + dev_x, y + dev_y, gi->gv, NULL, NULL);
ta = def_ta;
}
if (run->lrun->ort == GLYPH_ORIENT_SIDEWAYS_LEFT) {
log_y += run->gstr->glyphs[0].width;
if ((layout->rf & GRF_WRITING_MODE_MASK) ==
GRF_WRITING_MODE_VERTICAL_RL)
log_x -= line->height;
else if ((layout->rf & GRF_WRITING_MODE_MASK) ==
GRF_WRITING_MODE_VERTICAL_LR)
log_x += line->height;
}
if (run->lrun->flags & LAYOUTRUN_FLAG_NO_SHAPING) {
if (gi->width > 0 && bg_color) {
// FIXME: draw background here
}
}
else {
SetTextAlign(hdc, ta);
x_off = gi->x_off;
y_off = gi->y_off;
if (run->lrun->lf->rotation) {
_gdi_get_rotated_point(&x_off, &y_off,
run->lrun->lf->rotation);
}
DrawGlyph(hdc, x + log_x + x_off,
y + log_y + y_off, gi->gv, NULL, NULL);
n++;
}
log_x += gi->width;
line_adv += gi->width;
}
}
SelectFont(hdc, old_lf);
SetTextAlign(hdc, old_ta);
return n;
}
#if 0
int GUIAPI DrawShapedGlyphString(HDC hdc,
LOGFONT* logfont_upright, LOGFONT* logfont_sideways,
const ShapedGlyphS* shaped_glyphs,
const GLYPHPOS* glyph_pos, int nr_glyphs)
{
int i;
int n = 0;
Uint32 old_ta;
PLOGFONT old_lf;
if (shaped_glyphs == NULL || glyph_pos == NULL || nr_glyphs <= 0)
return 0;
old_ta = SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_UPDATECP);
old_lf = GetCurFont(hdc);
for (i = 0; i < nr_glyphs; i++) {
if (glyph_pos[i].suppressed == 0 && glyph_pos[i].whitespace == 0) {
Glyph32 gv = shaped_glyphs->cb_get_glyph_info(
shaped_glyphs->shaping_engine, shaped_glyphs->glyph_infos,
i, NULL);
if (glyph_pos[i].orientation == GLYPH_ORIENT_UPRIGHT) {
if (logfont_upright)
SelectFont(hdc, logfont_upright);
else
goto error;
}
else {
if (logfont_sideways)
SelectFont(hdc, logfont_sideways);
else
goto error;
}
DrawGlyph(hdc, glyph_pos[i].x, glyph_pos[i].y, gv,
NULL, NULL);
n++;
}
}
error:
SelectFont(hdc, old_lf);
SetTextAlign(hdc, old_ta);
return n;
}
#endif
#endif /* _MGCHARSET_UNICODE */
+23 -20
View File
@@ -1722,9 +1722,7 @@ static int traverse_line_glyphs(const LAYOUTINFO* layout,
struct list_head* i;
int line_adv = 0;
RENDERDATA extra;
Uint32 def_ta;
Uint32 up_ta;
int up_off_factor = 1;
Uint32 def_ta, up_ta;
extra.truninfo = layout->truninfo;
extra.layout = layout;
@@ -1739,13 +1737,11 @@ 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:
@@ -1759,7 +1755,7 @@ static int traverse_line_glyphs(const LAYOUTINFO* layout,
GlyphRun* run = (GlyphRun*)i;
for (j = 0; j < run->gstr->nr_glyphs; j++) {
GLYPHPOS pos;
ShapedGlyph* glyph_info;
ShapedGlyph* gi;
extra.logfont = run->lrun->lf;
#if 0
@@ -1771,9 +1767,8 @@ static int traverse_line_glyphs(const LAYOUTINFO* layout,
extra.uc = run->lrun->ucs[run->gstr->log_clusters[j]];
extra.uc_index = run->lrun->si + run->gstr->log_clusters[j];
glyph_info = run->gstr->glyphs + j;
gi = run->gstr->glyphs + j;
pos.x_off = pos.y_off = 0;
if (layout->rf & GRF_WRITING_MODE_VERTICAL_FLAG) {
pos.y = line_adv;
pos.x = 0;
@@ -1789,12 +1784,20 @@ static int traverse_line_glyphs(const LAYOUTINFO* layout,
extra.ta = up_ta;
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;
if ((layout->rf & GRF_WRITING_MODE_MASK) ==
GRF_WRITING_MODE_VERTICAL_RL)
pos.x -= (line->height - gi->height) / 2;
else if ((layout->rf & GRF_WRITING_MODE_MASK) ==
GRF_WRITING_MODE_VERTICAL_LR)
pos.x += (line->height + gi->height) / 2;
}
else if (run->lrun->ort == GLYPH_ORIENT_UPRIGHT) {
pos.x_off = (line->height - glyph_info->height) / 2;
pos.x_off *= up_off_factor;
if ((layout->rf & GRF_WRITING_MODE_MASK) ==
GRF_WRITING_MODE_VERTICAL_RL)
pos.x -= (line->height - gi->height) / 2;
else if ((layout->rf & GRF_WRITING_MODE_MASK) ==
GRF_WRITING_MODE_VERTICAL_LR)
pos.x += (line->height - gi->height) / 2;
}
}
else {
@@ -1820,23 +1823,23 @@ static int traverse_line_glyphs(const LAYOUTINFO* layout,
pos.x += line->height;
}
pos.x_off += glyph_info->x_off;
pos.y_off += glyph_info->y_off;
pos.x_off = gi->x_off;
pos.y_off = gi->y_off;
pos.advance = glyph_info->width;
pos.advance = gi->width;
pos.suppressed = 0;
pos.whitespace = 0;
pos.ellipsis = 0;
pos.orientation = run->lrun->ort;
pos.hanged = glyph_info->hanged;
pos.hanged = gi->hanged;
if (run->lrun->flags & LAYOUTRUN_FLAG_ELLIPSIS) {
pos.ellipsis = 1;
}
if (run->lrun->flags & LAYOUTRUN_FLAG_NO_SHAPING) {
if (glyph_info->width > 0) {
if (gi->width > 0) {
pos.whitespace = 1;
}
else {
@@ -1845,13 +1848,13 @@ 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,
__FUNCTION__, extra.uc, gi->width,
pos.x, pos.y, pos.x_off, pos.y_off);
if (!cb_laid_out(ctxt, glyph_info->gv, &pos, &extra))
if (!cb_laid_out(ctxt, gi->gv, &pos, &extra))
return j;
line_adv += glyph_info->width;
line_adv += gi->width;
}
}