summaryrefslogtreecommitdiff
path: root/src/pdf
diff options
context:
space:
mode:
authorMartin <mhaug@live.de>2021-04-07 13:50:21 +0200
committerGitHub <noreply@github.com>2021-04-07 13:50:21 +0200
commitdf58a4d89b67783b1ffc5c3b7282302d59db8c70 (patch)
tree2bdc3a7ad1704ccee7c14972df1fa3cb9c77097a /src/pdf
parent318eb9021edc493f5181247dbb7963de34126688 (diff)
parent3d2ee54848db80a8ede7e00fd5a53bc059138122 (diff)
Merge pull request #19 from typst/shape-runs 🔀
Text work
Diffstat (limited to 'src/pdf')
-rw-r--r--src/pdf/mod.rs47
1 files changed, 27 insertions, 20 deletions
diff --git a/src/pdf/mod.rs b/src/pdf/mod.rs
index a97dfa2c..36527544 100644
--- a/src/pdf/mod.rs
+++ b/src/pdf/mod.rs
@@ -15,6 +15,7 @@ use ttf_parser::{name_id, GlyphId};
use crate::color::Color;
use crate::env::{Env, ImageResource, ResourceId};
+use crate::font::{EmLength, VerticalFontMetric};
use crate::geom::{self, Length, Size};
use crate::layout::{Element, Fill, Frame, Image, Shape};
@@ -50,7 +51,7 @@ impl<'a> PdfExporter<'a> {
for frame in frames {
for (_, element) in &frame.elements {
match element {
- Element::Text(shaped) => fonts.insert(shaped.face),
+ Element::Text(shaped) => fonts.insert(shaped.face_id),
Element::Image(image) => {
let img = env.resources.loaded::<ImageResource>(image.res);
if img.buf.color().has_alpha() {
@@ -187,11 +188,11 @@ impl<'a> PdfExporter<'a> {
// Then, also check if we need to issue a font switching
// action.
- if shaped.face != face || shaped.size != size {
- face = shaped.face;
+ if shaped.face_id != face || shaped.size != size {
+ face = shaped.face_id;
size = shaped.size;
- let name = format!("F{}", self.fonts.map(shaped.face));
+ let name = format!("F{}", self.fonts.map(shaped.face_id));
text.font(Name(name.as_bytes()), size.to_pt() as f32);
}
@@ -234,24 +235,18 @@ impl<'a> PdfExporter<'a> {
flags.insert(FontFlags::SYMBOLIC);
flags.insert(FontFlags::SMALL_CAP);
- // Convert from OpenType font units to PDF glyph units.
- let em_per_unit = 1.0 / ttf.units_per_em().unwrap_or(1000) as f32;
- let convert = |font_unit: f32| (1000.0 * em_per_unit * font_unit).round();
- let convert_i16 = |font_unit: i16| convert(font_unit as f32);
- let convert_u16 = |font_unit: u16| convert(font_unit as f32);
-
let global_bbox = ttf.global_bounding_box();
let bbox = Rect::new(
- convert_i16(global_bbox.x_min),
- convert_i16(global_bbox.y_min),
- convert_i16(global_bbox.x_max),
- convert_i16(global_bbox.y_max),
+ face.convert(global_bbox.x_min).to_pdf(),
+ face.convert(global_bbox.y_min).to_pdf(),
+ face.convert(global_bbox.x_max).to_pdf(),
+ face.convert(global_bbox.y_max).to_pdf(),
);
let italic_angle = ttf.italic_angle().unwrap_or(0.0);
- let ascender = convert_i16(ttf.typographic_ascender().unwrap_or(0));
- let descender = convert_i16(ttf.typographic_descender().unwrap_or(0));
- let cap_height = ttf.capital_height().map(convert_i16);
+ let ascender = face.vertical_metric(VerticalFontMetric::Ascender).to_pdf();
+ let descender = face.vertical_metric(VerticalFontMetric::Descender).to_pdf();
+ let cap_height = face.vertical_metric(VerticalFontMetric::CapHeight).to_pdf();
let stem_v = 10.0 + 0.244 * (f32::from(ttf.weight().to_number()) - 50.0);
// Write the base font object referencing the CID font.
@@ -272,8 +267,8 @@ impl<'a> PdfExporter<'a> {
.individual(0, {
let num_glyphs = ttf.number_of_glyphs();
(0 .. num_glyphs).map(|g| {
- let advance = ttf.glyph_hor_advance(GlyphId(g));
- convert_u16(advance.unwrap_or(0))
+ let x = ttf.glyph_hor_advance(GlyphId(g)).unwrap_or(0);
+ face.convert(x).to_pdf()
})
});
@@ -286,7 +281,7 @@ impl<'a> PdfExporter<'a> {
.italic_angle(italic_angle)
.ascent(ascender)
.descent(descender)
- .cap_height(cap_height.unwrap_or(ascender))
+ .cap_height(cap_height)
.stem_v(stem_v)
.font_file2(refs.data);
@@ -571,3 +566,15 @@ where
self.to_layout.iter().copied()
}
}
+
+/// Additional methods for [`EmLength`].
+trait EmLengthExt {
+ /// Convert an em length to a number of PDF font units.
+ fn to_pdf(self) -> f32;
+}
+
+impl EmLengthExt for EmLength {
+ fn to_pdf(self) -> f32 {
+ 1000.0 * self.get() as f32
+ }
+}