]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
libply-splash-core: Add class to handle rich text
authorn3rdopolis <bluescreen_avenger@verizon.net>
Sun, 26 Nov 2023 16:37:30 +0000 (11:37 -0500)
committerRay Strode <rstrode@redhat.com>
Sat, 2 Dec 2023 22:44:10 +0000 (17:44 -0500)
In order to implement a terminal that supports colors and styles,
we need some way assign colors and styles to text.

This commit adds a new class ply_rich_text_t to handle that.

Code split out of ply-terminal-emulator.c by Ray Strode.

src/libply-splash-core/meson.build
src/libply-splash-core/ply-rich-text.c [new file with mode: 0644]
src/libply-splash-core/ply-rich-text.h [new file with mode: 0644]

index 69636b1338393562fd90af9c3034bdbf9c14e07e..4d8469752fd58611fa9932789e4fe6caca227357 100644 (file)
@@ -6,6 +6,7 @@ libply_splash_core_sources = files(
   'ply-pixel-buffer.c',
   'ply-pixel-display.c',
   'ply-renderer.c',
+  'ply-rich-text.c',
   'ply-terminal.c',
   'ply-text-display.c',
   'ply-text-progress-bar.c',
@@ -59,6 +60,7 @@ libply_splash_core_headers = files(
   'ply-pixel-display.h',
   'ply-renderer-plugin.h',
   'ply-renderer.h',
+  'ply-rich-text.h',
   'ply-terminal.h',
   'ply-text-display.h',
   'ply-text-progress-bar.h',
diff --git a/src/libply-splash-core/ply-rich-text.c b/src/libply-splash-core/ply-rich-text.c
new file mode 100644 (file)
index 0000000..0cc8789
--- /dev/null
@@ -0,0 +1,221 @@
+/* ply-rich-text.c - Text with colors and styles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ */
+
+#include "ply-array.h"
+#include "ply-rich-text.h"
+#include "ply-logger.h"
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include <stdio.h>
+
+struct _ply_rich_text_t
+{
+        ply_array_t *characters;
+        size_t       reference_count;
+};
+
+ply_rich_text_t *
+ply_rich_text_new (void)
+{
+        ply_rich_text_t *rich_text;
+
+        rich_text = calloc (1, sizeof(ply_rich_text_t));
+        rich_text->characters = ply_array_new (PLY_ARRAY_ELEMENT_TYPE_POINTER);
+        rich_text->reference_count = 1;
+
+        return rich_text;
+}
+
+void
+ply_rich_text_take_reference (ply_rich_text_t *rich_text)
+{
+        rich_text->reference_count++;
+}
+
+void
+ply_rich_text_drop_reference (ply_rich_text_t *rich_text)
+{
+        rich_text->reference_count--;
+
+        if (rich_text->reference_count == 0)
+                ply_rich_text_free (rich_text);
+}
+
+void
+ply_rich_text_free (ply_rich_text_t *rich_text)
+{
+        ply_rich_text_character_t **characters;
+
+        if (rich_text == NULL)
+                return;
+
+        characters = ply_rich_text_get_characters (rich_text);
+        characters = (ply_rich_text_character_t **) ply_array_get_pointer_elements (rich_text->characters);
+        for (size_t i = 0; characters[i] != NULL; i++) {
+                ply_rich_text_character_free (characters[i]);
+        }
+
+        ply_array_free (rich_text->characters);
+        free (rich_text);
+}
+
+char *
+ply_rich_text_get_string (ply_rich_text_t      *rich_text,
+                          ply_rich_text_span_t *span)
+{
+        char *string = NULL;
+        ply_buffer_t *buffer;
+        ply_rich_text_character_t **characters;
+
+        characters = ply_rich_text_get_characters (rich_text);
+
+        buffer = ply_buffer_new ();
+        for (size_t i = span->offset; characters[i] != NULL; i++) {
+                if (span->range >= 0) {
+                        if (i >= span->offset + span->range)
+                                break;
+                }
+
+                ply_buffer_append_bytes (buffer,
+                                         characters[i]->bytes,
+                                         characters[i]->length);
+        }
+
+        string = ply_buffer_steal_bytes (buffer);
+
+        ply_buffer_free (buffer);
+
+        return string;
+}
+
+void
+ply_rich_text_remove_characters (ply_rich_text_t *rich_text)
+{
+        ply_rich_text_character_t **characters;
+
+        if (rich_text == NULL)
+                return;
+
+        characters = ply_rich_text_get_characters (rich_text);
+        characters = (ply_rich_text_character_t **) ply_array_get_pointer_elements (rich_text->characters);
+        for (size_t i = 0; characters[i] != NULL; i++) {
+                ply_rich_text_character_free (characters[i]);
+        }
+
+        ply_array_free (rich_text->characters);
+        rich_text->characters = ply_array_new (PLY_ARRAY_ELEMENT_TYPE_POINTER);
+}
+
+size_t
+ply_rich_text_get_length (ply_rich_text_t *rich_text)
+{
+        ply_rich_text_character_t **characters;
+        size_t length = 0;
+
+        characters = ply_rich_text_get_characters (rich_text);
+
+        for (length = 0; characters[length] != NULL; length++) {
+        }
+
+        return length;
+}
+
+ply_rich_text_character_t *
+ply_rich_text_character_new (void)
+{
+        ply_rich_text_character_t *character = calloc (1, sizeof(ply_rich_text_character_t));
+        character->bytes = NULL;
+        character->length = 0;
+
+        return character;
+}
+
+void
+ply_rich_text_character_free (ply_rich_text_character_t *character)
+{
+        free (character->bytes);
+        free (character);
+}
+
+ply_rich_text_character_t **
+ply_rich_text_get_characters (ply_rich_text_t *rich_text)
+{
+        ply_rich_text_character_t **characters;
+
+        characters = (ply_rich_text_character_t **) ply_array_get_pointer_elements (rich_text->characters);
+        return characters;
+}
+
+void
+ply_rich_text_remove_character (ply_rich_text_t *rich_text,
+                                size_t           character_index)
+{
+        ply_rich_text_character_t **characters;
+
+        characters = ply_rich_text_get_characters (rich_text);
+
+        if (characters[character_index] == NULL)
+                return;
+
+        ply_rich_text_character_free (characters[character_index]);
+        characters[character_index] = NULL;
+}
+
+void
+ply_rich_text_move_character (ply_rich_text_t *rich_text,
+                              size_t           old_index,
+                              size_t           new_index)
+{
+        ply_rich_text_character_t **characters = ply_rich_text_get_characters (rich_text);
+        characters[new_index] = characters[old_index];
+        characters[old_index] = NULL;
+}
+
+void
+ply_rich_text_set_character (ply_rich_text_t                *rich_text,
+                             ply_rich_text_character_style_t style,
+                             size_t                          character_index,
+                             const char                     *character_string,
+                             size_t                          length)
+{
+        ply_rich_text_character_t **characters;
+        ply_rich_text_character_t *character;
+
+        characters = ply_rich_text_get_characters (rich_text);
+
+        if (characters[character_index] == NULL) {
+                character = ply_rich_text_character_new ();
+                ply_array_add_pointer_element (rich_text->characters, character);
+                characters = (ply_rich_text_character_t **) ply_array_get_pointer_elements (rich_text->characters);
+        } else {
+                character = characters[character_index];
+                if (character->bytes) {
+                        free (character->bytes);
+                        character->bytes = NULL;
+                }
+        }
+
+        characters[character_index] = character;
+        character->bytes = strdup (character_string);
+        character->length = length;
+        character->style = style;
+}
diff --git a/src/libply-splash-core/ply-rich-text.h b/src/libply-splash-core/ply-rich-text.h
new file mode 100644 (file)
index 0000000..27692de
--- /dev/null
@@ -0,0 +1,81 @@
+/* ply-rich-text.h - Text with colors and styles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ */
+#ifndef PLY_RICH_TEXT_H
+#define PLY_RICH_TEXT_H
+
+#include "ply-array.h"
+#include "ply-terminal.h"
+#include <stddef.h>
+
+#define PLY_UTF8_CHARACTER_MAX_SIZE 5
+
+typedef struct _ply_rich_text_t ply_rich_text_t;
+
+typedef struct
+{
+        ply_terminal_color_t foreground_color;
+        ply_terminal_color_t background_color;
+        uint32_t             bold_enabled : 1;
+        uint32_t             dim_enabled : 1;
+        uint32_t             italic_enabled : 1;
+        uint32_t             underline_enabled : 1;
+        uint32_t             reverse_enabled : 1;
+} ply_rich_text_character_style_t;
+
+typedef struct
+{
+        char                           *bytes;
+        size_t                          length;
+
+        ply_rich_text_character_style_t style;
+} ply_rich_text_character_t;
+
+typedef struct
+{
+        ssize_t offset;
+        ssize_t range;
+} ply_rich_text_span_t;
+
+#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
+ply_rich_text_t *ply_rich_text_new (void);
+void ply_rich_text_take_reference (ply_rich_text_t *rich_text);
+void ply_rich_text_drop_reference (ply_rich_text_t *rich_text);
+char *ply_rich_text_get_string (ply_rich_text_t      *rich_text,
+                                ply_rich_text_span_t *span);
+size_t ply_rich_text_get_length (ply_rich_text_t *rich_text);
+void ply_rich_text_set_character (ply_rich_text_t                *rich_text,
+                                  ply_rich_text_character_style_t style,
+                                  size_t                          index,
+                                  const char                     *bytes,
+                                  size_t                          length);
+void ply_rich_text_move_character (ply_rich_text_t *rich_text,
+                                   size_t           old_index,
+                                   size_t           new_index);
+void ply_rich_text_remove_character (ply_rich_text_t *rich_text,
+                                     size_t           character_index);
+
+void ply_rich_text_remove_characters (ply_rich_text_t *rich_text);
+ply_rich_text_character_t **ply_rich_text_get_characters (ply_rich_text_t *rich_text);
+void ply_rich_text_free (ply_rich_text_t *rich_text);
+
+ply_rich_text_character_t *ply_rich_text_character_new (void);
+void ply_rich_text_character_free (ply_rich_text_character_t *character);
+
+#endif //PLY_HIDE_FUNCTION_DECLARATIONS
+#endif //PLY_RICH_TEXT_H