[PATCH v2 1/1] video: fix positioning in TrueType console
Heinrich Schuchardt
xypron.glpk at gmx.de
Thu Oct 28 09:07:01 CEST 2021
On 10/28/21 7:19 AM, Heinrich Schuchardt wrote:
> With the patch accurate positioning is possible for mono-typed fonts:
>
> Fix the return value of console_truetype_putc_xy(). The current position
> is passed as parameter x. Some part of x represents a fractional pixel.
> The return value represents how much the character position must be
> advanced. This should only comprise the width of the current character and
> not the preexisting fractional pixel position.
>
> Characters are not square. As all characters of a mono-type font we can
> take the width of any character. 'W' as one of the widest ANSI characters
> provides also a good value for variable width fonts.
>
> The character width must be a float.
>
> Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
> ---
> v2:
> Adjust hash values in tests
There is still something wrong for systems without float support:
undefined reference to `__aeabi_dmul'
We should keep usage of floats restricted to truetype.
Best regards
Heinrich
> ---
> drivers/video/console_truetype.c | 27 ++++++++++++++++++++-------
> include/video_console.h | 2 +-
> test/dm/video.c | 6 +++---
> 3 files changed, 24 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
> index d9ad52cce0..6fe238eab3 100644
> --- a/drivers/video/console_truetype.c
> +++ b/drivers/video/console_truetype.c
> @@ -209,7 +209,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
> int width_frac, linenum;
> struct pos_info *pos;
> u8 *bits, *data;
> - int advance;
> + int advance, kern_adv;
> void *start, *line, *sync_start, *sync_end;
> int row, ret;
> int bg_r, bg_g, bg_b;
> @@ -224,8 +224,11 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
> * this character */
> xpos = frac(VID_TO_PIXEL((double)x));
> if (vc_priv->last_ch) {
> - xpos += priv->scale * stbtt_GetCodepointKernAdvance(font,
> - vc_priv->last_ch, ch);
> + kern_adv = stbtt_GetCodepointKernAdvance(font, vc_priv->last_ch,
> + ch);
> + xpos += priv->scale * kern_adv;
> + } else {
> + kern_adv = 0;
> }
>
> /*
> @@ -236,8 +239,8 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
> */
> x_shift = xpos - (double)tt_floor(xpos);
> xpos += advance * priv->scale;
> - width_frac = (int)VID_TO_POS(xpos);
> - if (x + width_frac >= vc_priv->xsize_frac)
> + width_frac = VID_TO_POS(priv->scale * (kern_adv + advance));
> + if (x + (int)VID_TO_POS(xpos) >= vc_priv->xsize_frac)
> return -EAGAIN;
>
> /* Write the current cursor position into history */
> @@ -585,20 +588,21 @@ static int console_truetype_probe(struct udevice *dev)
> struct udevice *vid_dev = dev->parent;
> struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
> stbtt_fontinfo *font = &priv->font;
> - int ascent;
> + int advance, ascent, lsb;
>
> debug("%s: start\n", __func__);
> +
> if (vid_priv->font_size)
> priv->font_size = vid_priv->font_size;
> else
> priv->font_size = CONFIG_CONSOLE_TRUETYPE_SIZE;
> +
> priv->font_data = console_truetype_find_font();
> if (!priv->font_data) {
> debug("%s: Could not find any fonts\n", __func__);
> return -EBFONT;
> }
>
> - vc_priv->x_charsize = priv->font_size;
> vc_priv->y_charsize = priv->font_size;
> vc_priv->xstart_frac = VID_TO_POS(2);
> vc_priv->cols = vid_priv->xsize / priv->font_size;
> @@ -612,6 +616,15 @@ static int console_truetype_probe(struct udevice *dev)
>
> /* Pre-calculate some things we will need regularly */
> priv->scale = stbtt_ScaleForPixelHeight(font, priv->font_size);
> +
> + /* Assuming that 'W' is the widest character */
> + stbtt_GetCodepointHMetrics(font, 'W', &advance, &lsb);
> + advance += stbtt_GetCodepointKernAdvance(font, 'W', 'W');
> + vc_priv->cols =
> + (int)VID_TO_POS(vid_priv->xsize - 2) /
> + (int)VID_TO_POS(advance * priv->scale);
> + vc_priv->x_charsize = advance * priv->scale;
> +
> stbtt_GetFontVMetrics(font, &ascent, 0, 0);
> priv->baseline = (int)(ascent * priv->scale);
> debug("%s: ready\n", __func__);
> diff --git a/include/video_console.h b/include/video_console.h
> index 06b798ef10..6ec9b4c5b0 100644
> --- a/include/video_console.h
> +++ b/include/video_console.h
> @@ -68,7 +68,7 @@ struct vidconsole_priv {
> int ycur;
> int rows;
> int cols;
> - int x_charsize;
> + double x_charsize;
> int y_charsize;
> int tab_width_frac;
> int xsize_frac;
> diff --git a/test/dm/video.c b/test/dm/video.c
> index 1d29b2d61c..c0ad83521a 100644
> --- a/test/dm/video.c
> +++ b/test/dm/video.c
> @@ -344,7 +344,7 @@ static int dm_test_video_truetype(struct unit_test_state *uts)
> ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
> ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
> vidconsole_put_string(con, test_string);
> - ut_asserteq(13001, compress_frame_buffer(uts, dev));
> + ut_asserteq(12752, compress_frame_buffer(uts, dev));
>
> return 0;
> }
> @@ -365,7 +365,7 @@ static int dm_test_video_truetype_scroll(struct unit_test_state *uts)
> ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
> ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
> vidconsole_put_string(con, test_string);
> - ut_asserteq(36952, compress_frame_buffer(uts, dev));
> + ut_asserteq(36493, compress_frame_buffer(uts, dev));
>
> return 0;
> }
> @@ -386,7 +386,7 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts)
> ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
> ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
> vidconsole_put_string(con, test_string);
> - ut_asserteq(30747, compress_frame_buffer(uts, dev));
> + ut_asserteq(31117, compress_frame_buffer(uts, dev));
>
> return 0;
> }
> --
> 2.30.2
>
More information about the U-Boot
mailing list