2017-09-08 15:26:16 +00:00
|
|
|
use render;
|
2017-09-06 15:31:13 +00:00
|
|
|
|
|
|
|
use sys::pango as sys_pango;
|
|
|
|
use pango;
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct Item {
|
|
|
|
pub item: sys_pango::Item,
|
2017-09-08 15:26:16 +00:00
|
|
|
pub cells_count: usize,
|
2017-09-06 15:31:13 +00:00
|
|
|
pub glyphs: Option<pango::GlyphString>,
|
2017-09-08 15:26:16 +00:00
|
|
|
pub ink_overflow: Option<InkOverflow>,
|
2017-09-06 15:31:13 +00:00
|
|
|
font: pango::Font,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Item {
|
2017-09-08 15:26:16 +00:00
|
|
|
pub fn new(item: sys_pango::Item, cells_count: usize) -> Self {
|
|
|
|
debug_assert!(cells_count > 0);
|
|
|
|
|
2017-09-06 15:31:13 +00:00
|
|
|
Item {
|
|
|
|
font: item.analysis().font(),
|
|
|
|
item,
|
2017-09-08 15:26:16 +00:00
|
|
|
cells_count,
|
2017-09-06 15:31:13 +00:00
|
|
|
glyphs: None,
|
2017-09-08 15:26:16 +00:00
|
|
|
ink_overflow: None,
|
2017-09-06 15:31:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn update(&mut self, item: sys_pango::Item) {
|
|
|
|
self.font = item.analysis().font();
|
|
|
|
self.item = item;
|
|
|
|
self.glyphs = None;
|
2017-09-08 15:26:16 +00:00
|
|
|
self.ink_overflow = None;
|
2017-09-06 15:31:13 +00:00
|
|
|
}
|
|
|
|
|
2017-09-08 15:26:16 +00:00
|
|
|
pub fn set_glyphs(&mut self, ctx: &render::Context, glyphs: pango::GlyphString) {
|
2017-09-06 15:31:13 +00:00
|
|
|
let mut glyphs = glyphs;
|
|
|
|
let (ink_rect, _) = glyphs.extents(&self.font);
|
2017-09-08 15:26:16 +00:00
|
|
|
self.ink_overflow = InkOverflow::from(ctx, &ink_rect, self.cells_count as i32);
|
2017-09-06 15:31:13 +00:00
|
|
|
self.glyphs = Some(glyphs);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn font(&self) -> &pango::Font {
|
|
|
|
&self.font
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn analysis(&self) -> sys_pango::Analysis {
|
|
|
|
self.item.analysis()
|
|
|
|
}
|
|
|
|
}
|
2017-09-08 15:26:16 +00:00
|
|
|
|
|
|
|
#[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,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|