[librsvg: 2/5] drawing_ctx: move draw_text to drawing context




commit 911913295447d2583d1f5ee73ac38de48d77d0c0
Author: Paolo Borelli <pborelli gnome org>
Date:   Thu Aug 27 23:07:23 2020 +0200

    drawing_ctx: move draw_text to drawing context
    
    This is now consistent with draw_path and draw_image.

 rsvg_internals/src/drawing_ctx.rs | 163 +++++++++++++++++++++++++++++++++++++-
 rsvg_internals/src/text.rs        | 153 +----------------------------------
 2 files changed, 165 insertions(+), 151 deletions(-)
---
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index e725052e..1b32b170 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -18,6 +18,7 @@ use crate::dpi::Dpi;
 use crate::element::Element;
 use crate::error::{AcquireError, RenderingError};
 use crate::filters;
+use crate::float_eq_cairo::ApproxEqCairo;
 use crate::marker;
 use crate::node::{CascadedValues, Node, NodeBorrow, NodeDraw};
 use crate::paint_server::{PaintServer, PaintSource};
@@ -25,7 +26,7 @@ use crate::path_builder::*;
 use crate::properties::ComputedValues;
 use crate::property_defs::{
     ClipRule, FillRule, MixBlendMode, Opacity, Overflow, ShapeRendering, StrokeDasharray,
-    StrokeLinecap, StrokeLinejoin,
+    StrokeLinecap, StrokeLinejoin, TextRendering,
 };
 use crate::rect::Rect;
 use crate::shapes::Markers;
@@ -1078,6 +1079,102 @@ impl DrawingCtx {
         })
     }
 
+    pub fn draw_text(
+        &mut self,
+        layout: &pango::Layout,
+        x: f64,
+        y: f64,
+        acquired_nodes: &mut AcquiredNodes,
+        values: &ComputedValues,
+        clipping: bool,
+    ) -> Result<BoundingBox, RenderingError> {
+        let transform = self.get_transform();
+
+        let gravity = layout.get_context().unwrap().get_gravity();
+
+        let bbox = compute_text_box(layout, x, y, transform, gravity);
+        if bbox.is_none() {
+            return Ok(self.empty_bbox());
+        }
+
+        let mut bbox = if clipping {
+            self.empty_bbox()
+        } else {
+            bbox.unwrap()
+        };
+
+        self.with_saved_cr(&mut |dc| {
+            let cr = dc.get_cairo_context();
+
+            cr.set_antialias(cairo::Antialias::from(values.text_rendering()));
+            dc.setup_cr_for_stroke(&cr, &values);
+            cr.move_to(x, y);
+
+            let rotation = gravity.to_rotation();
+            if !rotation.approx_eq_cairo(0.0) {
+                cr.rotate(-rotation);
+            }
+
+            let current_color = values.color().0;
+
+            let res = if !clipping {
+                dc.set_source_paint_server(
+                    acquired_nodes,
+                    &values.fill().0,
+                    values.fill_opacity().0,
+                    &bbox,
+                    current_color,
+                )
+                .map(|had_paint_server| {
+                    if had_paint_server {
+                        pangocairo::functions::update_layout(&cr, &layout);
+                        pangocairo::functions::show_layout(&cr, &layout);
+                    };
+                })
+            } else {
+                Ok(())
+            };
+
+            if res.is_ok() {
+                let mut need_layout_path = clipping;
+
+                let res = if !clipping {
+                    dc.set_source_paint_server(
+                        acquired_nodes,
+                        &values.stroke().0,
+                        values.stroke_opacity().0,
+                        &bbox,
+                        current_color,
+                    )
+                    .map(|had_paint_server| {
+                        if had_paint_server {
+                            need_layout_path = true;
+                        }
+                    })
+                } else {
+                    Ok(())
+                };
+
+                if res.is_ok() && need_layout_path {
+                    pangocairo::functions::update_layout(&cr, &layout);
+                    pangocairo::functions::layout_path(&cr, &layout);
+
+                    if !clipping {
+                        let (x0, y0, x1, y1) = cr.stroke_extents();
+                        let r = Rect::new(x0, y0, x1, y1);
+                        let ib = BoundingBox::new()
+                            .with_transform(transform)
+                            .with_ink_rect(r);
+                        cr.stroke();
+                        bbox.insert(&ib);
+                    }
+                }
+            }
+
+            res.map(|_: ()| bbox)
+        })
+    }
+
     pub fn get_snapshot(
         &self,
         width: i32,
@@ -1416,6 +1513,59 @@ fn compute_stroke_and_fill_box(cr: &cairo::Context, values: &ComputedValues) ->
     bbox
 }
 
