Saturday, 21 July 2007

Status

A number of interesting things are going on at the moment in my corner of Mozilla-land. While some of my textframe regression fixes wait for reviews, I've been working on a few other items.

I revisited an old bug about spoofing attacks based on having people type into the text input field of a file input control. This had led to the current trunk behaviour where the text input field is disabled and clicking on it pops up the platform file chooser dialog. A better alternative was suggested: allow the field to be focused and manipulated, and pop up the file chooser only when the user actually types in text. I implemented this and it works pretty well.

In my frame display list work early last year, I followed the z-ordering specification in CSS 2.1 appendix E to the letter, drawing 'outlines' very high up in z-order, even above positioned elements in the same stacking context --- which is what appendix E recommends, although it allows for some flexibility about the exact z-ordering of outlines. People complained about this and so after some discussion I moved outlines to be drawn above all regular non-positioned content in the stacking context, but below positioned elements. This matches expectations better and also happens to be compatible with IE and Webkit. Appendix E should probably be altered to designate this as the preferred layer. The good news is that it only requires changing a couple of lines of code --- I'm pleased, because I designed frame display lists with the goal of making this kind of change easy.

I created a patch that implements the 'text-rendering' SVG property for all elements. This allows authors to specify 'text-rendering:optimizeLegibility' to force the highest quality typography the platform supports (i.e. ligatures and kerning, on all our platforms), or 'text-rendering:optimizeSpeed' to select the lowest quality the platform supports (currently no effect on Mac, disables ligatures on Windows, and disables ligatures and kerning for Latin-1 text on Linux). The default setting is 'text-rendering:auto'. In that case we optimize for speed for text up to a certain size, and optimize for quality at or above that size. The idea is that quality is more needed at larger font sizes, and its cost will be relatively small at those sizes. The size is a preference, and setting it to zero means 'auto' will always choose quality. The default is currently 20 device pixels. An extension or even Firefox itself could easily expose this preference as a slider or just a toggle. (Yes, dynamic changes to the preference work correctly.)

'text-rendering' actually only applies to the rendering of DOM text nodes. Other text drawing, such as the drawing of XUL label attributes and page headers and footers, will always take the quality path. I think we should probably add 'text-rendering:optimizeLegibility' to the XUL <window> and <dialog> elements so all chrome looks nice, and also to text input boxes so they look nice.

I've got another patch that fixes a long-standing issue: the glyph bounds problem. The patch tries to avoid performance issues via aggressive caching of glyph bounds. When tight bounds are not needed (the common case where we only care if the glyph extends outside the font-box), we cache just the width of the glyphs that do not overflow the font-box, each packed into 16 bits, all in an array stored in our font object. This is fast and relatively small and allows us to reconstruct the loose bounds for a string in the presence of kerning. When we need tight bounds, or the glyph overflows the font-box, or in certain other corner cases, we cache the exact bounds in a hash table. Performance measurements show that on my Mac the cost of this patch is negligible; on Linux the cost is 1-2% on a standard page load benchmark. That seems pretty good to me, and the Linux number could be improved a little bit by bypassing cairo to measure glyphs, but I still need to get Windows numbers and I have yet to figure out to get stable performance numbers out of a Windows box :-(. Another option is to only enable accurate glyph bounds for 'quality' text as defined by text-rendering above.

There's been interesting work on text line breaking in the last couple of weeks. Masayuki Nakano landed a patch that uses JISx4051-like rules to break Latin-1 text. (We used to use these rules when a CJK character was detected in the vicinity, but that was rather quirky.) The new-textframe work means that these rules are now applied correctly no matter how the text is broken up into inlines. The practical impact is that now for the first time ever, Gecko will break lines after hyphens, slashes, and other punctuation. There's some contextual analysis to avoid silly breaks. I expect a certain amount of tweaking will be required but what we do is mostly IE-compatible so hopefully we'll be OK.

