From 7218cf2747cdaf76719b4a9fc2ae00d126c46871 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Mon, 12 Jul 2021 13:39:08 +0200 Subject: [PATCH 01/19] Implement checking if the font familly exists in pango fixes #430 --- piet-cairo/src/text.rs | 8 +++++++- piet/src/font.rs | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index 5666cee3..2788b513 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -7,6 +7,7 @@ use std::rc::Rc; use glib::translate::{from_glib_full, ToGlibPtr}; +use pango::prelude::FontFamilyExt; use pango::prelude::FontMapExt; use pango::AttrList; use pango_sys::pango_attr_insert_hyphens_new; @@ -166,7 +167,12 @@ impl Text for CairoText { type TextLayoutBuilder = CairoTextLayoutBuilder; fn font_family(&mut self, family_name: &str) -> Option { - //TODO: Veryify that a family exists with the requested name + // The pango documentation says this is always a stirng, and never null. I trust them on that. + // Would be weird to have a font family without a name anyways. + self.pango_context + .list_families() + .iter() + .find(|family| family.name().unwrap().as_str() == family_name); Some(FontFamily::new_unchecked(family_name)) } diff --git a/piet/src/font.rs b/piet/src/font.rs index 9e04ee86..f3927fa1 100644 --- a/piet/src/font.rs +++ b/piet/src/font.rs @@ -84,7 +84,7 @@ impl FontFamily { FontFamilyInner::SansSerif => "sans-serif", FontFamilyInner::SystemUi => "system-ui", FontFamilyInner::Monospace => "monospace", - FontFamilyInner::Named(s) => &s, + FontFamilyInner::Named(s) => s, } } From 43796b350e2e1f916c1b931631c695d686396b34 Mon Sep 17 00:00:00 2001 From: Jaap Aarts Date: Thu, 15 Jul 2021 19:53:57 +0200 Subject: [PATCH 02/19] Update piet-cairo/src/text.rs Co-authored-by: Colin Rofls --- piet-cairo/src/text.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index 2788b513..d088e824 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -167,8 +167,7 @@ impl Text for CairoText { type TextLayoutBuilder = CairoTextLayoutBuilder; fn font_family(&mut self, family_name: &str) -> Option { - // The pango documentation says this is always a stirng, and never null. I trust them on that. - // Would be weird to have a font family without a name anyways. + // The pango documentation says this is always a string, and never null. self.pango_context .list_families() .iter() From eb7b45505ebe199bb5619290494df70706298583 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Tue, 27 Jul 2021 13:48:07 +0200 Subject: [PATCH 03/19] Font matching always matches the best font available --- piet-cairo/src/text.rs | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index d088e824..71d05e2a 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -1,5 +1,6 @@ //! Text functionality for Piet cairo backend +use std::cmp::Ordering; use std::convert::TryInto; use std::fmt; use std::ops::{Range, RangeBounds}; @@ -7,9 +8,11 @@ use std::rc::Rc; use glib::translate::{from_glib_full, ToGlibPtr}; +use pango::prelude::FontFaceExt; use pango::prelude::FontFamilyExt; use pango::prelude::FontMapExt; -use pango::AttrList; +use pango::FontDescription; +use pango::{AttrList, FontFace}; use pango_sys::pango_attr_insert_hyphens_new; use pangocairo::FontMap; @@ -168,11 +171,36 @@ impl Text for CairoText { fn font_family(&mut self, family_name: &str) -> Option { // The pango documentation says this is always a string, and never null. - self.pango_context + + let font = FontDescription::from_string(family_name); + + let best_match = self + .pango_context .list_families() .iter() - .find(|family| family.name().unwrap().as_str() == family_name); - Some(FontFamily::new_unchecked(family_name)) + .filter(|family| { + family.name().unwrap().contains(family_name) + || family_name.contains(family.name().unwrap().as_str()) + }) + .map(|family| { + family + .list_faces() + .iter() + .map(|fontface| (family.clone(), fontface.clone())) + .collect::>() + }) + .flatten() + .map(|(family, fontface)| fontface.describe().map(|fontdesc| (family, fontdesc))) + .flatten() + .max_by(|a, b| { + if font.better_match(Some(&a.1), &b.1) { + Ordering::Less + } else { + Ordering::Greater + } + }); + + best_match.map(|(family, _)| FontFamily::new_unchecked(family.name().unwrap().as_str())) } fn load_font(&mut self, _data: &[u8]) -> Result { From b3d9b856ce1edd1e0cd463dac63a2f546851c045 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Tue, 27 Jul 2021 21:25:53 +0200 Subject: [PATCH 04/19] Fix filtering badly --- piet-cairo/src/text.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index 71d05e2a..779bab75 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -178,10 +178,6 @@ impl Text for CairoText { .pango_context .list_families() .iter() - .filter(|family| { - family.name().unwrap().contains(family_name) - || family_name.contains(family.name().unwrap().as_str()) - }) .map(|family| { family .list_faces() From f0e6f1cdbf983a062629863e7958fd518d7e7483 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Tue, 27 Jul 2021 21:31:53 +0200 Subject: [PATCH 05/19] Debug things --- piet-cairo/src/text.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index 779bab75..3fa2e16e 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -174,11 +174,14 @@ impl Text for CairoText { let font = FontDescription::from_string(family_name); + println!("AA"); + let best_match = self .pango_context .list_families() .iter() .map(|family| { + println!("Family: {:?}", family.name()); family .list_faces() .iter() @@ -186,7 +189,17 @@ impl Text for CairoText { .collect::>() }) .flatten() - .map(|(family, fontface)| fontface.describe().map(|fontdesc| (family, fontdesc))) + .map(|(family, fontface)| { + fontface.describe().map(|fontdesc| { + println!( + "Family/Fontdesc: {:?}/{:?}", + family.name(), + fontdesc.to_str() + ); + + (family, fontdesc) + }) + }) .flatten() .max_by(|a, b| { if font.better_match(Some(&a.1), &b.1) { From 6291c38f664444716c8c1a1e55f83a7486fc4304 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Tue, 27 Jul 2021 21:32:35 +0200 Subject: [PATCH 06/19] debug --- piet-cairo/src/text.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index 3fa2e16e..2f8ad9bf 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -209,7 +209,10 @@ impl Text for CairoText { } }); - best_match.map(|(family, _)| FontFamily::new_unchecked(family.name().unwrap().as_str())) + best_match.map(|(family, _)| { + println!("result: {:?}", family.name()); + FontFamily::new_unchecked(family.name().unwrap().as_str()) + }) } fn load_font(&mut self, _data: &[u8]) -> Result { From 154eaf660740e20be075ad1f987e373b21c6b303 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Tue, 27 Jul 2021 21:48:04 +0200 Subject: [PATCH 07/19] Checkout fontmap --- piet-cairo/Cargo.toml | 4 ++-- piet-cairo/src/text.rs | 19 +++++++++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/piet-cairo/Cargo.toml b/piet-cairo/Cargo.toml index ad0d5dbf..f84f7d20 100644 --- a/piet-cairo/Cargo.toml +++ b/piet-cairo/Cargo.toml @@ -14,8 +14,8 @@ categories = ["rendering::graphics-api"] piet = { version = "0.4.0", path = "../piet" } cairo-rs = { version = "0.14.0", default-features = false } # We don't need glib -pango = { version = "0.14.0", features = ["v1_44"] } -pango-sys = { version = "0.14.0", features = ["v1_44"] } +pango = { version = "0.14.0", features = ["v1_46"] } +pango-sys = { version = "0.14.0", features = ["v1_46"] } pangocairo = "0.14.0" glib = "0.14.0" unicode-segmentation = "1.3.0" diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index 2f8ad9bf..0d609b01 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -174,7 +174,7 @@ impl Text for CairoText { let font = FontDescription::from_string(family_name); - println!("AA"); + println!("request: {:?}", family_name); let best_match = self .pango_context @@ -208,11 +208,22 @@ impl Text for CairoText { Ordering::Greater } }); - - best_match.map(|(family, _)| { + best_match.clone().map(|(family, _)| { println!("result: {:?}", family.name()); FontFamily::new_unchecked(family.name().unwrap().as_str()) - }) + }); + + println!( + "result2: {:?}", + self.pango_context + .font_map() + .unwrap() + .family(family_name) + .unwrap() + .name() + ); + + best_match.map(|(family, _)| FontFamily::new_unchecked(family.name().unwrap().as_str())) } fn load_font(&mut self, _data: &[u8]) -> Result { From 1ff727629ec6a1cae47e35171872bfe4bc67428b Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Tue, 27 Jul 2021 22:03:21 +0200 Subject: [PATCH 08/19] Use the default font as initial value, if exists --- piet-cairo/src/text.rs | 60 +++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index 0d609b01..c28f4e36 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -175,42 +175,48 @@ impl Text for CairoText { let font = FontDescription::from_string(family_name); println!("request: {:?}", family_name); - let best_match = self .pango_context - .list_families() + .font_description() .iter() - .map(|family| { - println!("Family: {:?}", family.name()); - family - .list_faces() + .cloned() + .chain( + self.pango_context + .list_families() .iter() - .map(|fontface| (family.clone(), fontface.clone())) - .collect::>() - }) - .flatten() - .map(|(family, fontface)| { - fontface.describe().map(|fontdesc| { - println!( - "Family/Fontdesc: {:?}/{:?}", - family.name(), - fontdesc.to_str() - ); - - (family, fontdesc) - }) - }) - .flatten() + .map(|family| { + println!("Family: {:?}", family.name()); + family + .list_faces() + .iter() + .map(|fontface| (family.clone(), fontface.clone())) + .collect::>() + }) + .flatten() + .map(|(family, fontface)| { + fontface.describe().map(|fontdesc| { + println!( + "Family/Fontdesc: {:?}/{:?}", + family.name(), + fontdesc.to_str() + ); + + fontdesc + }) + }) + .flatten(), + ) .max_by(|a, b| { - if font.better_match(Some(&a.1), &b.1) { + if font.better_match(Some(a), b) { Ordering::Less } else { Ordering::Greater } }); - best_match.clone().map(|(family, _)| { - println!("result: {:?}", family.name()); - FontFamily::new_unchecked(family.name().unwrap().as_str()) + + best_match.clone().map(|fontdesc| { + println!("result: {:?}", fontdesc.to_str()); + FontFamily::new_unchecked(fontdesc.to_str().as_str()) }); println!( @@ -223,7 +229,7 @@ impl Text for CairoText { .name() ); - best_match.map(|(family, _)| FontFamily::new_unchecked(family.name().unwrap().as_str())) + best_match.map(|fontdesc| FontFamily::new_unchecked(fontdesc.to_str().as_str())) } fn load_font(&mut self, _data: &[u8]) -> Result { From 1101f303149eeac0e4769dc8d22069fe590c956a Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Tue, 27 Jul 2021 22:06:06 +0200 Subject: [PATCH 09/19] Back to 1.44 --- piet-cairo/Cargo.toml | 4 ++-- piet-cairo/src/text.rs | 10 ---------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/piet-cairo/Cargo.toml b/piet-cairo/Cargo.toml index f84f7d20..ad0d5dbf 100644 --- a/piet-cairo/Cargo.toml +++ b/piet-cairo/Cargo.toml @@ -14,8 +14,8 @@ categories = ["rendering::graphics-api"] piet = { version = "0.4.0", path = "../piet" } cairo-rs = { version = "0.14.0", default-features = false } # We don't need glib -pango = { version = "0.14.0", features = ["v1_46"] } -pango-sys = { version = "0.14.0", features = ["v1_46"] } +pango = { version = "0.14.0", features = ["v1_44"] } +pango-sys = { version = "0.14.0", features = ["v1_44"] } pangocairo = "0.14.0" glib = "0.14.0" unicode-segmentation = "1.3.0" diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index c28f4e36..b20a3d6d 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -219,16 +219,6 @@ impl Text for CairoText { FontFamily::new_unchecked(fontdesc.to_str().as_str()) }); - println!( - "result2: {:?}", - self.pango_context - .font_map() - .unwrap() - .family(family_name) - .unwrap() - .name() - ); - best_match.map(|fontdesc| FontFamily::new_unchecked(fontdesc.to_str().as_str())) } From f4132479104093fd3898dacb4259043dc0a9239f Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 28 Jul 2021 11:39:22 +0200 Subject: [PATCH 10/19] Use system-ui as default font --- piet-cairo/src/text.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index b20a3d6d..116215a1 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -8,9 +8,9 @@ use std::rc::Rc; use glib::translate::{from_glib_full, ToGlibPtr}; -use pango::prelude::FontFaceExt; use pango::prelude::FontFamilyExt; use pango::prelude::FontMapExt; +use pango::prelude::{FontExt, FontFaceExt}; use pango::FontDescription; use pango::{AttrList, FontFace}; use pango_sys::pango_attr_insert_hyphens_new; @@ -177,9 +177,18 @@ impl Text for CairoText { println!("request: {:?}", family_name); let best_match = self .pango_context - .font_description() + .font_map() + .unwrap() + .load_font( + &self.pango_context, + &FontDescription::from_string("system-ui"), + ) .iter() - .cloned() + .map(|font| { + println!("request: {:?}", font.describe().unwrap().to_str()); + + font.describe().unwrap() + }) .chain( self.pango_context .list_families() From d21f23a14a3cdbd18e6646cd2445537e8eff2a9b Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 28 Jul 2021 11:45:34 +0200 Subject: [PATCH 11/19] Print attributes --- piet-cairo/src/text.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index 116215a1..b3d91c59 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -402,6 +402,8 @@ impl TextLayoutBuilder for CairoTextLayoutBuilder { self.pango_layout.set_wrap(pango::WrapMode::WordChar); self.pango_layout.set_ellipsize(pango::EllipsizeMode::None); + println!("final attributes{:?}", self.pango_layout.attributes()); + // invalid until update_width() is called let mut layout = CairoTextLayout { is_rtl: util::first_strong_rtl(self.text.as_str()), From 7ca9372d9d9ce93e91804da9be8cdfad7d889220 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 28 Jul 2021 12:02:56 +0200 Subject: [PATCH 12/19] Default to system-ui like before --- piet-cairo/src/text.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index b3d91c59..9ed3cf6a 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -187,7 +187,7 @@ impl Text for CairoText { .map(|font| { println!("request: {:?}", font.describe().unwrap().to_str()); - font.describe().unwrap() + (glib::GString::from("system-ui"), font.describe().unwrap()) }) .chain( self.pango_context @@ -210,25 +210,24 @@ impl Text for CairoText { fontdesc.to_str() ); - fontdesc + (family.name().unwrap(), fontdesc) }) }) .flatten(), ) .max_by(|a, b| { - if font.better_match(Some(a), b) { + if font.better_match(Some(&a.1), &b.1) { Ordering::Less } else { Ordering::Greater } }); - best_match.clone().map(|fontdesc| { - println!("result: {:?}", fontdesc.to_str()); - FontFamily::new_unchecked(fontdesc.to_str().as_str()) + best_match.clone().map(|(family, _)| { + println!("result: {:?}", family); }); - best_match.map(|fontdesc| FontFamily::new_unchecked(fontdesc.to_str().as_str())) + best_match.map(|(family, _)| FontFamily::new_unchecked(family.as_str())) } fn load_font(&mut self, _data: &[u8]) -> Result { @@ -402,6 +401,12 @@ impl TextLayoutBuilder for CairoTextLayoutBuilder { self.pango_layout.set_wrap(pango::WrapMode::WordChar); self.pango_layout.set_ellipsize(pango::EllipsizeMode::None); + self.pango_layout + .attributes() + .unwrap() + .attributes() + .iter() + .for_each(|f| println!("{:?}", f)); println!("final attributes{:?}", self.pango_layout.attributes()); // invalid until update_width() is called From 88ccad211fb6edacdc83bd9ab9570e5930555844 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 28 Jul 2021 13:12:29 +0200 Subject: [PATCH 13/19] Cleanup --- piet-cairo/src/text.rs | 81 +++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 52 deletions(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index 9ed3cf6a..2cc136fc 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -8,11 +8,11 @@ use std::rc::Rc; use glib::translate::{from_glib_full, ToGlibPtr}; +use pango::prelude::FontFaceExt; use pango::prelude::FontFamilyExt; use pango::prelude::FontMapExt; -use pango::prelude::{FontExt, FontFaceExt}; +use pango::AttrList; use pango::FontDescription; -use pango::{AttrList, FontFace}; use pango_sys::pango_attr_insert_hyphens_new; use pangocairo::FontMap; @@ -170,63 +170,48 @@ impl Text for CairoText { type TextLayoutBuilder = CairoTextLayoutBuilder; fn font_family(&mut self, family_name: &str) -> Option { - // The pango documentation says this is always a string, and never null. + // We first do a case-insensitive match for the familly name + // After that we get the family which has the best matching font description. let font = FontDescription::from_string(family_name); - - println!("request: {:?}", family_name); + let target_lowercase = family_name.to_lowercase(); let best_match = self .pango_context - .font_map() - .unwrap() - .load_font( - &self.pango_context, - &FontDescription::from_string("system-ui"), - ) + .list_families() .iter() - .map(|font| { - println!("request: {:?}", font.describe().unwrap().to_str()); - - (glib::GString::from("system-ui"), font.describe().unwrap()) + .filter(|family| { + let family_lowercase = family.name().unwrap().to_lowercase(); + family_lowercase.contains(target_lowercase.as_str()) + || target_lowercase.contains(family_lowercase.as_str()) }) - .chain( - self.pango_context - .list_families() + .map(|family| { + family + .list_faces() .iter() - .map(|family| { - println!("Family: {:?}", family.name()); - family - .list_faces() - .iter() - .map(|fontface| (family.clone(), fontface.clone())) - .collect::>() + .map(|fontface| { + fontface + .describe() + .map(|fontdesc| (family.name().unwrap(), fontdesc)) }) .flatten() - .map(|(family, fontface)| { - fontface.describe().map(|fontdesc| { - println!( - "Family/Fontdesc: {:?}/{:?}", - family.name(), - fontdesc.to_str() - ); - - (family.name().unwrap(), fontdesc) - }) - }) - .flatten(), - ) + .collect::>() + }) + .flatten() .max_by(|a, b| { - if font.better_match(Some(&a.1), &b.1) { + //We can only use `better_match` with 2 args if the first argument matches matches + if font.better_match(None, &a.1) { + if font.better_match(Some(&a.1), &b.1) { + Ordering::Less + } else { + Ordering::Greater + } + } else if font.better_match(None, &b.1) { Ordering::Less } else { - Ordering::Greater + Ordering::Equal } }); - best_match.clone().map(|(family, _)| { - println!("result: {:?}", family); - }); - best_match.map(|(family, _)| FontFamily::new_unchecked(family.as_str())) } @@ -401,14 +386,6 @@ impl TextLayoutBuilder for CairoTextLayoutBuilder { self.pango_layout.set_wrap(pango::WrapMode::WordChar); self.pango_layout.set_ellipsize(pango::EllipsizeMode::None); - self.pango_layout - .attributes() - .unwrap() - .attributes() - .iter() - .for_each(|f| println!("{:?}", f)); - println!("final attributes{:?}", self.pango_layout.attributes()); - // invalid until update_width() is called let mut layout = CairoTextLayout { is_rtl: util::first_strong_rtl(self.text.as_str()), From bb0a74160d3ef0632d6699fc8f0e68407858a9f9 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 28 Jul 2021 16:53:08 +0200 Subject: [PATCH 14/19] Debug test --- piet-cairo/src/text.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index 2cc136fc..bfebfb1a 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -211,8 +211,8 @@ impl Text for CairoText { Ordering::Equal } }); - - best_match.map(|(family, _)| FontFamily::new_unchecked(family.as_str())) + Some(FontFamily::new_unchecked(family_name)) + // best_match.map(|(family, _)| FontFamily::new_unchecked(family.as_str())) } fn load_font(&mut self, _data: &[u8]) -> Result { @@ -381,7 +381,7 @@ impl TextLayoutBuilder for CairoTextLayoutBuilder { for attribute in self.attributes { pango_attributes.insert(attribute.into_pango()); } - + println!("{:?}", self.pango_layout.font_description()); self.pango_layout.set_attributes(Some(&pango_attributes)); self.pango_layout.set_wrap(pango::WrapMode::WordChar); self.pango_layout.set_ellipsize(pango::EllipsizeMode::None); From 03726513cf4a977dbaf6faa88c9a2a60c6c1eb12 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 28 Jul 2021 16:55:48 +0200 Subject: [PATCH 15/19] More debut --- piet-cairo/src/text.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index bfebfb1a..b8bfcda8 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -381,10 +381,11 @@ impl TextLayoutBuilder for CairoTextLayoutBuilder { for attribute in self.attributes { pango_attributes.insert(attribute.into_pango()); } - println!("{:?}", self.pango_layout.font_description()); + println!("1:{:?}", self.pango_layout.font_description()); self.pango_layout.set_attributes(Some(&pango_attributes)); self.pango_layout.set_wrap(pango::WrapMode::WordChar); self.pango_layout.set_ellipsize(pango::EllipsizeMode::None); + println!("2:{:?}", self.pango_layout.font_description()); // invalid until update_width() is called let mut layout = CairoTextLayout { From 720c44c902306a7c63b2526336a319fd035c2637 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 28 Jul 2021 17:31:06 +0200 Subject: [PATCH 16/19] This is what cairo should use --- piet-cairo/src/text.rs | 50 +++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index b8bfcda8..04b34ce7 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -177,26 +177,33 @@ impl Text for CairoText { let target_lowercase = family_name.to_lowercase(); let best_match = self .pango_context - .list_families() + .font_description() + .map(|fontdesc| (fontdesc.to_str(), fontdesc)) .iter() - .filter(|family| { - let family_lowercase = family.name().unwrap().to_lowercase(); - family_lowercase.contains(target_lowercase.as_str()) - || target_lowercase.contains(family_lowercase.as_str()) - }) - .map(|family| { - family - .list_faces() + .cloned() + .chain( + self.pango_context + .list_families() .iter() - .map(|fontface| { - fontface - .describe() - .map(|fontdesc| (family.name().unwrap(), fontdesc)) + .filter(|family| { + let family_lowercase = family.name().unwrap().to_lowercase(); + family_lowercase.contains(target_lowercase.as_str()) + || target_lowercase.contains(family_lowercase.as_str()) }) - .flatten() - .collect::>() - }) - .flatten() + .map(|family| { + family + .list_faces() + .iter() + .map(|fontface| { + fontface + .describe() + .map(|fontdesc| (family.name().unwrap(), fontdesc)) + }) + .flatten() + .collect::>() + }) + .flatten(), + ) .max_by(|a, b| { //We can only use `better_match` with 2 args if the first argument matches matches if font.better_match(None, &a.1) { @@ -211,8 +218,15 @@ impl Text for CairoText { Ordering::Equal } }); + println!( + "{:?}", + self.pango_context.font_description().unwrap().to_str() + ); + println!( + "{:?}", + best_match.map(|(family, _)| FontFamily::new_unchecked(family.as_str())) + ); Some(FontFamily::new_unchecked(family_name)) - // best_match.map(|(family, _)| FontFamily::new_unchecked(family.as_str())) } fn load_font(&mut self, _data: &[u8]) -> Result { From 4f1fdbc3a0793fc6792e243edb1dc5d9cef1a1ed Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 28 Jul 2021 17:35:05 +0200 Subject: [PATCH 17/19] ?? --- piet-cairo/src/text.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index 04b34ce7..89a182db 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -222,11 +222,7 @@ impl Text for CairoText { "{:?}", self.pango_context.font_description().unwrap().to_str() ); - println!( - "{:?}", - best_match.map(|(family, _)| FontFamily::new_unchecked(family.as_str())) - ); - Some(FontFamily::new_unchecked(family_name)) + best_match.map(|(family, _)| FontFamily::new_unchecked(family.as_str())) } fn load_font(&mut self, _data: &[u8]) -> Result { From 7eb17e81d53bfe06ba346b376aa3140ad091a2ed Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 28 Jul 2021 17:41:35 +0200 Subject: [PATCH 18/19] Debugging again --- piet-cairo/src/text.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index 89a182db..4ea542cc 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -208,13 +208,17 @@ impl Text for CairoText { //We can only use `better_match` with 2 args if the first argument matches matches if font.better_match(None, &a.1) { if font.better_match(Some(&a.1), &b.1) { + println!("{:?}>{:?}", a.1.to_str(), b.1.to_str()); Ordering::Less } else { + println!("{:?}<{:?}", a.1.to_str(), b.1.to_str()); Ordering::Greater } } else if font.better_match(None, &b.1) { + println!("{:?}<<{:?}", a.1.to_str(), b.1.to_str()); Ordering::Less } else { + println!("{:?}={:?}", a.1.to_str(), b.1.to_str()); Ordering::Equal } }); From bcedb2c5281e6166349c753e750395e2b9f8f24a Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Tue, 17 Aug 2021 16:37:03 +0200 Subject: [PATCH 19/19] Perfectly match how pango loads fonts This ignored char matching, language, and other attributes --- piet-cairo/src/text.rs | 189 ++++++++++++++++++++++++++++------------- 1 file changed, 130 insertions(+), 59 deletions(-) diff --git a/piet-cairo/src/text.rs b/piet-cairo/src/text.rs index 4ea542cc..907330be 100644 --- a/piet-cairo/src/text.rs +++ b/piet-cairo/src/text.rs @@ -8,11 +8,11 @@ use std::rc::Rc; use glib::translate::{from_glib_full, ToGlibPtr}; -use pango::prelude::FontFaceExt; -use pango::prelude::FontFamilyExt; use pango::prelude::FontMapExt; -use pango::AttrList; -use pango::FontDescription; +use pango::prelude::{FontExt, FontFaceExt}; +use pango::prelude::{FontFamilyExt, FontsetExt}; +use pango::{AttrList, Context}; +use pango::{FontDescription, Language}; use pango_sys::pango_attr_insert_hyphens_new; use pangocairo::FontMap; @@ -172,61 +172,117 @@ impl Text for CairoText { fn font_family(&mut self, family_name: &str) -> Option { // We first do a case-insensitive match for the familly name // After that we get the family which has the best matching font description. - let font = FontDescription::from_string(family_name); - let target_lowercase = family_name.to_lowercase(); - let best_match = self - .pango_context - .font_description() - .map(|fontdesc| (fontdesc.to_str(), fontdesc)) - .iter() - .cloned() - .chain( - self.pango_context - .list_families() - .iter() - .filter(|family| { - let family_lowercase = family.name().unwrap().to_lowercase(); - family_lowercase.contains(target_lowercase.as_str()) - || target_lowercase.contains(family_lowercase.as_str()) - }) - .map(|family| { - family - .list_faces() - .iter() - .map(|fontface| { - fontface - .describe() - .map(|fontdesc| (family.name().unwrap(), fontdesc)) - }) - .flatten() - .collect::>() - }) - .flatten(), - ) - .max_by(|a, b| { - //We can only use `better_match` with 2 args if the first argument matches matches - if font.better_match(None, &a.1) { - if font.better_match(Some(&a.1), &b.1) { - println!("{:?}>{:?}", a.1.to_str(), b.1.to_str()); - Ordering::Less - } else { - println!("{:?}<{:?}", a.1.to_str(), b.1.to_str()); - Ordering::Greater - } - } else if font.better_match(None, &b.1) { - println!("{:?}<<{:?}", a.1.to_str(), b.1.to_str()); - Ordering::Less - } else { - println!("{:?}={:?}", a.1.to_str(), b.1.to_str()); - Ordering::Equal - } + + // println!( + // "{:?}", + // self.pango_context + // .list_families() + // .iter() + // .map(|family| family.name().unwrap()) + // .collect::>() + // ); + + // Option 1: + // println!( + // "{:?}", + // self.pango_context + // .font_map() + // .unwrap() + // .load_font(&Context::default(), &font) + // .unwrap() + // .describe() + // .unwrap() + // .to_string() + // ); + // let fam = self + // .pango_context + // .font_map() + // .unwrap() + // .load_font(&Context::default(), &font) + // .unwrap() + // .describe() + // .unwrap() + // .to_string(); + // Some(FontFamily::new_unchecked(fam)) + + // Option 2: + let mut font_description: FontDescription = FontDescription::default(); + self.pango_context + .font_map() + .unwrap() + .load_fontset(&Context::default(), &font, &Language::default()) + .unwrap() + .foreach(|_fontset, font| { + font_description = font.describe().unwrap(); + true }); - println!( - "{:?}", - self.pango_context.font_description().unwrap().to_str() - ); - best_match.map(|(family, _)| FontFamily::new_unchecked(family.as_str())) + println!("{:?}", font_description.to_string()); + Some(FontFamily::new_unchecked(font_description.to_string())) + + // Option 3: + // let target_lowercase = family_name.to_lowercase(); + // let best_match = self + // .pango_context + // .list_families() + // .first() + // .map(|fontfam| fontfam.list_faces().first().unwrap().describe().unwrap()) + // .map(|font_desc| (font_desc.to_str(), font_desc)) + // .iter() + // .cloned() + // .chain( + // self.pango_context + // .list_families() + // .iter() + // .filter(|family| { + // let family_lowercase = family.name().unwrap().to_lowercase(); + // family_lowercase.contains(target_lowercase.as_str()) + // || target_lowercase.contains(family_lowercase.as_str()) + // }) + // .map(|family| { + // family + // .list_faces() + // .iter() + // .map(|fontface| { + // fontface + // .describe() + // .map(|fontdesc| (family.name().unwrap(), fontdesc)) + // }) + // .flatten() + // .collect::>() + // }) + // .flatten(), + // ) + // .max_by(|a, b| { + // //We can only use `better_match` with 2 args if the first argument matches matches + // if font.better_match(None, &a.1) { + // if font.better_match(Some(&a.1), &b.1) { + // println!("{:?}>{:?}", a.1.to_str(), b.1.to_str()); + // Ordering::Greater + // } else { + // println!("{:?}<{:?}", a.1.to_str(), b.1.to_str()); + // Ordering::Less + // } + // } else if font.better_match(None, &b.1) { + // println!("{:?}<<{:?}", a.1.to_str(), b.1.to_str()); + // Ordering::Greater + // } else { + // println!("{:?}={:?}", a.1.to_str(), b.1.to_str()); + // Ordering::Equal + // } + // }); + // println!( + // "{:?}", + // self.pango_context.font_description().unwrap().to_str() + // ); + // println!("{:?}", family_name); + // println!("{:?}", best_match); + + // best_match.map(|(family, _)| { + // println!("{:?}", family); + // FontFamily::new_unchecked(family_name) + // }) + // itemize_state_init } fn load_font(&mut self, _data: &[u8]) -> Result { @@ -391,9 +447,24 @@ impl TextLayoutBuilder for CairoTextLayoutBuilder { } .into_pango(), ); + for attr in pango_attributes.iterator().unwrap().attrs() { + println!("attr:{:?}", attr.type_()); + } - for attribute in self.attributes { - pango_attributes.insert(attribute.into_pango()); + for attribute in &self.attributes { + if let TextAttribute::FontFamily(fam) = &attribute.attribute { + println!("{:?}", fam); + pango_attributes.insert( + AttributeWithRange { + attribute: TextAttribute::FontFamily(fam.clone()), + range: None, + } + .into_pango(), + ); + } + } + for attr in pango_attributes.iterator().unwrap().attrs() { + println!("attr:{:?}", attr.type_()); } println!("1:{:?}", self.pango_layout.font_description()); self.pango_layout.set_attributes(Some(&pango_attributes));