+fn compute_text_box(
+    layout: &pango::Layout,
+    x: f64,
+    y: f64,
+    transform: Transform,
+    gravity: pango::Gravity,
+) -> Option<BoundingBox> {
+    #![allow(clippy::many_single_char_names)]
+
+    let (ink, _) = layout.get_extents();
+    if ink.width == 0 || ink.height == 0 {
+        return None;
+    }
+
+    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);
+    let pango_scale = f64::from(pango::SCALE);
+
+    let (x, y, w, h) = if gravity_is_vertical(gravity) {
+        (
+            x + (ink_x - ink_height) / pango_scale,
+            y + ink_y / pango_scale,
+            ink_height / pango_scale,
+            ink_width / pango_scale,
+        )
+    } else {
+        (
+            x + ink_x / pango_scale,
+            y + ink_y / pango_scale,
+            ink_width / pango_scale,
+            ink_height / pango_scale,
+        )
+    };
+
+    let r = Rect::new(x, y, x + w, y + h);
+    let bbox = BoundingBox::new()
+        .with_transform(transform)
+        .with_rect(r)
+        .with_ink_rect(r);
+
+    Some(bbox)
+}
+
+// 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,
+    }
+}
+
 /// escape quotes and backslashes with backslash
 fn escape_link_target(value: &str) -> Cow<'_, str> {
     static REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"['\\]").unwrap());
@@ -1500,3 +1650,14 @@ impl From<ShapeRendering> for cairo::Antialias {
         }
     }
 }
+
+impl From<TextRendering> for cairo::Antialias {
+    fn from(tr: TextRendering) -> cairo::Antialias {
+        match tr {
+            TextRendering::Auto
+            | TextRendering::OptimizeLegibility
+            | TextRendering::GeometricPrecision => cairo::Antialias::Default,
+            TextRendering::OptimizeSpeed => cairo::Antialias::None,
+        }
+    }
+}
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index a1c566de..016e7503 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -10,7 +10,6 @@ use crate::document::AcquiredNodes;
 use crate::drawing_ctx::DrawingCtx;
 use crate::element::{Draw, Element, ElementResult, SetAttributes};
 use crate::error::*;
-use crate::float_eq_cairo::ApproxEqCairo;
 use crate::font_props::FontWeight;
 use crate::length::*;
 use crate::node::{CascadedValues, Node, NodeBorrow};
@@ -18,12 +17,10 @@ use crate::parsers::ParseValue;
 use crate::properties::ComputedValues;
 use crate::property_bag::PropertyBag;
 use crate::property_defs::{
-    Direction, FontStretch, FontStyle, FontVariant, TextAnchor, TextRendering, UnicodeBidi,
-    WritingMode, XmlLang, XmlSpace,
+    Direction, FontStretch, FontStyle, FontVariant, TextAnchor, UnicodeBidi, WritingMode, XmlLang,
+    XmlSpace,
 };
-use crate::rect::Rect;
 use crate::space::{xml_space_normalize, NormalizeDefault, XmlSpaceNormalize};
-use crate::transform::Transform;
 
 /// An absolutely-positioned array of `Span`s
 ///
