[librsvg: 3/6] drawing-ctx: move draw_pango_layout to the drawing ctx
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 3/6] drawing-ctx: move draw_pango_layout to the drawing ctx
- Date: Tue, 26 Jun 2018 02:03:19 +0000 (UTC)
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,
- ¤t_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,
+ ¤t_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]