Format cursor code and add documentation

As requested a few comments have been added to the darwin code. There
also was an off by one error in the ascent calculation which has been
corrected.

The beam cursor width has also been tweaked to be slightly slimmer in
general.

All code added in this PR has also been run through the default rustfmt
to make sure the formatting is okay.
This commit is contained in:
Christian Duerr 2017-12-09 17:07:07 +01:00 committed by Joe Wilm
parent ce8bd1aaf2
commit 8195d71034
3 changed files with 42 additions and 22 deletions

View File

@ -462,17 +462,31 @@ impl Font {
pub fn get_glyph(&self, character: char, _size: f64, use_thin_strokes: bool) -> Result<RasterizedGlyph, Error> { pub fn get_glyph(&self, character: char, _size: f64, use_thin_strokes: bool) -> Result<RasterizedGlyph, Error> {
// Render custom symbols for underline and beam cursor // Render custom symbols for underline and beam cursor
if character == super::UNDERLINE_CURSOR_CHAR { match character {
let descent = -(self.ct_font.descent() as i32); super::UNDERLINE_CURSOR_CHAR => {
let width = self.glyph_advance('0') as i32; // Get the bottom of the bounding box
return super::get_underline_cursor_glyph(descent, width); let descent = -(self.ct_font.descent() as i32);
} else if character == super::BEAM_CURSOR_CHAR { // Get the width of the cell
let metrics = self.metrics(); let width = self.glyph_advance('0') as i32;
let height = metrics.line_height; // Return the new custom glyph
let ascent = height - self.ct_font.descent() + 1.; return super::get_underline_cursor_glyph(descent, width);
let width = self.glyph_advance('0') as i32; },
return super::get_beam_cursor_glyph(ascent as i32, height as i32, width); super::BEAM_CURSOR_CHAR => {
}; // Get the top of the bounding box
let metrics = self.metrics();
let height = metrics.line_height;
let mut ascent = height - self.ct_font.descent() + 1.;
if ascent.floor() == ascent {
// Fix off-by-one with an exact X.0 ascent
ascent -= 1.;
}
// Get the width of the cell
let width = self.glyph_advance('0') as i32;
// Return the new custom glyph
return super::get_beam_cursor_glyph(ascent as i32, height as i32, width);
},
_ => (),
}
let glyph_index = self.glyph_index(character) let glyph_index = self.glyph_index(character)
.ok_or(Error::MissingGlyph(character))?; .ok_or(Error::MissingGlyph(character))?;

View File

@ -298,7 +298,8 @@ impl FreeTypeRasterizer {
match glyph_key.c { match glyph_key.c {
super::UNDERLINE_CURSOR_CHAR => { super::UNDERLINE_CURSOR_CHAR => {
// Get the bottom of the bounding box // Get the bottom of the bounding box
let size_metrics = face.ft_face.size_metrics() let size_metrics = face.ft_face
.size_metrics()
.ok_or(Error::MissingSizeMetrics)?; .ok_or(Error::MissingSizeMetrics)?;
let descent = (size_metrics.descender / 64) as i32; let descent = (size_metrics.descender / 64) as i32;
@ -308,10 +309,11 @@ impl FreeTypeRasterizer {
// Return the new custom glyph // Return the new custom glyph
super::get_underline_cursor_glyph(descent, width) super::get_underline_cursor_glyph(descent, width)
}, }
super::BEAM_CURSOR_CHAR => { super::BEAM_CURSOR_CHAR => {
// Get the top of the bounding box // Get the top of the bounding box
let size_metrics = face.ft_face.size_metrics() let size_metrics = face.ft_face
.size_metrics()
.ok_or(Error::MissingSizeMetrics)?; .ok_or(Error::MissingSizeMetrics)?;
let ascent = (size_metrics.ascender / 64) as i32 - 1; let ascent = (size_metrics.ascender / 64) as i32 - 1;
@ -325,7 +327,7 @@ impl FreeTypeRasterizer {
// Return the new custom glyph // Return the new custom glyph
super::get_beam_cursor_glyph(ascent, height, width) super::get_beam_cursor_glyph(ascent, height, width)
}, }
_ => { _ => {
// If it's not a special char, return the normal glyph // If it's not a special char, return the normal glyph
Ok(RasterizedGlyph { Ok(RasterizedGlyph {

View File

@ -43,7 +43,7 @@ extern crate foreign_types;
extern crate log; extern crate log;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::fmt; use std::{fmt, cmp};
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
// If target isn't macos, reexport everything from ft // If target isn't macos, reexport everything from ft
@ -65,6 +65,8 @@ pub const UNDERLINE_CURSOR_CHAR: char = '\u{10a3e2}';
/// Character used for the beam cursor /// Character used for the beam cursor
// This is part of the private use area and should not conflict with any font // This is part of the private use area and should not conflict with any font
pub const BEAM_CURSOR_CHAR: char = '\u{10a3e3}'; pub const BEAM_CURSOR_CHAR: char = '\u{10a3e3}';
/// Width of the beam cursor relative to the font width
pub const BEAM_CURSOR_WIDTH_PERCENTAGE: i32 = 15;
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FontDesc { pub struct FontDesc {
@ -211,11 +213,10 @@ impl Default for RasterizedGlyph {
} }
// Returns a custom underline cursor character // Returns a custom underline cursor character
// TODO: Make sure this works with positive/0 descent -> small fonts
pub fn get_underline_cursor_glyph(descent: i32, width: i32) -> Result<RasterizedGlyph, Error> { pub fn get_underline_cursor_glyph(descent: i32, width: i32) -> Result<RasterizedGlyph, Error> {
// Create a new rectangle, the height is half the distance between // Create a new rectangle, the height is half the distance between
// bounding box bottom and the baseline // bounding box bottom and the baseline
let height = i32::abs(descent / 2); let height = cmp::max(i32::abs(descent / 2), 1);
let buf = vec![255u8; (width * height * 3) as usize]; let buf = vec![255u8; (width * height * 3) as usize];
// Create a custom glyph with the rectangle data attached to it // Create a custom glyph with the rectangle data attached to it
@ -230,10 +231,13 @@ pub fn get_underline_cursor_glyph(descent: i32, width: i32) -> Result<Rasterized
} }
// Returns a custom beam cursor character // Returns a custom beam cursor character
// TODO: Make sure this works with positive/0 descent -> small fonts pub fn get_beam_cursor_glyph(
pub fn get_beam_cursor_glyph(ascent: i32, height: i32, width: i32) -> Result<RasterizedGlyph, Error> { ascent: i32,
// Create a new rectangle height: i32,
let beam_width = (f64::from(width) / 5.) as i32; width: i32,
) -> Result<RasterizedGlyph, Error> {
// Create a new rectangle that is at least one pixel wide
let beam_width = cmp::max(width * BEAM_CURSOR_WIDTH_PERCENTAGE / 100, 1);
let buf = vec![255u8; (beam_width * height * 3) as usize]; let buf = vec![255u8; (beam_width * height * 3) as usize];
// Create a custom glyph with the rectangle data attached to it // Create a custom glyph with the rectangle data attached to it