[librsvg: 7/14] New functions to create a Path from a pango::Layout
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 7/14] New functions to create a Path from a pango::Layout
- Date: Wed, 9 Mar 2022 23:43:11 +0000 (UTC)
commit 84eeacece6b563725e779901c9221826b797f465
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Feb 4 20:23:56 2022 -0600
New functions to create a Path from a pango::Layout
Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/673>
src/drawing_ctx.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
---
diff --git a/src/drawing_ctx.rs b/src/drawing_ctx.rs
index 99096163d..11634e230 100644
--- a/src/drawing_ctx.rs
+++ b/src/drawing_ctx.rs
@@ -1827,6 +1827,50 @@ pub fn create_pango_context(font_options: &FontOptions, transform: &Transform) -
context
}
+/// Converts a Pango layout to a Cairo path on the specified cr starting at (x, y).
+/// Does not clear the current path first.
+fn pango_layout_to_cairo(
+ x: f64,
+ y: f64,
+ layout: &pango::Layout,
+ gravity: pango::Gravity,
+ cr: &cairo::Context,
+) {
+ let rotation_from_gravity = gravity.to_rotation();
+ let rotation = if !rotation_from_gravity.approx_eq_cairo(0.0) {
+ Some(-rotation_from_gravity)
+ } else {
+ None
+ };
+
+ cr.move_to(x, y);
+
+ let matrix = cr.matrix();
+ if let Some(rot) = rotation {
+ cr.rotate(rot);
+ }
+
+ pangocairo::functions::update_layout(cr, layout);
+ pangocairo::functions::layout_path(cr, layout);
+ cr.set_matrix(matrix);
+}
+
+/// Converts a Pango layout to a Path starting at (x, y).
+pub fn pango_layout_to_path(
+ x: f64,
+ y: f64,
+ layout: &pango::Layout,
+ gravity: pango::Gravity,
+) -> Result<Path, RenderingError> {
+ let surface = cairo::RecordingSurface::create(cairo::Content::ColorAlpha, None)?;
+ let cr = cairo::Context::new(&surface)?;
+
+ pango_layout_to_cairo(x, y, layout, gravity, &cr);
+
+ let cairo_path = cr.copy_path()?;
+ Ok(Path::from_cairo(cairo_path))
+}
+
// https://www.w3.org/TR/css-masking-1/#ClipPathElement
fn element_can_be_used_inside_clip_path(element: &Element) -> bool {
matches!(
@@ -2295,4 +2339,29 @@ mod tests {
],
);
}
+
+ #[test]
+ fn empty_or_whitespace_text_yields_empty_path() {
+ let context = create_pango_context(
+ &FontOptions {
+ options: cairo::FontOptions::new().unwrap(),
+ },
+ &Transform::identity(),
+ );
+
+ // empty text
+
+ let layout = pango::Layout::new(&context);
+ layout.set_text("");
+
+ let path = pango_layout_to_path(0.0, 0.0, &layout, pango::Gravity::Auto).unwrap();
+ assert!(path.is_empty());
+
+ // only whitespace
+
+ layout.set_text(" ");
+
+ let path = pango_layout_to_path(0.0, 0.0, &layout, pango::Gravity::Auto).unwrap();
+ assert!(path.is_empty());
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]