summaryrefslogtreecommitdiffstats
path: root/font
diff options
context:
space:
mode:
Diffstat (limited to 'font')
-rw-r--r--font/src/darwin/mod.rs36
-rw-r--r--font/src/ft/mod.rs10
-rw-r--r--font/src/lib.rs18
3 files changed, 42 insertions, 22 deletions
diff --git a/font/src/darwin/mod.rs b/font/src/darwin/mod.rs
index 877564fa..a6deba3b 100644
--- a/font/src/darwin/mod.rs
+++ b/font/src/darwin/mod.rs
@@ -462,17 +462,31 @@ impl Font {
pub fn get_glyph(&self, character: char, _size: f64, use_thin_strokes: bool) -> Result<RasterizedGlyph, Error> {
// Render custom symbols for underline and beam cursor
- if character == super::UNDERLINE_CURSOR_CHAR {
- let descent = -(self.ct_font.descent() as i32);
- let width = self.glyph_advance('0') as i32;
- return super::get_underline_cursor_glyph(descent, width);
- } else if character == super::BEAM_CURSOR_CHAR {
- let metrics = self.metrics();
- let height = metrics.line_height;
- let ascent = height - self.ct_font.descent() + 1.;
- let width = self.glyph_advance('0') as i32;
- return super::get_beam_cursor_glyph(ascent as i32, height as i32, width);
- };
+ match character {
+ super::UNDERLINE_CURSOR_CHAR => {
+ // Get the bottom of the bounding box
+ let descent = -(self.ct_font.descent() as i32);
+ // Get the width of the cell
+ let width = self.glyph_advance('0') as i32;
+ // Return the new custom glyph
+ return super::get_underline_cursor_glyph(descent, 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)
.ok_or(Error::MissingGlyph(character))?;
diff --git a/font/src/ft/mod.rs b/font/src/ft/mod.rs
index 7b22fb03..765e8efb 100644
--- a/font/src/ft/mod.rs
+++ b/font/src/ft/mod.rs
@@ -298,7 +298,8 @@ impl FreeTypeRasterizer {
match glyph_key.c {
super::UNDERLINE_CURSOR_CHAR => {
// 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)?;
let descent = (size_metrics.descender / 64) as i32;
@@ -308,10 +309,11 @@ impl FreeTypeRasterizer {
// Return the new custom glyph
super::get_underline_cursor_glyph(descent, width)
- },
+ }
super::BEAM_CURSOR_CHAR => {
// 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)?;
let ascent = (size_metrics.ascender / 64) as i32 - 1;
@@ -325,7 +327,7 @@ impl FreeTypeRasterizer {
// Return the new custom glyph
super::get_beam_cursor_glyph(ascent, height, width)
- },
+ }
_ => {
// If it's not a special char, return the normal glyph
Ok(RasterizedGlyph {
diff --git a/font/src/lib.rs b/font/src/lib.rs
index a2580fc8..f9eaaac6 100644
--- a/font/src/lib.rs
+++ b/font/src/lib.rs
@@ -43,7 +43,7 @@ extern crate foreign_types;
extern crate log;
use std::hash::{Hash, Hasher};
-use std::fmt;
+use std::{fmt, cmp};
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
// 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
// This is part of the private use area and should not conflict with any font
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)]
pub struct FontDesc {
@@ -211,11 +213,10 @@ impl Default for RasterizedGlyph {
}
// 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> {
// Create a new rectangle, the height is half the distance between
// 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];
// 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
-// TODO: Make sure this works with positive/0 descent -> small fonts
-pub fn get_beam_cursor_glyph(ascent: i32, height: i32, width: i32) -> Result<RasterizedGlyph, Error> {
- // Create a new rectangle
- let beam_width = (f64::from(width) / 5.) as i32;
+pub fn get_beam_cursor_glyph(
+ ascent: i32,
+ height: 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];
// Create a custom glyph with the rectangle data attached to it