summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2026-01-21 14:00:26 +0100
committerManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2026-01-21 14:00:26 +0100
commit14a5f705c8e3385a637be3377f0800b30c38e589 (patch)
treec8199a77311468cec3cc7fc2e0b168e60b39a109 /src/drivers
parent2f7d7adfcf4bec55fa5e007947e4a455e85d8930 (diff)
Improve handling of text containing context-dependent unicode points.
This commit makes platforms Windows and macOS compute string widths with the same mechanism as what is in place for platforms Wayland/X11: - the width of a string containing a single codepoint is computed and memorized in the table of character widths; - the width of a string containing several codepoints is computed as such rather than as the sum of the widths of its composing characters. The result is that FLTK text widgets input and draw correctly also complex emojis encoded with context-dependent codepoints. Function fl_utf8_remove_context_dependent() is no longer necessary.
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx23
-rw-r--r--src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx17
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx6
3 files changed, 39 insertions, 7 deletions
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx
index e901db971..49111f10e 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx
@@ -1,7 +1,7 @@
//
// Windows font utilities for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2025 by Bill Spitzak and others.
+// Copyright 1998-2026 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -366,6 +366,27 @@ Fl_Fontsize Fl_GDI_Graphics_Driver::size_unscaled() {
}
double Fl_GDI_Graphics_Driver::width_unscaled(const char* c, int n) {
+ if (n == 0) return 0;
+ int len1 = fl_utf8len1(*c);
+ if (n > len1 && len1 > 0) { // a text with several codepoints: compute its typographical width
+ int wn = fl_utf8toUtf16(c, n, wstr, wstr_len);
+ if (wn >= wstr_len) {
+ wstr = (unsigned short*) realloc(wstr, sizeof(unsigned short) * (wn + 1));
+ wstr_len = wn + 1;
+ wn = fl_utf8toUtf16(c, n, wstr, wstr_len);
+ }
+ HDC gc2 = gc_;
+ HWND hWnd;
+ if (!gc2) {
+ hWnd = Fl::first_window() ? fl_xid(Fl::first_window()) : NULL;
+ gc2 = GetDC(hWnd);
+ }
+ SelectObject(gc2, ((Fl_GDI_Font_Descriptor*)font_descriptor())->fid);
+ SIZE s;
+ GetTextExtentPoint32W(gc2, (WCHAR*)wstr, wn, &s);
+ if (gc2 && gc2 != gc_) ReleaseDC(hWnd, gc2);
+ return (double)s.cx;
+ }
int i = 0;
if (!font_descriptor()) return -1.0;
double w = 0.0;
diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
index 7b2085c23..a277010e3 100644
--- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
+++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx
@@ -1,7 +1,7 @@
//
// MacOS font selection routines for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2018 by Bill Spitzak and others.
+// Copyright 1998-2026 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -300,6 +300,21 @@ void Fl_Quartz_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) {
}
double Fl_Quartz_Graphics_Driver::width(const char* txt, int n) {
+ if (n == 0) return 0;
+ int len1 = fl_utf8len1(*txt);
+ if (len1 > 0 && n > len1) { // a text with several codepoints: compute its typographical width
+ CFStringRef str = CFStringCreateWithBytes(NULL, (const UInt8*)txt, n, kCFStringEncodingUTF8, false);
+ if (str) {
+ CFDictionarySetValue(attributes, kCTFontAttributeName, valid_font_descriptor()->fontref);
+ CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str, attributes);
+ CFRelease(str);
+ CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
+ CFRelease(mastr);
+ double d = CTLineGetTypographicBounds(ctline, NULL, NULL, NULL);
+ CFRelease(ctline);
+ return d;
+ }
+ }
int wc_len = n;
UniChar *uniStr = mac_Utf8_to_Utf16(txt, n, &wc_len);
return width(uniStr, wc_len);
diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
index c9774f895..9199f3a5f 100644
--- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
@@ -53,7 +53,6 @@ extern "C" {
bool fl_is_surface_from_GTK_titlebar (struct wl_surface *surface, struct libdecor_frame *frame,
bool *using_GTK);
}
-extern int fl_utf8_remove_context_dependent(char *text, int len);
// set this to 1 for keyboard debug output, 0 for no debug output
#define DEBUG_KEYBOARD 0
@@ -1017,10 +1016,7 @@ void text_input_commit_string(void *data, struct zwp_text_input_v3 *zwp_text_inp
const char *text) {
//printf("text_input_commit_string %s\n",text);
free(pending_commit);
- if (text) {
- pending_commit = strdup(text);
- fl_utf8_remove_context_dependent(pending_commit, strlen(pending_commit));
- } else pending_commit = NULL;
+ pending_commit = (text ? strdup(text) : NULL);
}