1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
use crate::render; use pango; #[derive(Clone)] pub struct Item { pub item: pango::Item, pub cells_count: usize, pub glyphs: Option<pango::GlyphString>, pub ink_overflow: Option<InkOverflow>, font: pango::Font, } impl Item { pub fn new(item: pango::Item, cells_count: usize) -> Self { debug_assert!(cells_count > 0); Item { font: item.analysis().font(), item, cells_count, glyphs: None, ink_overflow: None, } } pub fn update(&mut self, item: pango::Item) { self.font = item.analysis().font(); self.item = item; self.glyphs = None; self.ink_overflow = None; } pub fn set_glyphs(&mut self, ctx: &render::Context, glyphs: pango::GlyphString) { let mut glyphs = glyphs; let (ink_rect, _) = glyphs.extents(&self.font); self.ink_overflow = InkOverflow::from(ctx, &ink_rect, self.cells_count as i32); self.glyphs = Some(glyphs); } pub fn font(&self) -> &pango::Font { &self.font } pub fn analysis(&self) -> &pango::Analysis { self.item.analysis() } } #[derive(Clone)] pub struct InkOverflow { pub left: f64, pub right: f64, pub top: f64, pub bot: f64, } impl InkOverflow { pub fn from( ctx: &render::Context, ink_rect: &pango::Rectangle, cells_count: i32, ) -> Option<Self> { let cell_metrix = ctx.cell_metrics(); let ink_descent = ink_rect.y + ink_rect.height; let ink_ascent = ink_rect.y.abs(); let mut top = ink_ascent - cell_metrix.pango_ascent; if top < 0 { top = 0; } let mut bot = ink_descent - cell_metrix.pango_descent; if bot < 0 { bot = 0; } let left = if ink_rect.x < 0 { ink_rect.x.abs() } else { 0 }; let mut right = ink_rect.width - cells_count * cell_metrix.pango_char_width; if right < 0 { right = 0; } if left == 0 && right == 0 && top == 0 && right == 0 { None } else { Some(InkOverflow { left: left as f64 / pango::SCALE as f64, right: right as f64 / pango::SCALE as f64, top: top as f64 / pango::SCALE as f64, bot: bot as f64 / pango::SCALE as f64, }) } } }