[librsvg: 6/37] rsvg-view: Allow quitting the program with Ctrl-Q or Ctrl-W



commit b550fdf992420ea43d1db8127afbdb8ee822109e
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Oct 30 11:57:17 2018 -0600

    rsvg-view: Allow quitting the program with Ctrl-Q or Ctrl-W

 rsvg-view.c                | 24 +++++++++++++
 rsvg_internals/src/text.rs | 87 +++++++++++++++++++++++++++++++++++-----------
 2 files changed, 91 insertions(+), 20 deletions(-)
---
diff --git a/rsvg-view.c b/rsvg-view.c
index 10f0e094..0de6a80d 100644
--- a/rsvg-view.c
+++ b/rsvg-view.c
@@ -535,6 +535,16 @@ populate_window (GtkWidget * win,
     gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 0);
 }
 
+static gboolean
+quit_accel_cb (GtkAccelGroup  *accel_group,
+               GObject        *acceleratable,
+               guint           keyval,
+               GdkModifierType modifier)
+{
+    gtk_main_quit ();
+    return TRUE;
+}
+
 static void
 view_surface (ViewerCbInfo * info, 
               cairo_surface_t *surface /* adopted */,
@@ -552,6 +562,20 @@ view_surface (ViewerCbInfo * info,
     g_signal_connect (win, "destroy", G_CALLBACK (quit_cb), NULL);
     g_signal_connect (win, "delete_event", G_CALLBACK (quit_cb), NULL);
 
+    /* Ctrl-Q */
+    gtk_accel_group_connect (info->accel_group,
+                             GDK_KEY_Q,
+                             GDK_CONTROL_MASK,
+                             0,
+                             g_cclosure_new ((GCallback) quit_accel_cb, NULL, NULL));
+
+    /* Ctrl-W */
+    gtk_accel_group_connect (info->accel_group,
+                             GDK_KEY_W,
+                             GDK_CONTROL_MASK,
+                             0,
+                             g_cclosure_new ((GCallback) quit_accel_cb, NULL, NULL));
+
     if (bg_color && strcmp (bg_color, "none") != 0) {
         GdkRGBA rgba;
 
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index 15c217d7..d67ac83f 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -24,6 +24,51 @@ use state::{
     XmlSpace,
 };
 
+/// An absolutely-positioned array of `Span`s
+///
+/// SVG defines a "[text chunk]" to occur when a text-related element
+/// has an absolute position adjustment, that is, `x` or `y`
+/// attributes.
+///
+/// A `<text>` element always starts with an absolute position from
+/// such attributes, or (0, 0) if they are not specified.
+///
+/// Subsequent children of the `<text>` element will create new chunks
+/// whenever they have `x` or `y` attributes.
+///
+/// [text chunk]: https://www.w3.org/TR/SVG11/text.html#TextLayoutIntroduction
+struct Chunk {
+    specified_x: Option<f64>,
+    specified_y: Option<f64>,
+    final_x: f64,
+    final_y: f64,
+    spans: Vec<Span>,
+}
+
+struct Span {
+    values: ComputedValues,
+    text: String,
+    layout: pango::Layout,
+    layout_size: (f64, f64),
+}
+
+impl Span {
+    fn new(text: &str, values: ComputedValues, draw_ctx: &DrawingCtx) -> Span {
+        let layout = create_pango_layout(draw_ctx, &values, text);
+        let (w, h) = layout.get_size();
+
+        let w = f64::from(w) / f64::from(pango::SCALE);
+        let h = f64::from(h) / f64::from(pango::SCALE);
+
+        Span {
+            values,
+            text: text.to_string(),
+            layout,
+            layout_size: (w, h),
+        }
+    }
+}
+
 /// In SVG text elements, we use `NodeChars` to store character data.  For example,
 /// an element like `<text>Foo Bar</text>` will be a `NodeText` with a single child,
 /// and the child will be a `NodeChars` with "Foo Bar" for its contents.
@@ -86,23 +131,16 @@ impl NodeChars {
         }
     }
 
-    fn create_layout(
-        &self,
-        node: &RsvgNode,
-        values: &ComputedValues,
-        draw_ctx: &DrawingCtx,
-    ) -> pango::Layout {
+    fn measure(&self, node: &RsvgNode, values: &ComputedValues, draw_ctx: &DrawingCtx) -> f64 {
         self.ensure_normalized_string(node, values);
-        let norm = self.space_normalized.borrow();
-        let s = norm.as_ref().unwrap();
-        create_pango_layout(draw_ctx, values, &s)
-    }
 
-    fn measure(&self, node: &RsvgNode, values: &ComputedValues, draw_ctx: &DrawingCtx) -> f64 {
-        let layout = self.create_layout(node, values, draw_ctx);
-        let (width, _) = layout.get_size();
+        let span = Span::new(
+            self.space_normalized.borrow().as_ref().unwrap(),
+            values.clone(),
+            draw_ctx,
+        );
 
-        f64::from(width) / f64::from(pango::SCALE)
+        span.layout_size.0
     }
 
     fn render(
@@ -114,8 +152,17 @@ impl NodeChars {
         y: f64,
         clipping: bool,
     ) -> Result<(f64, f64), RenderingError> {
-        let layout = self.create_layout(node, values, draw_ctx);
-        let (width, _) = layout.get_size();
+        self.ensure_normalized_string(node, values);
+
+        let span = Span::new(
+            self.space_normalized.borrow().as_ref().unwrap(),
+            values.clone(),
+            draw_ctx,
+        );
+
+        let layout = &span.layout;
+        let width = span.layout_size.0;
+        let values = &span.values;
 
         let baseline = f64::from(layout.get_baseline()) / f64::from(pango::SCALE);
         let offset = baseline
@@ -125,11 +172,11 @@ impl NodeChars {
                 .normalize(values, &draw_ctx.get_view_params());
 
         if values.text_gravity_is_vertical() {
-            draw_ctx.draw_pango_layout(&layout, values, x + offset, y, clipping)?;
-            Ok((x, y + f64::from(width) / f64::from(pango::SCALE)))
+            draw_ctx.draw_pango_layout(layout, values, x + offset, y, clipping)?;
+            Ok((x, y + width))
         } else {
-            draw_ctx.draw_pango_layout(&layout, values, x, y - offset, clipping)?;
-            Ok((x + f64::from(width) / f64::from(pango::SCALE), y))
+            draw_ctx.draw_pango_layout(layout, values, x, y - offset, clipping)?;
+            Ok((x + width, y))
         }
     }
 }


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