[gtk/textview-baseline-shift] wip: Add superscript and subscript to GtkTextTag




commit e91c1861efa9cb680d092f50e9f32045607bfcae
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Sep 1 13:11:51 2021 -0400

    wip: Add superscript and subscript to GtkTextTag
    
    And update the markup demo to just use <sup>.
    since it works now.
    
    FIXME: this does not work since it does not accumulate.

 demos/gtk-demo/fontify.c  |  7 ++++---
 demos/gtk-demo/markup.txt |  2 +-
 gtk/gtktextattributes.c   |  6 +++++-
 gtk/gtktextattributes.h   |  3 ++-
 gtk/gtktextbuffer.c       |  7 ++++---
 gtk/gtktextlayout.c       | 15 +++++++++++++++
 gtk/gtktexttag.c          | 41 +++++++++++++++++++++++++++++++++++++++++
 gtk/gtktexttagprivate.h   |  1 +
 8 files changed, 73 insertions(+), 9 deletions(-)
---
diff --git a/demos/gtk-demo/fontify.c b/demos/gtk-demo/fontify.c
index cdbdf654d3..6f28e4c5b0 100644
--- a/demos/gtk-demo/fontify.c
+++ b/demos/gtk-demo/fontify.c
@@ -287,10 +287,11 @@ insert_tags_for_attributes (GtkTextBuffer     *buffer,
           INT_ATTR (baseline_shift);
           break;
 
+        /* Ignore font scale, since we treat baseline-shift as indicating
+         * both. And in practice, they will basically always occur together
+         * (from a <sup> or <sub>)
+         */
         case PANGO_ATTR_FONT_SCALE:
-          INT_ATTR (font_scale);
-          break;
-
         case PANGO_ATTR_SHAPE:
         case PANGO_ATTR_ABSOLUTE_SIZE:
         case PANGO_ATTR_GRAVITY:
diff --git a/demos/gtk-demo/markup.txt b/demos/gtk-demo/markup.txt
index 96399b9d81..5a6f31eb3d 100644
--- a/demos/gtk-demo/markup.txt
+++ b/demos/gtk-demo/markup.txt
@@ -11,7 +11,7 @@ Colorful <span underline="low" underline-color="blue"><span underline="double" u
 
 Colorful <span strikethrough="true" strikethrough-color="magenta">strikethroughs</span> and <span 
overline="single" overline_color="green">overlines</span>
 
-Superscripts and subscripts: 𝜀<span rise="-6000" size="x-small" font_desc="italic">0</span> = 𝜔<span 
rise="8000" size="smaller">𝜔<span rise="14000" size="smaller">𝜔<span rise="20000">.<span rise="23000">.<span 
rise="26000">.</span></span></span></span></span>
+Superscripts and subscripts: <span font="italic">ε<sub><span size='smaller'>0</span></sub> = 
ω<sup>ω<sup>ω<sup>.<sup>.<sup>.</sup></sup></sup></sup></sup></span>
 
 <span letter_spacing="3000">Letterspacing</span>
 
diff --git a/gtk/gtktextattributes.c b/gtk/gtktextattributes.c
index 856b4f3310..16e18b3099 100644
--- a/gtk/gtktextattributes.c
+++ b/gtk/gtktextattributes.c
@@ -447,6 +447,9 @@ _gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest,
 
       if (tag->priv->sentence_set)
         dest->sentence = vals->sentence;
+
+      if (tag->priv->baseline_shift_set)
+        dest->baseline_shift = vals->baseline_shift;
     }
 
   dest->left_margin += left_margin_accumulative;
@@ -477,7 +480,8 @@ _gtk_text_tag_affects_size (GtkTextTag *tag)
     priv->invisible_set ||
     priv->font_features_set ||
     priv->letter_spacing_set ||
-    priv->text_transform_set;
+    priv->text_transform_set ||
+    priv->baseline_shift_set;
 }
 
 gboolean
diff --git a/gtk/gtktextattributes.h b/gtk/gtktextattributes.h
index 3aa01c8690..ba84bb1d56 100644
--- a/gtk/gtktextattributes.h
+++ b/gtk/gtktextattributes.h
@@ -108,7 +108,7 @@ struct _GtkTextAppearance
  * @wrap_mode: `GtkWrapMode` for text.
  * @language: `PangoLanguage` for text.
  * @invisible: Hide the text.
- * @bg_full_height: Background is fit to full line height rather than
+ * @bg_full_height: Background is fit to full line height rather than:
  *    baseline +/- ascent/descent (font height).
  * @editable: Can edit this text.
  * @no_fallback: Whether to disable font fallback.
@@ -162,6 +162,7 @@ struct _GtkTextAttributes
   guint text_transform : 3; /* PangoTextTransform */
   guint word : 1;
   guint sentence : 1;
+  guint baseline_shift : 2; /* PangoFontScale / PangoBaselineShift */
 };
 
 GtkTextAttributes* gtk_text_attributes_new         (void);
