[pango/baseline-handling: 7/8] pango-view: Show more baselines




commit 974b731323da94a8e586f76f6874525fb7f14969
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Feb 14 18:40:37 2022 -0600

    pango-view: Show more baselines
    
    With --annotation=run-baselines, show the
    baselines from the BASE table for each run,
    if harfbuzz knows them. We draw a solid
    line for baselines that come from the BASE
    table, and a dashed line for baselines that
    are synthesized.

 utils/viewer-pangocairo.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 94 insertions(+), 1 deletion(-)
---
diff --git a/utils/viewer-pangocairo.c b/utils/viewer-pangocairo.c
index 8fe9db59..d2acc79c 100644
--- a/utils/viewer-pangocairo.c
+++ b/utils/viewer-pangocairo.c
@@ -26,6 +26,9 @@
 
 #include <pango/pangocairo.h>
 
+#include <hb-ot.h>
+#include <hb-glib.h>
+
 static int opt_annotate = 0;
 
 typedef struct
@@ -158,7 +161,8 @@ enum {
   ANNOTATE_GLYPH_EXTENTS     =  256,
   ANNOTATE_CARET_POSITIONS   =  512,
   ANNOTATE_CARET_SLOPE       = 1024,
-  ANNOTATE_LAST              = 2048,
+  ANNOTATE_RUN_BASELINES     = 2048,
+  ANNOTATE_LAST              = 4096,
 };
 
 static struct {
@@ -169,6 +173,7 @@ static struct {
   { ANNOTATE_GRAVITY_ROOF,      "gravity-roof",      "gravity" },
   { ANNOTATE_BLOCK_PROGRESSION, "block-progression", "progression" },
   { ANNOTATE_BASELINES,         "baselines",         "baselines" },
+  { ANNOTATE_RUN_BASELINES,     "run-baselines",     "run-baselines" },
   { ANNOTATE_LAYOUT_EXTENTS,    "layout-extents",    "layout" },
   { ANNOTATE_LINE_EXTENTS,      "line-extents",      "line" },
   { ANNOTATE_RUN_EXTENTS,       "run-extents",       "run" },
@@ -308,6 +313,94 @@ render_callback (PangoLayout *layout,
           cairo_restore (cr);
         }
 
+      if (annotate & ANNOTATE_RUN_BASELINES)
+        {
+          /* draw baselines for runs in blue */
+          cairo_save (cr);
+          cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, 0.5);
+
+          iter = pango_layout_get_iter (layout);
+          do
+            {
+              PangoLayoutRun *run;
+              PangoRectangle rect;
+              hb_font_t *hb_font;
+              hb_ot_layout_baseline_tag_t baselines[] = {
+                HB_OT_LAYOUT_BASELINE_TAG_ROMAN,
+                HB_OT_LAYOUT_BASELINE_TAG_HANGING,
+                HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT,
+                HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT,
+                HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT,
+                HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT,
+                HB_OT_LAYOUT_BASELINE_TAG_MATH
+              };
+              hb_direction_t dir;
+              hb_tag_t script, lang;
+              hb_position_t coord;
+              gboolean font_baseline;
+
+              run = pango_layout_iter_get_run (iter);
+              if (!run)
+                continue;
+
+              y = pango_layout_iter_get_run_baseline (iter);
+              pango_layout_iter_get_run_extents (iter, NULL, &rect);
+
+              hb_font = pango_font_get_hb_font (run->item->analysis.font);
+              dir = HB_DIRECTION_LTR;
+              script = hb_glib_script_to_script (run->item->analysis.script);
+              lang = HB_TAG_NONE;
+
+              for (int i = 0; i < G_N_ELEMENTS (baselines); i++)
+                {
+                  char buf[5] = { 0, };
+                  hb_tag_to_string (baselines[i], buf);
+                  if (hb_ot_layout_get_baseline (hb_font,
+                                                 baselines[i],
+                                                 dir,
+                                                 script,
+                                                 lang,
+                                                 &coord))
+                    font_baseline = TRUE;
+                  else if (hb_ot_layout_get_baseline_with_fallback (hb_font,
+                                                                    baselines[i],
+                                                                    dir,
+                                                                    script,
+                                                                    lang,
+                                                                    &coord))
+                    font_baseline = FALSE;
+                  else
+                    continue;
+
+                  cairo_save (cr);
+                  if (font_baseline)
+                    {
+                      cairo_set_dash (cr, NULL, 0, 0);
+                    }
+                  else
+                    {
+                      double dashes[] = { 4 * lw, 4 * lw };
+                      cairo_set_dash (cr, dashes, 2, 0);
+                      cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+                    }
+                  cairo_move_to (cr,
+                                 (double)rect.x / PANGO_SCALE,
+                                 (double)(y - coord) / PANGO_SCALE);
+                  cairo_rel_line_to (cr, (double)rect.width / PANGO_SCALE, 0);
+                  cairo_stroke (cr);
+                  cairo_set_source_rgb (cr, 0, 0, 0);
+                  cairo_move_to (cr,
+                                 (double)rect.x / PANGO_SCALE - 5,
+                                 (double)(y - coord) / PANGO_SCALE - 5);
+                  cairo_show_text (cr, buf);
+                  cairo_restore (cr);
+                }
+            }
+          while (pango_layout_iter_next_run (iter));
+          pango_layout_iter_free (iter);
+          cairo_restore (cr);
+        }
+
       if (annotate & ANNOTATE_LAYOUT_EXTENTS)
         {
           /* draw the logical rect in red */


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