Add rounded corners and strokes to highlight (#3526)
This commit is contained in:
parent
030041466b
commit
67ba8d6c0e
@ -5,12 +5,14 @@ use ttf_parser::{GlyphId, OutlineBuilder};
|
|||||||
use crate::diag::SourceResult;
|
use crate::diag::SourceResult;
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::foundations::{elem, Content, Packed, Show, Smart, StyleChain};
|
use crate::foundations::{elem, Content, Packed, Show, Smart, StyleChain};
|
||||||
use crate::layout::{Abs, Em, Frame, FrameItem, Length, Point, Size};
|
use crate::layout::{
|
||||||
|
Abs, Corners, Em, Frame, FrameItem, Length, Point, Rel, Sides, Size,
|
||||||
|
};
|
||||||
use crate::syntax::Span;
|
use crate::syntax::Span;
|
||||||
use crate::text::{
|
use crate::text::{
|
||||||
BottomEdge, BottomEdgeMetric, TextElem, TextItem, TopEdge, TopEdgeMetric,
|
BottomEdge, BottomEdgeMetric, TextElem, TextItem, TopEdge, TopEdgeMetric,
|
||||||
};
|
};
|
||||||
use crate::visualize::{Color, FixedStroke, Geometry, Paint, Stroke};
|
use crate::visualize::{styled_rect, Color, FixedStroke, Geometry, Paint, Stroke};
|
||||||
|
|
||||||
/// Underlines text.
|
/// Underlines text.
|
||||||
///
|
///
|
||||||
@ -283,6 +285,12 @@ pub struct HighlightElem {
|
|||||||
#[default(Color::from_u8(0xFF, 0xFD, 0x11, 0xA1).into())]
|
#[default(Color::from_u8(0xFF, 0xFD, 0x11, 0xA1).into())]
|
||||||
pub fill: Paint,
|
pub fill: Paint,
|
||||||
|
|
||||||
|
/// The highlight's border color. See the
|
||||||
|
/// [rectangle's documentation]($rect.stroke) for more details.
|
||||||
|
#[resolve]
|
||||||
|
#[fold]
|
||||||
|
pub stroke: Sides<Option<Option<Stroke>>>,
|
||||||
|
|
||||||
/// The top end of the background rectangle.
|
/// The top end of the background rectangle.
|
||||||
///
|
///
|
||||||
/// ```example
|
/// ```example
|
||||||
@ -316,6 +324,12 @@ pub struct HighlightElem {
|
|||||||
#[resolve]
|
#[resolve]
|
||||||
pub extent: Length,
|
pub extent: Length,
|
||||||
|
|
||||||
|
/// How much to round the highlight's corners. See the
|
||||||
|
/// [rectangle's documentation]($rect.radius) for more details.
|
||||||
|
#[resolve]
|
||||||
|
#[fold]
|
||||||
|
pub radius: Corners<Option<Rel<Length>>>,
|
||||||
|
|
||||||
/// The content that should be highlighted.
|
/// The content that should be highlighted.
|
||||||
#[required]
|
#[required]
|
||||||
pub body: Content,
|
pub body: Content,
|
||||||
@ -327,8 +341,13 @@ impl Show for Packed<HighlightElem> {
|
|||||||
Ok(self.body().clone().styled(TextElem::set_deco(smallvec![Decoration {
|
Ok(self.body().clone().styled(TextElem::set_deco(smallvec![Decoration {
|
||||||
line: DecoLine::Highlight {
|
line: DecoLine::Highlight {
|
||||||
fill: self.fill(styles),
|
fill: self.fill(styles),
|
||||||
|
stroke: self
|
||||||
|
.stroke(styles)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.map(|stroke| stroke.map(Stroke::unwrap_or_default)),
|
||||||
top_edge: self.top_edge(styles),
|
top_edge: self.top_edge(styles),
|
||||||
bottom_edge: self.bottom_edge(styles),
|
bottom_edge: self.bottom_edge(styles),
|
||||||
|
radius: self.radius(styles).unwrap_or_default(),
|
||||||
},
|
},
|
||||||
extent: self.extent(styles),
|
extent: self.extent(styles),
|
||||||
}])))
|
}])))
|
||||||
@ -348,10 +367,30 @@ pub struct Decoration {
|
|||||||
/// A kind of decorative line.
|
/// A kind of decorative line.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||||
enum DecoLine {
|
enum DecoLine {
|
||||||
Underline { stroke: Stroke<Abs>, offset: Smart<Abs>, evade: bool, background: bool },
|
Underline {
|
||||||
Strikethrough { stroke: Stroke<Abs>, offset: Smart<Abs>, background: bool },
|
stroke: Stroke<Abs>,
|
||||||
Overline { stroke: Stroke<Abs>, offset: Smart<Abs>, evade: bool, background: bool },
|
offset: Smart<Abs>,
|
||||||
Highlight { fill: Paint, top_edge: TopEdge, bottom_edge: BottomEdge },
|
evade: bool,
|
||||||
|
background: bool,
|
||||||
|
},
|
||||||
|
Strikethrough {
|
||||||
|
stroke: Stroke<Abs>,
|
||||||
|
offset: Smart<Abs>,
|
||||||
|
background: bool,
|
||||||
|
},
|
||||||
|
Overline {
|
||||||
|
stroke: Stroke<Abs>,
|
||||||
|
offset: Smart<Abs>,
|
||||||
|
evade: bool,
|
||||||
|
background: bool,
|
||||||
|
},
|
||||||
|
Highlight {
|
||||||
|
fill: Paint,
|
||||||
|
stroke: Sides<Option<FixedStroke>>,
|
||||||
|
top_edge: TopEdge,
|
||||||
|
bottom_edge: BottomEdge,
|
||||||
|
radius: Corners<Rel<Abs>>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add line decorations to a single run of shaped text.
|
/// Add line decorations to a single run of shaped text.
|
||||||
@ -365,12 +404,18 @@ pub(crate) fn decorate(
|
|||||||
) {
|
) {
|
||||||
let font_metrics = text.font.metrics();
|
let font_metrics = text.font.metrics();
|
||||||
|
|
||||||
if let DecoLine::Highlight { fill, top_edge, bottom_edge } = &deco.line {
|
if let DecoLine::Highlight { fill, stroke, top_edge, bottom_edge, radius } =
|
||||||
|
&deco.line
|
||||||
|
{
|
||||||
let (top, bottom) = determine_edges(text, *top_edge, *bottom_edge);
|
let (top, bottom) = determine_edges(text, *top_edge, *bottom_edge);
|
||||||
let rect = Geometry::Rect(Size::new(width + 2.0 * deco.extent, top - bottom))
|
let size = Size::new(width + 2.0 * deco.extent, top - bottom);
|
||||||
.filled(fill.clone());
|
let rects = styled_rect(size, *radius, Some(fill.clone()), stroke.clone());
|
||||||
let origin = Point::new(pos.x - deco.extent, pos.y - top - shift);
|
let origin = Point::new(pos.x - deco.extent, pos.y - top - shift);
|
||||||
frame.prepend(origin, FrameItem::Shape(rect, Span::detached()));
|
frame.prepend_multiple(
|
||||||
|
rects
|
||||||
|
.into_iter()
|
||||||
|
.map(|shape| (origin, FrameItem::Shape(shape, Span::detached()))),
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 63 KiB |
@ -58,6 +58,17 @@ We can also specify a customized value
|
|||||||
#highlight[abc]
|
#highlight[abc]
|
||||||
#highlight[abc #sym.integral]
|
#highlight[abc #sym.integral]
|
||||||
|
|
||||||
|
---
|
||||||
|
// Test highlight radius
|
||||||
|
#highlight(radius: 3pt)[abc],
|
||||||
|
#highlight(radius: 1em)[#lorem(5)]
|
||||||
|
|
||||||
|
---
|
||||||
|
// Test highlight stroke
|
||||||
|
#highlight(stroke: 2pt + blue)[abc]
|
||||||
|
#highlight(stroke: (top: blue, left: red, bottom: green, right: orange))[abc]
|
||||||
|
#highlight(stroke: 1pt, radius: 3pt)[#lorem(5)]
|
||||||
|
|
||||||
---
|
---
|
||||||
// Test underline background
|
// Test underline background
|
||||||
#set underline(background: true, stroke: (thickness: 0.5em, paint: red, cap: "round"))
|
#set underline(background: true, stroke: (thickness: 0.5em, paint: red, cap: "round"))
|
||||||
@ -68,7 +79,6 @@ We can also specify a customized value
|
|||||||
#set overline(background: true, stroke: (thickness: 0.5em, paint: red, cap: "round"))
|
#set overline(background: true, stroke: (thickness: 0.5em, paint: red, cap: "round"))
|
||||||
#overline[This is in the background]
|
#overline[This is in the background]
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
// Test strike background
|
// Test strike background
|
||||||
#set strike(background: true, stroke: 5pt + red)
|
#set strike(background: true, stroke: 5pt + red)
|
||||||
|
Loading…
Reference in New Issue
Block a user