Comments (7)
Hi, @soegaard—I just took a look at this. After some investigation, I suspect that pango_context_set_round_glyph_positions
may be relevant. By default, Pango rounds all glyph positions to pixels, regardless of hinting settings, but that function can be used to disable that behavior.
Unfortunately, when I actually experimented with disabling rounding, I found that it didn’t seem to affect the rendering at all on my machine. While I’m not sure why that would be the case, after some further reading, I get the sense this may be because the version of Cairo I have on my machine (which is running Ubuntu 20.04) doesn’t support subpixel positioning (which is distinct from what’s normally called “subpixel rendering”!) for the necessary font backend. If you’re on macOS, you might want to give it a try yourself (and disable hinting) and see if that changes anything.
Having said all of this, I think you probably don’t want to be using draw-text
if you’re animating text, anyway. Font rendering is really complicated, and there are so many different moving parts involved in a modern text rendering stack that it makes my head spin. Lots of those parts have to make tough choices about how to place glyphs in a readable fashion, and arranging for all those choices to be temporally consistent under transformation seems like probably a lost cause.
Instead, I think what you almost certainly want to do is convert the text to an outline first using the text-outline
method of dc-path%
, then fill the resulting path using the draw-path
method of dc<%>
. This will run through the whole text shaping and layout pipeline with the glyphs in a well-behaved configuration, namely placed in a straight line, then give you back a set of vector paths. Then, when you call draw-path
, Cairo will render the path itself as an ordinary shape, skipping the OS- and backend-specific text rendering pathways altogether. Cairo certainly knows how to do antialiasing for arbitrary paths, so you’ll get a smooth animation.
There are two major downsides to rendering text this way:
-
Since Cairo’s drawing the paths itself, all of the fancy logic in your operating system’s text layout and rendering stack will be skipped: you’ll get no font hinting or subpixel antialiasing/LCD smoothing, and any user-controlled, OS-wide font rendering options will be ignored.
In your case, this is more of a feature than a bug, since you want to animate the paths yourself. But it does mean that you may need to take some extra care to avoid blurry edges resulting from misalignment—though, fortunately,
dc<%>
’s'aligned
drawing mode is probably sufficient to avoid that most of the time. -
Since you’ve converted the glyphs to a shape, their textual content is necessarily lost before they get to the backend. This means that if you’re using a
pdf-dc%
, for example, the rendered text won’t be selectable in a PDF viewer.This probably doesn’t matter to you, because if you’re rendering an animation, you aren’t going to be using the PDF backend, anyway. Moreover, I’m not sure
racket/draw
currently actually sets the relevant options to have the text stored in the PDF in the first place.
tl;dr: I’m not exactly sure what the problem is, but there are probably too many moving parts to make animated text look good in a backend-agnostic way without just drawing the glyphs yourself. Try that, instead.
from draw.
FWIW, I thought the answer to the dancing text was going to be creating a font with 'unaligned
hinting, but that does not solve the problem.
from draw.
An obversation - made after I wrote the guess below:
The rotate? flag in do-text
is set to (and draw-mode (not (zero? angle)))
.
But what if a rotation has been made with (send dc rotate angle)
then the normal code path is taken.
Is that intended?
The loop in do-text
draws in one of the paths each character individually.
https://github.com/racket/draw/blob/master/draw-lib/racket/draw/private/dc.rkt#L1709
My intution - but I am far from sure - is that the alignments of each individual character
gives a different result than using the line "top line" of the rectangular binding box
of the string.
Let's say we want to draw the text hello. The bounding box is a rectangle ABCD with the line AB
being at the top. Due to rotation the line AB might no be parallel to an axis.
If A is aligned to A1 and we set B1 to B+(A1-A), then the upper left corners of each
character ought to be on the line from A1 to B1. However if we align each individual
character, then I think there is a risk that two neighbour characters might move in
different directions relative to the line when aligned. At least when rotation is involved.
I haven't grooked the Pango part of the draw-text code, but this aligns each individual character:
https://github.com/racket/draw/blob/master/draw-lib/racket/draw/private/dc.rkt#L1709
from draw.
You can avoid the character-by-character loop by providing #t
as the combine?
argument to draw-text
. But I think that doesn't solve the problem here.
Yes, as I remember/understand the code, the normal code path is meant to be taken when rotation is in the transformation.
from draw.
You are right, using #t
as the combine?
flag for draw-text
didn't help.
from draw.
You have looked at fonts and text rendering recently.
Have you spotted something that explains the behaviour in the video?
/Jens Axel
from draw.
Hi @lexi-lambda
Thanks for the very thorough answer.
I am currently using draw-text
to implement text
[1] in Sketching.
The text
function optionally accepts a rectangle to draw the text within
and supports left, center and right alignment of the text.
Since it is part of Sketching, I don't know whether the text will be used
for animation or for static text.
I'll make an experiment with text-outline
+ draw-path
instead of draw-text
.
If the results look identically I'll just use the new method.
I was hoping there were some low-level Cairo routines I could have used.
from draw.
Related Issues (20)
- get-recorded-procedure on record-dc seems to drop `set-clipping-rect`
- `draw-text` with `combine?` = `#t` missplaces diacritics. HOT 6
- Pango warning printed out in Racket 7.6 CS
- Is it possible to display bitmap in a loop? HOT 1
- [Feature Request] Add draw-circle and draw-square methods to dc<%> in racket/draw HOT 1
- Pango AppKit workaround for CS and/or Aarch64? HOT 1
- Should guard-foreign-escape use `#:callback-exns?`? HOT 1
- Emoji error when using macro stepper HOT 1
- A font% does not contain the leading
- Rotating circles HOT 1
- memcpy given #<eof> in read-png-bytes HOT 3
- Possible bug? HOT 1
- get-text-extent errors for a bitmap-dc% object without a bitmap installed HOT 1
- Odd baseline for text drawn with `'swiss` on when that means Nimbus Sans HOT 1
- Bugs caused by internally constructed objects
- Internal error when getting pen% and brush% color
- racket/draw draw-text ignores kerning HOT 6
- [Feature Request] draw font% does not expose kerning
- manual class sections lack a <h3> title
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from draw.