From patchwork Thu Oct 28 18:01:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heinrich Schuchardt X-Patchwork-Id: 1547629 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=gmx.net header.i=@gmx.net header.a=rsa-sha256 header.s=badeba3b8450 header.b=GmSPH6Sz; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HgD073JgPz9sRN for ; Fri, 29 Oct 2021 05:01:41 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 0B98B834A4; Thu, 28 Oct 2021 20:01:34 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=gmx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; secure) header.d=gmx.net header.i=@gmx.net header.b="GmSPH6Sz"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 63C2F8356D; Thu, 28 Oct 2021 20:01:31 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FROM,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.2 Received: from mout.gmx.net (mout.gmx.net [212.227.15.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 7A492832C6 for ; Thu, 28 Oct 2021 20:01:26 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=xypron.glpk@gmx.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1635444085; bh=tsGjy/8iSWGfkWI51YBBmD7AxTrgZKvfMVR6CWY9C4I=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date; b=GmSPH6Szu/h7EjvPqjzWYah8Kblfwrz7fbkBNr7p8gmuu8u+kZuHGdt/c0njLIZAB 953K56JDWYQZKmN9wTZaf2u5CP2KgAczQ4v0cXdZv4QjrHDra0FiZbtYOxEJDTG43Q rosw+swVPuCoCK0UOU7ooYrNlutKEbzB5PQAc2V8= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from LT02.fritz.box ([88.152.144.157]) by mail.gmx.net (mrgmx005 [212.227.17.184]) with ESMTPSA (Nemesis) id 1MrhUE-1n35zF1xeW-00njl5; Thu, 28 Oct 2021 20:01:25 +0200 From: Heinrich Schuchardt To: Anatolij Gustschin Cc: Simon Glass , u-boot@lists.denx.de, Heinrich Schuchardt Subject: [PATCH v3] video: fix positioning in TrueType console Date: Thu, 28 Oct 2021 20:01:20 +0200 Message-Id: <20211028180120.3309-1-xypron.glpk@gmx.de> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 X-Provags-ID: V03:K1:4ym9nuR/SFmHaDyjcAX5ge7RsonzOul8L9YS5sY7eggVLhXND9R f+t2WRYBGuuX/u3QTzovdip/o65K9hITJ2s7Kz0Pc2BaLIqBIZSaw1mtN1Rvjl3D9RIoIKV pH9Bm5UM67om+Rk3kSmSzMFlgmRPuU5JjyTLS0NYaJySxkSZeiTStvXL7F9y88KGG8HIFSt /tKzbk/wCwQFn99mq5rIA== X-UI-Out-Filterresults: notjunk:1;V03:K0:NIA3HLfAHIw=:JNsS+6HQjQBzLIWD3WfOmk /QQvD9plwiscA5pbrUH4nrkKccnw3iZa8h5ABi6oHSzkoggiSgTzHhGtzJbQGPdlZkI9sf3Ss 4wyRkbfVn6iAv/o4bxrhHoaZ2s544R1jFWyt9BZ9QISHs5oc0m6zqiilsZ97OxaDmkLZZAJEE fyBjsViM6VPSyQDUKEG8cV1zvJ307EEEVDor3nARC8aJYT2LPexHhuh0g0RvqbImqr+TMpd5V 1Rvh/LfE7GcsJLiGXbI+Qcl1rkgVSLwQtdfOhCjvYS4FaLKkmXE5WLh9D+9BERv6YawAtaZRT zO+TInicM0cJwVSxlPM/35QPwHlGY2AV0puZ6tKVPZrcO7gLzi+N3PVVJJs7lc08GbkwxaONm iWKImm0MyovwGT5NvU9b7wmS3zau0Psvsnvn4IoYUcxuHmi3vq8ALqT7RgLw+xwZc/dfMgQyE xy64F6G4PuCdrUeGypUCH/wkDu0qWvYr0ElUAH4Cr39IQL7nYkuS+iDawjvlvFbD0PkbEr3jE 6Cu1MPh+mgdZLrqSUbzwCFn8YFOm94H7hKqXyt8DAHrG9pMCLMbwA9lPrC/G2PeCKTPyhXnyW MCee625CGcMerjBjF/Ac664Mx0JcedMURc623JTeFiG/XqYLUfjqu+vPfF9iZ9XxcYqUHznWs a6RV7PfBU9/3yIg8UpnS5Zwpd+/iyc9abbX+8c6K7nWT5AFjV/rdkNEYGpDbzI+GIB2DESGJb I1gf03LfEF53PpucmmPed3DChAWER45Xi9jEjmjICAwm6xAkSrtHrlrsVtMe9Gtx6VO7J4y8k T59eB8Y4u75mppACBvfcXHA0ekVK+6vfo4PS2WFD7jtAkNiFsVKacxJVTh1ERJUydjurtH22t gQ5fBjTn0QXV5i4zi1DpxSLGuFuBoiuubh1NE3jET3IYcwQYw9VD5xRhC2pOuI2btVGG6UyYD 5wEZE8PH7m1XCC4mFy+zmxUKfuTySW+v+1hxsEouk8e1EGnkzEfKl00UNaS6dlVq7SPv8KsxX S2FjX05PwVC6TfKBAHsHttappL11aXXgb47GAJohpXpmm87kYeXHUCUEZnL4ABpHQPSvHOwUy h8NvFzCq0K4sDg= X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean 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 for TrueType. Signed-off-by: Heinrich Schuchardt Tested-by: Simon Glass --- v3: Use floating point only with the TrueType console. v2: Adjust hash values in tests --- drivers/video/console_truetype.c | 27 ++++++++++++++++++++------- include/video_console.h | 4 ++++ test/dm/video.c | 6 +++--- 3 files changed, 27 insertions(+), 10 deletions(-) -- 2.30.2 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..c339dc3956 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -68,7 +68,11 @@ struct vidconsole_priv { int ycur; int rows; int cols; +#ifdef CONFIG_CONSOLE_TRUETYPE + double x_charsize; +#else int x_charsize; +#endif 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; }