1
0
Fork 0
forked from wry/wry

text: add metrics and dynamic height

This commit is contained in:
Julian Orth 2022-07-30 16:16:35 +02:00
parent 2568b7b1f5
commit 8b93957f31
4 changed files with 84 additions and 28 deletions

View file

@ -76,14 +76,21 @@ pub fn measure(
text: &str,
markup: bool,
scale: Option<f64>,
) -> Result<Rect, TextError> {
full: bool,
) -> Result<TextMeasurement, TextError> {
let data = create_data(font, 1, 1, scale)?;
if markup {
data.layout.set_markup(text);
} else {
data.layout.set_text(text);
}
Ok(data.layout.inc_pixel_rect())
let mut res = TextMeasurement::default();
res.ink_rect = data.layout.inc_pixel_rect();
if full {
res.logical_rect = data.layout.logical_pixel_rect();
res.baseline = data.layout.pixel_baseline();
}
Ok(res)
}
pub fn render(
@ -96,13 +103,14 @@ pub fn render(
scale: Option<f64>,
) -> Result<Rc<Texture>, TextError> {
render2(
ctx, 1, width, height, 1, font, text, color, true, false, scale,
ctx, 1, None, width, height, 1, font, text, color, true, false, scale,
)
}
fn render2(
ctx: &Rc<RenderContext>,
x: i32,
y: Option<i32>,
width: i32,
height: i32,
padding: i32,
@ -128,8 +136,8 @@ fn render2(
data.cctx.set_operator(CAIRO_OPERATOR_SOURCE);
data.cctx
.set_source_rgba(color.r as _, color.g as _, color.b as _, color.a as _);
data.cctx
.move_to(x as f64, ((height - font_height) / 2) as f64);
let y = y.unwrap_or((height - font_height) / 2);
data.cctx.move_to(x as f64, y as f64);
data.layout.show_layout();
data.image.flush();
let bytes = match data.image.data() {
@ -144,19 +152,44 @@ fn render2(
pub fn render_fitting(
ctx: &Rc<RenderContext>,
height: i32,
height: Option<i32>,
font: &str,
text: &str,
color: Color,
markup: bool,
scale: Option<f64>,
) -> Result<Rc<Texture>, TextError> {
let rect = measure(font, text, markup, scale)?;
render2(
render_fitting2(ctx, height, font, text, color, markup, scale, false).map(|(a, _)| a)
}
#[derive(Debug, Copy, Clone, Default)]
pub struct TextMeasurement {
pub ink_rect: Rect,
pub logical_rect: Rect,
pub baseline: i32,
}
pub fn render_fitting2(
ctx: &Rc<RenderContext>,
height: Option<i32>,
font: &str,
text: &str,
color: Color,
markup: bool,
scale: Option<f64>,
include_measurements: bool,
) -> Result<(Rc<Texture>, TextMeasurement), TextError> {
let measurement = measure(font, text, markup, scale, include_measurements)?;
let y = match height {
Some(_) => None,
_ => Some(measurement.ink_rect.y1().neg()),
};
let res = render2(
ctx,
rect.x1().neg(),
rect.width(),
height,
measurement.ink_rect.x1().neg(),
y,
measurement.ink_rect.width(),
height.unwrap_or(measurement.ink_rect.height()),
0,
font,
text,
@ -164,5 +197,6 @@ pub fn render_fitting(
false,
markup,
scale,
)
);
res.map(|r| (r, measurement))
}