Another great piece of work that just landed was a patch by Theppitak Karoonboonyanan. His patch collects runs of "hard" characters (currently Thai and Lao) and calls Pango to perform line-breaking on them. Thai line-breaking is a hard problem, requiring dictionary-based analysis, and modern Pangos can hook up to libthai to make this happen. This analysis requires unbounded context, but again thanks to the new-textframe work, we can provide all the context needed. So as of yesterday our Thai support should be greatly improved on modern Linux distributions. Someone still needs to write the glue code to hook up Uniscribe and ATSUI (or other libraries?) in the same way. This work is easily extensible to any other "hard" languages we may discover. It's also quite efficient because the new-textframe infrastructure caches the results of line-break analysis in textruns.

We had to reconcile the desire to use platform linebreaking facilities with the need to provide consistent cross-platform linebreaking. Our solution is to use Masayuki's cross-platform linebreaking code for everything except the (few) languages it can't realistically handle. So the breaks between Thai characters will be determined by Pango, and could vary across platforms, but all other breaks will be determined by Gecko and will be consistent across platforms.

Chris Double has made fantastic progress with his work on the <video> element. He's got sound and video working on all platforms, good AV sync, fairly stable, both stored streams and live streaming, and even Javascript volume control. Also I don't think I mentioned it here before, but Karl's landed support for windowless plugins on Linux. We still need plugin authors to actually update their plugins to use it, of course.

In somewhat unrelated news I've made quite a bit of progress on the Chronologer debugger UI. I've got a timeline pane to which you can add queries for the invocation of named functions. I've got a call stack pane and an implementation of history-based stack reconstruction that produces a good call stack for the currently selected time, with display of parameters. I've got a rudimentary data pane that displays the values of variables in memory at the currently selected time. I just need a few more features to have something kinda useful --- a "go back to the last write to this variable" command, and a source-code view with history woven in. I'd like to get these done soon because I've captured a Chronicle trace of Firefox which includes a cycle collector fault, and I'd really like to find a real bug with this stuff :-).

I'm still unsatisfied with all the suggested names, though. My newest idea: Revelation.



9 comments:

  1. While it's good to see the improvements of rendering complex fonts and texts when are the regressions of the more "regular" pages being dealt with? Is this going to happen before the first public beta or after? Right now rendering of pages like e.g. your blog looks worse on current Linux builds than it does with Firefox 2. See bug 382418 for an example.

    ReplyDelete
  2. Is there a workaround to disable the new file picker behavior? Personally, I think that forcing people to use the file picker is a really bad feature, if there is a preference somewhere that reverts to the old behavior I will be relieved. If I'm forced to use a platform file picker it will be a sad day.

    ReplyDelete
  3. >I'm still unsatisfied with all the suggested names, though. My newest idea: Revelation.
    Since you are using code to look inside of code, maybe you could call it "Introspection". Technically the name wouldn't be accurate (unless you use the debugger to debug itself), but it sounds cool and that's what's important. :)
    PS - Great work!

    ReplyDelete
  4. Have to agree there :/
    Worse still is when the GTK file thing pops up for the Open With box and I accidentally try to use the GUI to open a file in /usr/bin/[5 minute pause]gvim.

    ReplyDelete
  5. Your time-travel debugger sure has a lot of names ;) I like "Amber" and "Chronologer" better than "Chronicle", and I don't like "Revelation".

    ReplyDelete
  6. Note that there is a preference on Linux to use the XUL filepicker instead of the GTK one...

    ReplyDelete
  7. Very excited by <video>. Will we be able to control playback volume using the CSS "volume" property? This would enable people to control and override default settings in an accessible way.

    ReplyDelete
  8. Geoff Langdale26 July 2007 05:50

    I think Jonathan Shewchuck's advice should serve as a guide for your debugger, and as far as I know none of his three names are used for other systems. So Puggsley, Vomitsauce and Infectoid are wide-open. Joy!

    ReplyDelete
  9. @Boris: Thanks for that, I had no idea there was even a choice!

    ReplyDelete