From 271889386861ab8685cebddcebeaa87eea3fa417 Mon Sep 17 00:00:00 2001
From: Vito Caputo <vcaputo@pengaru.com>
Date: Tue, 3 Oct 2023 17:13:19 -0700
Subject: libs/txt: implement txt_render_fragment_offsetted() variant

Instead of rigid txt_align_t enums to specify how the text is
aligned relative to the x/y coordinates, you specify float
offsets in normalized coordinates -1..+1 allowing fine-grained
control of the offsets.

modules/asc will use this to automatically adjust the offsets
when requested, so x/y coordinates may be varied dynamically
using taps with the text automagically adjusting its offset to
try stay in-fragment.
---
 src/libs/txt/txt.c | 26 ++++++++++++++++++++++++++
 src/libs/txt/txt.h |  1 +
 2 files changed, 27 insertions(+)

(limited to 'src')

diff --git a/src/libs/txt/txt.c b/src/libs/txt/txt.c
index d575821..2e74340 100644
--- a/src/libs/txt/txt.c
+++ b/src/libs/txt/txt.c
@@ -210,3 +210,29 @@ void txt_render_fragment_aligned(txt_t *txt, til_fb_fragment_t *fragment, uint32
 
 	return txt_render(txt, fragment, color, jx, jy);
 }
+
+
+/* Like txt_render_fragment_aligned(), except instead of specifying halign/valign enum variants,
+ * you provide -1..+1 normalized offsets within the rendered text rectangle to anchor the
+ * provided x,y pixel coordinates.  This enables progressively varying the justification
+ * offset rather than it behaving like a step function of three options left/right/center or
+ * top/bottom/center etc.  (modules/asc was the impetus for adding this)
+ */
+void txt_render_fragment_offsetted(txt_t *txt, til_fb_fragment_t *fragment, uint32_t color, int x, int y, float x_offset, float y_offset)
+{
+	int	jx = x, jy = y;
+
+	assert(txt);
+
+	/* XXX: one could argue the offsets should be clamped to -1..+1, but
+	 * I can see valid use cases where one wants to go grater than abs(1)
+	 * to achieve extremely offset texts in dynamic situations.  So I'm
+	 * just letting whatever comes in pass thru for now, considering this
+	 * is "art" oriented where allowing creative stuff to just work trumps
+	 * preventing potential buggy behavior.
+	 */
+	jx -= x_offset * txt->width * .5f + txt->width * .5f;
+	jy -= y_offset * txt->height * .5f + txt->height * .5f;
+
+	return txt_render(txt, fragment, color, jx, jy);
+}
diff --git a/src/libs/txt/txt.h b/src/libs/txt/txt.h
index 9318546..04cf09e 100644
--- a/src/libs/txt/txt.h
+++ b/src/libs/txt/txt.h
@@ -29,5 +29,6 @@ txt_t * txt_new(const char *str);
 txt_t * txt_newf(const char *fmt, ...);
 txt_t * txt_free(txt_t *txt);
 void txt_render_fragment_aligned(txt_t *txt, til_fb_fragment_t *fragment, uint32_t color, int x, int y, txt_align_t alignment);
+void txt_render_fragment_offsetted(txt_t *txt, til_fb_fragment_t *fragment, uint32_t color, int x, int y, float x_offset, float y_offset);
 
 #endif
-- 
cgit v1.2.3