diff --git a/src/core/graphics.rs b/src/core/graphics.rs index 4fab16f..62c6d9b 100644 --- a/src/core/graphics.rs +++ b/src/core/graphics.rs @@ -16,6 +16,7 @@ use rgb::alt::BGRA; use std::collections::HashMap; use std::fs::File; use std::io::Read; +use std::cmp; use std::iter; use std::ptr; use std::sync::atomic::AtomicPtr; @@ -73,12 +74,17 @@ pub trait Display { fn end(&mut self, x: u32, y: u32, width: u32, height: u32); } +struct TextRaster { + img: ImgVec, + y: usize, +} + pub struct Graphics { disp: D, fonts: Vec<(String, freetype::FT_Long)>, fontbufs: Vec>, - labels: HashMap>, - sublabels: HashMap>, + labels: HashMap, + sublabels: HashMap, ft: AtomicPtr, x_scale: f64, @@ -279,7 +285,7 @@ impl Graphics { ftface } - fn rasterize_text(&mut self, size: f64, text: &str) -> ImgVec + fn rasterize_text(&mut self, size: f64, text: &str) -> TextRaster { let ftface = self.open_font_for_text(text).unwrap(); unsafe { @@ -303,12 +309,26 @@ impl Graphics { metrics.max_advance as usize / 64 * (text.len() - 1) + glyph_width }; - let height = (metrics.ascender - metrics.descender) as usize / 64; + let y_max = cmp::max(metrics.ascender as isize / 64, + bbox.yMax as isize + * metrics.y_ppem as isize + / units_per_em as isize); + let y_min = cmp::min(metrics.descender as isize / 64, + bbox.yMin as isize + * metrics.y_ppem as isize + / units_per_em as isize); + let mut y = y_max as usize - metrics.ascender as usize / 64; + let height = (y_max - y_min) as usize; + + println!("{} {}, {}", (-bbox.yMin) as usize, + metrics.y_ppem as usize, + metrics.descender); let vec: Vec = vec![0; stride * height]; let mut img = ImgVec::new(vec, stride, height); let mut pen: i64 = 0; + let mut height = (y_max as i64 - metrics.descender / 64) as usize; for c in text.chars() { let glyph = unsafe { @@ -323,7 +343,11 @@ impl Graphics { } let dest_x = pen + glyph.bitmap_left as i64; - let dest_y = metrics.ascender / 64 - glyph.bitmap_top as i64; + let dest_y = y_max as i64 - glyph.bitmap_top as i64; + + if y > dest_y as usize { + y = dest_y as usize; + } let src = bitmap_to_imgref(&glyph.bitmap); let dest = img.sub_image_mut(dest_x as usize, @@ -347,7 +371,14 @@ impl Graphics { }; let vec = img.into_buf(); - ImgVec::new_stride(vec, width, height, stride) + println!("{}, {}x{}", vec.len(), stride, height); + let img = ImgVec::new_stride(vec, width, height, stride); + img.sub_image(0, 0, width, height - y); + + TextRaster { + img, + y, + } } /* @@ -420,31 +451,31 @@ impl Graphics { } } - fn draw_label_part(labels: &HashMap>, + fn draw_label_part(labels: &HashMap, x_anchor: Anchor, y_anchor: Anchor, - img: &mut ImgRefMut>, + dest: &mut ImgRefMut>, label: &str, fg_color: BGR) { let src = labels.get(label) .expect("Layout and size should be set before drawing"); + let width = src.img.width(); + let height = src.img.height() - src.y; + let x = match x_anchor { Anchor::Min => 0, - Anchor::Center => (img.width() - src.width()) / 2, - Anchor::Max => img.width() - src.width(), + Anchor::Center => (dest.width() - width) / 2, + Anchor::Max => dest.width() - width, }; let y = match y_anchor { Anchor::Min => 0, - Anchor::Center => (img.height() - src.height()) / 2, - Anchor::Max => img.height() - src.height(), + Anchor::Center => (dest.height() - height) / 2, + Anchor::Max => dest.height() - height, }; - let width = src.width(); - let height = src.height(); - - let src = src.sub_image(0, 0, width, height); - let dest = img.sub_image_mut(x, y, width, height); + let src = src.img.sub_image(0, src.y, width, height); + let dest = dest.sub_image_mut(x, y, width, height); convert_gray_to_bgrx(dest, src, fg_color); } @@ -461,7 +492,8 @@ impl Graphics { if modifier != 0 { let modifier = modifier - 1; if mod_state[modifier] == ModState::Locked - || mod_state[modifier] == ModState::HeldLocked { + || mod_state[modifier] == ModState::HeldLocked + || mod_state[modifier] == ModState::HeldLockedPressed { return color_locked; } else if mod_state[modifier] != ModState::Released { return color_pressed; @@ -487,8 +519,8 @@ impl Graphics { color_label } - fn draw_key(labels: &HashMap>, - sublabels: &HashMap>, + fn draw_key(labels: &HashMap, + sublabels: &HashMap, x_scale: f64, y_scale: f64, img: &mut ImgRefMut>, key: &Key, mod_state: &[ModState])