1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
//! ```rust
//! let ilmenite = Ilmenite::new();
//!
//! ilmenite.add_font(
//! 	ImtFont::from_file(
//! 		"MyFont",
//! 		ImtWeight::Normal,
//! 		ImtRasterOpts::default(),
//! 		device,
//! 		queue,
//! 		"MyFont.ttf",
//! 		)
//! 	.unwrap(),
//! 	);
//!
//! let glyphs = ilmenite
//! 	.glyphs_for_text("MyFont", ImtWeight::Normal, 12.0, None, "Hello World!")
//! 	.unwrap();
//! ```

extern crate allsorts;
extern crate crossbeam;
extern crate ordered_float;
extern crate parking_lot;
extern crate vulkano;
extern crate vulkano_shaders;

pub mod bitmap;
pub mod error;
pub mod font;
pub mod parse;
pub mod primative;
pub mod raster;
pub mod script;
pub mod shaders;
pub mod shape;

pub use bitmap::ImtGlyphBitmap;
use crossbeam::sync::ShardedLock;
pub use error::{ImtError, ImtErrorSrc, ImtErrorTy};
pub(crate) use font::ImtFontKey;
pub use font::{ImtFont, ImtWeight};
pub use parse::{ImtFontProps, ImtParsedGlyph, ImtParser};
pub use primative::{ImtGeometry, ImtPoint, ImtPosition};
pub use raster::{
	ImtFillQuality, ImtRaster, ImtRasterOpts, ImtRasteredGlyph, ImtSampleQuality,
};
pub use script::{ImtLang, ImtScript};
pub use shape::{
	ImtGlyphInfo, ImtHoriAlign, ImtShapeOpts, ImtShapedGlyph, ImtShaper, ImtTextWrap,
	ImtVertAlign,
};
use std::{collections::HashMap, sync::Arc};

pub struct ImtGlyph {
	pub x: f32,
	pub y: f32,
	pub w: u32,
	pub h: u32,
	pub crop_x: f32,
	pub crop_y: f32,
	pub family: String,
	pub weight: ImtWeight,
	pub index: u16,
	/// Bitmap layout is Linear RGBA.
	pub bitmap: Option<Arc<Vec<f32>>>,
}

pub struct Ilmenite {
	fonts: ShardedLock<HashMap<ImtFontKey, ImtFont>>,
}

impl Ilmenite {
	pub fn new() -> Self {
		Ilmenite {
			fonts: ShardedLock::new(HashMap::new()),
		}
	}

	pub fn add_font(&self, font: ImtFont) {
		let key = font.key();
		self.fonts.write().unwrap().insert(key, font);
	}

	pub fn glyphs_for_text<T: AsRef<str>>(
		&self,
		family: String,
		weight: ImtWeight,
		text_height: f32,
		shape_ops: Option<ImtShapeOpts>,
		text: T,
	) -> Result<Vec<ImtGlyph>, ImtError> {
		self.fonts
			.read()
			.unwrap()
			.get(&ImtFontKey {
				family,
				weight,
			})
			.ok_or(ImtError::src_and_ty(ImtErrorSrc::Ilmenite, ImtErrorTy::MissingFont))?
			.glyphs_for_text(text_height, shape_ops.unwrap_or(ImtShapeOpts::default()), text)
	}
}