summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/viewer-pangocairo.c358
1 files changed, 229 insertions, 129 deletions
diff --git a/utils/viewer-pangocairo.c b/utils/viewer-pangocairo.c
index ac3b49c3..77201666 100644
--- a/utils/viewer-pangocairo.c
+++ b/utils/viewer-pangocairo.c
@@ -148,20 +148,32 @@ pangocairo_view_destroy_surface (gpointer instance,
g_slice_free (CairoSurface, surface);
}
+enum {
+ ANNOTATE_GRAVITY_ROOF = 1,
+ ANNOTATE_BLOCK_PROGRESSION = 2,
+ ANNOTATE_BASELINES = 4,
+ ANNOTATE_LAYOUT_EXTENTS = 8,
+ ANNOTATE_LINE_EXTENTS = 16,
+ ANNOTATE_RUN_EXTENTS = 32,
+ ANNOTATE_CLUSTER_EXTENTS = 64,
+ ANNOTATE_CHAR_EXTENTS = 128,
+ ANNOTATE_LAST = 256,
+};
+
static void
render_callback (PangoLayout *layout,
- int x,
- int y,
- gpointer context,
- gpointer state)
+ int x,
+ int y,
+ gpointer context,
+ gpointer state)
{
cairo_t *cr = (cairo_t *) context;
- int annotate = (GPOINTER_TO_INT (state) + opt_annotate) % 4;
+ int annotate = (GPOINTER_TO_INT (state) + opt_annotate) % ANNOTATE_LAST;
cairo_save (cr);
cairo_translate (cr, x, y);
- if (annotate)
+ if (annotate != 0)
{
cairo_pattern_t *pattern;
PangoRectangle ink, logical;
@@ -170,127 +182,135 @@ render_callback (PangoLayout *layout,
pango_layout_get_extents (layout, &ink, &logical);
- if (annotate >= 2)
+ if (annotate & ANNOTATE_GRAVITY_ROOF)
+ {
+ /* draw resolved gravity "roof" in blue */
+ cairo_save (cr);
+ cairo_translate (cr,
+ (double)logical.x / PANGO_SCALE,
+ (double)logical.y / PANGO_SCALE);
+ cairo_scale (cr,
+ (double)logical.width / PANGO_SCALE * 0.5,
+ (double)logical.height / PANGO_SCALE * 0.5);
+ cairo_translate (cr, 1.0, 1.0);
+ cairo_rotate (cr,
+ pango_gravity_to_rotation (
+ pango_context_get_gravity (
+ pango_layout_get_context (layout))));
+ cairo_move_to (cr, -1.0, -1.0);
+ cairo_rel_line_to (cr, +1.0, -0.2); /* / */
+ cairo_rel_line_to (cr, +1.0, +0.2); /* \ */
+ cairo_close_path (cr); /* - */
+ pattern = cairo_pattern_create_linear (0, -1.0, 0, -1.2);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 0.0, 1.0, 0.0);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 0.0, 1.0, 0.15);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ /* once more, without close_path this time */
+ cairo_move_to (cr, -1.0, -1.0);
+ cairo_rel_line_to (cr, +1.0, -0.2); /* / */
+ cairo_rel_line_to (cr, +1.0, +0.2); /* \ */
+ /* silly line_width is not locked :(. get rid of scale. */
+ cairo_restore (cr);
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.7, 0.2);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+ }
+
+ if (annotate & ANNOTATE_BLOCK_PROGRESSION)
+ {
+ /* draw block progression arrow in green */
+ cairo_save (cr);
+ cairo_translate (cr,
+ (double)logical.x / PANGO_SCALE,
+ (double)logical.y / PANGO_SCALE);
+ cairo_scale (cr,
+ (double)logical.width / PANGO_SCALE * 0.5,
+ (double)logical.height / PANGO_SCALE * 0.5);
+ cairo_translate (cr, 1.0, 1.0);
+ cairo_move_to (cr, -0.4, -0.7);
+ cairo_rel_line_to (cr, +0.8, 0.0); /* -- */
+ cairo_rel_line_to (cr, 0.0, +0.9); /* | */
+ cairo_rel_line_to (cr, +0.4, 0.0); /* - */
+ cairo_rel_line_to (cr, -0.8, +0.5); /* / */
+ cairo_rel_line_to (cr, -0.8, -0.5); /* \ */
+ cairo_rel_line_to (cr, +0.4, 0.0); /* - */
+ cairo_close_path (cr); /* | */
+ pattern = cairo_pattern_create_linear (0, -0.7, 0, 0.7);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 1.0, 0.0, 0.0);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 1.0, 0.0, 0.15);
+ cairo_set_source (cr, pattern);
+ cairo_fill_preserve (cr);
+ /* silly line_width is not locked :(. get rid of scale. */
+ cairo_restore (cr);
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 0.0, 0.7, 0.0, 0.2);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+ }
+
+ if (annotate & ANNOTATE_BASELINES)
+ {
+ /* draw baselines with line direction arrow in orange */
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 1.0, 0.5, 0.0, 0.5);
+ iter = pango_layout_get_iter (layout);
+ do
+ {
+ PangoLayoutLine *line = pango_layout_iter_get_line (iter);
+ double width = (double)logical.width / PANGO_SCALE;
+
+ y = pango_layout_iter_get_baseline (iter);
+ cairo_save (cr);
+ cairo_translate (cr,
+ (double)logical.x / PANGO_SCALE + width * 0.5,
+ (double)y / PANGO_SCALE);
+ if (line->resolved_dir)
+ cairo_scale (cr, -1, 1);
+ cairo_move_to (cr, -width * .5, -lw*0.2);
+ cairo_rel_line_to (cr, +width * .9, -lw*0.3);
+ cairo_rel_line_to (cr, 0, -lw);
+ cairo_rel_line_to (cr, +width * .1, +lw*1.5);
+ cairo_rel_line_to (cr, -width * .1, +lw*1.5);
+ cairo_rel_line_to (cr, 0, -lw);
+ cairo_rel_line_to (cr, -width * .9, -lw*0.3);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+ cairo_restore (cr);
+ }
+ while (pango_layout_iter_next_line (iter));
+ pango_layout_iter_free (iter);
+ cairo_restore (cr);
+ }
+
+ if (annotate & ANNOTATE_LAYOUT_EXTENTS)
{
- /* draw resolved gravity "roof" in blue */
- cairo_save (cr);
- cairo_translate (cr,
- (double)logical.x / PANGO_SCALE,
- (double)logical.y / PANGO_SCALE);
- cairo_scale (cr,
- (double)logical.width / PANGO_SCALE * 0.5,
- (double)logical.height / PANGO_SCALE * 0.5);
- cairo_translate (cr, 1.0, 1.0);
- cairo_rotate (cr,
- pango_gravity_to_rotation (
- pango_context_get_gravity (
- pango_layout_get_context (layout))));
- cairo_move_to (cr, -1.0, -1.0);
- cairo_rel_line_to (cr, +1.0, -0.2); /* / */
- cairo_rel_line_to (cr, +1.0, +0.2); /* \ */
- cairo_close_path (cr); /* - */
- pattern = cairo_pattern_create_linear (0, -1.0, 0, -1.2);
- cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 0.0, 1.0, 0.0);
- cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 0.0, 1.0, 0.15);
- cairo_set_source (cr, pattern);
- cairo_fill (cr);
- /* once more, without close_path this time */
- cairo_move_to (cr, -1.0, -1.0);
- cairo_rel_line_to (cr, +1.0, -0.2); /* / */
- cairo_rel_line_to (cr, +1.0, +0.2); /* \ */
- /* silly line_width is not locked :(. get rid of scale. */
- cairo_restore (cr);
- cairo_save (cr);
- cairo_set_source_rgba (cr, 0.0, 0.0, 0.7, 0.2);
- cairo_stroke (cr);
- cairo_restore (cr);
-
-
- /* draw block progression arrow in green */
- cairo_save (cr);
- cairo_translate (cr,
- (double)logical.x / PANGO_SCALE,
- (double)logical.y / PANGO_SCALE);
- cairo_scale (cr,
- (double)logical.width / PANGO_SCALE * 0.5,
- (double)logical.height / PANGO_SCALE * 0.5);
- cairo_translate (cr, 1.0, 1.0);
- cairo_move_to (cr, -0.4, -0.7);
- cairo_rel_line_to (cr, +0.8, 0.0); /* -- */
- cairo_rel_line_to (cr, 0.0, +0.9); /* | */
- cairo_rel_line_to (cr, +0.4, 0.0); /* - */
- cairo_rel_line_to (cr, -0.8, +0.5); /* / */
- cairo_rel_line_to (cr, -0.8, -0.5); /* \ */
- cairo_rel_line_to (cr, +0.4, 0.0); /* - */
- cairo_close_path (cr); /* | */
- pattern = cairo_pattern_create_linear (0, -0.7, 0, 0.7);
- cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 1.0, 0.0, 0.0);
- cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 1.0, 0.0, 0.15);
- cairo_set_source (cr, pattern);
- cairo_fill_preserve (cr);
- /* silly line_width is not locked :(. get rid of scale. */
- cairo_restore (cr);
- cairo_save (cr);
- cairo_set_source_rgba (cr, 0.0, 0.7, 0.0, 0.2);
- cairo_stroke (cr);
- cairo_restore (cr);
- }
-
- /* draw baselines with line direction arrow in orange */
- cairo_save (cr);
- cairo_set_source_rgba (cr, 1.0, 0.5, 0.0, 0.5);
- iter = pango_layout_get_iter (layout);
- do
- {
- PangoLayoutLine *line = pango_layout_iter_get_line (iter);
- double width = (double)logical.width / PANGO_SCALE;
-
- y = pango_layout_iter_get_baseline (iter);
- cairo_save (cr);
- cairo_translate (cr,
- (double)logical.x / PANGO_SCALE + width * 0.5,
- (double)y / PANGO_SCALE);
- if (line->resolved_dir)
- cairo_scale (cr, -1, 1);
- cairo_move_to (cr, -width * .5, -lw*0.2);
- cairo_rel_line_to (cr, +width * .9, -lw*0.3);
- cairo_rel_line_to (cr, 0, -lw);
- cairo_rel_line_to (cr, +width * .1, +lw*1.5);
- cairo_rel_line_to (cr, -width * .1, +lw*1.5);
- cairo_rel_line_to (cr, 0, -lw);
- cairo_rel_line_to (cr, -width * .9, -lw*0.3);
- cairo_close_path (cr);
- cairo_fill (cr);
- cairo_restore (cr);
- }
- while (pango_layout_iter_next_line (iter));
- pango_layout_iter_free (iter);
- cairo_restore (cr);
-
- /* draw the logical rect in red */
- cairo_save (cr);
- cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, 0.5);
-
- cairo_rectangle (cr,
- (double)logical.x / PANGO_SCALE - lw / 2,
- (double)logical.y / PANGO_SCALE - lw / 2,
- (double)logical.width / PANGO_SCALE + lw,
- (double)logical.height / PANGO_SCALE + lw);
- cairo_stroke (cr);
- cairo_restore (cr);
-
- /* draw the ink rect in green */
- cairo_save (cr);
- cairo_set_source_rgba (cr, 0.0, 1.0, 0.0, 0.5);
- cairo_rectangle (cr,
- (double)ink.x / PANGO_SCALE - lw / 2,
- (double)ink.y / PANGO_SCALE - lw / 2,
- (double)ink.width / PANGO_SCALE + lw,
- (double)ink.height / PANGO_SCALE + lw);
- cairo_stroke (cr);
- cairo_restore (cr);
-
- if (opt_annotate >= 3)
+ /* draw the logical rect in red */
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, 0.5);
+
+ cairo_rectangle (cr,
+ (double)logical.x / PANGO_SCALE - lw / 2,
+ (double)logical.y / PANGO_SCALE - lw / 2,
+ (double)logical.width / PANGO_SCALE + lw,
+ (double)logical.height / PANGO_SCALE + lw);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ /* draw the ink rect in green */
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 0.0, 1.0, 0.0, 0.5);
+ cairo_rectangle (cr,
+ (double)ink.x / PANGO_SCALE - lw / 2,
+ (double)ink.y / PANGO_SCALE - lw / 2,
+ (double)ink.width / PANGO_SCALE + lw,
+ (double)ink.height / PANGO_SCALE + lw);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+ }
+
+ if (annotate & ANNOTATE_LINE_EXTENTS)
{
/* draw the logical rects for lines in red */
cairo_save (cr);
@@ -298,7 +318,7 @@ render_callback (PangoLayout *layout,
iter = pango_layout_get_iter (layout);
do
- {
+ {
PangoRectangle rect;
pango_layout_iter_get_line_extents (iter, NULL, &rect);
@@ -313,6 +333,78 @@ render_callback (PangoLayout *layout,
pango_layout_iter_free (iter);
cairo_restore (cr);
}
+
+ if (annotate & ANNOTATE_RUN_EXTENTS)
+ {
+ /* draw the logical rects 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
+ {
+ PangoRectangle rect;
+
+ pango_layout_iter_get_run_extents (iter, NULL, &rect);
+ cairo_rectangle (cr,
+ (double)rect.x / PANGO_SCALE - lw / 2,
+ (double)rect.y / PANGO_SCALE - lw / 2,
+ (double)rect.width / PANGO_SCALE + lw,
+ (double)rect.height / PANGO_SCALE + lw);
+ cairo_stroke (cr);
+ }
+ while (pango_layout_iter_next_run (iter));
+ pango_layout_iter_free (iter);
+ cairo_restore (cr);
+ }
+
+ if (annotate & ANNOTATE_CLUSTER_EXTENTS)
+ {
+ /* draw the logical rects for clusters in purple */
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 1.0, 0.0, 1.0, 0.5);
+
+ iter = pango_layout_get_iter (layout);
+ do
+ {
+ PangoRectangle rect;
+
+ pango_layout_iter_get_cluster_extents (iter, NULL, &rect);
+ cairo_rectangle (cr,
+ (double)rect.x / PANGO_SCALE - lw / 2,
+ (double)rect.y / PANGO_SCALE - lw / 2,
+ (double)rect.width / PANGO_SCALE + lw,
+ (double)rect.height / PANGO_SCALE + lw);
+ cairo_stroke (cr);
+ }
+ while (pango_layout_iter_next_cluster (iter));
+ pango_layout_iter_free (iter);
+ cairo_restore (cr);
+ }
+
+ if (annotate & ANNOTATE_CHAR_EXTENTS)
+ {
+ /* draw the logical rects for chars in orange */
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 1.0, 0.5, 0.0, 0.5);
+
+ iter = pango_layout_get_iter (layout);
+ do
+ {
+ PangoRectangle rect;
+
+ pango_layout_iter_get_cluster_extents (iter, NULL, &rect);
+ cairo_rectangle (cr,
+ (double)rect.x / PANGO_SCALE - lw / 2,
+ (double)rect.y / PANGO_SCALE - lw / 2,
+ (double)rect.width / PANGO_SCALE + lw,
+ (double)rect.height / PANGO_SCALE + lw);
+ cairo_stroke (cr);
+ }
+ while (pango_layout_iter_next_cluster (iter));
+ pango_layout_iter_free (iter);
+ cairo_restore (cr);
+ }
}
cairo_move_to (cr, 0, 0);
@@ -458,8 +550,16 @@ pangocairo_view_get_option_group (const PangoViewer *klass G_GNUC_UNUSED)
{
GOptionEntry entries[] =
{
- {"annotate", 0, 0, G_OPTION_ARG_INT, &opt_annotate,
- "Annotate the output", "1, 2 or 3"},
+ {"annotate", 0, 0, G_OPTION_ARG_INT, &opt_annotate,
+ "Annotate the output\n"
+ "\t\t\t\t\t\t\t 1 - gravity\n"
+ "\t\t\t\t\t\t\t 2 - block progression\n"
+ "\t\t\t\t\t\t\t 4 - baselines\n"
+ "\t\t\t\t\t\t\t 8 - layout extents\n"
+ "\t\t\t\t\t\t\t 16 - line extents\n"
+ "\t\t\t\t\t\t\t 32 - run extents\n"
+ "\t\t\t\t\t\t\t 64 - cluster extents\n"
+ "\t\t\t\t\t\t\t 128 - char extents", "FLAGS"},
{NULL}
};
GOptionGroup *group;