Skip to content

Commit

Permalink
up
Browse files Browse the repository at this point in the history
  • Loading branch information
jaytaph committed Jan 15, 2025
1 parent 6f3cd0a commit aa9d1b7
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 118 deletions.
9 changes: 5 additions & 4 deletions src/bin/gtk2-test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ fn draw(manager: &FontManager, font: &FontInfo, cr: &gtk4::cairo::Context, layou
}
}

fn create_layout(manager: &mut FontManager, font: &FontInfo, text: &str, width: f64, font_size: f64) -> Layout<ColorBrush> {
fn create_layout(manager: &FontManager, font: &FontInfo, text: &str, width: f64, font_size: f64) -> Layout<ColorBrush> {
let display_scale = 1.0_f32;
let max_advance = Some(width as f32 * display_scale);

Expand All @@ -198,12 +198,13 @@ fn create_layout(manager: &mut FontManager, font: &FontInfo, text: &str, width:
// let underline_style = StyleProperty::Underline(true);
// let strikethrough_style = StyleProperty::Strikethrough(true);

let font = manager.parley_load_font(&font).unwrap();
let mut font_context = manager.parley_context_mut().expect("Failed to get parley context");
let font_stack = manager.parley_get_font_stack(&font).unwrap();
let binding = manager.parley_context().expect("Failed to get font context");
let mut font_context = binding.borrow_mut();

let mut builder = layout_cx.ranged_builder(&mut font_context, &text, display_scale);
builder.push_default(brush_style);
builder.push_default(font);
builder.push_default(font_stack);
builder.push_default(StyleProperty::LineHeight(1.3));
builder.push_default(StyleProperty::FontSize(font_size as f32));
builder.push_default(StyleProperty::LetterSpacing(5.0));
Expand Down
31 changes: 11 additions & 20 deletions src/bin/parley.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use image::codecs::png::PngEncoder;
use image::{self, Pixel, Rgba, RgbaImage};
use parley::layout::{Alignment, Glyph, GlyphRun, Layout, PositionedLayoutItem};
use parley::style::{FontStack, FontWeight, StyleProperty};
use parley::{FontContext, InlineBox, LayoutContext};
use parley::style::{FontWeight, StyleProperty};
use parley::{InlineBox, LayoutContext};
use std::fs::File;
use swash::scale::image::Content;
use swash::scale::{Render, ScaleContext, Scaler, Source, StrikeWith};
use swash::zeno;
use swash::FontRef;
use zeno::{Format, Vector};
use fontmanager::font_manager::FontStyle;
use fontmanager::{FontManager, FontSourceType, FontStyle};

#[derive(Clone, Copy, Debug, PartialEq)]
struct ColorBrush {
Expand All @@ -35,21 +35,10 @@ fn main() {

let padding = 20;

let mut font_cx = FontContext::new();

font_cx.collection.family_names().for_each(|name| {
println!("Family: {}", name);
});
let font_stack = FontStack::from("comic sans ms");

let fontmanager = fontmanager::font_manager::FontManager::new();
let Some(font_info) = fontmanager.find(vec!["arial"], FontStyle::Normal) else {
panic!("Font not found");
};
let font = fontmanager.load(&font_info).expect("Error loading font");



let manager = FontManager::new();
let font_info = manager.find(FontSourceType::Parley, &["consolas", "verdana", "comic sans ms", "arial"], FontStyle::Normal).expect("font not found");
let font_stack = manager.parley_get_font_stack(&font_info).expect("Comic sans not found");
let font_cx = manager.parley_context().expect("Parley context not found");

let mut layout_cx = LayoutContext::new();
let mut scale_cx = ScaleContext::new();
Expand All @@ -63,7 +52,8 @@ fn main() {
let text = "Some text here. Let's make it a bit longer so that line wrapping kicks in 😊. And also some اللغة العربية arabic text.\nThis is underline and strikethrough text";
// let text = fontmanager::flatland::TEXT;

let mut builder = layout_cx.ranged_builder(&mut font_cx, &text, display_scale);
let mut binding = font_cx.borrow_mut();
let mut builder = layout_cx.ranged_builder(&mut binding, &text, display_scale);
builder.push_default(brush_style);
builder.push_default(font_stack);
builder.push_default(StyleProperty::LineHeight(1.3));
Expand Down Expand Up @@ -127,9 +117,10 @@ fn main() {
path.push("swash_render.png");
path
};
let output_file = File::create(output_path).unwrap();
let output_file = File::create(output_path.clone()).unwrap();
let png_encoder = PngEncoder::new(output_file);
img.write_with_encoder(png_encoder).unwrap();
println!("Image written to: {:?}", output_path);
}


Expand Down
48 changes: 20 additions & 28 deletions src/font_manager/manager.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::cell::RefCell;
use std::collections::HashMap;
use std::sync::Arc;
use anyhow::anyhow;
use log::error;
use crate::font_manager::font_info::{FontInfo, FontStyle};
Expand Down Expand Up @@ -64,13 +66,15 @@ impl FontManager {
}

pub fn find(&self, source_type: FontSourceType, families: &[&str], style: FontStyle) -> Option<FontInfo> {
match self.sources.get(&source_type) {
Some(source) => source.find(families, style).ok(),
None => {
error!(target: LOG_TARGET, "Unknown font source: {:?}", source_type);
None
for &fam in families {
for fi in self.available_fonts(source_type) {
if fi.family.eq_ignore_ascii_case(fam) && fi.style == style {
return Some(fi.clone());
}
}
}

None
}
}

Expand Down Expand Up @@ -98,26 +102,16 @@ impl FontManager {
ps.load_freetype_font(font_info)
}

#[cfg(feature = "source_parley")]
pub fn parley_load_font(&self, _font_info: &FontInfo) -> Result<parley::FontStack, anyhow::Error> {
let Some(source) = self.sources.get(&FontSourceType::Parley) else {
return Err(anyhow!("Parley source not found"))
};

let _ps = source.as_any().downcast_ref::<ParleySource>()
.ok_or_else(|| anyhow!("Failed to downcast ParleySource"))?;

// ps.context().load_font(font_info)
Err(anyhow!("Not implemented"))
}

#[cfg(feature = "source_pango")]
pub fn pango_load_font(&self, _font_info: &FontInfo) -> Result<pangocairo::Font, anyhow::Error> {
let Some(_source) = self.sources.get(&FontSourceType::Pango) else {
pub fn pango_load_font(&self, font_info: &FontInfo) -> Result<pangocairo::pango::Font, anyhow::Error> {
let Some(source) = self.sources.get(&FontSourceType::Pango) else {
return Err(anyhow!("Pango source not found"))
};

Err(anyhow!("Not implemented"))
let ps = source.as_any().downcast_ref::<PangoSource>()
.ok_or_else(|| anyhow!("Failed to downcast PangoSource"))?;

ps.load_font(font_info)
}

#[cfg(feature = "source_pango")]
Expand All @@ -133,7 +127,7 @@ impl FontManager {
}

#[cfg(feature = "source_parley")]
pub fn parley_context(&self) -> Result<&parley::FontContext, anyhow::Error> {
pub fn parley_context(&self) -> Result<Arc<RefCell<parley::FontContext>>, anyhow::Error> {
let Some(source) = self.sources.get(&FontSourceType::Parley) else {
return Err(anyhow!("Parley source not found"))
};
Expand All @@ -144,17 +138,15 @@ impl FontManager {
Ok(ps.context())
}


#[cfg(feature = "source_parley")]
pub fn parley_context_mut(&mut self) -> Result<&mut parley::FontContext, anyhow::Error> {
let Some(source) = self.sources.get_mut(&FontSourceType::Parley) else {
pub fn parley_get_font_stack(&self, font_info: &FontInfo) -> Result<parley::FontStack, anyhow::Error> {
let Some(source) = self.sources.get(&FontSourceType::Parley) else {
return Err(anyhow!("Parley source not found"))
};

let ps= source.as_any_mut().downcast_mut::<ParleySource>()
let ps = source.as_any().downcast_ref::<ParleySource>()
.ok_or_else(|| anyhow!("Failed to downcast ParleySource"))?;

Ok(ps.context_mut())
Ok(ps.get_font_stack(font_info.family.clone()))
}

}
7 changes: 1 addition & 6 deletions src/font_manager/sources.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::font_manager::font_info::{FontInfo, FontStyle};
use crate::font_manager::font_info::FontInfo;
use std::any::Any;
use std::path::{Path, PathBuf};

Expand All @@ -14,22 +14,17 @@ pub mod pango;
pub trait FontSource: AsAny {
fn new() -> Self where Self: Sized;
fn available_fonts(&self) -> &[FontInfo];
fn find(&self, family: &[&str], style: FontStyle) -> Result<FontInfo, anyhow::Error>;
}

pub trait AsAny {
#[allow(unused)]
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}

impl<T: FontSource + Any> AsAny for T {
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}

#[derive(Clone, Copy, Hash, Eq, PartialEq, Debug)]
Expand Down
13 changes: 0 additions & 13 deletions src/font_manager/sources/fontique.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::collections::HashSet;
use std::path::PathBuf;
use log::info;
use anyhow::Error;
use fontique::{Collection, CollectionOptions, SourceKind};
use crate::font_manager::font_info::{FontInfo, FontStyle};
use crate::font_manager::sources::{resolve_symlink, FontSource, FontSourceType};
Expand Down Expand Up @@ -74,16 +73,4 @@ impl FontSource for FontiqueSource {
fn available_fonts(&self) -> &[FontInfo] {
&self.font_info
}

fn find(&self, family: &[&str], style: FontStyle) -> Result<FontInfo, Error> {
for &fam in family {
for fi in &self.font_info {
if fi.family.eq_ignore_ascii_case(fam) && fi.style == style {
return Ok(fi.clone());
}
}
}

Err(Error::msg("Font not found"))
}
}
14 changes: 1 addition & 13 deletions src/font_manager/sources/fontkit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::font_manager::manager::LOG_TARGET;
use std::collections::{HashMap, HashSet};
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use anyhow::{anyhow, Error};
use anyhow::anyhow;
use font_kit::handle::Handle;
use font_kit::source::SystemSource;
use freetype::{Face, Library};
Expand Down Expand Up @@ -53,18 +53,6 @@ impl FontSource for FontKitSource {
fn available_fonts(&self) -> &[FontInfo] {
&self.font_info
}

fn find(&self, family: &[&str], style: FontStyle) -> Result<FontInfo, Error> {
for &fam in family {
for fi in &self.font_info {
if fi.family.eq_ignore_ascii_case(fam) && fi.style == style {
return Ok(fi.clone());
}
}
}

Err(Error::msg("Font not found"))
}
}

impl FontKitSource {
Expand Down
17 changes: 6 additions & 11 deletions src/font_manager/sources/pango.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,16 @@ impl FontSource for PangoSource {
fn available_fonts(&self) -> &[FontInfo] {
&self.font_info
}
}

fn find(&self, family: &[&str], style: FontStyle) -> Result<FontInfo, Error> {
for &fam in family {
for fi in &self.font_info {
if fi.family.eq_ignore_ascii_case(fam) && fi.style == style {
return Ok(fi.clone());
}
}
}
impl PangoSource {
pub fn load_font(&self, info: &FontInfo) -> Result<pangocairo::pango::Font, Error> {
let family = self.font_map.load_font(&self.context, &self.get_description(info, 12.0))
.ok_or_else(|| Error::msg("Failed to load font"))?;

Err(Error::msg("Font not found"))
Ok(family)
}
}

impl PangoSource {
pub fn get_description(&self, info: &FontInfo, size: f64) -> pangocairo::pango::FontDescription {
let mut desc = pangocairo::pango::FontDescription::new();
desc.set_family(&info.family.clone());
Expand Down
33 changes: 10 additions & 23 deletions src/font_manager/sources/parley.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use std::borrow::Cow;
use std::collections::HashSet;
use std::path::PathBuf;
use anyhow::Error;
use log::info;
use std::cell::RefCell;
use std::sync::Arc;
use crate::font_manager::font_info::{FontInfo, FontStyle};
use crate::font_manager::sources::{resolve_symlink, FontSource, FontSourceType};

// #[allow(unused)]
pub struct ParleySource {
context: RefCell<parley::FontContext>,
context: Arc<RefCell<parley::FontContext>>,
font_info: Vec<FontInfo>
}

Expand Down Expand Up @@ -65,38 +66,24 @@ impl FontSource for ParleySource {
info!("Loaded {} fonts from parley.", font_info.len());

Self {
context: RefCell::new(context),
context: Arc::new(RefCell::new(context)),
font_info,
}
}

fn available_fonts(&self) -> &[FontInfo] {
&self.font_info
}

fn find(&self, family: &[&str], style: FontStyle) -> Result<FontInfo, Error> {
for &fam in family {
for fi in &self.font_info {
if fi.family.eq_ignore_ascii_case(fam) && fi.style == style {
return Ok(fi.clone());
}
}
}

Err(Error::msg("Font not found"))
}
}

impl ParleySource {
pub fn context(&self) -> RefCell<parley::FontContext> {
self.context
pub fn context(&self) -> Arc<RefCell<parley::FontContext>> {
self.context.clone()
}

pub fn context_mut(&mut self) -> &mut parley::FontContext {
&mut self.context.borrow_mut()
pub fn get_font_stack(&self, family: String) -> parley::FontStack {
parley::FontStack::Single(
parley::style::FontFamily::Named(Cow::Owned(family))
)
}

// pub fn load_font(&self, _font_info: &FontInfo) -> Result<parley::FontStack, anyhow::Error> {
// Err(anyhow!("Not implemented"))
// }
}

0 comments on commit aa9d1b7

Please sign in to comment.