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

Pango #49

Merged
merged 7 commits into from May 22, 2014
Merged

Pango #49

merged 7 commits into from May 22, 2014

Conversation

bergey
Copy link
Member

@bergey bergey commented May 17, 2014

This branch uses Pango for font layout instead of the toy API that ships with Cairo. I haven't started on Cairo.Text, yet, so this doesn't address #19. It may fix #43; I'm not sure.

I also want to put together some examples that use non-Latin characters, BIDI, combining chars---all the nice stuff Pango should give us. Pending figuring out what's wrong with my Fontconfig.

I'm seeking advice on the right way to interleave Pango and Cairo functions. Pango returns in IO, rather than in Cairo.Render. I hacked the code together with unsafePerformIO, which is obviously wrong.

@bergey
Copy link
Member Author

bergey commented May 20, 2014

This is very broken right now. Folks should hold off looking at it until I finish transitioning to Pango and sort out some major scaling problems.

not just for querying extent.  Handle Local FontSize by scaling before
layout.  This looks better, but it's possible we should implement both
interpretations.
@bergey
Copy link
Member Author

bergey commented May 20, 2014

I added some debugging code to draw the extent rectangle around the text. I believe this branch fixes the issues described in #19, though textLineBoundedIO remains unusable since the introduction of Measure.

Here's my test code:

