[librsvg] text: move text drawing into text.rs
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] text: move text drawing into text.rs
- Date: Tue, 1 Jan 2019 00:03:39 +0000 (UTC)
commit c9f89c9ce04252c0c3a24cbcec788d5ba585971c
Author: Paolo Borelli <pborelli gnome org>
Date: Mon Dec 31 16:00:20 2018 +0100
text: move text drawing into text.rs
rsvg_internals/src/drawing_ctx.rs | 146 +---------------------------------
rsvg_internals/src/text.rs | 160 ++++++++++++++++++++++++++++++++++----
2 files changed, 145 insertions(+), 161 deletions(-)
---
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 21fe5315..515df453 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -2,8 +2,7 @@ use cairo;
use cairo::MatrixTrait;
use cairo_sys;
use glib::translate::*;
-use pango::{self, ContextExt, FontMapExt, LayoutExt};
-use pango_sys;
+use pango::{self, FontMapExt};
use pangocairo;
use std::cell::RefCell;
use std::rc::{Rc, Weak};
@@ -15,7 +14,6 @@ use defs::Fragment;
use dpi::Dpi;
use error::RenderingError;
use filters;
-use float_eq_cairo::ApproxEqCairo;
use gradient::NodeGradient;
use handle::{self, RsvgHandle};
use length::Dasharray;
@@ -634,104 +632,7 @@ impl DrawingCtx {
context
}
- pub fn draw_pango_layout(
- &mut self,
- layout: &pango::Layout,
- values: &ComputedValues,
- x: f64,
- y: f64,
- clipping: bool,
- ) -> Result<(), RenderingError> {
- let (ink, _) = layout.get_extents();
-
- if ink.width == 0 || ink.height == 0 {
- return Ok(());
- }
-
- 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;
-
- let res = if !clipping {
- self.set_source_paint_server(&values.fill.0, fill_opacity, &bbox, current_color)
- .and_then(|had_paint_server| {
- if had_paint_server {
- pangocairo::functions::update_layout(&cr, layout);
- pangocairo::functions::show_layout(&cr, layout);
- };
- Ok(())
- })
- } else {
- Ok(())
- };
-
- if res.is_ok() {
- let stroke_opacity = &values.stroke_opacity.0;
-
- let mut need_layout_path = clipping;
-
- let res = if !clipping {
- self.set_source_paint_server(
- &values.stroke.0,
- stroke_opacity,
- &bbox,
- ¤t_color,
- )
- .and_then(|had_paint_server| {
- if had_paint_server {
- need_layout_path = true;
- }
- Ok(())
- })
- } else {
- Ok(())
- };
-
- if res.is_ok() {
- 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();
-
- res
- }
-
- fn setup_cr_for_stroke(&self, cr: &cairo::Context, values: &ComputedValues) {
+ pub fn setup_cr_for_stroke(&self, cr: &cairo::Context, values: &ComputedValues) {
let params = self.get_view_params();
cr.set_line_width(values.stroke_width.0.normalize(values, ¶ms));
@@ -925,49 +826,6 @@ impl DrawingCtx {
}
}
-// 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 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 rect = if gravity_is_vertical(gravity) {
- 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 {
- cairo::Rectangle {
- x: x + ink_x / pango_scale,
- y: y + ink_y / pango_scale,
- width: ink_width / pango_scale,
- height: ink_height / pango_scale,
- }
- };
-
- BoundingBox::new(affine)
- .with_rect(Some(rect))
- .with_ink_rect(Some(rect))
-}
-
fn compute_stroke_and_fill_box(cr: &cairo::Context, values: &ComputedValues) -> BoundingBox {
let affine = cr.get_matrix();
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index b0360f66..ad62e05d 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -1,10 +1,14 @@
+use glib::translate::*;
use pango::{self, ContextExt, LayoutExt};
+use pango_sys;
use std::cell::{Cell, RefCell};
use attributes::Attribute;
+use bbox::BoundingBox;
use defs::Fragment;
use drawing_ctx::DrawingCtx;
use error::{AttributeResultExt, RenderingError};
+use float_eq_cairo::ApproxEqCairo;
use font_props::FontWeightSpec;
use handle::RsvgHandle;
use length::*;
@@ -13,16 +17,8 @@ use parsers::ParseValue;
use property_bag::PropertyBag;
use space::{xml_space_normalize, NormalizeDefault, XmlSpaceNormalize};
use state::{
- ComputedValues,
- Direction,
- FontStretch,
- FontStyle,
- FontVariant,
- TextAnchor,
- UnicodeBidi,
- WritingMode,
- XmlLang,
- XmlSpace,
+ ComputedValues, Direction, FontStretch, FontStyle, FontVariant, TextAnchor, UnicodeBidi,
+ WritingMode, XmlLang, XmlSpace,
};
/// An absolutely-positioned array of `Span`s
@@ -258,13 +254,143 @@ impl PositionedSpan {
}
fn draw(&self, draw_ctx: &mut DrawingCtx, clipping: bool) -> Result<(), RenderingError> {
- draw_ctx.draw_pango_layout(
- &self.layout,
- &self.values,
- self.rendered_position.0,
- self.rendered_position.1,
- clipping,
- )
+ let cr = draw_ctx.get_cairo_context();
+ cr.save();
+
+ draw_ctx.set_affine_on_cr(&cr);
+
+ let affine = cr.get_matrix();
+
+ let gravity = self.layout.get_context().unwrap().get_gravity();
+ let bbox = self.compute_text_bbox(&affine, gravity);
+ if bbox.is_none() {
+ cr.restore();
+ return Ok(());
+ }
+
+ let bbox = bbox.unwrap();
+
+ if !clipping {
+ draw_ctx.insert_bbox(&bbox);
+ }
+
+ cr.set_antialias(cairo::Antialias::from(self.values.text_rendering));
+
+ draw_ctx.setup_cr_for_stroke(&cr, &self.values);
+
+ cr.move_to(self.rendered_position.0, self.rendered_position.1);
+
+ let rotation = unsafe { pango_sys::pango_gravity_to_rotation(gravity.to_glib()) };
+ if !rotation.approx_eq_cairo(&0.0) {
+ cr.rotate(-rotation);
+ }
+
+ let current_color = &self.values.color.0;
+
+ let fill_opacity = &self.values.fill_opacity.0;
+
+ let res = if !clipping {
+ draw_ctx
+ .set_source_paint_server(&self.values.fill.0, fill_opacity, &bbox, current_color)
+ .and_then(|had_paint_server| {
+ if had_paint_server {
+ pangocairo::functions::update_layout(&cr, &self.layout);
+ pangocairo::functions::show_layout(&cr, &self.layout);
+ };
+ Ok(())
+ })
+ } else {
+ Ok(())
+ };
+
+ if res.is_ok() {
+ let stroke_opacity = &self.values.stroke_opacity.0;
+
+ let mut need_layout_path = clipping;
+
+ let res = if !clipping {
+ draw_ctx
+ .set_source_paint_server(
+ &self.values.stroke.0,
+ stroke_opacity,
+ &bbox,
+ ¤t_color,
+ )
+ .and_then(|had_paint_server| {
+ if had_paint_server {
+ need_layout_path = true;
+ }
+ Ok(())
+ })
+ } else {
+ Ok(())
+ };
+
+ if res.is_ok() {
+ if need_layout_path {
+ pangocairo::functions::update_layout(&cr, &self.layout);
+ pangocairo::functions::layout_path(&cr, &self.layout);
+
+ if !clipping {
+ let ib = BoundingBox::new(&affine).with_ink_extents(cr.stroke_extents());
+ cr.stroke();
+ draw_ctx.insert_bbox(&ib);
+ }
+ }
+ }
+ }
+
+ cr.restore();
+
+ res
+ }
+
+ fn compute_text_bbox(
+ &self,
+ affine: &cairo::Matrix,
+ gravity: pango::Gravity,
+ ) -> Option<BoundingBox> {
+ 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 rect = if gravity_is_vertical(gravity) {
+ 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 {
+ cairo::Rectangle {
+ x: x + ink_x / pango_scale,
+ y: y + ink_y / pango_scale,
+ width: ink_width / pango_scale,
+ height: ink_height / pango_scale,
+ }
+ };
+
+ let bbox = BoundingBox::new(affine)
+ .with_rect(Some(rect))
+ .with_ink_rect(Some(rect));
+
+ 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,
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]