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

diagrams with empty envelopes are not properly separated by struts #115

Closed
byorgey opened this issue Sep 19, 2013 · 3 comments
Closed

diagrams with empty envelopes are not properly separated by struts #115

byorgey opened this issue Sep 19, 2013 · 3 comments
Labels

Comments

@byorgey
Copy link
Member

byorgey commented Sep 19, 2013

A cut down example based on code from av in #diagrams:

{-# LANGUAGE NoMonomorphismRestriction #-}

import           Diagrams.Backend.Cairo.CmdLine
import           Diagrams.Prelude

label s t = text t # fontSize s

d = vcat [ label 0.08 "first line"
         , strutY 0.1
         , label 0.08 "second line"
         ]

main = defaultMain (d <> square 1)

produces
issue115

(see also http://paste.hskll.org/get/374 and http://paste.hskll.org/get/375).

This may be related to #37 (in fact it's possible that fixing #37 would also fix this; I am not sure).

More generally, we ought to work out and write down a coherent semantics for empty envelopes, juxtaposition, struts, and cat' / sep.

@bergey
Copy link
Member

bergey commented Sep 20, 2013

Using Cut to accumulate repeated seperations, as discussed in #37, doesn't help here. In vcat, sep is 0, so it doesn't matter what we do with sep. As another example,

vcat' with {sep = 0.1} [label 0.08 "FIRST LINE", label 0.08 "SECOND LINE"]

produces two non-overlapping lines, as expected.

The issue here seems to be in how juxtapose behaves when one argument has an empty envelope. I expected that juxtaposing the first label with the strut would shift the origin of the strut to the top. Instead, the strut is returned unchanged, with origin at the bottom. juxtaposeDefault unit_Y strutX strutY, by contrast, has origin at the top. I think it would be less surprising if juxtaposeDefault moved the origin as long as at least one envelope is non-empty:

juxtaposeDefault :: (Enveloped a, HasOrigin a) => V a -> a -> a -> a
juxtaposeDefault v a1 a2 =
  case (mv1, mv2) of
    (Just v1, Just v2) -> moveOriginBy (v1 ^+^ v2) a2
    (Nothing, Just v2) -> moveOriginBy v2 a2
    (Just v1, Nothing) -> moveOriginBy v1 a2
    _                  -> a2
  where mv1 = negateV <$> envelopeVMay v a1
        mv2 = envelopeVMay (negateV v) a2

This makes av's example do as expected. Do other parts of the code depend on the current behavior?

@byorgey
Copy link
Member Author

byorgey commented Sep 22, 2013

OK, I had an hour to think about this on my flight yesterday, and I think I now have a good understanding of what is going on and a good story for moving forward.

First, the reason the behavior changed between 0.6 and 0.7 is diagrams/diagrams-core@0a457da4. We made mempty an identity element for juxtapose (and hence also for cat, (|||), (===), and so on). I think this is actually good, and I would rather not change it as suggested by @bergey above. This is a nice, simple semantics, and if you go about combining the empty diagram with things it will behave reasonably.

@bergey is right that this is unrelated to #37. The problem is really diagrams which have an empty envelope but not an empty appearance: juxtaposing them is very counterintuitive. The right solution, I think, is to give text primitives a point envelope instead of an empty envelope, as suggested in #116. Then they will combine as expected. This makes sense: although text objects take up no space they do have a concrete location. In fact, @bergey's suggested change to juxtaposeDefault amounts to treating empty envelopes as if they were point envelopes.

@bergey
Copy link
Member

bergey commented Sep 22, 2013

The right solution, I think, is to give text primitives a point envelope instead of an empty envelope, as suggested in #116.

That does sound better than changing juxtapose, and reintroducing the second part of #37!

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

No branches or pull requests

2 participants