ndless-freetype 0.1.3

Bindings for FreeType font library for Ndless
Documentation
use crate::{ffi, Bitmap, FtResult, Glyph, GlyphMetrics, Outline, RenderMode, Vector};
use std::ptr::null_mut;

/// A description of a given subglyph returned by `GlyphSlot::get_subglyph_info`
/// function.
#[derive(Copy, Clone)]
pub struct SubGlyphInfo {
	/// The glyph index of the subglyph.
	pub index: i32,
	/// The subglyph flags, see FT_SUBGLYPH_FLAG_XXX.
	pub flags: u32,
	/// The subglyph's first argument (if any).
	pub arg1: i32,
	/// The subglyph's second argument (if any).
	pub arg2: i32,
	/// The subglyph transformation (if any).
	pub transfrom: ffi::FT_Matrix,
}

impl Default for SubGlyphInfo {
	fn default() -> Self {
		SubGlyphInfo {
			index: 0,
			flags: 0,
			arg1: 0,
			arg2: 0,
			transfrom: ffi::FT_Matrix {
				xx: 0,
				xy: 0,
				yx: 0,
				yy: 0,
			},
		}
	}
}

/// A struct encapsulating the space for a glyph within a `Library`
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct GlyphSlot {
	library_raw: ffi::FT_Library,
	raw: ffi::FT_GlyphSlot,
}

impl GlyphSlot {
	/// Create a `GlyphSlot` from its constituent C parts
	pub unsafe fn from_raw(library_raw: ffi::FT_Library, raw: ffi::FT_GlyphSlot) -> Self {
		GlyphSlot { library_raw, raw }
	}

	/// Convert a given glyph image to a bitmap. It does so by inspecting the glyph image format,
	/// finding the relevant renderer, and invoking it.
	pub fn render_glyph(&self, render_mode: RenderMode) -> FtResult<()> {
		let err = unsafe { ffi::FT_Render_Glyph(self.raw, render_mode as u32) };
		if err == ffi::FT_Err_Ok {
			Ok(())
		} else {
			Err(err.into())
		}
	}

	/// Retrieve a description of a given subglyph. Only use it if the glyph's format is
	/// FT_GLYPH_FORMAT_COMPOSITE; an error is returned otherwise.
	pub fn get_subglyph_info(&self, sub_index: u32) -> FtResult<SubGlyphInfo> {
		let mut info = SubGlyphInfo::default();
		let err = unsafe {
			ffi::FT_Get_SubGlyph_Info(
				self.raw,
				sub_index,
				&mut info.index,
				&mut info.flags,
				&mut info.arg1,
				&mut info.arg2,
				&mut info.transfrom,
			)
		};
		if err == ffi::FT_Err_Ok {
			Ok(info)
		} else {
			Err(err.into())
		}
	}

	/// Returns a glyph object, that is similar to a `GlyphSlot` but managed outside of the library
	pub fn get_glyph(&self) -> FtResult<Glyph> {
		let mut aglyph = null_mut();

		let err = unsafe { ffi::FT_Get_Glyph(self.raw, &mut aglyph) };
		if err == ffi::FT_Err_Ok {
			Ok(unsafe { Glyph::from_raw(self.library_raw, aglyph) })
		} else {
			Err(err.into())
		}
	}

	/// In freetype, the `Outline` object is a scalable glyph. This method unpacks a glyph into
	/// this object, or returns `None` if the glyph has no `outline`
	pub fn outline(&self) -> Option<Outline> {
		let outline = unsafe { &(*self.raw).outline };
		let format = unsafe { (*self.raw).format };

		if format == ffi::FT_GLYPH_FORMAT_OUTLINE {
			let outline = unsafe { Outline::from_raw(outline) };
			Some(outline)
		} else {
			None
		}
	}

	/// This field is used as a bitmap descriptor when the slot format is FT_GLYPH_FORMAT_BITMAP.
	/// Note that the address and content of the bitmap buffer can change between calls of
	/// FT_Load_Glyph and a few other functions.
	#[inline(always)]
	pub fn bitmap(&self) -> Bitmap {
		unsafe { Bitmap::from_raw(&(*self.raw).bitmap) }
	}

	/// The bitmap's left bearing expressed in integer pixels. Only valid if the format is
	/// FT_GLYPH_FORMAT_BITMAP, this is, if the glyph slot contains a bitmap.
	#[inline(always)]
	pub fn bitmap_left(&self) -> i32 {
		unsafe { (*self.raw).bitmap_left }
	}

	/// The bitmap's top bearing expressed in integer pixels. Remember that this is the distance
	/// from the baseline to the top-most glyph scanline, upwards y coordinates being positive.
	#[inline(always)]
	pub fn bitmap_top(&self) -> i32 {
		unsafe { (*self.raw).bitmap_top }
	}

	/// This shorthand is, depending on FT_LOAD_IGNORE_TRANSFORM, the transformed (hinted) advance
	/// width for the glyph, in 26.6 fractional pixel format. As specified with
	/// FT_LOAD_VERTICAL_LAYOUT, it uses either the ‘horiAdvance’ or the ‘vertAdvance’ value of
	/// ‘metrics’ field.
	#[inline(always)]
	pub fn advance(&self) -> Vector {
		unsafe { (*self.raw).advance }
	}

	/// The advance width of the unhinted glyph. Its value is expressed in 16.16 fractional pixels,
	/// unless FT_LOAD_LINEAR_DESIGN is set when loading the glyph. This field can be important to
	/// perform correct WYSIWYG layout. Only relevant for outline glyphs.
	#[inline(always)]
	pub fn linear_hori_advance(&self) -> ffi::FT_Fixed {
		unsafe { (*self.raw).linearHoriAdvance }
	}

	/// The advance height of the unhinted glyph. Its value is expressed in 16.16 fractional
	/// pixels, unless FT_LOAD_LINEAR_DESIGN is set when loading the glyph. This field can be
	/// important to perform correct WYSIWYG layout. Only relevant for outline glyphs.
	#[inline(always)]
	pub fn linear_vert_advance(&self) -> ffi::FT_Fixed {
		unsafe { (*self.raw).linearVertAdvance }
	}

	/// The metrics of the last loaded glyph in the slot. The returned values depend on the last
	/// load flags (see the FT_Load_Glyph API function) and can be expressed either in 26.6
	/// fractional pixels or font units.
	#[inline(always)]
	pub fn metrics(&self) -> GlyphMetrics {
		unsafe { (*self.raw).metrics }
	}

	/// Get a pointer to the underlying c struct
	#[inline(always)]
	pub fn raw(&self) -> &ffi::FT_GlyphSlotRec {
		unsafe { &*self.raw }
	}
}