mirror of
https://github.com/typst/typst
synced 2025-05-15 17:45:27 +08:00
Convert font units to lengths earlier
This commit is contained in:
parent
c975d0d5e9
commit
8d67c0ca5e
@ -162,7 +162,7 @@ impl FontState {
|
|||||||
size: self.resolve_size(),
|
size: self.resolve_size(),
|
||||||
top_edge: self.top_edge,
|
top_edge: self.top_edge,
|
||||||
bottom_edge: self.bottom_edge,
|
bottom_edge: self.bottom_edge,
|
||||||
color: self.color,
|
fill: self.color,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,8 +205,8 @@ pub struct FontProps {
|
|||||||
pub top_edge: VerticalFontMetric,
|
pub top_edge: VerticalFontMetric,
|
||||||
/// What line to consider the bottom edge of text.
|
/// What line to consider the bottom edge of text.
|
||||||
pub bottom_edge: VerticalFontMetric,
|
pub bottom_edge: VerticalFontMetric,
|
||||||
/// The color of the text.
|
/// The fill color of the text.
|
||||||
pub color: Fill,
|
pub fill: Fill,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Font family definitions.
|
/// Font family definitions.
|
||||||
|
@ -63,7 +63,7 @@ pub struct Text {
|
|||||||
/// A glyph in a run of shaped text.
|
/// A glyph in a run of shaped text.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Glyph {
|
pub struct Glyph {
|
||||||
/// The glyph's ID in the face.
|
/// The glyph's index in the face.
|
||||||
pub id: u16,
|
pub id: u16,
|
||||||
/// The advance width of the glyph.
|
/// The advance width of the glyph.
|
||||||
pub x_advance: Length,
|
pub x_advance: Length,
|
||||||
|
@ -185,7 +185,7 @@ impl<'a> ParLayout<'a> {
|
|||||||
while !stack.areas.current.height.fits(line.size.height)
|
while !stack.areas.current.height.fits(line.size.height)
|
||||||
&& !stack.areas.in_full_last()
|
&& !stack.areas.in_full_last()
|
||||||
{
|
{
|
||||||
stack.finish_area(ctx);
|
stack.finish_area();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the line does not fit horizontally or we have a mandatory
|
// If the line does not fit horizontally or we have a mandatory
|
||||||
@ -212,7 +212,7 @@ impl<'a> ParLayout<'a> {
|
|||||||
stack.push(line);
|
stack.push(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
stack.finish(ctx)
|
stack.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the index of the item whose range contains the `text_offset`.
|
/// Find the index of the item whose range contains the `text_offset`.
|
||||||
@ -297,7 +297,7 @@ impl<'a> LineStack<'a> {
|
|||||||
self.lines.push(line);
|
self.lines.push(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish_area(&mut self, ctx: &mut LayoutContext) {
|
fn finish_area(&mut self) {
|
||||||
if self.areas.fixed.horizontal {
|
if self.areas.fixed.horizontal {
|
||||||
self.size.width = self.areas.current.width;
|
self.size.width = self.areas.current.width;
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@ impl<'a> LineStack<'a> {
|
|||||||
let mut first = true;
|
let mut first = true;
|
||||||
|
|
||||||
for line in std::mem::take(&mut self.lines) {
|
for line in std::mem::take(&mut self.lines) {
|
||||||
let frame = line.build(ctx, self.size.width);
|
let frame = line.build(self.size.width);
|
||||||
|
|
||||||
let pos = Point::new(Length::ZERO, offset);
|
let pos = Point::new(Length::ZERO, offset);
|
||||||
if first {
|
if first {
|
||||||
@ -324,8 +324,8 @@ impl<'a> LineStack<'a> {
|
|||||||
self.size = Size::ZERO;
|
self.size = Size::ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(mut self, ctx: &mut LayoutContext) -> Vec<Frame> {
|
fn finish(mut self) -> Vec<Frame> {
|
||||||
self.finish_area(ctx);
|
self.finish_area();
|
||||||
self.finished
|
self.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -442,7 +442,7 @@ impl<'a> LineLayout<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Build the line's frame.
|
/// Build the line's frame.
|
||||||
fn build(&self, ctx: &mut LayoutContext, width: Length) -> Frame {
|
fn build(&self, width: Length) -> Frame {
|
||||||
let size = Size::new(self.size.width.max(width), self.size.height);
|
let size = Size::new(self.size.width.max(width), self.size.height);
|
||||||
let free = size.width - self.size.width;
|
let free = size.width - self.size.width;
|
||||||
|
|
||||||
@ -458,7 +458,7 @@ impl<'a> LineLayout<'a> {
|
|||||||
}
|
}
|
||||||
ParItem::Text(ref shaped, align) => {
|
ParItem::Text(ref shaped, align) => {
|
||||||
ruler = ruler.max(align);
|
ruler = ruler.max(align);
|
||||||
shaped.build(ctx)
|
shaped.build()
|
||||||
}
|
}
|
||||||
ParItem::Frame(ref frame, align) => {
|
ParItem::Frame(ref frame, align) => {
|
||||||
ruler = ruler.max(align);
|
ruler = ruler.max(align);
|
||||||
|
@ -3,7 +3,6 @@ use std::fmt::{self, Debug, Formatter};
|
|||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use rustybuzz::UnicodeBuffer;
|
use rustybuzz::UnicodeBuffer;
|
||||||
use ttf_parser::GlyphId;
|
|
||||||
|
|
||||||
use super::{Element, Frame, Glyph, LayoutContext, Text};
|
use super::{Element, Frame, Glyph, LayoutContext, Text};
|
||||||
use crate::env::FaceId;
|
use crate::env::FaceId;
|
||||||
@ -38,12 +37,12 @@ pub struct ShapedText<'a> {
|
|||||||
pub struct ShapedGlyph {
|
pub struct ShapedGlyph {
|
||||||
/// The font face the glyph is contained in.
|
/// The font face the glyph is contained in.
|
||||||
pub face_id: FaceId,
|
pub face_id: FaceId,
|
||||||
/// The glyph's ID in the face.
|
/// The glyph's index in the face.
|
||||||
pub glyph_id: GlyphId,
|
pub glyph_id: u16,
|
||||||
/// The advance width of the glyph.
|
/// The advance width of the glyph.
|
||||||
pub x_advance: i32,
|
pub x_advance: Length,
|
||||||
/// The horizontal offset of the glyph.
|
/// The horizontal offset of the glyph.
|
||||||
pub x_offset: i32,
|
pub x_offset: Length,
|
||||||
/// The start index of the glyph in the source text.
|
/// The start index of the glyph in the source text.
|
||||||
pub text_index: usize,
|
pub text_index: usize,
|
||||||
/// Whether splitting the shaping result before this glyph would yield the
|
/// Whether splitting the shaping result before this glyph would yield the
|
||||||
@ -61,7 +60,7 @@ enum Side {
|
|||||||
|
|
||||||
impl<'a> ShapedText<'a> {
|
impl<'a> ShapedText<'a> {
|
||||||
/// Build the shaped text's frame.
|
/// Build the shaped text's frame.
|
||||||
pub fn build(&self, ctx: &mut LayoutContext) -> Frame {
|
pub fn build(&self) -> Frame {
|
||||||
let mut frame = Frame::new(self.size, self.baseline);
|
let mut frame = Frame::new(self.size, self.baseline);
|
||||||
let mut offset = Length::ZERO;
|
let mut offset = Length::ZERO;
|
||||||
|
|
||||||
@ -70,20 +69,17 @@ impl<'a> ShapedText<'a> {
|
|||||||
let mut text = Text {
|
let mut text = Text {
|
||||||
face_id,
|
face_id,
|
||||||
size: self.props.size,
|
size: self.props.size,
|
||||||
fill: self.props.color,
|
fill: self.props.fill,
|
||||||
glyphs: vec![],
|
glyphs: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let face = ctx.env.face(face_id);
|
|
||||||
for glyph in group {
|
for glyph in group {
|
||||||
let x_advance = face.to_em(glyph.x_advance).to_length(self.props.size);
|
|
||||||
let x_offset = face.to_em(glyph.x_offset).to_length(self.props.size);
|
|
||||||
text.glyphs.push(Glyph {
|
text.glyphs.push(Glyph {
|
||||||
id: glyph.glyph_id.0,
|
id: glyph.glyph_id,
|
||||||
x_advance,
|
x_advance: glyph.x_advance,
|
||||||
x_offset,
|
x_offset: glyph.x_offset,
|
||||||
});
|
});
|
||||||
offset += x_advance;
|
offset += glyph.x_advance;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.push(pos, Element::Text(text));
|
frame.push(pos, Element::Text(text));
|
||||||
@ -246,7 +242,8 @@ fn shape_segment<'a>(
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Shape!
|
// Shape!
|
||||||
let buffer = rustybuzz::shape(ctx.env.face(face_id).ttf(), &[], buffer);
|
let mut face = ctx.env.face(face_id);
|
||||||
|
let buffer = rustybuzz::shape(face.ttf(), &[], buffer);
|
||||||
let infos = buffer.glyph_infos();
|
let infos = buffer.glyph_infos();
|
||||||
let pos = buffer.glyph_positions();
|
let pos = buffer.glyph_positions();
|
||||||
|
|
||||||
@ -262,9 +259,9 @@ fn shape_segment<'a>(
|
|||||||
// TODO: Don't ignore y_advance and y_offset.
|
// TODO: Don't ignore y_advance and y_offset.
|
||||||
glyphs.push(ShapedGlyph {
|
glyphs.push(ShapedGlyph {
|
||||||
face_id,
|
face_id,
|
||||||
glyph_id: GlyphId(info.codepoint as u16),
|
glyph_id: info.codepoint as u16,
|
||||||
x_advance: pos[i].x_advance,
|
x_advance: face.to_em(pos[i].x_advance).to_length(props.size),
|
||||||
x_offset: pos[i].x_offset,
|
x_offset: face.to_em(pos[i].x_offset).to_length(props.size),
|
||||||
text_index: base + cluster,
|
text_index: base + cluster,
|
||||||
safe_to_break: !info.unsafe_to_break(),
|
safe_to_break: !info.unsafe_to_break(),
|
||||||
});
|
});
|
||||||
@ -319,6 +316,8 @@ fn shape_segment<'a>(
|
|||||||
families.clone(),
|
families.clone(),
|
||||||
first_face,
|
first_face,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
face = ctx.env.face(face_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
@ -355,7 +354,7 @@ fn measure(
|
|||||||
expand_vertical(face);
|
expand_vertical(face);
|
||||||
|
|
||||||
for glyph in group {
|
for glyph in group {
|
||||||
width += face.to_em(glyph.x_advance).to_length(props.size);
|
width += glyph.x_advance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user