[librsvg: 4/18] (#249): Basic implementation of the unicode-bidi property




commit bb2c019f5c15d30e74faa150dca0f68da01d6633
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon Oct 25 17:53:45 2021 -0500

    (#249): Basic implementation of the unicode-bidi property
    
    This commit causes each span's text to be wrapped with the directional
    control characters specified in
    https://www.w3.org/TR/css-writing-modes-3/#unicode-bidi
    
    For a more complete implementation of unicode-bidi, we'll have to
    change the code to actually bidi/shape the whole character content of
    a <text> element and its children, not just each individual span.
    That will come soon.
    
    Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/621>

 src/text.rs                                       | 27 ++++++++++++++++++++++-
 tests/fixtures/text/unicode-bidi-override-ref.svg |  6 +++++
 tests/fixtures/text/unicode-bidi-override.svg     |  6 +++++
 tests/src/text.rs                                 |  6 +++++
 4 files changed, 44 insertions(+), 1 deletion(-)
---
diff --git a/src/text.rs b/src/text.rs
index afa24360..00258def 100644
--- a/src/text.rs
+++ b/src/text.rs
@@ -335,7 +335,14 @@ impl MeasuredSpan {
         let params = NormalizeParams::new(&values, &view_params);
 
         let properties = FontProperties::new(&values, text_writing_mode, &params);
-        let layout = create_pango_layout(draw_ctx, &properties, &span.text);
+
+        let bidi_control = BidiControl::from_unicode_bidi_and_direction(
+            properties.unicode_bidi,
+            properties.direction,
+        );
+
+        let with_control_chars = wrap_with_direction_control_chars(&span.text, &bidi_control);
+        let layout = create_pango_layout(draw_ctx, &properties, &with_control_chars);
         let (w, h) = layout.size();
 
         let w = f64::from(w) / f64::from(pango::SCALE);
@@ -1144,6 +1151,24 @@ impl BidiControl {
     }
 }
 
+/// Prepends and appends Unicode directional formatting characters.
+fn wrap_with_direction_control_chars(s: &str, bidi_control: &BidiControl) -> String {
+    let mut res =
+        String::with_capacity(s.len() + bidi_control.start.len() + bidi_control.end.len());
+
+    for &ch in bidi_control.start {
+        res.push(ch);
+    }
+
+    res.push_str(s);
+
+    for &ch in bidi_control.end {
+        res.push(ch);
+    }
+
+    res
+}
+
 fn create_pango_layout(draw_ctx: &DrawingCtx, props: &FontProperties, text: &str) -> pango::Layout {
     let pango_context = draw_ctx.create_pango_context();
 
diff --git a/tests/fixtures/text/unicode-bidi-override-ref.svg 
b/tests/fixtures/text/unicode-bidi-override-ref.svg
new file mode 100644
index 00000000..2357471b
--- /dev/null
+++ b/tests/fixtures/text/unicode-bidi-override-ref.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; width="600" height="600">
+  <rect x="0" y="0" width="100%" height="100%" fill="white"/>
+
+  <text x="100" y="100" font-family="Ahem" font-size="20">ÉAppAÉÉAp</text>
+</svg>
diff --git a/tests/fixtures/text/unicode-bidi-override.svg b/tests/fixtures/text/unicode-bidi-override.svg
new file mode 100644
index 00000000..5b230d26
--- /dev/null
+++ b/tests/fixtures/text/unicode-bidi-override.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; width="600" height="600">
+  <rect x="0" y="0" width="100%" height="100%" fill="white"/>
+
+  <text x="100" y="100" font-family="Ahem" font-size="20">ÉAp<tspan direction="rtl" 
unicode-bidi="bidi-override">ÉAp</tspan>ÉAp</text>
+</svg>
diff --git a/tests/src/text.rs b/tests/src/text.rs
index cc3c1527..779fb127 100644
--- a/tests/src/text.rs
+++ b/tests/src/text.rs
@@ -39,3 +39,9 @@ test_svg_reference!(
     "tests/fixtures/text/span-bounds-when-offset-by-dx.svg",
     "tests/fixtures/text/span-bounds-when-offset-by-dx-ref.svg"
 );
+
+test_svg_reference!(
+    unicode_bidi_override,
+    "tests/fixtures/text/unicode-bidi-override.svg",
+    "tests/fixtures/text/unicode-bidi-override-ref.svg"
+);


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