diff --git a/gtk/gtktextbuffer.c b/gtk/gtktextbuffer.c
index 4ec5fe6077..055b8505ca 100644
--- a/gtk/gtktextbuffer.c
+++ b/gtk/gtktextbuffer.c
@@ -4740,10 +4740,11 @@ insert_tags_for_attributes (GtkTextBuffer     *buffer,
           INT_ATTR (baseline_shift);
           break;
 
+        /* Ignore font scale, since we treat baseline-shift as indicating
+         * both. And in practice, they will basically always occur together
+         * (from a <sup> or <sub>)
+         */
         case PANGO_ATTR_FONT_SCALE:
-          INT_ATTR (font_scale);
-          break;
-
         case PANGO_ATTR_SHAPE:
         case PANGO_ATTR_ABSOLUTE_SIZE:
         case PANGO_ATTR_GRAVITY:
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index 1873b03d74..bccce5f767 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -1710,6 +1710,21 @@ add_text_attrs (GtkTextLayout      *layout,
       attr->start_index = start;
       attr->end_index = start + byte_count;
 
+      pango_attr_list_insert (attrs, attr);
+    }
+
+  if (style->baseline_shift)
+    {
+      attr = pango_attr_baseline_shift_new (style->baseline_shift);
+      attr->start_index = start;
+      attr->end_index = start + byte_count;
+
+      pango_attr_list_insert (attrs, attr);
+
+      attr = pango_attr_font_scale_new (style->baseline_shift);
+      attr->start_index = start;
+      attr->end_index = start + byte_count;
+
       pango_attr_list_insert (attrs, attr);
     }
 }
diff --git a/gtk/gtktexttag.c b/gtk/gtktexttag.c
index 8b252fb725..1b7dcb7109 100644
--- a/gtk/gtktexttag.c
+++ b/gtk/gtktexttag.c
@@ -137,6 +137,7 @@ enum {
   PROP_TEXT_TRANSFORM,
   PROP_WORD,
   PROP_SENTENCE,
+  PROP_BASELINE_SHIFT,
 
   /* Behavior args */
   PROP_ACCUMULATIVE_MARGIN,
@@ -182,6 +183,7 @@ enum {
   PROP_TEXT_TRANSFORM_SET,
   PROP_WORD_SET,
   PROP_SENTENCE_SET,
+  PROP_BASELINE_SHIFT_SET,
 
   LAST_ARG
 };
@@ -912,6 +914,23 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
                                                          FALSE,
                                                          GTK_PARAM_READWRITE));
 
+  /**
+   * GtkTextTag:baseline-shift:
+   *
+   * Whether the tag contents should be shifted to superscript or subscript position,
+   * relative to the previous content. This also changes the font to a smaller size.
+   *
+   * Since: 4.6
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_BASELINE_SHIFT,
+                                   g_param_spec_enum ("baseline-shift",
+                                                      P_("Baseline Shift"),
+                                                      P_("Whether to shift the baseline."),
+                                                      PANGO_TYPE_BASELINE_SHIFT,
+                                                      PANGO_BASELINE_SHIFT_NONE,
+                                                      GTK_PARAM_READWRITE));
+
   /**
    * GtkTextTag:accumulative-margin:
    *
@@ -1102,6 +1121,10 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
   ADD_SET_PROP ("sentence-set", PROP_WORD_SET,
                 P_("Sentence set"),
                 P_("Whether this tag represents a single sentence"));
+
+  ADD_SET_PROP ("baseline-shift-set", PROP_BASELINE_SHIFT_SET,
+                P_("Baseline Shift set"),
+                P_("Whether this tag represents a baseline shift"));
 }
 
 static void
@@ -1869,6 +1892,12 @@ gtk_text_tag_set_property (GObject      *object,
       g_object_notify (object, "sentence-set");
       break;
 
+    case PROP_BASELINE_SHIFT:
+      priv->baseline_shift_set = TRUE;
+      priv->values->baseline_shift = g_value_get_enum (value);
+      g_object_notify (object, "baseline-shift-set");
+      break;
+
     case PROP_ACCUMULATIVE_MARGIN:
       priv->accumulative_margin = g_value_get_boolean (value);
       g_object_notify (object, "accumulative-margin");
@@ -2045,6 +2074,10 @@ gtk_text_tag_set_property (GObject      *object,
       priv->sentence_set = g_value_get_boolean (value);
       break;
 
+    case PROP_BASELINE_SHIFT_SET:
+      priv->baseline_shift_set = g_value_get_boolean (value);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2269,6 +2302,10 @@ gtk_text_tag_get_property (GObject      *object,
       g_value_set_boolean (value, priv->values->sentence);
       break;
 
+    case PROP_BASELINE_SHIFT:
+      g_value_set_boolean (value, priv->values->baseline_shift);
+      break;
+
     case PROP_ACCUMULATIVE_MARGIN:
       g_value_set_boolean (value, priv->accumulative_margin);
       break;
@@ -2423,6 +2460,10 @@ gtk_text_tag_get_property (GObject      *object,
       g_value_set_boolean (value, priv->sentence_set);
       break;
 
+    case PROP_BASELINE_SHIFT_SET:
+      g_value_set_boolean (value, priv->baseline_shift_set);
+      break;
+
     case PROP_BACKGROUND:
     case PROP_FOREGROUND:
     case PROP_PARAGRAPH_BACKGROUND:
diff --git a/gtk/gtktexttagprivate.h b/gtk/gtktexttagprivate.h
index 57ce42c2c6..5e9f712466 100644
--- a/gtk/gtktexttagprivate.h
+++ b/gtk/gtktexttagprivate.h
@@ -90,6 +90,7 @@ struct _GtkTextTagPrivate
   guint text_transform_set : 1;
   guint word_set : 1;
   guint sentence_set : 1;
+  guint baseline_shift_set : 1;
 
   /* Whether these margins accumulate or override */
   guint accumulative_margin : 1;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]