Skip to content

Commit fdd579a

Browse files
authored
Merge pull request #941 from pkgw/weave-html
Update HTML support for tt-weave work
2 parents 85d20d0 + c7e776f commit fdd579a

7 files changed

Lines changed: 1682 additions & 160 deletions

File tree

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/engine_spx2html/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ edition = "2018"
1919

2020
[dependencies]
2121
byteorder = "^1.4"
22+
html-escape = "^0.2"
2223
percent-encoding = "^2.1"
2324
pinot = "^0.1.4"
2425
tectonic_bridge_core = { path = "../bridge_core", version = "0.0.0-dev.0" }

crates/engine_spx2html/src/font.rs

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use pinot::{
1515
types::{FWord, Tag, UfWord},
1616
FontDataRef, TableProvider,
1717
};
18-
use std::{collections::HashMap, fmt::Write, num::Wrapping, path::Path};
18+
use std::{collections::HashMap, num::Wrapping, path::Path};
1919
use tectonic_errors::prelude::*;
2020

2121
use crate::FixedPoint;
@@ -44,6 +44,10 @@ pub struct FontData {
4444
/// Information about how glyphs can be reverse-mapped to Unicode input
4545
gmap: HashMap<GlyphId, MapEntry>,
4646

47+
/// The glyph for the basic space character, or zero (typically .notdef) if
48+
/// it can't be found.
49+
space_glyph: GlyphId,
50+
4751
units_per_em: UfWord,
4852

4953
hmetrics: Vec<HorizontalMetrics>,
@@ -184,14 +188,17 @@ impl FontData {
184188

185189
let units_per_em = head.units_per_em();
186190

187-
// Get the direct mappings.
191+
// Get the direct mappings. While we're at it, figure out the glyph for
192+
// the space character, so that we can know how wide spaces are, so that
193+
// we can guess when to insert spaces into our HTML content.
188194

189195
let cmap = a_ok_or!(
190196
font.cmap();
191197
["unable to parse OpenType font: missing/invalid CMAP table"]
192198
);
193199

194200
let mut gmap = HashMap::new();
201+
let mut space_glyph = 0;
195202

196203
for usv in valid_usvs() {
197204
let c = char::from_u32(usv).unwrap();
@@ -203,6 +210,10 @@ impl FontData {
203210
}
204211
};
205212

213+
if c == ' ' {
214+
space_glyph = gidx;
215+
}
216+
206217
gmap.insert(gidx, MapEntry::Direct(c));
207218
}
208219

@@ -284,6 +295,7 @@ impl FontData {
284295
basename,
285296
buffer,
286297
gmap,
298+
space_glyph,
287299
units_per_em,
288300
hmetrics,
289301
ascender,
@@ -333,6 +345,17 @@ impl FontData {
333345
})
334346
}
335347

348+
/// Get the width of the space character as a TeX size.
349+
pub fn space_width(&self, tex_size: FixedPoint) -> Option<FixedPoint> {
350+
if self.space_glyph == 0 {
351+
None
352+
} else {
353+
self.hmetrics.get(self.space_glyph as usize).map(|hm| {
354+
(hm.advance as f64 * tex_size as f64 / self.units_per_em as f64) as FixedPoint
355+
})
356+
}
357+
}
358+
336359
/// Request that an alternative mapping be allocated for a glyph.
337360
///
338361
/// The caller must suggest a Unicode character to use for the alternative,
@@ -366,9 +389,11 @@ impl FontData {
366389
*map
367390
}
368391

369-
/// Emit customized fonts to the filesystem and compute
370-
/// associated CSS for them. Consumes the object.
371-
pub fn emit<W: Write>(self, out_base: &Path, base_facename: &str, mut css: W) -> Result<()> {
392+
/// Emit customized fonts to the filesystem and return information so that
393+
/// appropriate CSS can be generated. Consumes the object.
394+
///
395+
/// Return value is a vec of (alternate-map-index, CSS-src-field).
396+
pub fn emit(self, out_base: &Path) -> Result<Vec<(Option<usize>, String)>> {
372397
// Write the main font file.
373398

374399
let mut out_path = out_base.to_owned();
@@ -378,21 +403,10 @@ impl FontData {
378403
["cannot write output file `{}`", out_path.display()]
379404
);
380405

381-
// CSS for the main font.
382-
//
383-
// We don't atry!() the write because I know that it's to a String,
384-
// which can panic but not Err.
406+
// CSS info for the main font.
385407

386408
let rel_url = utf8_percent_encode(&self.basename, CONTROLS).to_string();
387-
388-
writeln!(
389-
css,
390-
r#"@font-face {{
391-
font-family: "{}";
392-
src: url("{}") format("opentype");
393-
}}"#,
394-
base_facename, rel_url
395-
)?;
409+
let mut rv = vec![(None, format!(r#"url("{}") format("opentype")"#, rel_url))];
396410

397411
// Alternates until we're done
398412

@@ -452,20 +466,15 @@ impl FontData {
452466
// step 5: update CSS
453467

454468
let rel_url = utf8_percent_encode(&varname, CONTROLS).to_string();
455-
456-
writeln!(
457-
css,
458-
r#"@font-face {{
459-
font-family: "{}vg{}";
460-
src: url("{}") format("opentype");
461-
}}"#,
462-
base_facename, cur_map_index, rel_url
463-
)?;
469+
rv.push((
470+
Some(cur_map_index),
471+
format!(r#"url("{}") format("opentype")"#, rel_url),
472+
));
464473
}
465474

466475
// All done!
467476

468-
Ok(())
477+
Ok(rv)
469478
}
470479
}
471480

0 commit comments

Comments
 (0)