mirror of
https://github.com/typst/typst
synced 2025-08-15 15:38:33 +08:00
IDE: implement frame clip and transform
This commit is contained in:
parent
1f1c133878
commit
5865f0e9e9
@ -53,10 +53,14 @@ pub fn jump_from_click(
|
|||||||
for (mut pos, item) in frame.items().rev() {
|
for (mut pos, item) in frame.items().rev() {
|
||||||
match item {
|
match item {
|
||||||
FrameItem::Group(group) => {
|
FrameItem::Group(group) => {
|
||||||
// TODO: Handle transformation.
|
let pos = click - pos;
|
||||||
if let Some(span) =
|
if let Some(clip) = &group.clip {
|
||||||
jump_from_click(world, document, &group.frame, click - pos)
|
if !clip.contains(pos) {
|
||||||
{
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let pos = pos.transform_inf(group.transform.invert().unwrap());
|
||||||
|
if let Some(span) = jump_from_click(world, document, &group.frame, pos) {
|
||||||
return Some(span);
|
return Some(span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,9 +150,8 @@ pub fn jump_from_cursor(
|
|||||||
fn find_in_frame(frame: &Frame, span: Span) -> Option<Point> {
|
fn find_in_frame(frame: &Frame, span: Span) -> Option<Point> {
|
||||||
for (mut pos, item) in frame.items() {
|
for (mut pos, item) in frame.items() {
|
||||||
if let FrameItem::Group(group) = item {
|
if let FrameItem::Group(group) = item {
|
||||||
// TODO: Handle transformation.
|
|
||||||
if let Some(point) = find_in_frame(&group.frame, span) {
|
if let Some(point) = find_in_frame(&group.frame, span) {
|
||||||
return Some(point + pos);
|
return Some(pos + point.transform(group.transform));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,6 +272,42 @@ mod tests {
|
|||||||
test_click("$a + b$", point(28.0, 14.0), cursor(5));
|
test_click("$a + b$", point(28.0, 14.0), cursor(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_jump_from_click_transform_clip() {
|
||||||
|
let margin = point(10.0, 10.0);
|
||||||
|
test_click(
|
||||||
|
"#rect(width: 20pt, height: 20pt)",
|
||||||
|
point(10.0, 10.0) + margin,
|
||||||
|
cursor(1),
|
||||||
|
);
|
||||||
|
test_click("#rect(width: 60pt, height: 10pt)", point(5.0, 30.0) + margin, None);
|
||||||
|
test_click(
|
||||||
|
"#rotate(90deg, origin: bottom + left, rect(width: 60pt, height: 10pt))",
|
||||||
|
point(5.0, 30.0) + margin,
|
||||||
|
cursor(38),
|
||||||
|
);
|
||||||
|
test_click(
|
||||||
|
"#scale(x: 300%, y: 300%, origin: top + left, rect(width: 10pt, height: 10pt))",
|
||||||
|
point(20.0, 20.0) + margin,
|
||||||
|
cursor(45),
|
||||||
|
);
|
||||||
|
test_click(
|
||||||
|
"#box(width: 10pt, height: 10pt, clip: true, scale(x: 300%, y: 300%, origin: top + left, rect(width: 10pt, height: 10pt)))",
|
||||||
|
point(20.0, 20.0) + margin,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
test_click(
|
||||||
|
"#box(width: 10pt, height: 10pt, clip: false, rect(width: 30pt, height: 30pt))",
|
||||||
|
point(20.0, 20.0) + margin,
|
||||||
|
cursor(45),
|
||||||
|
);
|
||||||
|
test_click(
|
||||||
|
"#box(width: 10pt, height: 10pt, clip: true, rect(width: 30pt, height: 30pt))",
|
||||||
|
point(20.0, 20.0) + margin,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_jump_from_cursor() {
|
fn test_jump_from_cursor() {
|
||||||
let s = "*Hello* #box[ABC] World";
|
let s = "*Hello* #box[ABC] World";
|
||||||
@ -281,6 +320,15 @@ mod tests {
|
|||||||
test_cursor("$a + b$", -3, pos(1, 27.51, 16.83));
|
test_cursor("$a + b$", -3, pos(1, 27.51, 16.83));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_jump_from_cursor_transform() {
|
||||||
|
test_cursor(
|
||||||
|
r#"#rotate(90deg, origin: bottom + left, [hello world])"#,
|
||||||
|
-5,
|
||||||
|
pos(1, 10.0, 16.58),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_backlink() {
|
fn test_backlink() {
|
||||||
let s = "#footnote[Hi]";
|
let s = "#footnote[Hi]";
|
||||||
|
@ -530,3 +530,30 @@ impl Curve {
|
|||||||
Size::new(max_x - min_x, max_y - min_y)
|
Size::new(max_x - min_x, max_y - min_y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn point_to_kurbo(point: Point) -> kurbo::Point {
|
||||||
|
kurbo::Point::new(point.x.to_raw(), point.y.to_raw())
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Curve {
|
||||||
|
fn to_kurbo(&self) -> kurbo::BezPath {
|
||||||
|
use kurbo::{BezPath, PathEl};
|
||||||
|
|
||||||
|
let path = self.0.iter().map(|item| match *item {
|
||||||
|
CurveItem::Move(point) => PathEl::MoveTo(point_to_kurbo(point)),
|
||||||
|
CurveItem::Line(point) => PathEl::LineTo(point_to_kurbo(point)),
|
||||||
|
CurveItem::Cubic(point, point1, point2) => PathEl::CurveTo(
|
||||||
|
point_to_kurbo(point),
|
||||||
|
point_to_kurbo(point1),
|
||||||
|
point_to_kurbo(point2),
|
||||||
|
),
|
||||||
|
CurveItem::Close => PathEl::ClosePath,
|
||||||
|
});
|
||||||
|
BezPath::from_vec(path.collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// When this curve is interpreted as a clip mask, would it contain `point`?
|
||||||
|
pub fn contains(&self, needle: Point) -> bool {
|
||||||
|
kurbo::Shape::contains(&self.to_kurbo(), point_to_kurbo(needle))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user