From patchwork Fri Sep 19 20:14:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 368 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1758313013; bh=2IaM+57NMHz64ihkgcV7I1szG2MecxX0xHz7XBx+3sY=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=jB5LuRPWCeVdZtvGSrLIvWsLSh24hpY8d004AtW3cGRGDXiTIBXnGGxe0ib910J+g UW0MjQ0k0ugq3afaUSWrGjXrkq4KyO0bt7durMqiT/b6irUf2EGiyxyQlcX9tHEIqn jiZEdb1Bh03xRSLHVnCRmbv380T9pymrSsVCHQOf8ETApBZ37r7OgujNFQZyUeegYk RJ2sUFXb8NMc/OPOdnTVww/J/6XMxjqR868fjP9xWARpKtBy26oXeDzFgQic24Gnmd eLWnWIQxUuNM3fb0RAzcY0S/+CkrqLlFsDxnK1gYQExoDSR9ANKTdHIp8kUgg0odqU ZQwvqRiVxPVuA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id E0C0167B3B for ; Fri, 19 Sep 2025 14:16:53 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id zVX5FjeCkhYy for ; Fri, 19 Sep 2025 14:16:53 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1758313013; bh=2IaM+57NMHz64ihkgcV7I1szG2MecxX0xHz7XBx+3sY=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=jB5LuRPWCeVdZtvGSrLIvWsLSh24hpY8d004AtW3cGRGDXiTIBXnGGxe0ib910J+g UW0MjQ0k0ugq3afaUSWrGjXrkq4KyO0bt7durMqiT/b6irUf2EGiyxyQlcX9tHEIqn jiZEdb1Bh03xRSLHVnCRmbv380T9pymrSsVCHQOf8ETApBZ37r7OgujNFQZyUeegYk RJ2sUFXb8NMc/OPOdnTVww/J/6XMxjqR868fjP9xWARpKtBy26oXeDzFgQic24Gnmd eLWnWIQxUuNM3fb0RAzcY0S/+CkrqLlFsDxnK1gYQExoDSR9ANKTdHIp8kUgg0odqU ZQwvqRiVxPVuA== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id D0D3367C5B for ; Fri, 19 Sep 2025 14:16:53 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1758313012; bh=cZ+3fLAUxSB+DWNGSeQV3clJJnMcnMY2SCfVJFd346U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aF5SOxSEeayAcnYsSNEa4C7eDIAohwY13CxVldKziW+M0iHnRZ7O0+8DnYVok1nmx KBslxBXBhGcxJ9zMmkeqI8Uy/BMA31kqLAEnmEa5CzM7S984WnZWMzRZ0/dzY36nBs BOWAA9fHUZq28b/cg/jFRl3KabpmQgdFS4ba/wBzGwTetnzfbAy6ke27QtWISfXBly NYaM73w18S1yNTUHj9nMkUo8eGaC4haVol5xsnWujbA0J3Xjnn0M8UkHAHAxuUQn5x brWSlQqG7spYAyRDSTq1G8QJHbdCvk16mEZF+pqX3H7E6QgKG3x4VjoeljmBHu/UTG 2px/mKv/19S6w== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id E84C667BFC; Fri, 19 Sep 2025 14:16:52 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id ywlZlTvF2LIX; Fri, 19 Sep 2025 14:16:52 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1758313008; bh=NgP0g26/8q8+Oh7uGRi9y7ojxaMVa4PvbnPWJNluoxY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZySuLjk9GSly7ziodNhiXWlNen6yhLmwqQivuUtJnVYvPW0DPwFfj8TXI2xOaU9Lx iifUqitOGUSnL2+mWsHnTeLutwxK069SHWlGtm59YDyz5Y7dUW/iiHqRuuqAP9QNR5 5T3jeaCmYBzaUa640RWRSFGrYSVu7y8qZpVRnbAepfaxIz5CAVxo/RWafkTWGDZBl+ uDPVo6w7ipOo582+VheKDeM7qnu//5Pk+IRVi96Wrfs5jg1OCGxh91j3LWDsVBKwON cnxfgt4TQm+ME5gMVJREp2ZB7Ad1aWl6jweKxwaV7F7P/BGmosPDlN/Xigf5PiKujv M5Ij9ujQv2YSQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 1091167B55; Fri, 19 Sep 2025 14:16:47 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Fri, 19 Sep 2025 14:14:33 -0600 Message-ID: <20250919201507.4024144-27-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250919201507.4024144-1-sjg@u-boot.org> References: <20250919201507.4024144-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: IVM7UJSKT4YFMQDQVNH6Q7D37XR4SGPD X-Message-ID-Hash: IVM7UJSKT4YFMQDQVNH6Q7D37XR4SGPD X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 26/42] video: truetype: Track characters and their widths List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass 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 --- 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));