Add capability to synthesize italic
This commit is contained in:
parent
46d60a3723
commit
bd5f2f95e8
7 changed files with 55 additions and 7 deletions
|
|
@ -10,6 +10,7 @@ repository = "https://github.com/pop-os/cosmic-text"
|
|||
rust-version = "1.65"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "2.4.1"
|
||||
cosmic_undo_2 = { version = "0.2.0", optional = true }
|
||||
fontdb = { version = "0.16.0", default-features = false }
|
||||
hashbrown = { version = "0.14.1", optional = true, default-features = false }
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use cosmic_text::{
|
||||
Action, Attrs, Buffer, Color, Edit, Editor, Family, FontSystem, Metrics, Motion, Shaping,
|
||||
Style, SwashCache, Weight,
|
||||
Action, Attrs, Buffer, CacheKeyFlags, Color, Edit, Editor, Family, FontSystem, Metrics, Motion,
|
||||
Shaping, Style, SwashCache, Weight,
|
||||
};
|
||||
use orbclient::{EventOption, Renderer, Window, WindowFlag};
|
||||
use std::{
|
||||
|
|
@ -63,6 +63,10 @@ fn main() {
|
|||
("Sans-Serif Normal ", attrs),
|
||||
("Sans-Serif Bold ", attrs.weight(Weight::BOLD)),
|
||||
("Sans-Serif Italic ", attrs.style(Style::Italic)),
|
||||
(
|
||||
"Sans-Serif Fake Italic ",
|
||||
attrs.cache_key_flags(CacheKeyFlags::FAKE_ITALIC),
|
||||
),
|
||||
(
|
||||
"Sans-Serif Bold Italic\n",
|
||||
attrs.weight(Weight::BOLD).style(Style::Italic),
|
||||
|
|
|
|||
15
src/attrs.rs
15
src/attrs.rs
|
|
@ -6,9 +6,11 @@ use alloc::{
|
|||
vec::Vec,
|
||||
};
|
||||
use core::ops::Range;
|
||||
use rangemap::RangeMap;
|
||||
|
||||
use crate::CacheKeyFlags;
|
||||
|
||||
pub use fontdb::{Family, Stretch, Style, Weight};
|
||||
use rangemap::RangeMap;
|
||||
|
||||
/// Text color
|
||||
#[derive(Clone, Copy, Debug, PartialOrd, Ord, Eq, Hash, PartialEq)]
|
||||
|
|
@ -109,6 +111,7 @@ pub struct Attrs<'a> {
|
|||
pub style: Style,
|
||||
pub weight: Weight,
|
||||
pub metadata: usize,
|
||||
pub cache_key_flags: CacheKeyFlags,
|
||||
}
|
||||
|
||||
impl<'a> Attrs<'a> {
|
||||
|
|
@ -123,6 +126,7 @@ impl<'a> Attrs<'a> {
|
|||
style: Style::Normal,
|
||||
weight: Weight::NORMAL,
|
||||
metadata: 0,
|
||||
cache_key_flags: CacheKeyFlags::empty(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -162,6 +166,12 @@ impl<'a> Attrs<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Set [`CacheKeyFlags`]
|
||||
pub fn cache_key_flags(mut self, cache_key_flags: CacheKeyFlags) -> Self {
|
||||
self.cache_key_flags = cache_key_flags;
|
||||
self
|
||||
}
|
||||
|
||||
/// Check if font matches
|
||||
pub fn matches(&self, face: &fontdb::FaceInfo) -> bool {
|
||||
//TODO: smarter way of including emoji
|
||||
|
|
@ -190,6 +200,7 @@ pub struct AttrsOwned {
|
|||
pub style: Style,
|
||||
pub weight: Weight,
|
||||
pub metadata: usize,
|
||||
pub cache_key_flags: CacheKeyFlags,
|
||||
}
|
||||
|
||||
impl AttrsOwned {
|
||||
|
|
@ -201,6 +212,7 @@ impl AttrsOwned {
|
|||
style: attrs.style,
|
||||
weight: attrs.weight,
|
||||
metadata: attrs.metadata,
|
||||
cache_key_flags: attrs.cache_key_flags,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -212,6 +224,7 @@ impl AttrsOwned {
|
|||
style: self.style,
|
||||
weight: self.weight,
|
||||
metadata: self.metadata,
|
||||
cache_key_flags: self.cache_key_flags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,15 @@
|
|||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
bitflags::bitflags! {
|
||||
/// Flags that change rendering
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
#[repr(transparent)]
|
||||
pub struct CacheKeyFlags: u32 {
|
||||
/// Skew by 14 degrees to synthesize italic
|
||||
const FAKE_ITALIC = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// Key for building a glyph cache
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub struct CacheKey {
|
||||
|
|
@ -13,6 +23,8 @@ pub struct CacheKey {
|
|||
pub x_bin: SubpixelBin,
|
||||
/// Binning of fractional Y offset
|
||||
pub y_bin: SubpixelBin,
|
||||
/// [`CacheKeyFlags`]
|
||||
pub flags: CacheKeyFlags,
|
||||
}
|
||||
|
||||
impl CacheKey {
|
||||
|
|
@ -21,6 +33,7 @@ impl CacheKey {
|
|||
glyph_id: u16,
|
||||
font_size: f32,
|
||||
pos: (f32, f32),
|
||||
flags: CacheKeyFlags,
|
||||
) -> (Self, i32, i32) {
|
||||
let (x, x_bin) = SubpixelBin::new(pos.0);
|
||||
let (y, y_bin) = SubpixelBin::new(pos.1);
|
||||
|
|
@ -31,6 +44,7 @@ impl CacheKey {
|
|||
font_size_bits: font_size.to_bits(),
|
||||
x_bin,
|
||||
y_bin,
|
||||
flags,
|
||||
},
|
||||
x,
|
||||
y,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use core::fmt::Display;
|
|||
#[cfg(not(feature = "std"))]
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use crate::{CacheKey, Color};
|
||||
use crate::{CacheKey, CacheKeyFlags, Color};
|
||||
|
||||
/// A laid out glyph
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
@ -50,6 +50,8 @@ pub struct LayoutGlyph {
|
|||
pub color_opt: Option<Color>,
|
||||
/// Metadata from `Attrs`
|
||||
pub metadata: usize,
|
||||
/// [`CacheKeyFlags`]
|
||||
pub cache_key_flags: CacheKeyFlags,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
@ -75,6 +77,7 @@ impl LayoutGlyph {
|
|||
(self.x + x_offset) * scale + offset.0,
|
||||
libm::truncf((self.y - y_offset) * scale + offset.1), // Hinting in Y axis
|
||||
),
|
||||
self.cache_key_flags,
|
||||
);
|
||||
|
||||
PhysicalGlyph { cache_key, x, y }
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ use unicode_segmentation::UnicodeSegmentation;
|
|||
|
||||
use crate::fallback::FontFallbackIter;
|
||||
use crate::{
|
||||
Align, AttrsList, Color, Font, FontSystem, LayoutGlyph, LayoutLine, ShapePlanCache, Wrap,
|
||||
Align, AttrsList, CacheKeyFlags, Color, Font, FontSystem, LayoutGlyph, LayoutLine,
|
||||
ShapePlanCache, Wrap,
|
||||
};
|
||||
|
||||
/// The shaping strategy of some text.
|
||||
|
|
@ -148,6 +149,7 @@ fn shape_fallback(
|
|||
//TODO: color should not be related to shaping
|
||||
color_opt: attrs.color_opt,
|
||||
metadata: attrs.metadata,
|
||||
cache_key_flags: attrs.cache_key_flags,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -373,6 +375,7 @@ fn shape_skip(
|
|||
glyph_id,
|
||||
color_opt: attrs.color_opt,
|
||||
metadata: attrs.metadata,
|
||||
cache_key_flags: attrs.cache_key_flags,
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
|
@ -393,6 +396,7 @@ pub struct ShapeGlyph {
|
|||
pub glyph_id: u16,
|
||||
pub color_opt: Option<Color>,
|
||||
pub metadata: usize,
|
||||
pub cache_key_flags: CacheKeyFlags,
|
||||
}
|
||||
|
||||
impl ShapeGlyph {
|
||||
|
|
@ -418,6 +422,7 @@ impl ShapeGlyph {
|
|||
y_offset: self.y_offset,
|
||||
color_opt: self.color_opt,
|
||||
metadata: self.metadata,
|
||||
cache_key_flags: self.cache_key_flags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/swash.rs
12
src/swash.rs
|
|
@ -7,10 +7,10 @@ use swash::scale::{image::Content, ScaleContext};
|
|||
use swash::scale::{Render, Source, StrikeWith};
|
||||
use swash::zeno::{Format, Vector};
|
||||
|
||||
use crate::{CacheKey, Color, FontSystem, HashMap};
|
||||
use crate::{CacheKey, CacheKeyFlags, Color, FontSystem, HashMap};
|
||||
|
||||
pub use swash::scale::image::{Content as SwashContent, Image as SwashImage};
|
||||
pub use swash::zeno::{Command, Placement};
|
||||
pub use swash::zeno::{Angle, Command, Placement, Transform};
|
||||
|
||||
fn swash_image(
|
||||
font_system: &mut FontSystem,
|
||||
|
|
@ -49,6 +49,14 @@ fn swash_image(
|
|||
.format(Format::Alpha)
|
||||
// Apply the fractional offset
|
||||
.offset(offset)
|
||||
.transform(if cache_key.flags.contains(CacheKeyFlags::FAKE_ITALIC) {
|
||||
Some(Transform::skew(
|
||||
Angle::from_degrees(14.0),
|
||||
Angle::from_degrees(0.0),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
})
|
||||
// Render the image
|
||||
.render(&mut scaler, cache_key.glyph_id)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue