
From: Simon Glass <sjg@chromium.org> The Truetype driver maintains a list of x and y positions for every character in the line being entered by the user. This allows it to backspace reliably without having to re-measure lots of text. For kerning, the video console maintains a last_ch variable which holds the last character written to the console. This allows accurate kerning between one character and the next. At present lash_ch is cleared on backspace, since we cannot know what the character before last_ch is. The slightly strange part is that the truetype console currently has no knowledge about what the characters were, only their x and y positions, with the x position being fractional. It also has no idea of the width of each character, since it doesn't need to: the CLI will always write out a new character in order to move forward during command-editing, since there is no actual concept of 'move the cursor to the right'. Part of the reason this works is that truetype implements backspace by actually clearing the character from the display. So if you type some text and then press the left arrow, it looks like it is doing a backspace. This has been a known limitation for some time. The correct way to implement left-arrow is to leave the display alone, only clearing it if characters are later added. This is necessary since Truetype fonts are OR'd onto the screen, which is assumed to be initially cleared to the background colour. We cannot do this clearing without knowing the width of the characters we need to clear, so add a 'width' to the struct pos_info for that. For kerning we must know the previous character to kern against, but we cannot yet make that change, since we don't want to kern against characters that were there before an erase. So that will be dealt with later, in 'Clear after the current char on insert'. Signed-off-by: Simon Glass <sjg@chromium.org> --- drivers/video/console_truetype.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index edd2eb0a309..aabacd10afe 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -120,10 +120,14 @@ static double tt_acos(double val) * * @xpos_frac: Fractional X position in pixels (multiplied by VID_FRAC_DIV) * @ypos: Y position (pixels from the top) + * @width: Width of the character at this position in pixels (rounded up) + * @cp: Unicode code point of the character */ struct pos_info { int xpos_frac; int ypos; + int width; + int cp; }; /* @@ -175,6 +179,7 @@ struct console_tt_metrics { * @cur_fontdata: Current fixed font data (NULL if using TrueType) * @pos_start: Value of pos_ptr when the cursor is at the start of the text * being entered by the user + * @pos_count: Maximum value reached by pos_ptr (initially zero) */ struct console_tt_priv { struct console_tt_metrics *cur_met; @@ -184,6 +189,7 @@ struct console_tt_priv { int pos_ptr; struct video_fontdata *cur_fontdata; int pos_start; + int pos_count; }; /** @@ -354,7 +360,11 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, pos = &priv->pos[priv->pos_ptr]; pos->xpos_frac = vc_priv->xcur_frac; pos->ypos = vc_priv->ycur; + pos->width = (width_frac + VID_FRAC_DIV - 1) / VID_FRAC_DIV; + pos->cp = cp; priv->pos_ptr++; + if (priv->pos_ptr > priv->pos_count) + priv->pos_count = priv->pos_ptr; } /* @@ -530,6 +540,7 @@ static int console_truetype_entry_start(struct udevice *dev) /* A new input line has start, so clear our history */ priv->pos_ptr = 0; + priv->pos_count = 0; vc_priv->last_ch = 0; return 0; @@ -1000,6 +1011,7 @@ static int truetype_entry_restore(struct udevice *dev, struct abuf *buf) vc_priv->xcur_frac = store.cur.xpos_frac; vc_priv->ycur = store.cur.ypos; priv->pos_ptr = store.priv.pos_ptr; + priv->pos_count = store.priv.pos_count; memcpy(priv->pos, store.priv.pos, store.priv.pos_ptr * sizeof(struct pos_info)); -- 2.43.0