summaryrefslogtreecommitdiff
path: root/pango2/pango-impl-utils.h
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2022-07-04 11:16:05 -0400
committerMatthias Clasen <mclasen@redhat.com>2022-07-04 11:17:21 -0400
commitbcdce34c8ac0adffd589e9fb68b62ff09368bb0f (patch)
tree7b92ba875b22212d15ffb9d9620d517cfa427a1e /pango2/pango-impl-utils.h
parentb197cc08b18bc44a3e93f859ca7e61dfe335bbc5 (diff)
downloadpango-bcdce34c8ac0adffd589e9fb68b62ff09368bb0f.tar.gz
Move the code from pango/ to pango2/
Life is easier if the src path matches the installed header path prefix, so make them match. Update all users.
Diffstat (limited to 'pango2/pango-impl-utils.h')
-rw-r--r--pango2/pango-impl-utils.h240
1 files changed, 240 insertions, 0 deletions
diff --git a/pango2/pango-impl-utils.h b/pango2/pango-impl-utils.h
new file mode 100644
index 00000000..cc21bc0b
--- /dev/null
+++ b/pango2/pango-impl-utils.h
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2003 Red Hat Software
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib.h>
+#include <glib-object.h>
+#include <pango2/pango.h>
+
+G_BEGIN_DECLS
+
+
+/* String interning for static strings */
+#define I_(string) g_intern_static_string (string)
+
+/* We define these functions static here because we don't want to add public API
+ * for them (if anything, it belongs to glib, but glib found it trivial enough
+ * not to add API for). At some point metrics calculations will be
+ * centralized and this mess can be minimized. Or so I hope.
+ */
+
+static inline G_GNUC_UNUSED int
+pango2_unichar_width (gunichar c)
+{
+ return G_UNLIKELY (g_unichar_iszerowidth (c)) ? 0 :
+ G_UNLIKELY (g_unichar_iswide (c)) ? 2 : 1;
+}
+
+static G_GNUC_UNUSED glong
+pango2_utf8_strwidth (const char *p)
+{
+ glong len = 0;
+ g_return_val_if_fail (p != NULL, 0);
+
+ while (*p)
+ {
+ len += pango2_unichar_width (g_utf8_get_char (p));
+ p = g_utf8_next_char (p);
+ }
+
+ return len;
+}
+
+/* Glib's g_utf8_strlen() is broken and stops at embedded NUL's.
+ * Wrap it here. */
+static G_GNUC_UNUSED glong
+pango2_utf8_strlen (const char *p,
+ gssize max)
+{
+ glong len = 0;
+ const char *start = p;
+ g_return_val_if_fail (p != NULL || max == 0, 0);
+
+ if (max <= 0)
+ return g_utf8_strlen (p, max);
+
+ p = g_utf8_next_char (p);
+ while (p - start < max)
+ {
+ ++len;
+ p = g_utf8_next_char (p);
+ }
+
+ /* only do the last len increment if we got a complete
+ * char (don't count partial chars)
+ */
+ if (p - start <= max)
+ ++len;
+
+ return len;
+}
+
+
+/* To be made public at some point */
+
+static G_GNUC_UNUSED void
+pango2_glyph_string_reverse_range (Pango2GlyphString *glyphs,
+ int start,
+ int end)
+{
+ int i, j;
+
+ for (i = start, j = end - 1; i < j; i++, j--)
+ {
+ Pango2GlyphInfo glyph_info;
+ int log_cluster;
+
+ glyph_info = glyphs->glyphs[i];
+ glyphs->glyphs[i] = glyphs->glyphs[j];
+ glyphs->glyphs[j] = glyph_info;
+
+ log_cluster = glyphs->log_clusters[i];
+ glyphs->log_clusters[i] = glyphs->log_clusters[j];
+ glyphs->log_clusters[j] = log_cluster;
+ }
+}
+
+static inline gboolean
+pango2_is_default_ignorable (gunichar ch)
+{
+ int plane = ch >> 16;
+
+ if (G_LIKELY (plane == 0))
+ {
+ int page = ch >> 8;
+ switch (page)
+ {
+ case 0x00: return ch == 0x00ad;
+ case 0x03: return ch == 0x034f;
+ case 0x06: return ch == 0x061c;
+ case 0x17: return (0x17b4 <= ch && ch <= 0x17b5);
+ case 0x18: return (0x180b <= ch && ch <= 0x180e);
+ case 0x20: return (0x200b <= ch && ch <= 0x200f) ||
+ (0x202a <= ch && ch <= 0x202e) ||
+ (0x2060 <= ch && ch <= 0x206f);
+ case 0xfe: return (0xfe00 <= ch && ch <= 0xfe0f) || ch == 0xfeff;
+ case 0xff: return (0xfff0 <= ch && ch <= 0xfff8);
+ default: return FALSE;
+ }
+ }
+ else
+ {
+ /* Other planes */
+ switch (plane)
+ {
+ case 0x01: return (0x1d173 <= ch && ch <= 0x1d17a);
+ case 0x0e: return (0xe0000 <= ch && ch <= 0xe0fff);
+ default: return FALSE;
+ }
+ }
+}
+
+/* These are the default ignorables that we render as hexboxes
+ * with nicks if PANGO2_SHOW_IGNORABLES is used.
+ *
+ * The cairo hexbox drawing code assumes that these nicks are
+ * 1-6 ASCII chars
+ */
+static struct {
+ gunichar ch;
+ const char *nick;
+} ignorables[] = {
+ { 0x00ad, "SHY" }, /* SOFT HYPHEN */
+ { 0x034f, "CGJ" }, /* COMBINING GRAPHEME JOINER */
+ { 0x061c, "ALM" }, /* ARABIC LETTER MARK */
+ { 0x200b, "ZWS" }, /* ZERO WIDTH SPACE */
+ { 0x200c, "ZWNJ" }, /* ZERO WIDTH NON-JOINER */
+ { 0x200d, "ZWJ" }, /* ZERO WIDTH JOINER */
+ { 0x200e, "LRM" }, /* LEFT-TO-RIGHT MARK */
+ { 0x200f, "RLM" }, /* RIGHT-TO-LEFT MARK */
+ { 0x2028, "LS" }, /* LINE SEPARATOR */
+ { 0x2029, "PS" }, /* PARAGRAPH SEPARATOR */
+ { 0x202a, "LRE" }, /* LEFT-TO-RIGHT EMBEDDING */
+ { 0x202b, "RLE" }, /* RIGHT-TO-LEFT EMBEDDING */
+ { 0x202c, "PDF" }, /* POP DIRECTIONAL FORMATTING */
+ { 0x202d, "LRO" }, /* LEFT-TO-RIGHT OVERRIDE */
+ { 0x202e, "RLO" }, /* RIGHT-TO-LEFT OVERRIDE */
+ { 0x2060, "WJ" }, /* WORD JOINER */
+ { 0x2061, "FA" }, /* FUNCTION APPLICATION */
+ { 0x2062, "IT" }, /* INVISIBLE TIMES */
+ { 0x2063, "IS" }, /* INVISIBLE SEPARATOR */
+ { 0x2066, "LRI" }, /* LEFT-TO-RIGHT ISOLATE */
+ { 0x2067, "RLI" }, /* RIGHT-TO-LEFT ISOLATE */
+ { 0x2068, "FSI" }, /* FIRST STRONG ISOLATE */
+ { 0x2069, "PDI" }, /* POP DIRECTIONAL ISOLATE */
+ { 0xfeff, "ZWNBS" }, /* ZERO WIDTH NO-BREAK SPACE */
+};
+
+static inline G_GNUC_UNUSED const char *
+pango2_get_ignorable (gunichar ch)
+{
+ for (guint i = 0; i < G_N_ELEMENTS (ignorables); i++)
+ {
+ if (ch < ignorables[i].ch)
+ return NULL;
+
+ if (ch == ignorables[i].ch)
+ return ignorables[i].nick;
+ }
+
+ return NULL;
+}
+
+static inline G_GNUC_UNUSED const char *
+pango2_get_ignorable_size (gunichar ch,
+ int *rows,
+ int *cols)
+{
+ const char *nick;
+ int len;
+
+ nick = pango2_get_ignorable (ch);
+ if (nick)
+ {
+ len = strlen (nick);
+ if (len < 4)
+ {
+ *rows = 1;
+ *cols = len;
+ }
+ else if (len > 4)
+ {
+ *rows = 2;
+ *cols = 3;
+ }
+ else
+ {
+ *rows = 2;
+ *cols = 2;
+ }
+ }
+
+ return nick;
+}
+
+/* Backward compatibility shim, to avoid bumping up the minimum
+ * required version of GLib; most of our uses of g_memdup() are
+ * safe, and those that aren't have been fixed
+ */
+#if !GLIB_CHECK_VERSION (2, 67, 3)
+# define g_memdup2(mem,size) g_memdup((mem),(size))
+#endif
+
+G_END_DECLS