Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement checking if the font familly exists in pango #455

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 137 additions & 6 deletions piet-cairo/src/text.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -8,7 +9,10 @@ use std::rc::Rc;
use glib::translate::{from_glib_full, ToGlibPtr};

use pango::prelude::FontMapExt;
use pango::AttrList;
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;

Expand Down Expand Up @@ -166,8 +170,119 @@ impl Text for CairoText {
type TextLayoutBuilder = CairoTextLayoutBuilder;

fn font_family(&mut self, family_name: &str) -> Option<FontFamily> {
//TODO: Veryify that a family exists with the requested name
Some(FontFamily::new_unchecked(family_name))
// 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!(
// "{:?}",
// self.pango_context
// .list_families()
// .iter()
// .map(|family| family.name().unwrap())
// .collect::<Vec<glib::GString>>()
// );

// 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!("{:?}", 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::<Vec<(glib::GString, FontDescription)>>()
// })
// .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<FontFamily, Error> {
Expand Down Expand Up @@ -332,14 +447,30 @@ impl TextLayoutBuilder for CairoTextLayoutBuilder {
}
.into_pango(),
);

for attribute in self.attributes {
pango_attributes.insert(attribute.into_pango());
for attr in pango_attributes.iterator().unwrap().attrs() {
println!("attr:{:?}", attr.type_());
}

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));
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 {
Expand Down
2 changes: 1 addition & 1 deletion piet/src/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}

Expand Down