summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--font/src/ft/mod.rs75
-rw-r--r--font/src/lib.rs42
-rw-r--r--src/term/mod.rs2
3 files changed, 87 insertions, 32 deletions
diff --git a/font/src/ft/mod.rs b/font/src/ft/mod.rs
index b8559237..7b22fb03 100644
--- a/font/src/ft/mod.rs
+++ b/font/src/ft/mod.rs
@@ -24,7 +24,7 @@ use libc::c_uint;
pub mod fc;
-use super::{FontDesc, RasterizedGlyph, Metrics, Size, FontKey, GlyphKey, Weight, Slant, Style, UNDERLINE_CURSOR_CHAR};
+use super::{FontDesc, RasterizedGlyph, Metrics, Size, FontKey, GlyphKey, Weight, Slant, Style};
struct FixedSize {
pixelsize: f64,
@@ -294,37 +294,50 @@ impl FreeTypeRasterizer {
let (pixel_width, buf) = Self::normalize_buffer(&glyph.bitmap())?;
- // Render a custom symbol for the underline cursor
- if glyph_key.c == UNDERLINE_CURSOR_CHAR {
- // Get the bottom of the bounding box
- let size_metrics = face.ft_face.size_metrics()
- .ok_or(Error::MissingSizeMetrics)?;
- let descent = (size_metrics.descender / 64) as f32;
-
- // Create a new rectangle, the height is half the distance between
- // bounding box bottom and the baseline
- let height = f32::abs(descent / 2.) as i32;
- let buf = vec![255u8; (pixel_width * height * 3) as usize];
-
- // Create a custom glyph with the rectangle data attached to it
- return Ok(RasterizedGlyph {
- c: glyph_key.c,
- top: descent as i32 + height,
- left: glyph.bitmap_left(),
- height,
- width: pixel_width,
- buf: buf,
- });
- }
+ // Render a custom symbol for the underline and beam cursor
+ match glyph_key.c {
+ super::UNDERLINE_CURSOR_CHAR => {
+ // Get the bottom of the bounding box
+ let size_metrics = face.ft_face.size_metrics()
+ .ok_or(Error::MissingSizeMetrics)?;
+ let descent = (size_metrics.descender / 64) as i32;
- Ok(RasterizedGlyph {
- c: glyph_key.c,
- top: glyph.bitmap_top(),
- left: glyph.bitmap_left(),
- width: pixel_width,
- height: glyph.bitmap().rows(),
- buf: buf,
- })
+ // Get the width of the cell
+ let metrics = glyph.metrics();
+ let width = (metrics.vertAdvance as f32 / 128.).round() as i32;
+
+ // 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()
+ .ok_or(Error::MissingSizeMetrics)?;
+ let ascent = (size_metrics.ascender / 64) as i32 - 1;
+
+ // Get the height of the cell
+ let descent = (size_metrics.descender / 64) as i32;
+ let height = ascent - descent;
+
+ // Get the width of the cell
+ let metrics = glyph.metrics();
+ let width = (metrics.vertAdvance as f32 / 128.).round() as i32;
+
+ // 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 {
+ c: glyph_key.c,
+ top: glyph.bitmap_top(),
+ left: glyph.bitmap_left(),
+ width: pixel_width,
+ height: glyph.bitmap().rows(),
+ buf: buf,
+ })
+ }
+ }
}
fn ft_load_flags(pat: &fc::Pattern) -> freetype::face::LoadFlag {
diff --git a/font/src/lib.rs b/font/src/lib.rs
index 5d35e47a..776127ea 100644
--- a/font/src/lib.rs
+++ b/font/src/lib.rs
@@ -65,6 +65,13 @@ pub const UNDERLINE_CURSOR_CHAR: char = '\u{10a3e2}';
#[cfg(target_os = "macos")]
pub const UNDERLINE_CURSOR_CHAR: char = '▁';
+/// Character used for the beam cursor
+#[cfg(not(target_os = "macos"))]
+// This is part of the private use area and should not conflict with any font
+pub const BEAM_CURSOR_CHAR: char = '\u{10a3e3}';
+#[cfg(target_os = "macos")]
+pub const BEAM_CURSOR_CHAR: char = '▎';
+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FontDesc {
name: String,
@@ -209,6 +216,41 @@ impl Default for RasterizedGlyph {
}
}
+// Returns a custom underline cursor character
+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 buf = vec![255u8; (width * height * 3) as usize];
+
+ // Create a custom glyph with the rectangle data attached to it
+ return Ok(RasterizedGlyph {
+ c: UNDERLINE_CURSOR_CHAR,
+ top: descent + height,
+ left: 0,
+ height,
+ width,
+ buf: buf,
+ });
+}
+
+// Returns a custom beam cursor character
+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;
+ let buf = vec![255u8; (beam_width * height * 3) as usize];
+
+ // Create a custom glyph with the rectangle data attached to it
+ return Ok(RasterizedGlyph {
+ c: BEAM_CURSOR_CHAR,
+ top: ascent,
+ left: 0,
+ height,
+ width: beam_width,
+ buf: buf,
+ });
+}
+
struct BufDebugger<'a>(&'a [u8]);
impl<'a> fmt::Debug for BufDebugger<'a> {
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 2e1365fb..86115171 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -181,7 +181,7 @@ impl<'a> RenderableCellsIter<'a> {
});
let cursor_color = self.text_cursor_color(&cursor_cell);
- cursor_cell.c = '▎';
+ cursor_cell.c = font::BEAM_CURSOR_CHAR;
cursor_cell.fg = cursor_color;
self.cursor_cells.push_back(Indexed {
line: self.cursor.line,