Skip to content

Commit

Permalink
Merge pull request #106 from PgBiel/use-fields
Browse files Browse the repository at this point in the history
Use fields from Typst 0.7.0 when possible
  • Loading branch information
PgBiel authored Dec 31, 2023
2 parents eda2457 + 96d47f9 commit f287e5c
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 7 deletions.
16 changes: 16 additions & 0 deletions src/common.typ
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@
calc.floor(a) - calc.floor(b * calc.floor(a / b))
}

// Returns the sign of the operand.
// -1 for negative, 1 for positive or zero.
#let calc-sign(x) = {
// For positive: true - false = 1 - 0 = 1
// For zero: true - false = 1 - 0 = 1
// For negative: false - true = 0 - 1 = -1
int(0 <= x) - int(x < 0)
}

// get the types of things so we can compare with them
// (0.2.0-0.7.0: they're strings; 0.8.0+: they're proper types)
#let _array-type = type(())
Expand All @@ -33,3 +42,10 @@
// but keep it like this for pre-0.8.0
#let _align-type = type(left)
#let _2d-align-type = type(top + left)

// If types aren't strings, this means we're using 0.8.0+.
#let using-typst-v080-or-later = str(type(_str-type)) == "type"

// This is true if types have fields in the current Typst version.
// This means we can use stroke.thickness, length.em, and so on.
#let typst-fields-supported = using-typst-v080-or-later
2 changes: 1 addition & 1 deletion src/type-validators.typ
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@

// Check if the given length has type '_length-type' and no 'em' component.
#let is-purely-pt-len(len) = {
type(len) == _length-type and "em" not in repr(len)
type(len) == _length-type and ((typst-fields-supported and len.em == 0) or (not typst-fields-supported and "em" not in repr(len)))
}

// Check if this is a valid color (color, gradient or pattern).
Expand Down
31 changes: 25 additions & 6 deletions src/utilities.typ
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@
//
// styles: from style()
#let measure-pt(len, styles) = {
if typst-fields-supported {
// We can use fields to separate em from pt.
let pt = len.abs
let em = len.em
// Measure with abs (and later multiply by the sign) so negative em works.
// Otherwise it would return 0pt, and we would need to measure again with abs.
let measured-em = calc-sign(em) * measure(box(width: calc.abs(em) * 1em), styles).width

return pt + measured-em
}

// Fields not supported, so we have to measure twice when em can be negative.
let measured-pt = measure(box(width: len), styles).width

// If the measured length is positive, `len` must have overall been positive.
Expand All @@ -151,7 +163,7 @@
// styles: from style()
#let convert-length-type-to-pt(len, styles: none) = {
// repr examples: "1pt", "1em", "0.5pt", "0.5em", "1pt + 1em", "-0.5pt + -0.5em"
if "em" not in repr(len) {
if is-purely-pt-len(len) {
// No need to do any conversion because it must already be in pt.
return len
}
Expand Down Expand Up @@ -217,17 +229,18 @@
// styles: from style()
// page-size: equivalent to 100% (optional because the length may not have a ratio component)
#let convert-relative-type-to-pt(len, styles, page-size: none) = {
if typst-fields-supported or eval(repr(0.00005em)) != 0.00005em {
// em repr changed in 0.11.0 => need to use fields here
// or use fields if they're supported anyway
return convert-ratio-type-to-pt(len.ratio, page-size) + convert-length-type-to-pt(len.length, styles: styles)
}

// We will need to draw a line for measurement later,
// so we need the styles.
if styles == none {
panic("Cannot convert relative length to pt ('styles' not specified).")
}

if eval(repr(0.00005em)) != 0.00005em {
// em repr changed in 0.11.0 => can safely use fields here
return convert-ratio-type-to-pt(len.ratio, page-size) + convert-length-type-to-pt(len.length, styles: styles)
}

// Note on precision: the `repr` for em components is precise, unlike
// other length components, which are rounded to a precision of 2.
// This is true up to Typst 0.9.0 and possibly later versions.
Expand Down Expand Up @@ -305,6 +318,12 @@
} else if is-color(stroke) {
1pt
} else if type(stroke) == _stroke-type {
if typst-fields-supported {
// No need for any repr() parsing, just use the thickness field.
let thickness = default-if-auto(stroke.thickness, 1pt)
return convert-length-to-pt(thickness, styles: styles)
}

// support:
// - 2pt / 2em / 2cm / 2in + color
// - 2.5pt / 2.5em / ... + color
Expand Down

0 comments on commit f287e5c

Please sign in to comment.