@@ -273,141 +270,8 @@ impl PositionedSpan {
         draw_ctx: &mut DrawingCtx,
         clipping: bool,
     ) -> Result<BoundingBox, RenderingError> {
-        draw_ctx.with_saved_cr(&mut |dc| {
-            let transform = dc.get_transform();
-
-            let gravity = self.layout.get_context().unwrap().get_gravity();
-            let bbox = self.compute_text_bbox(transform, gravity);
-            if bbox.is_none() {
-                return Ok(dc.empty_bbox());
-            }
-
-            let mut bbox = if clipping {
-                dc.empty_bbox()
-            } else {
-                bbox.unwrap()
-            };
-
-            let cr = dc.get_cairo_context();
-            cr.set_antialias(cairo::Antialias::from(self.values.text_rendering()));
-            dc.setup_cr_for_stroke(&cr, &self.values);
-            cr.move_to(self.rendered_position.0, self.rendered_position.1);
-
-            let rotation = gravity.to_rotation();
-            if !rotation.approx_eq_cairo(0.0) {
-                cr.rotate(-rotation);
-            }
-
-            let current_color = self.values.color().0;
-
-            let res = if !clipping {
-                dc.set_source_paint_server(
-                    acquired_nodes,
-                    &self.values.fill().0,
-                    self.values.fill_opacity().0,
-                    &bbox,
-                    current_color,
-                )
-                .map(|had_paint_server| {
-                    if had_paint_server {
-                        pangocairo::functions::update_layout(&cr, &self.layout);
-                        pangocairo::functions::show_layout(&cr, &self.layout);
-                    };
-                })
-            } else {
-                Ok(())
-            };
-
-            if res.is_ok() {
-                let mut need_layout_path = clipping;
-
-                let res = if !clipping {
-                    dc.set_source_paint_server(
-                        acquired_nodes,
-                        &self.values.stroke().0,
-                        self.values.stroke_opacity().0,
-                        &bbox,
-                        current_color,
-                    )
-                    .map(|had_paint_server| {
-                        if had_paint_server {
-                            need_layout_path = true;
-                        }
-                    })
-                } else {
-                    Ok(())
-                };
-
-                if res.is_ok() && need_layout_path {
-                    pangocairo::functions::update_layout(&cr, &self.layout);
-                    pangocairo::functions::layout_path(&cr, &self.layout);
-
-                    if !clipping {
-                        let (x0, y0, x1, y1) = cr.stroke_extents();
-                        let r = Rect::new(x0, y0, x1, y1);
-                        let ib = BoundingBox::new()
-                            .with_transform(transform)
-                            .with_ink_rect(r);
-                        cr.stroke();
-                        bbox.insert(&ib);
-                    }
-                }
-            }
-
-            res.map(|_: ()| bbox)
-        })
-    }
-
-    fn compute_text_bbox(
-        &self,
-        transform: Transform,
-        gravity: pango::Gravity,
-    ) -> Option<BoundingBox> {
-        #![allow(clippy::many_single_char_names)]
-
-        let (ink, _) = self.layout.get_extents();
-        if ink.width == 0 || ink.height == 0 {
-            return None;
-        }
-
         let (x, y) = self.rendered_position;
-        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);
-        let pango_scale = f64::from(pango::SCALE);
-
-        let (x, y, w, h) = if gravity_is_vertical(gravity) {
-            (
-                x + (ink_x - ink_height) / pango_scale,
-                y + ink_y / pango_scale,
-                ink_height / pango_scale,
-                ink_width / pango_scale,
-            )
-        } else {
-            (
-                x + ink_x / pango_scale,
-                y + ink_y / pango_scale,
-                ink_width / pango_scale,
-                ink_height / pango_scale,
-            )
-        };
-
-        let r = Rect::new(x, y, x + w, y + h);
-        let bbox = BoundingBox::new()
-            .with_transform(transform)
-            .with_rect(r)
-            .with_ink_rect(r);
-
-        Some(bbox)
-    }
-}
-
-// 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,
+        draw_ctx.draw_text(&self.layout, x, y, acquired_nodes, &self.values, clipping)
     }
 }
 
@@ -796,17 +660,6 @@ impl<'a> From<&'a XmlLang> for pango::Language {
     }
 }
 
-impl From<TextRendering> for cairo::Antialias {
-    fn from(tr: TextRendering) -> cairo::Antialias {
-        match tr {
-            TextRendering::Auto
-            | TextRendering::OptimizeLegibility
-            | TextRendering::GeometricPrecision => cairo::Antialias::Default,
-            TextRendering::OptimizeSpeed => cairo::Antialias::None,
-        }
-    }
-}
-
 impl From<FontStyle> for pango::Style {
     fn from(s: FontStyle) -> pango::Style {
         match s {


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