use std::mem;
use Alignment;
use Draw;
use DrawContext;
use HorizontalAlignment;
use matrix::Matrix;
pub fn flow<D: ?Sized + Draw>(draw: &DrawContext<D>, text_style: &D::TextStyle, text: &str,
alignment: &HorizontalAlignment)
{
let draw = draw.animation_stop();
helper(&draw, text_style, text, |ratio| {
let current_width_per_height = draw.width_per_height();
let draw = draw.horizontal_rescale(ratio / current_width_per_height, &alignment);
if !draw.cursor_hovered_widget() {
if draw.is_cursor_hovering() {
draw.set_cursor_hovered_widget();
}
}
draw.matrix()
})
}
pub fn contain<D: ?Sized + Draw>(draw: &DrawContext<D>, text_style: &D::TextStyle, text: &str,
alignment: &Alignment)
{
let draw = draw.animation_stop();
helper(&draw, text_style, text, |ratio| {
let draw = draw.enforce_aspect_ratio_downscale(ratio, alignment);
if !draw.cursor_hovered_widget() {
if draw.is_cursor_hovering() {
draw.set_cursor_hovered_widget();
}
}
draw.matrix()
})
}
pub fn cover<D: ?Sized + Draw>(draw: &DrawContext<D>, text_style: &D::TextStyle, text: &str,
alignment: &Alignment)
{
let draw = draw.animation_stop();
helper(&draw, text_style, text, |ratio| {
let draw = draw.enforce_aspect_ratio_upscale(ratio, alignment);
if !draw.cursor_hovered_widget() {
if draw.is_cursor_hovering() {
draw.set_cursor_hovered_widget();
}
}
draw.matrix()
})
}
fn helper<D: ?Sized + Draw, F>(draw: &DrawContext<D>, text_style: &D::TextStyle, text: &str,
final_matrix: F)
where F: FnOnce(f32) -> Matrix
{
let mut glyphs: Vec<(char, Matrix)> = Vec::with_capacity(text.len());
let mut previous_chr = None;
let mut x = 0.0;
for chr in text.chars() {
let glyph_infos = draw.draw().glyph_infos(text_style, chr);
let kerning = match mem::replace(&mut previous_chr, Some((chr, glyph_infos))) {
Some((prev, _)) => draw.draw().kerning(text_style, prev, chr),
None => 0.0
};
x += kerning;
let matrix = Matrix::translate(x + glyph_infos.x_offset,
glyph_infos.y_offset - glyph_infos.height)
* Matrix::scale_wh(glyph_infos.width, glyph_infos.height)
* Matrix::translate(0.5, 0.5)
* Matrix::scale(0.5);
glyphs.push((chr, matrix));
x += glyph_infos.x_advance;
}
if let Some((_, prev_infos)) = previous_chr {
x -= prev_infos.x_advance;
x += prev_infos.x_offset;
x += prev_infos.width;
}
let recenter_matrix = Matrix::scale_wh(2.0 / x, 2.0)
* Matrix::translate(-x / 2.0, -0.5);
let final_matrix = final_matrix(x);
for (chr, matrix) in glyphs.into_iter() {
draw.draw().draw_glyph(text_style, chr, &(final_matrix * recenter_matrix * matrix));
}
}