[librsvg] rsvg_text_create_layout(): This is now implemented in Rust. Yay!
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] rsvg_text_create_layout(): This is now implemented in Rust. Yay!
- Date: Fri, 15 Dec 2017 18:54:22 +0000 (UTC)
commit 8f1a6bc2c6a1133a2c8bf925854bfb494d70a1ef
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Dec 15 11:48:04 2017 -0600
rsvg_text_create_layout(): This is now implemented in Rust. Yay!
rsvg-text.c | 81 ++-----------------------------------------
rust/src/lib.rs | 5 +++
rust/src/text.rs | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 109 insertions(+), 79 deletions(-)
---
diff --git a/rsvg-text.c b/rsvg-text.c
index ff72a53..1107864 100644
--- a/rsvg-text.c
+++ b/rsvg-text.c
@@ -549,85 +549,8 @@ rsvg_new_tref (const char *element_name, RsvgNode *parent)
rsvg_node_tref_free);
}
-static PangoLayout *
-rsvg_text_create_layout (RsvgDrawingCtx *ctx, const char *text)
-{
- RsvgState *state;
- PangoContext *context;
- PangoFontDescription *font_desc;
- PangoLayout *layout;
- PangoAttrList *attr_list;
- double dpi_y;
- const char *lang;
- UnicodeBidi unicode_bidi;
- RsvgLength letter_spacing;
- const TextDecoration *font_decor;
-
- g_assert (text != NULL);
-
- state = rsvg_current_state (ctx);
-
- context = rsvg_drawing_ctx_get_pango_context (ctx);
-
- lang = rsvg_state_get_language (state);
- if (lang)
- pango_context_set_language (context, pango_language_from_string (lang));
-
- unicode_bidi = rsvg_state_get_unicode_bidi (state);
- if (unicode_bidi == UNICODE_BIDI_OVERRIDE || unicode_bidi == UNICODE_BIDI_EMBED)
- pango_context_set_base_dir (context,
- rsvg_state_get_text_dir (state));
-
- if (PANGO_GRAVITY_IS_VERTICAL (rsvg_state_get_text_gravity (state)))
- pango_context_set_base_gravity (context, rsvg_state_get_text_gravity (state));
-
- font_desc = pango_font_description_copy (pango_context_get_font_description (context));
-
- if (rsvg_state_get_font_family (state))
- pango_font_description_set_family (font_desc, rsvg_state_get_font_family (state));
-
- pango_font_description_set_style (font_desc, rsvg_state_get_font_style (state));
- pango_font_description_set_variant (font_desc, rsvg_state_get_font_variant (state));
- pango_font_description_set_weight (font_desc, rsvg_state_get_font_weight (state));
- pango_font_description_set_stretch (font_desc, rsvg_state_get_font_stretch (state));
-
- rsvg_drawing_ctx_get_dpi (ctx, NULL, &dpi_y);
- pango_font_description_set_size (font_desc,
- rsvg_drawing_ctx_get_normalized_font_size (ctx) * PANGO_SCALE / dpi_y *
72);
-
- layout = pango_layout_new (context);
- pango_layout_set_font_description (layout, font_desc);
- pango_font_description_free (font_desc);
-
- attr_list = pango_attr_list_new ();
- letter_spacing = rsvg_state_get_letter_spacing (state);
- pango_attr_list_insert (attr_list,
- pango_attr_letter_spacing_new (rsvg_length_normalize (&letter_spacing, ctx) *
PANGO_SCALE));
-
- font_decor = rsvg_state_get_font_decor (state);
- if (font_decor) {
- if (font_decor->underline) {
- pango_attr_list_insert (attr_list,
- pango_attr_underline_new (PANGO_UNDERLINE_SINGLE));
- }
- if (font_decor->strike) {
- pango_attr_list_insert (attr_list,
- pango_attr_strikethrough_new (TRUE));
- }
- }
-
- pango_layout_set_attributes (layout, attr_list);
- pango_attr_list_unref (attr_list);
-
- pango_layout_set_alignment (layout, (rsvg_state_get_text_dir (state) == PANGO_DIRECTION_LTR) ?
- PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT);
-
- pango_layout_set_text (layout, text, -1);
-
- g_object_unref (context);
-
- return layout;
-}
+/* Defined in rust/src/text.rs */
+extern PangoLayout *rsvg_text_create_layout (RsvgDrawingCtx *ctx, const char *text);
static void
rsvg_text_render_text (RsvgDrawingCtx * ctx, const char *text, gdouble * x, gdouble * y)
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index ffc2a2f..5d5e769 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -140,6 +140,10 @@ pub use structure::{
rsvg_node_use_new,
};
+pub use text::{
+ rsvg_text_create_layout,
+};
+
pub use transform::{
rsvg_parse_transform,
};
@@ -180,6 +184,7 @@ mod space;
mod state;
mod stop;
mod structure;
+mod text;
mod transform;
mod util;
mod viewbox;
diff --git a/rust/src/text.rs b/rust/src/text.rs
new file mode 100644
index 0000000..24d7823
--- /dev/null
+++ b/rust/src/text.rs
@@ -0,0 +1,102 @@
+use libc;
+use glib::translate::*;
+use pango::{self, ContextExt, LayoutExt};
+use pango_sys;
+
+use drawing_ctx::{self, RsvgDrawingCtx};
+use state::{self, UnicodeBidi};
+
+// FIXME: should the pango crate provide this like PANGO_GRAVITY_IS_VERTICAL() / PANGO_GRAVITY_IS_IMPROPER()?
+fn gravity_is_vertical(gravity: pango::Gravity) -> bool {
+ match gravity {
+ pango::Gravity::East | pango::Gravity::West => true,
+ _ => false
+ }
+}
+
+fn to_pango_units(v: f64) -> i32 {
+ (v * pango::SCALE as f64) as i32
+}
+
+fn create_pango_layout(draw_ctx: *const RsvgDrawingCtx, text: &str) -> pango::Layout {
+ let state = drawing_ctx::get_current_state(draw_ctx);
+ let pango_context = drawing_ctx::get_pango_context(draw_ctx);
+
+ if let Some(lang) = state::get_language(state) {
+ let pango_lang = pango::Language::from_string(&lang);
+ pango_context.set_language(&pango_lang);
+ }
+
+ let unicode_bidi = state::get_unicode_bidi(state);
+ match unicode_bidi {
+ UnicodeBidi::Override | UnicodeBidi::Embed => {
+ pango_context.set_base_dir(state::get_text_dir(state));
+ },
+
+ _ => ()
+ }
+
+ let gravity = state::get_text_gravity(state);
+ if gravity_is_vertical(gravity) {
+ pango_context.set_base_gravity(gravity);
+ }
+
+ let mut font_desc = pango_context.get_font_description().unwrap();
+
+ if let Some(font_family) = state::get_font_family(state) {
+ font_desc.set_family(&font_family);
+ }
+
+ font_desc.set_style(state::get_font_style(state));
+ font_desc.set_variant(state::get_font_variant(state));
+ font_desc.set_weight(state::get_font_weight(state));
+ font_desc.set_stretch(state::get_font_stretch(state));
+
+ let (_, dpi_y) = drawing_ctx::get_dpi(draw_ctx);
+ font_desc.set_size(to_pango_units(drawing_ctx::get_normalized_font_size(draw_ctx) / dpi_y * 72.0));
+
+ let layout = pango::Layout::new(&pango_context);
+ layout.set_font_description(&font_desc);
+
+ let attr_list = pango::AttrList::new();
+
+ attr_list.insert(
+ pango::Attribute::new_letter_spacing(
+ to_pango_units(state::get_letter_spacing(state).normalize(draw_ctx))
+ ).unwrap());
+
+ if let Some(font_decor) = state::get_font_decor(state) {
+ if font_decor.underline {
+ attr_list.insert(pango::Attribute::new_underline(pango::Underline::Single)
+ .unwrap());
+ }
+
+ if font_decor.strike {
+ attr_list.insert(pango::Attribute::new_strikethrough(true)
+ .unwrap());
+ }
+ }
+
+ layout.set_attributes(&attr_list);
+
+ layout.set_alignment(
+ match state::get_text_dir(state) {
+ pango::Direction::Ltr => pango::Alignment::Left,
+ _ => pango::Alignment::Right,
+ }
+ );
+
+ layout.set_text(text);
+
+ layout
+}
+
+#[no_mangle]
+pub extern fn rsvg_text_create_layout(draw_ctx: *const RsvgDrawingCtx,
+ text: *const libc::c_char) -> *const pango_sys::PangoLayout {
+ assert!(!text.is_null());
+ let s = unsafe { String::from_glib_none(text) };
+ let layout = create_pango_layout(draw_ctx, &s);
+
+ layout.to_glib_full()
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]