Skip to content

Commit

Permalink
fix(exporter): partially disable incr rendering
Browse files Browse the repository at this point in the history
+ on elements that contains gradient fill
  • Loading branch information
Myriad-Dreamin committed Oct 31, 2023
1 parent a9069f8 commit 6186f49
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 5 deletions.
14 changes: 10 additions & 4 deletions exporter/svg/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use typst_ts_core::{
mod escape;
use escape::{PcDataEscapes, TextContentDataEscapes};

use crate::utils::ToCssExt;
use crate::{frontend::HasGradient, utils::ToCssExt};

pub trait BuildClipPath {
fn build_clip_path(&mut self, path: &ir::PathItem) -> Fingerprint;
Expand Down Expand Up @@ -586,8 +586,10 @@ impl<
}

/// See [`FlatGroupContext`].
impl<'m, C: FlatIncrRenderVm<'m, Resultant = Arc<SvgTextNode>, Group = SvgTextBuilder>>
FlatIncrGroupContext<C> for SvgTextBuilder
impl<
'm,
C: FlatIncrRenderVm<'m, Resultant = Arc<SvgTextNode>, Group = SvgTextBuilder> + HasGradient,
> FlatIncrGroupContext<C> for SvgTextBuilder
{
fn render_diff_item_ref_at(
&mut self,
Expand All @@ -597,7 +599,8 @@ impl<'m, C: FlatIncrRenderVm<'m, Resultant = Arc<SvgTextNode>, Group = SvgTextBu
item: &Fingerprint,
prev_item: &Fingerprint,
) {
let content = if item == prev_item {
let has_gradient = ctx.has_gradient(item);
let content = if item == prev_item && !has_gradient {
// todo: update transform
vec![]
} else {
Expand All @@ -612,6 +615,9 @@ impl<'m, C: FlatIncrRenderVm<'m, Resultant = Arc<SvgTextNode>, Group = SvgTextBu
};
attributes.push(("data-tid", item.as_svg_id("p")));
attributes.push(("data-reuse-from", prev_item.as_svg_id("p")));
if has_gradient {
attributes.push(("data-bad-equality", "1".to_owned()));
}

self.content.push(SvgText::Content(Arc::new(SvgTextNode {
attributes,
Expand Down
35 changes: 34 additions & 1 deletion exporter/svg/src/frontend/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use typst_ts_core::{
flat_vm::{FlatGroupContext, FlatIncrRenderVm, FlatRenderVm},
ir::{
self, BuildGlyph, FontIndice, FontRef, GlyphHashStablizer, GlyphIndice, GlyphItem,
GlyphPackBuilder, GlyphRef, ImmutStr, PathItem, Scalar, StyleNs,
GlyphPackBuilder, GlyphRef, ImmutStr, PathItem, PathStyle, Scalar, StyleNs,
},
vm::GroupContext,
vm::{RenderState, RenderVm},
Expand All @@ -21,9 +21,12 @@ use crate::{
BuildClipPath, BuildFillStyleClass, DynExportFeature, NotifyPaint, SvgText, SvgTextBuilder,
SvgTextNode,
},
utils::MemorizeFree,
ExportFeature, GlyphProvider, SvgGlyphBuilder,
};

use super::HasGradient;

/// Maps the style name to the style definition.
/// See [`StyleNs`].
pub(crate) type StyleDefMap = HashMap<(StyleNs, ImmutStr), String>;
Expand Down Expand Up @@ -146,6 +149,36 @@ impl<'m, 't, Feat: ExportFeature> BuildClipPath for RenderContext<'m, 't, Feat>
}
}

#[comemo::memoize]
fn has_gradient<'m, 't, Feat: ExportFeature>(
ctx: &MemorizeFree<RenderContext<'m, 't, Feat>>,
x: &Fingerprint,
) -> bool {
let Some(item) = ctx.0.get_item(x) else {
// overestimated
return true;
};

use FlatSvgItem::*;
match item {
Gradient(..) => true,
Image(..) | Link(..) | None => false,
Item(t) => has_gradient(ctx, &t.1),
Group(g, ..) => g.0.iter().any(|(_, x)| has_gradient(ctx, x)),
Path(p) => p.styles.iter().any(|s| match s {
PathStyle::Fill(color) | PathStyle::Stroke(color) => color.starts_with('@'),
_ => false,
}),
Text(p) => p.shape.fill.starts_with('@'),
}
}

impl<'m, 't, Feat: ExportFeature> HasGradient for RenderContext<'m, 't, Feat> {
fn has_gradient(&self, a: &Fingerprint) -> bool {
has_gradient(&MemorizeFree(self), a)
}
}

impl<'m, 't, Feat: ExportFeature> NotifyPaint for RenderContext<'m, 't, Feat> {
fn notify_paint(&mut self, url_ref: ImmutStr) -> (u8, Fingerprint, Option<bool>) {
if let Some(f) = self.gradients.get(&url_ref) {
Expand Down
4 changes: 4 additions & 0 deletions exporter/svg/src/frontend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -752,3 +752,7 @@ impl std::fmt::Display for RatioRepr {
write!(f, "{:.3}%", self.0 * 100.0)
}
}

pub trait HasGradient {
fn has_gradient(&self, f: &Fingerprint) -> bool;
}
15 changes: 15 additions & 0 deletions exporter/svg/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,18 @@ impl ToCssExt for ir::Transform {
)
}
}

#[derive(Clone, Copy)]
pub(crate) struct MemorizeFree<'a, T>(pub &'a T);

impl<'a, T> std::hash::Hash for MemorizeFree<'a, T> {
fn hash<H: std::hash::Hasher>(&self, _state: &mut H) {}
}

impl<'a, T> std::cmp::PartialEq for MemorizeFree<'a, T> {
fn eq(&self, _other: &Self) -> bool {
true
}
}

impl<'a, T> std::cmp::Eq for MemorizeFree<'a, T> {}

0 comments on commit 6186f49

Please sign in to comment.