summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorMalo <57839069+MDLC01@users.noreply.github.com>2025-01-23 19:24:35 +0100
committerGitHub <noreply@github.com>2025-01-23 18:24:35 +0000
commit2d33393df967bbe55646b839e188c04380d823fe (patch)
treeef9bf38a5ee0fb1bc68e99ab95c49f755b3950fe /crates
parentb7546bace7fb8640d1e7121b8bd7baf3cdb576e1 (diff)
Add support for `c2sc` OpenType feature in `smallcaps` (#5655)
Diffstat (limited to 'crates')
-rw-r--r--crates/typst-library/src/model/bibliography.rs6
-rw-r--r--crates/typst-library/src/text/mod.rs10
-rw-r--r--crates/typst-library/src/text/smallcaps.rs35
3 files changed, 38 insertions, 13 deletions
diff --git a/crates/typst-library/src/model/bibliography.rs b/crates/typst-library/src/model/bibliography.rs
index 95db8a22..762a97fd 100644
--- a/crates/typst-library/src/model/bibliography.rs
+++ b/crates/typst-library/src/model/bibliography.rs
@@ -38,7 +38,8 @@ use crate::model::{
};
use crate::routines::{EvalMode, Routines};
use crate::text::{
- FontStyle, Lang, LocalName, Region, SubElem, SuperElem, TextElem, WeightDelta,
+ FontStyle, Lang, LocalName, Region, Smallcaps, SubElem, SuperElem, TextElem,
+ WeightDelta,
};
use crate::World;
@@ -1046,7 +1047,8 @@ fn apply_formatting(mut content: Content, format: &hayagriva::Formatting) -> Con
match format.font_variant {
citationberg::FontVariant::Normal => {}
citationberg::FontVariant::SmallCaps => {
- content = content.styled(TextElem::set_smallcaps(true));
+ content =
+ content.styled(TextElem::set_smallcaps(Some(Smallcaps::Minuscules)));
}
}
diff --git a/crates/typst-library/src/text/mod.rs b/crates/typst-library/src/text/mod.rs
index 6cca2458..edbd2413 100644
--- a/crates/typst-library/src/text/mod.rs
+++ b/crates/typst-library/src/text/mod.rs
@@ -755,11 +755,10 @@ pub struct TextElem {
#[ghost]
pub case: Option<Case>,
- /// Whether small capital glyphs should be used. ("smcp")
+ /// Whether small capital glyphs should be used. ("smcp", "c2sc")
#[internal]
- #[default(false)]
#[ghost]
- pub smallcaps: bool,
+ pub smallcaps: Option<Smallcaps>,
}
impl TextElem {
@@ -1249,8 +1248,11 @@ pub fn features(styles: StyleChain) -> Vec<Feature> {
}
// Features that are off by default in Harfbuzz are only added if enabled.
- if TextElem::smallcaps_in(styles) {
+ if let Some(sc) = TextElem::smallcaps_in(styles) {
feat(b"smcp", 1);
+ if sc == Smallcaps::All {
+ feat(b"c2sc", 1);
+ }
}
if TextElem::alternates_in(styles) {
diff --git a/crates/typst-library/src/text/smallcaps.rs b/crates/typst-library/src/text/smallcaps.rs
index 1e88974f..924a45e8 100644
--- a/crates/typst-library/src/text/smallcaps.rs
+++ b/crates/typst-library/src/text/smallcaps.rs
@@ -12,11 +12,11 @@ use crate::text::TextElem;
/// ```
///
/// # Smallcaps fonts
-/// By default, this enables the OpenType `smcp` feature for the font. Not all
-/// fonts support this feature. Sometimes smallcaps are part of a dedicated
-/// font. This is, for example, the case for the _Latin Modern_ family of fonts.
-/// In those cases, you can use a show-set rule to customize the appearance of
-/// the text in smallcaps:
+/// By default, this uses the `smcp` and `c2sc` OpenType features on the font.
+/// Not all fonts support these features. Sometimes, smallcaps are part of a
+/// dedicated font. This is, for example, the case for the _Latin Modern_ family
+/// of fonts. In those cases, you can use a show-set rule to customize the
+/// appearance of the text in smallcaps:
///
/// ```typ
/// #show smallcaps: set text(font: "Latin Modern Roman Caps")
@@ -45,6 +45,17 @@ use crate::text::TextElem;
/// ```
#[elem(title = "Small Capitals", Show)]
pub struct SmallcapsElem {
+ /// Whether to turn uppercase letters into small capitals as well.
+ ///
+ /// Unless overridden by a show rule, this enables the `c2sc` OpenType
+ /// feature.
+ ///
+ /// ```example
+ /// #smallcaps(all: true)[UNICEF] is an
+ /// agency of #smallcaps(all: true)[UN].
+ /// ```
+ #[default(false)]
+ pub all: bool,
/// The content to display in small capitals.
#[required]
pub body: Content,
@@ -52,7 +63,17 @@ pub struct SmallcapsElem {
impl Show for Packed<SmallcapsElem> {
#[typst_macros::time(name = "smallcaps", span = self.span())]
- fn show(&self, _: &mut Engine, _: StyleChain) -> SourceResult<Content> {
- Ok(self.body.clone().styled(TextElem::set_smallcaps(true)))
+ fn show(&self, _: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
+ let sc = if self.all(styles) { Smallcaps::All } else { Smallcaps::Minuscules };
+ Ok(self.body.clone().styled(TextElem::set_smallcaps(Some(sc))))
}
}
+
+/// What becomes small capitals.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum Smallcaps {
+ /// Minuscules become small capitals.
+ Minuscules,
+ /// All letters become small capitals.
+ All,
+}