[librsvg: 5/15] layout::TextSpan - compute the span's bbox and store it here, not in the drawing code
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 5/15] layout::TextSpan - compute the span's bbox and store it here, not in the drawing code
- Date: Mon, 18 Oct 2021 23:15:47 +0000 (UTC)
commit eb93155bc4778d19e930b1e8a969fa22ae1a3af5
Author: Federico Mena Quintero <federico gnome org>
Date: Mon Oct 18 12:02:29 2021 -0500
layout::TextSpan - compute the span's bbox and store it here, not in the drawing code
Unfortunately this requires asking the draw_ctx for its current
transform. We'll refactor this later.
Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/613>
src/drawing_ctx.rs | 59 +++++-------------------------------------------------
src/layout.rs | 2 ++
src/text.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 62 insertions(+), 54 deletions(-)
---
diff --git a/src/drawing_ctx.rs b/src/drawing_ctx.rs
index 9ddd1508..72708a79 100644
--- a/src/drawing_ctx.rs
+++ b/src/drawing_ctx.rs
@@ -333,7 +333,9 @@ impl DrawingCtx {
self.measuring
}
- fn get_transform(&self) -> Transform {
+ // FIXME: this is public just so that text.rs can access it. Maybe the draw_fn passed to
with_discrete_layer should
+ // obtain the current transform as an argument?
+ pub fn get_transform(&self) -> Transform {
Transform::from(self.cr.matrix())
}
@@ -1362,12 +1364,11 @@ impl DrawingCtx {
let paint_order = values.paint_order();
- let bbox = compute_text_box(&span.layout, span.x, span.y, transform, span.gravity);
- if bbox.is_none() {
+ if span.bbox.is_none() {
return Ok(self.empty_bbox());
}
- let mut bbox = bbox.unwrap();
+ let mut bbox = span.bbox.unwrap();
with_saved_cr(&self.cr.clone(), || {
self.cr
@@ -1914,51 +1915,6 @@ fn compute_stroke_and_fill_box(
Ok(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.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)
-}
-
fn setup_cr_for_stroke(cr: &cairo::Context, stroke: &Stroke) {
cr.set_line_width(stroke.width);
cr.set_miter_limit(stroke.miter_limit.0);
@@ -1974,11 +1930,6 @@ fn setup_cr_for_stroke(cr: &cairo::Context, stroke: &Stroke) {
}
}
-// FIXME: should the pango crate provide this like PANGO_GRAVITY_IS_VERTICAL() ?
-fn gravity_is_vertical(gravity: pango::Gravity) -> bool {
- matches!(gravity, pango::Gravity::East | pango::Gravity::West)
-}
-
/// escape quotes and backslashes with backslash
fn escape_link_target(value: &str) -> Cow<'_, str> {
static REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"['\\]").unwrap());
diff --git a/src/layout.rs b/src/layout.rs
index c0dff1fb..085cf584 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -5,6 +5,7 @@
use std::rc::Rc;
use crate::aspect_ratio::AspectRatio;
+use crate::bbox::BoundingBox;
use crate::coord_units::CoordUnits;
use crate::dasharray::Dasharray;
use crate::document::AcquiredNodes;
@@ -97,6 +98,7 @@ pub struct Image {
pub struct TextSpan {
pub layout: pango::Layout,
pub gravity: pango::Gravity,
+ pub bbox: Option<BoundingBox>,
pub is_visible: bool,
pub x: f64,
pub y: f64,
diff --git a/src/text.rs b/src/text.rs
index 103dcd4b..285b59b0 100644
--- a/src/text.rs
+++ b/src/text.rs
@@ -17,7 +17,9 @@ use crate::properties::{
ComputedValues, Direction, FontStretch, FontStyle, FontVariant, FontWeight, TextAnchor,
UnicodeBidi, WritingMode, XmlLang, XmlSpace,
};
+use crate::rect::Rect;
use crate::space::{xml_space_normalize, NormalizeDefault, XmlSpaceNormalize};
+use crate::transform::Transform;
use crate::xml::Attributes;
/// An absolutely-positioned array of `Span`s
@@ -275,6 +277,56 @@ impl MeasuredSpan {
}
}
+// FIXME: should the pango crate provide this like PANGO_GRAVITY_IS_VERTICAL() ?
+fn gravity_is_vertical(gravity: pango::Gravity) -> bool {
+ matches!(gravity, pango::Gravity::East | pango::Gravity::West)
+}
+
+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.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)
+}
+
impl PositionedSpan {
fn draw(
&self,
@@ -311,9 +363,12 @@ impl PositionedSpan {
let gravity = layout.context().unwrap().gravity();
+ let bbox = compute_text_box(&layout, x, y, draw_ctx.get_transform(), gravity);
+
let span = layout::TextSpan {
layout,
gravity,
+ bbox,
is_visible,
x,
y,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]