Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
widget_style.c
Go to the documentation of this file.
1/*
2 * This file is part of darktable,
3 * Copyright (C) 2016 johannes hanika.
4 * Copyright (C) 2016, 2020 Tobias Ellinghaus.
5 * Copyright (C) 2020 Pascal Obry.
6 * Copyright (C) 2021 Sakari Kapanen.
7 * Copyright (C) 2022 Martin Baƙinka.
8 *
9 * darktable is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * darktable is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with darktable. If not, see <http://www.gnu.org/licenses/>.
21 */
22
25#include "system/macros.h" // IS_NULL_PTR -- a pure macro header, no state
26
27#include <pango/pangocairo.h>
28
29#include <glib.h>
30#include <string.h>
31
32void dt_gui_add_class(GtkWidget *widget, const gchar *class_name)
33{
36 {
39 }
40}
41
42void dt_gui_remove_class(GtkWidget *widget, const gchar *class_name)
43{
46 {
49 }
50}
51
52void dt_capitalize_label(gchar *text)
53{
54 if(!text || !text[0]) return;
55
56 // Deal with strings beginning with a Mnemonics underscore
57 gchar *p = text;
58 if(*p == '_' && p[1]) p++;
59
60 // `p[0] = g_unichar_toupper(p[0])` used to write here directly, but `p[0]` is only
61 // the first *byte* of `p`, not the first character: translated labels routinely
62 // start with a multi-byte UTF-8 character (accented capitals, non-Latin scripts).
63 // Mutating one byte of a multi-byte sequence produces a different, still
64 // "valid-looking" sequence followed by an orphaned continuation byte - invalid
65 // UTF-8 that crashes later collation (e.g. g_utf8_collate -> glibc wcscoll_l).
67 if(c == (gunichar)-1 || c == (gunichar)-2) return; // invalid UTF-8, leave untouched
68
69 gunichar upper = g_unichar_toupper(c);
70 if(upper == c) return;
71
72 gchar utf8_buf[6] = { 0 };
73 gint n = g_unichar_to_utf8(upper, utf8_buf);
74 gint orig_len = g_utf8_next_char(p) - p;
75
76 // Callers pass buffers sized exactly for the original string (often g_strdup'd),
77 // not a longer one - only mutate in place if the uppercase form fits.
78 if(n == orig_len) memcpy(p, utf8_buf, n);
79}
80
82{
83 if(IS_NULL_PTR(cr)) return;
84
85 // Source GTK's resolved text-rendering options (anti-aliasing, hinting, subpixel order,
86 // hint-metrics/kerning), which GTK populates from GtkSettings/Xft/fontconfig. The widget's
87 // Pango context is the same source native widgets use; fall back to the main window, then to the
88 // screen defaults, so an off-screen/scratch Cairo surface never silently reverts to Cairo's
89 // AA-on defaults (which would make our cairo-drawn text look unlike the rest of the UI).
91
92 if(widget)
93 {
96 }
97 if(!fo)
98 {
100 if(root)
101 {
104 }
105 }
106 if(!fo)
107 {
109 if(screen) fo = gdk_screen_get_font_options(screen);
110 }
111
112 // cairo_set_font_options() copies internally, so the const pointer's lifetime is not a concern.
114}
115
116// clang-format off
117// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
118// vim: shiftwidth=2 expandtab tabstop=2 cindent
119// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
120// clang-format on
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
Definition colorspaces.h:98
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition macros.h:65
GtkWidget * dt_widget_root_window(void)
void dt_gui_cairo_set_font_options(cairo_t *cr, GtkWidget *widget)
void dt_gui_remove_class(GtkWidget *widget, const gchar *class_name)
void dt_capitalize_label(gchar *text)
void dt_gui_add_class(GtkWidget *widget, const gchar *class_name)