Closed Bug 492214 Opened 16 years ago Closed 6 years ago

-moz-transform appears not to rotate letters (at small angles) because glyph positions are pixel-snapped on OSX

Categories

(Core :: Layout, defect)

All
macOS
defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME
Tracking Status
blocking2.0 --- -

People

(Reporter: wichert, Unassigned)

References

()

Details

Attachments

(7 files)

User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4 Build Identifier: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4 The line on which text is drawn is rotated, but the letters themselves are not. This results in a weird staircase effect. Reproducible: Always Steps to Reproduce: 1.create a block with text in it 2. rotate it with -moz-transfor
Attached image Firefox 3.5b4 rendering
Attached image Safari 4 rendering
Attachment #376576 - Attachment description: Firefix 3.5b4 rendering → Firefox 3.5b4 rendering
Version: unspecified → 3.5 Branch
Confirmed with Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b5pre) Gecko/20090504 Shiretoko/3.5b5pre With the latest trunk build also the backgrounds are not drawn.
Component: General → Layout
Product: Firefox → Core
QA Contact: general → layout
Version: 3.5 Branch → Trunk
I'm not sure that the letters are unrotated -- but it's clearly a problem that we're snapping them all to the nearest pixel as far as positioning goes. I see this on Linux as well.
OS: Mac OS X → All
Hardware: x86 → All
I have to assume this is a cairo issue, we don't do any per-glyph snapping.
On OSX it looks like this caused by quartz doing the snapping. Perhaps the reason that it doesn't show up in Safari is because Safari's transforming an image of the content and not the content itself?
Is there a way to turn that snapping off? We already do our own baseline snappping. You would think surely we're not the only app in the world that wants to draw rotated text nicely.
(In reply to comment #7) > We already do our own baseline snappping. (Not per-glyph, but per-frame, and snapped before transforms like rotation, so it wouldn't produce the bug here.)
I wasn't able to find anything that would suggest that we can disable this behaviour. None of the coregraphics symbols that I saw seemed related.
what if you use CGContextShowGlyphsAtPositions?
Drawing text with CGContextShowGlyphsAtPositions seems to have the same behaviour as shown.
Can we ask someone at Apple for help? I suppose we *could* have _cairo_quartz_show_glyphs handle complex transforms by drawing the glyphs to a temporary surface and then transforming that surface... or we could change our -moz-transform code to render to a temporary surface of appropriate resolution and transform that ... but neither of those are terribly appealing.
The situation is worse on our other platforms. On win32 we don't have any subpixel positioning and don't really have any options until we use DirectWrite. On linux we can subpixel positioning is possibly but a reasonable amount of work. Behdad wrote about a possible path forward here: http://lists.cairographics.org/archives/cairo/2008-May/014149.html
You're probably right, having nsDisplayTransform::Paint render to a regular surface (with the right resolution) and transforming the result sounds like the way to go. Probably too late for 1.9.1 though.
A little birdie told me about a couple of hidden CG APIs CGContextSetShouldSubpixelQuantizeFonts(CGContextRef, bool); CGContextSetShouldSubpixelPositionFonts(CGContextRef, bool);
(In reply to comment #16) > A little birdie told me about a couple of hidden CG APIs > CGContextSetShouldSubpixelQuantizeFonts(CGContextRef, bool); > CGContextSetShouldSubpixelPositionFonts(CGContextRef, bool); Those are included in the test case that I attached. If I recall they didn't help. Does your birdie have any information that would suggest otherwise?
Webkit uses CGContextSetShouldSubpixelQuantizeFonts
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: -moz-transform does not rotate letters → -moz-transform appears not to rotate letters (at small angles) because glyph positions are pixel-snapped
(In reply to comment #18) > Webkit uses CGContextSetShouldSubpixelQuantizeFonts But doesn't Webkit also implement css transforms as an image transformation?
Maybe. Maybe my source was confused.
It looks like they don't necessarily. http://people.mozilla.org/~jmuizelaar/rotated-grid.html http://people.mozilla.org/~jmuizelaar/rotate.html Seem to suggest otherwise, especially when viewed in Safari on windows...
(In reply to comment #21) > It looks like they don't necessarily. > To clarify, it looks like webkit doesn't necessarily use a rotated image. So I'm confused. If someone can make the text look good/like safari in the example program I attached then we can fix this. Otherwise, I don't know what to do...
I don't know if this is relevant or not, but I found this WebKit bug from 2007 about pixel snapping the glyphs. https://bugs.webkit.org/show_bug.cgi?id=12172 The first testcase seems to show a problem in Firefox but not Safari (glyphs jump around when you resize the window), they seem to have fixed it by calling a private API.
It seems the private API (CGContextSetFontRenderingStyle) does allow for proper rotation and sub-pixel positioning, this is the result of the previous program when it calls the API passing true and then false for the two boolean parameters.
(The only thing noted in my dupe bug that might be of interest here: in Windows Safari, there is similar serious stairstepping, until you set the Text Smoothing preference to use internal CoreGraphics anti-aliasing, not Windows Default anti-aliasing. Thanks for looking into this problem.)
The duplicate bug was asking if it should block 2.0, reflecting that.
blocking2.0: --- → ?
blocking2.0: ? → -
What this can't be blocking2.0?
It really doesn't seem serious enough to block. We should fix it, but I'm not going to hold the schedule for rotated text on mac.
To make it clear: IT'S NOT JUST ON THE MAC. In fact, this bug is at its absolute worst on Windows Firefox. (See my Bug 585114 for screenshots.)
Sorry -- I meant Bug 534064 has screenshots so you can see how it looks on Firefox Windows. In particular attachment 416986 [details] shows the problem on Windows.
The problem here is meant to be OS X specific. I've reopened 585114 for the problem on windows.
OS: All → Windows 7
Summary: -moz-transform appears not to rotate letters (at small angles) because glyph positions are pixel-snapped → -moz-transform appears not to rotate letters (at small angles) because glyph positions are pixel-snapped on OSX
This is not Mac specific, it's also on Linux.
(In reply to comment #33) > The problem here is meant to be OS X specific. I've reopened 585114 for the > problem on windows. You don't seem to have reopened 585114, it's still duped to this bug. This bug is present with Quartz, GDI and X, because all those platform APIs pixel-snap. Fixing it on GDI and X is hard, but we should spin off new bugs for those. Fixing this bug is easy per comment #24.
(In reply to comment #24) > It seems the private API (CGContextSetFontRenderingStyle) does allow for proper > rotation and sub-pixel positioning, this is the result of the previous program > when it calls the API passing true and then false for the two boolean > parameters. What previous program? Google can't seem to find any description of CGContextSetFontRenderingStyle anywhere. It does seem that CGContextSetFontRenderingStyle is only in 10.6 though, replacing previously also undocumented CGContextSetFontRenderingMode. I agree this should not block. It sucks, but it's a moving target.
Attached file Updated test app
Oops, sorry for not being more helpful before. The only reference I've found to CGContextSetFontRenderingStyle is the WebKit source code, looking for it on Google just gets problem reports. I've attached the updated sample app that makes use of the 2 required API calls to get it working (I missed out on the fact you also need to call CGContextSetShouldSubpixelPositionFonts for it to make any difference)
And I seem to have missed the fact that the API calls don't make any effect on CGContextShowGlyphsAtPositions, only on CGContextShowText. Sorry.
(In reply to comment #35) > (In reply to comment #33) > > The problem here is meant to be OS X specific. I've reopened 585114 for the > > problem on windows. > > You don't seem to have reopened 585114, it's still duped to this bug. I too meant bug 534064.
OS: Windows 7 → Mac OS X
Would this bug be the same underlying cause for rotated SVG text looking bouncy (bug 720607)?
It's very likely the same underlying cause, as I see exactly the same rendering whether I have a rotated div, rotated svg text, or svg text in a rotated div.
Is there any progress on this bug? Any change we can use the same (private) CG* calls that WebKit is using?
I plan to fix this is a part of the switch Azure CoreGraphics for content work
Adding to this, rotated text still looks weird on OS X, even at large angles, because of snapping: http://codepen.io/anon/pen/BNQwNv It made my CSS3 "Fork me on GitHub" ribbon look bad on FF (I had to tweak it so that the letters align properly in my context).
Look it at it closely, sub-pixel anti-aliasing is applied differently to the glyphs, where you'expect pixel snapping to make them all look identical in that scenario... Still, there's some bad rounding going on.

Seems OK now.

Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: