[librsvg: 3/6] drawing-ctx: move draw_pango_layout to the drawing ctx



commit 6e6ff754aeaf72a0ccc4320e9b2b6e21db6735b1
Author: Paolo Borelli <pborelli gnome org>
Date:   Mon Jun 25 22:57:18 2018 +0200

    drawing-ctx: move draw_pango_layout to the drawing ctx

 rsvg_internals/src/draw.rs        | 161 +------------------------------------
 rsvg_internals/src/drawing_ctx.rs | 163 +++++++++++++++++++++++++++++++++++++-
 rsvg_internals/src/text.rs        |   5 +-
 3 files changed, 164 insertions(+), 165 deletions(-)
---
diff --git a/rsvg_internals/src/draw.rs b/rsvg_internals/src/draw.rs
index b91d83d1..07a3f03b 100644
--- a/rsvg_internals/src/draw.rs
+++ b/rsvg_internals/src/draw.rs
@@ -1,14 +1,9 @@
 use cairo;
 use cairo_sys;
 use glib::translate::*;
-use pango::{self, ContextExt, LayoutExt};
-use pango_sys;
-use pangocairo;
 
 use bbox::BoundingBox;
 use drawing_ctx::DrawingCtx;
-use float_eq_cairo::ApproxEqCairo;
-use length::Dasharray;
 use paint_server;
 use paint_server::PaintServer;
 use path_builder::PathBuilder;
@@ -18,7 +13,6 @@ use state::{
     ComputedValues,
     FillRule,
     ShapeRendering,
-    StrokeDasharray,
     StrokeLinecap,
     StrokeLinejoin,
     TextRendering,
@@ -47,7 +41,7 @@ pub fn draw_path_builder(
 fn stroke_and_fill(cr: &cairo::Context, draw_ctx: &mut DrawingCtx, values: &ComputedValues) {
     cr.set_antialias(cairo::Antialias::from(values.shape_rendering));
 
-    setup_cr_for_stroke(cr, draw_ctx, values);
+    draw_ctx.setup_cr_for_stroke(cr, values);
 
     // Update the bbox in the rendering context.  Below, we actually set the
     // fill/stroke patterns on the cairo_t.  That process requires the
@@ -180,29 +174,6 @@ impl From<TextRendering> for cairo::Antialias {
     }
 }
 
-fn setup_cr_for_stroke(cr: &cairo::Context, draw_ctx: &DrawingCtx, values: &ComputedValues) {
-    cr.set_line_width(values.stroke_width.0.normalize(values, draw_ctx));
-    cr.set_miter_limit(values.stroke_miterlimit.0);
-    cr.set_line_cap(cairo::LineCap::from(values.stroke_line_cap));
-    cr.set_line_join(cairo::LineJoin::from(values.stroke_line_join));
-
-    if let StrokeDasharray(Dasharray::Array(ref dashes)) = values.stroke_dasharray {
-        let normalized_dashes: Vec<f64> = dashes
-            .iter()
-            .map(|l| l.normalize(values, draw_ctx))
-            .collect();
-
-        let total_length = normalized_dashes.iter().fold(0.0, |acc, &len| acc + len);
-
-        if total_length > 0.0 {
-            let offset = values.stroke_dashoffset.0.normalize(values, draw_ctx);
-            cr.set_dash(&normalized_dashes, offset);
-        } else {
-            cr.set_dash(&[], 0.0);
-        }
-    }
-}
-
 // remove this binding once cairo-rs has Context::path_extents()
 fn path_extents(cr: &cairo::Context) -> (f64, f64, f64, f64) {
     let mut x1: f64 = 0.0;
@@ -256,133 +227,3 @@ fn compute_stroke_and_fill_box(cr: &cairo::Context, values: &ComputedValues) ->
 
     bbox
 }
-
-pub fn draw_pango_layout(
-    draw_ctx: &mut DrawingCtx,
-    values: &ComputedValues,
-    layout: &pango::Layout,
-    x: f64,
-    y: f64,
-    clipping: bool,
-) {
-    let gravity = layout.get_context().unwrap().get_gravity();
-
-    let (ink, _) = layout.get_extents();
-
-    if ink.width == 0 || ink.height == 0 {
-        return;
-    }
-
-    let cr = draw_ctx.get_cairo_context();
-    cr.save();
-
-    draw_ctx.set_affine_on_cr(&cr);
-
-    let affine = cr.get_matrix();
-
-    let bbox = compute_text_bbox(&ink, x, y, &affine, gravity);
-
-    if !clipping {
-        draw_ctx.insert_bbox(&bbox);
-    }
-
-    cr.set_antialias(cairo::Antialias::from(values.text_rendering));
-
-    setup_cr_for_stroke(&cr, draw_ctx, values);
-
-    let rotation = unsafe { pango_sys::pango_gravity_to_rotation(gravity.to_glib()) };
-
-    cr.move_to(x, y);
-    if !rotation.approx_eq_cairo(&0.0) {
-        cr.rotate(-rotation);
-    }
-
-    let current_color = &values.color.0;
-
-    let fill_opacity = &values.fill_opacity.0;
-
-    if !clipping {
-        if paint_server::set_source_paint_server(
-            draw_ctx,
-            &values.fill.0,
-            fill_opacity,
-            &bbox,
-            current_color,
-        ) {
-            pangocairo::functions::update_layout(&cr, layout);
-            pangocairo::functions::show_layout(&cr, layout);
-        }
-    }
-
-    let stroke_opacity = &values.stroke_opacity.0;
-
-    let mut need_layout_path = clipping;
-
-    if !clipping {
-        if paint_server::set_source_paint_server(
-            draw_ctx,
-            &values.stroke.0,
-            stroke_opacity,
-            &bbox,
-            &current_color,
-        ) {
-            need_layout_path = true;
-        }
-    }
-
-    if need_layout_path {
-        pangocairo::functions::update_layout(&cr, layout);
-        pangocairo::functions::layout_path(&cr, layout);
-
-        if !clipping {
-            let ib = BoundingBox::new(&affine).with_ink_extents(cr.stroke_extents());
-            cr.stroke();
-            draw_ctx.insert_bbox(&ib);
-        }
-    }
-
-    cr.restore();
-}
-
-// FIXME: should the pango crate provide this like PANGO_GRAVITY_IS_VERTICAL() ?
-fn gravity_is_vertical(gravity: pango::Gravity) -> bool {
-    match gravity {
-        pango::Gravity::East | pango::Gravity::West => true,
-        _ => false,
-    }
-}
-
-fn compute_text_bbox(
-    ink: &pango::Rectangle,
-    x: f64,
-    y: f64,
-    affine: &cairo::Matrix,
-    gravity: pango::Gravity,
-) -> BoundingBox {
-    let pango_scale = f64::from(pango::SCALE);
-
-    let mut bbox = BoundingBox::new(affine);
-
-    let ink_x = f64::from(ink.x);
-    let ink_y = f64::from(ink.y);
-    let ink_width = f64::from(ink.width);
-    let ink_height = f64::from(ink.height);
-
-    if gravity_is_vertical(gravity) {
-        bbox.rect = Some(cairo::Rectangle {
-            x: x + (ink_x - ink_height) / pango_scale,
-            y: y + ink_y / pango_scale,
-            width: ink_height / pango_scale,
-            height: ink_width / pango_scale,
-        });
-    } else {
-        bbox.rect = Some(cairo::Rectangle {
-            x: x + ink_x / pango_scale,
-            y: y + ink_y / pango_scale,
-            width: ink_width / pango_scale,
-            height: ink_height / pango_scale,
-        });
-    }
-
-    bbox
-}
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index f800601c..9c28819e 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -4,8 +4,9 @@ use cairo_sys;
 use glib::translate::*;
 use glib_sys;
 use libc;
-use pango::{self, FontMapExt};
+use pango::{self, ContextExt, FontMapExt, LayoutExt};
 use pango_cairo_sys;
+use pango_sys;
 use pangocairo;
 use std::cell::RefCell;
 
@@ -14,10 +15,18 @@ use clip_path::{ClipPathUnits, NodeClipPath};
 use coord_units::CoordUnits;
 use defs::{self, RsvgDefs};
 use filters::filter_render;
+use float_eq_cairo::ApproxEqCairo;
+use length::Dasharray;
 use mask::NodeMask;
 use node::{rc_node_ptr_eq, CascadedValues, NodeType, RsvgNode};
+use paint_server;
 use rect::RectangleExt;
-use state::{CompOp, ComputedValues, EnableBackground};
+use state::{
+    CompOp,
+    ComputedValues,
+    EnableBackground,
+    StrokeDasharray,
+};
 use unitinterval::UnitInterval;
 use viewbox::ViewBox;
 
@@ -407,6 +416,113 @@ impl<'a> DrawingCtx {
         context
     }
 
+    pub fn draw_pango_layout(
+        &mut self,
+        layout: &pango::Layout,
+        values: &ComputedValues,
+        x: f64,
+        y: f64,
+        clipping: bool,
+    ) {
+        let (ink, _) = layout.get_extents();
+
+        if ink.width == 0 || ink.height == 0 {
+            return;
+        }
+
+        let cr = self.get_cairo_context();
+        cr.save();
+
+        self.set_affine_on_cr(&cr);
+
+        let affine = cr.get_matrix();
+
+        let gravity = layout.get_context().unwrap().get_gravity();
+        let bbox = compute_text_bbox(&ink, x, y, &affine, gravity);
+
+        if !clipping {
+            self.insert_bbox(&bbox);
+        }
+
+        cr.set_antialias(cairo::Antialias::from(values.text_rendering));
+
+        self.setup_cr_for_stroke(&cr, values);
+
+        let rotation = unsafe { pango_sys::pango_gravity_to_rotation(gravity.to_glib()) };
+
+        cr.move_to(x, y);
+        if !rotation.approx_eq_cairo(&0.0) {
+            cr.rotate(-rotation);
+        }
+
+        let current_color = &values.color.0;
+
+        let fill_opacity = &values.fill_opacity.0;
+
+        if !clipping {
+            if paint_server::set_source_paint_server(
+                self,
+                &values.fill.0,
+                fill_opacity,
+                &bbox,
+                current_color,
+            ) {
+                pangocairo::functions::update_layout(&cr, layout);
+                pangocairo::functions::show_layout(&cr, layout);
+            }
+        }
+
+        let stroke_opacity = &values.stroke_opacity.0;
+
+        let mut need_layout_path = clipping;
+
+        if !clipping {
+            if paint_server::set_source_paint_server(
+                self,
+                &values.stroke.0,
+                stroke_opacity,
+                &bbox,
+                &current_color,
+            ) {
+                need_layout_path = true;
+            }
+        }
+
+        if need_layout_path {
+            pangocairo::functions::update_layout(&cr, layout);
+            pangocairo::functions::layout_path(&cr, layout);
+
+            if !clipping {
+                let ib = BoundingBox::new(&affine).with_ink_extents(cr.stroke_extents());
+                cr.stroke();
+                self.insert_bbox(&ib);
+            }
+        }
+
+        cr.restore();
+    }
+
+    pub fn setup_cr_for_stroke(&self, cr: &cairo::Context, values: &ComputedValues) {
+        cr.set_line_width(values.stroke_width.0.normalize(values, self));
+        cr.set_miter_limit(values.stroke_miterlimit.0);
+        cr.set_line_cap(cairo::LineCap::from(values.stroke_line_cap));
+        cr.set_line_join(cairo::LineJoin::from(values.stroke_line_join));
+
+        if let StrokeDasharray(Dasharray::Array(ref dashes)) = values.stroke_dasharray {
+            let normalized_dashes: Vec<f64> =
+                dashes.iter().map(|l| l.normalize(values, self)).collect();
+
+            let total_length = normalized_dashes.iter().fold(0.0, |acc, &len| acc + len);
+
+            if total_length > 0.0 {
+                let offset = values.stroke_dashoffset.0.normalize(values, self);
+                cr.set_dash(&normalized_dashes, offset);
+            } else {
+                cr.set_dash(&[], 0.0);
+            }
+        }
+    }
+
     pub fn set_affine_on_cr(&self, cr: &cairo::Context) {
         let (x0, y0) = self.get_offset();
         let affine = cr.get_matrix();
@@ -515,6 +631,49 @@ fn set_font_options(context: &pango::Context, options: &cairo::FontOptions) {
     }
 }
 
+// FIXME: should the pango crate provide this like PANGO_GRAVITY_IS_VERTICAL() ?
+fn gravity_is_vertical(gravity: pango::Gravity) -> bool {
+    match gravity {
+        pango::Gravity::East | pango::Gravity::West => true,
+        _ => false,
+    }
+}
+
+fn compute_text_bbox(
+    ink: &pango::Rectangle,
+    x: f64,
+    y: f64,
+    affine: &cairo::Matrix,
+    gravity: pango::Gravity,
+) -> BoundingBox {
+    let pango_scale = f64::from(pango::SCALE);
+
+    let mut bbox = BoundingBox::new(affine);
+
+    let ink_x = f64::from(ink.x);
+    let ink_y = f64::from(ink.y);
+    let ink_width = f64::from(ink.width);
+    let ink_height = f64::from(ink.height);
+
+    if gravity_is_vertical(gravity) {
+        bbox.rect = Some(cairo::Rectangle {
+            x: x + (ink_x - ink_height) / pango_scale,
+            y: y + ink_y / pango_scale,
+            width: ink_height / pango_scale,
+            height: ink_width / pango_scale,
+        });
+    } else {
+        bbox.rect = Some(cairo::Rectangle {
+            x: x + ink_x / pango_scale,
+            y: y + ink_y / pango_scale,
+            width: ink_width / pango_scale,
+            height: ink_height / pango_scale,
+        });
+    }
+
+    bbox
+}
+
 #[no_mangle]
 pub extern "C" fn rsvg_drawing_ctx_draw_node_from_stack(
     raw_draw_ctx: *mut RsvgDrawingCtx,
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index 3601fa5d..7a6a3c86 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -5,7 +5,6 @@ use std::cell::{Cell, RefCell};
 use std::str;
 
 use attributes::Attribute;
-use draw::draw_pango_layout;
 use drawing_ctx::DrawingCtx;
 use handle::RsvgHandle;
 use length::*;
@@ -94,10 +93,10 @@ impl NodeChars {
         let offset = baseline + values.baseline_shift.0.normalize(values, draw_ctx);
 
         if values.text_gravity_is_vertical() {
-            draw_pango_layout(draw_ctx, values, &layout, *x + offset, *y, clipping);
+            draw_ctx.draw_pango_layout(&layout, values, *x + offset, *y, clipping);
             *y += f64::from(width) / f64::from(pango::SCALE);
         } else {
-            draw_pango_layout(draw_ctx, values, &layout, *x, *y - offset, clipping);
+            draw_ctx.draw_pango_layout(&layout, values, *x, *y - offset, clipping);
             *x += f64::from(width) / f64::from(pango::SCALE);
         }
     }


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