{-# LANGUAGE NoMonomorphismRestriction #-}

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

main = defaultMain $ example # centerXY # pad 1.1

-- For debugging, I've hacked the Cairo Backend to add a rectangle
-- around text, corresponding to the logical extent as reported by
-- Pango.
--
-- This mimics the test in
-- https://github.com/diagrams/diagrams-cairo/issues/19 , which we
-- can't currently reproduce because the `textLineBounded` API is
-- broken by Measure changes.

washington = text "Washington" # fontSizeL 1

is = replicate 10 'i'

is1 = text is # fontSizeL 1

is2 = text is # fontSizeL 2

isO = text is # fontSizeO 24

wsO = text (replicate 10 'w') # fontSizeO 24

isMono = text is # fontSizeO 14 # font "monospace"

washMono = text "Washington" # fontSizeO 24 # font "monospace"

example = vcat' (with & sep .~ 2) [washington, is1, is2, isO, wsO, isMono, washMono] # centerY <> square 16

And output:
bug-19-pango-1

@bergey
Copy link
Member Author

bergey commented May 20, 2014

I like good kerning, but multilingual support is what really pushed me to work on this. Here are some examples from the UTF-8 Sampler showing that Pango handles right-to-left scripts and joining characters. (From top: English, Hebrew, Hindi, Urdu)

pango-multilingual-6

(Updated image with a proper Nastaleeq font.)

@bergey
Copy link
Member Author

bergey commented May 21, 2014

Thanks again to @jeffreyrosenbluth and @fryguybob for sorting me out on use of MonadIO. I think this is ready to merge.

I cannot reproduce #43, so I can't say if it's resolved. #19 seems resolved modulo the regression in Diagrams.Cairo.Text. That is, Pango calculates the correct extents for text, but Diagrams cannot query or draw that rectangle.

Possibly we should remove Diagrams.Cairo.Text entirely, since it's unusable. I think we'll be able to replace it when we have a cleaner semantics (fixed point or maybe constraint solving) for resolving Measures. I could be persuaded to hack out a local Context type until then to get it working.

@jeffreyrosenbluth
Copy link
Member

I built the user manual with the pango branch and noticed a few things:

  • The default font is now serif (this could be a previous change I'm not sure)
  • In general it seems like the text is larger, e.g. it is extending outside of the rectangles.
  • topLeftText and baseLineText render the opposite way they do currently.
  • The kerning on "there" in "Hello there world" seems too tight.

@bergey
Copy link
Member Author

bergey commented May 21, 2014

Thanks for doing that!

The default font will depend on your system configuration. On Linux this is via Fontconfig. I don't know about MacOS. Diagrams just sets Font "", though we could change this.

The default FontSize is Local 1. This will reliably look bad when scaled up substantially. In my tests, the letter height was very close to that of Global text with the scaling pre-applied, but the kerning was wider, and the leading (inter-line space) was much larger. For single-line text, that means Pango centers the big box , and the actual glyphs end up off-center. Is this what you observed?

Those sound like bugs in topLeftText and baseLineText for sure. I'll take a look.

@jeffreyrosenbluth
Copy link
Member

Given my cairo problems on OSX I"m using a linux setup to build the docs running, Ubuntu 13.04
I think these screen shots will be better than trying to describe what I'm seeing

helloworld
hellothere

Pango's origin is at upper left, so for (BoxAlignedText 0 1) we want an
offset r2 (0,0).  Cairo's origin is at baseline, so handling BaselineText
used to be trivial.
@bergey
Copy link
Member Author

bergey commented May 21, 2014

I think I've fixed the positioning, but now I'm seeing very buggy layout. This will probably be harder to debug than the positioning, unless it's just a bad font.

helloworld
text-positioning

@bergey
Copy link
Member Author

bergey commented May 21, 2014

Apparently the images above are the intended semantics; font hinting extrapolated to unreadably small sizes results in the overlap and weirder things. Practically, I suggest we make the default FontSize something non-Local, like Global 1, and revise the examples in the manual as necessary. But that's enough work that I'd like other opinions before I start.

@jeffreyrosenbluth I think you're right about serif fonts; the Fontconfig default is sans, but Pango must be requesting a serif when Diagrams doesn't request anything in particular.

@jeffreyrosenbluth
Copy link
Member

I'm fine with changing the default but I would prefer either Normalized or Output or even perhaps
Normalized x 'atleast' Output y.

@byorgey
Copy link
Member

byorgey commented May 21, 2014

Aha, I knew this would come around to bite us eventually. The problem is that (particularly in the case of Local) we are conflating the size of text in a diagram with font size (the latter measures the physical size of text in a printed medium, whereas the former is completely abstract).

There might be an argument for letting users control the two attributes separately; I don't know if there would be any need for that. In the meantime, however, how about just picking some "reasonable" font size (e.g. 12pt), and always choose that font size when rendering text, but applying an extra scaling factor to make the text the requested logical size?

@bergey
Copy link
Member Author

bergey commented May 21, 2014

I think we've mentioned 3 possible semantics for FontSize Local l now.

  1. layout text with em-height l, then apply any Transformation tt (current)
  2. layout text at 12-pt, scale by l/12, then apply tt
  3. layout text at final output size, apply tn, the Transformation normalized to avgScale 1

1 has the feature that you can illustrate how letterforms and kerning change nonlinearly.

1 & 2 have the advantage that scaling is always linear. That is, the output is always the same as if the text were converted to a Path before scaling.

2 & 3 have the advantage that text scaled to a reasonable size is legible.

3 has the feature that Local text will be laid out the same as Normalized or Output text at the same final size.

All 3 admit non-uniform scaling, and should end up close to the same size.

I favor option 3; I think it will look best and be least surprising. I think it's consistent with my intuition of LineWeight since the Measure changes---a more parametric semantics, rather than direct scaling of the {line, text} outline.

2 is clearly better than 1, but it introduces a slightly arbitrary constant, and I think it's most complicated to explain.

Am I neglecting some diagrams that can be made with 2 but not with 3?

@byorgey
Copy link
Member

byorgey commented May 22, 2014

With (1), calling the fact that you can illustrate how letterforms and kerning change nonlinearly a "feature" is a stretch. =)

I think I agree (3) is the best approach, I hadn't considered that option before. I also don't like the arbitrary constant in (2).

The only thing we would lose with (3) is that we can't use a single letter F to illustrate transformations in the user manual anymore, since, for example, applying scaleY 2 would result in some text that was taller only by a factor of sqrt 2. (Right?) But that is not really a big deal; in fact, illustrating transformations is the only time I have ever wanted the current behavior! Instead we could e.g. make a standard diagram that looks like a capital F but is really a path, not text.

@bergey
Copy link
Member Author

bergey commented May 22, 2014

I think scaleY 2 will still result in text taller by a factor of 2. We factor the transformation into a uniform scaling component and a "stretching" component. The uniform scaling (here sqrt 2) is used for layout & hinting, and then the result is stretched, multiplying the height by sqrt 2 again.

Here's an example from the manual with Local:
localf
And with Normal:
normalf

layout text at final output size, apply tn, the Transformation
normalized to avgScale 1

Revert "restore semantics of Local FontSize"

This reverts commit d1a70cb.

Conflicts:
	src/Diagrams/Backend/Cairo/Internal.hs
@byorgey
Copy link
Member

byorgey commented May 22, 2014

Aha! In that case (3) is indisputably the best option.

jeffreyrosenbluth added a commit that referenced this pull request May 22, 2014
@jeffreyrosenbluth jeffreyrosenbluth merged commit b953ae9 into master May 22, 2014
@jeffreyrosenbluth jeffreyrosenbluth deleted the pango branch May 22, 2014 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Mac OS X/XQuartz: Can't render single letter
3 participants