Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Content-Relative Anchors #683

Closed
timfi opened this issue Aug 13, 2024 · 24 comments · Fixed by #684
Closed

[Feature Request] Content-Relative Anchors #683

timfi opened this issue Aug 13, 2024 · 24 comments · Fixed by #684
Labels
feature 🎁 Feature Request

Comments

@timfi
Copy link

timfi commented Aug 13, 2024

Cetz currently doesn't support anchors whose position is relative to the properties of a nodes content—see base*, mid*, and text in the image below.

grafik
(Credits to Packt for the image.)

After a short, productive discussion with @fenjalien (see #680), it turns out that:

No we currently don't [support] as it would require inspecting the provided content and measuring it. This is difficult as theres no official documentation for how content values are supposed to act and could change with any release. Once Typst provides more ways to control content it would be something we'll be looking into.
— Originally commented by fenjalien in the discussion mentioned above.

@timfi timfi changed the title Content-relative anchors [Feature Request] Content-Relative Anchors Aug 13, 2024
@johannes-wolf
Copy link
Member

I think we can create those anchors for content(..., frame: "rect|circle") content, because we can access the Typst content bounds.

@johannes-wolf johannes-wolf added the feature 🎁 Feature Request label Aug 13, 2024
@timfi
Copy link
Author

timfi commented Aug 13, 2024

I think we can create those anchors for content(..., frame: "rect|circle") content, because we can access the Typst content bounds.

Can one access them in the current version using the snippet you provided? And if so, what are the called?

@johannes-wolf
Copy link
Member

No, we do not create them yet. How are you using content(...)? Are you using either padding: or frame:?

@timfi
Copy link
Author

timfi commented Aug 13, 2024

As it stands I'm using padding.

@johannes-wolf
Copy link
Member

johannes-wolf commented Aug 13, 2024

So all you want is "unpadded" anchors of the contents bounding box (more or less)?

@timfi
Copy link
Author

timfi commented Aug 13, 2024

Roughly, the most important feature to me is that the anchors are on the same height as the baseline of the content. This makes drawing things such that text lines up across multiple parts much easier. I'm not sure if that is exactly what you meant just now.

@johannes-wolf
Copy link
Member

Not exactly, as Typst does not give access to the baseline. So no, this cannot be implemented right now.

@timfi
Copy link
Author

timfi commented Aug 13, 2024

Ok, I'm looking forward to whenever the folks over at Typst get around to implementing external access to such properties.

@johannes-wolf
Copy link
Member

Wait… it should work.
If you place two contents at (0,0), the baselines line up.

@timfi
Copy link
Author

timfi commented Aug 13, 2024

Without setting the anchors?

@timfi
Copy link
Author

timfi commented Aug 13, 2024

Or do the horizontal anchors naturally fall along the baseline of included text?

@johannes-wolf
Copy link
Member

Yes, but only if padding is 0, I guess.

@johannes-wolf
Copy link
Member

So what cetz needs to do, is to expose the bounding box anchors of the content without the padding applied.

@timfi
Copy link
Author

timfi commented Aug 13, 2024

Seems so. As long as the natural aligning of the baseline to the east and west anchor is something one can rely on.

@johannes-wolf
Copy link
Member

No, east and west are centered. Sorry I missunderstood you.
Here

let w = width/2
the anchors of the contents bbox get computed, which needs to be done twice; a second time without the padding.

@timfi
Copy link
Author

timfi commented Aug 13, 2024

Ah, I see. I guess this means waiting for Typst to properly expose these measurements/properties?

@johannes-wolf
Copy link
Member

johannes-wolf commented Aug 13, 2024

But you can get what you want with a workaround, I guess:

#import "@preview/cetz:0.2.2"
#set page(width: auto, height: auto)

#let content2(..args, anchor: none, name: none, padding: 0) = {
  cetz.draw.group(name: name, anchor: anchor, {
    cetz.draw.group(name: "tmp-group", padding: padding, {
      cetz.draw.content(..args, name: "content")
    })
  
    cetz.draw.rect("tmp-group.south-west", "tmp-group.north-east")
    
    cetz.draw.anchor("baseline-west", ("tmp-group.content.south-west", "-|", "tmp-group.west"))
    cetz.draw.anchor("baseline-east", ("tmp-group.content.south-east", "-|", "tmp-group.east"))
  })
}
#cetz.canvas({
  import cetz.draw: *

  content2((0, 10), [Alle Autos!], anchor: "south", padding: 1, name: "a")
  content2("a.baseline-east", [geile Autos, yeah! \ geniaiaeaeiaenein],
    anchor: "baseline-west")
})

Gives:
grafik

So you can implement this feature via cetz itself :)

@timfi
Copy link
Author

timfi commented Aug 13, 2024

Wow! I'll need to give that a try a soon as I'm back in front of my machine.

@timfi
Copy link
Author

timfi commented Aug 14, 2024

@johannes-wolf Your workaround works nicely, thank you very much! But I believe it works since—and forgive me if I don't have the proper Typst terminology down—the bottom-edge of text objects is set to "baseline" by default, i.e., doesn't include descenders. Your example shows this nicely with the g poking out at the bottom of the second node.


As an aside, I'm bewilder by the fact that Typst doesn't automatically choose the smallest possible settings for bottom-edge and top-edge, but rather defaults to "baseline" and "cap-height", respectively. For me at least, this makes drawing tight boxes around arbitrary text unintuitive since one always needs to tweak the extents of the boxes based on the content. There may well be good reasons for this that I am unaware of; for example, I assume that layouting free form text is simplified a bit by this, since the baselines will just line up once all the text objects are vertically aligned along their bottom edge.

@timfi
Copy link
Author

timfi commented Aug 14, 2024

Though not particularly relevant to this issue if found a resolution to the aside in my previous comment. Typst also supports "bounds" for both top-edge and bottom-edge, which sets the limits—as the docs put it—to "the top/bottom edge of the glyph's bounding box".

@johannes-wolf
Copy link
Member

@timfi Yes, I think Typsts measure should return multiple heights, one for the baseline and one for a tight bounding box that contains descenders. @laurmaedje, would that be possible? Should I create an issue?

@laurmaedje
Copy link

Would it be possible to instead measure twice with different settings for text edge?

@johannes-wolf
Copy link
Member

Would it be possible to instead measure twice with different settings for text edge?

That should work, yes.

@johannes-wolf johannes-wolf linked a pull request Aug 14, 2024 that will close this issue
@johannes-wolf
Copy link
Member

PR is ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature 🎁 Feature Request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants