mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Add support for c2sc
OpenType feature in smallcaps
(#5655)
This commit is contained in:
parent
b7546bace7
commit
2d33393df9
@ -38,7 +38,8 @@ use crate::model::{
|
|||||||
};
|
};
|
||||||
use crate::routines::{EvalMode, Routines};
|
use crate::routines::{EvalMode, Routines};
|
||||||
use crate::text::{
|
use crate::text::{
|
||||||
FontStyle, Lang, LocalName, Region, SubElem, SuperElem, TextElem, WeightDelta,
|
FontStyle, Lang, LocalName, Region, Smallcaps, SubElem, SuperElem, TextElem,
|
||||||
|
WeightDelta,
|
||||||
};
|
};
|
||||||
use crate::World;
|
use crate::World;
|
||||||
|
|
||||||
@ -1046,7 +1047,8 @@ fn apply_formatting(mut content: Content, format: &hayagriva::Formatting) -> Con
|
|||||||
match format.font_variant {
|
match format.font_variant {
|
||||||
citationberg::FontVariant::Normal => {}
|
citationberg::FontVariant::Normal => {}
|
||||||
citationberg::FontVariant::SmallCaps => {
|
citationberg::FontVariant::SmallCaps => {
|
||||||
content = content.styled(TextElem::set_smallcaps(true));
|
content =
|
||||||
|
content.styled(TextElem::set_smallcaps(Some(Smallcaps::Minuscules)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -755,11 +755,10 @@ pub struct TextElem {
|
|||||||
#[ghost]
|
#[ghost]
|
||||||
pub case: Option<Case>,
|
pub case: Option<Case>,
|
||||||
|
|
||||||
/// Whether small capital glyphs should be used. ("smcp")
|
/// Whether small capital glyphs should be used. ("smcp", "c2sc")
|
||||||
#[internal]
|
#[internal]
|
||||||
#[default(false)]
|
|
||||||
#[ghost]
|
#[ghost]
|
||||||
pub smallcaps: bool,
|
pub smallcaps: Option<Smallcaps>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextElem {
|
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.
|
// 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);
|
feat(b"smcp", 1);
|
||||||
|
if sc == Smallcaps::All {
|
||||||
|
feat(b"c2sc", 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if TextElem::alternates_in(styles) {
|
if TextElem::alternates_in(styles) {
|
||||||
|
@ -12,11 +12,11 @@ use crate::text::TextElem;
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Smallcaps fonts
|
/// # Smallcaps fonts
|
||||||
/// By default, this enables the OpenType `smcp` feature for the font. Not all
|
/// By default, this uses the `smcp` and `c2sc` OpenType features on the font.
|
||||||
/// fonts support this feature. Sometimes smallcaps are part of a dedicated
|
/// Not all fonts support these features. Sometimes, smallcaps are part of a
|
||||||
/// font. This is, for example, the case for the _Latin Modern_ family of fonts.
|
/// dedicated font. This is, for example, the case for the _Latin Modern_ family
|
||||||
/// In those cases, you can use a show-set rule to customize the appearance of
|
/// of fonts. In those cases, you can use a show-set rule to customize the
|
||||||
/// the text in smallcaps:
|
/// appearance of the text in smallcaps:
|
||||||
///
|
///
|
||||||
/// ```typ
|
/// ```typ
|
||||||
/// #show smallcaps: set text(font: "Latin Modern Roman Caps")
|
/// #show smallcaps: set text(font: "Latin Modern Roman Caps")
|
||||||
@ -45,6 +45,17 @@ use crate::text::TextElem;
|
|||||||
/// ```
|
/// ```
|
||||||
#[elem(title = "Small Capitals", Show)]
|
#[elem(title = "Small Capitals", Show)]
|
||||||
pub struct SmallcapsElem {
|
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.
|
/// The content to display in small capitals.
|
||||||
#[required]
|
#[required]
|
||||||
pub body: Content,
|
pub body: Content,
|
||||||
@ -52,7 +63,17 @@ pub struct SmallcapsElem {
|
|||||||
|
|
||||||
impl Show for Packed<SmallcapsElem> {
|
impl Show for Packed<SmallcapsElem> {
|
||||||
#[typst_macros::time(name = "smallcaps", span = self.span())]
|
#[typst_macros::time(name = "smallcaps", span = self.span())]
|
||||||
fn show(&self, _: &mut Engine, _: StyleChain) -> SourceResult<Content> {
|
fn show(&self, _: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
|
||||||
Ok(self.body.clone().styled(TextElem::set_smallcaps(true)))
|
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,
|
||||||
|
}
|
||||||
|
BIN
tests/ref/smallcaps-all.png
Normal file
BIN
tests/ref/smallcaps-all.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 512 B |
@ -10,3 +10,7 @@
|
|||||||
|
|
||||||
#show smallcaps: set text(fill: red)
|
#show smallcaps: set text(fill: red)
|
||||||
#smallcaps[Smallcaps]
|
#smallcaps[Smallcaps]
|
||||||
|
|
||||||
|
--- smallcaps-all ---
|
||||||
|
#smallcaps(all: false)[Test 012] \
|
||||||
|
#smallcaps(all: true)[Test 012]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user