[Mono-dev] Complex script / international support in Winforms/libgdiplus

Sebastien Pouliot sebastien.pouliot at gmail.com
Fri Jan 23 08:07:20 EST 2009


On Fri, 2009-01-23 at 10:34 +0700, Jonathan Anderson wrote:
> Hello,
> 
> I posted a note on mono-devel a couple months ago about possible work on
> libgdiplus to get pango support working well.  I've been working on
> doing just that for a little while now, and I'm getting close to having
> something that does reasonably well within the gdi+ framework.  

That's great news!

> I don't
> have all the formatting options supported yet, but then again, it
> doesn't look like the current cairo text module does either.

Right. Only the most "common" formatting options are supported. A few of
them have some limitations as well.

> With getting pango working, it will be able to render complex scripts
> correctly to support languages like Arabic, Thai, Hebrew, Burmese, etc.
>   I'm currently doing some volunteer work for SIL Internatioal 
> (www.sil.org) where we do lots of work with minority and complex 
> scripts, so this support is essential for widespread adoption of  mono, 
> which we're using to do ports of windows forms apps.
> 
> However, I've discovered that getting pango working in libgdiplus is
> only part of the story for getting good complex script support in
> winforms.  With pango in libgdiplus, you get well-rendered strings for
> any controls that just draw a whole string, which is most controls,
> although some need work on right-to-left support.  The TextBox control
> and any controls that share the TextBoxBase implementation
> (MaskedTextBox, RtfTextBox) are where the biggest problems are.
> 
> The problem is that the implementation of the TextBox makes some very
> basic assumptions that don't work for complex scripts, i.e. the width of
> a string is not necessarily equal to the sum of the widths of the
> individual characters.  This can even be true for Latin fonts that use
> kerning and ligatures like ae, ff, and fi.  Also, separate code points
> can form one grapheme (one rendered symbol).  All this causes problems
> with selection, caret placement, and line breaking.
> 
> Now, all that being said, I've been working on the TextBox as well to
> improve the implementation.  I'm not done yet, so I don't have any good
> code to post here yet.  One of the problems that I'm working against is
> that the gdi+ interface doesn't supply the information needed to do the
> TextBox correctly, that is, if I want to work with libgdiplus to make
> the pango calls, I'll need to add some linux-specific functions that I
> can call for text metrics.  I noticed there are some other functions in
> libgdiplus with "_linux" in the names, so I'm assuming that this won't
> be a huge problem - otherwise, a lot of code for the cairo/pango
> interaction would have to be copied into winforms.

It's hard to say without seeing the code. Winforms does not depend,
directly, on libgdiplus, System.Drawing does. *_linux functions are used
in limited cases (like some OS specific stuff to generalize creating a
graphic instance). At the end both Mono's System.Drawing and Winforms*
needs to be able to execute under Windows.

* Mono's Winforms also needs to be able to execute on top on MS S.D.

> I'm doing the extra text metrics by adding methods in the
> TextBoxTextRenderer class, which seemed to be the best place to do that.
>   For the Windows side of things, I'm having it make calls to gdi, which
> provides some better metrics than gdi+, although not quite everything
> I'd like.  I can fill in the rest by making best guesses which won't be
> any worse than the current situation.  Since complex script rendering
> through gdi gets passed into uniscribe on Windows, I think that gdi may
> be a good place to start, but it would probably be best to use uniscribe
> directly at some point in the future for the best complex script support
> in Windows.  One of the problems with the vanilla gdi interface is
> handling drawing bits of text in different colors like you could get
> with the RtfTextBox or with any selection, whereas uniscribe provides
> methods to do that sort of thing.
> 
> I just wanted to let everyone know that I'm working on this, and I
> wanted to see if the direction I'm taking using TextBoxTextRenderer and
> libgdiplus seemed appropriate.  Also, as I'll have a good bit of code
> for both libgdiplus and winforms that will depend on each other, what's
> the best way for me to get it into the project once I've got it working.

On each other ? Really ? because I don't see why libgdiplus would depend
on winforms changes (unless you meant S.D versus Winforms). 

Generally you should plan to merge the libgdiplus changes first, then
System.Drawing and finally Winforms. Of course it's quite possible that
it will require more than a single iteration.

>   I know I'll need to have all the current unit tests passing with new
> code, and quite possibly some new tests.  

Yep, new features will need new tests. There are also a lot of open bugs
(most with test cases) about string drawing/measuring that should be
helpful.

> Also, I may implement the new
> libgdiplus calls in cairo-text.c as well as a fallback, although they'd
> be no better than the current stuff.

It does not have to get better - but it does have to continue working
"as well" as it does now since it will still be used on older systems
(where old cairo versions are shipped on the system).

Thanks!
Sebastien



More information about the Mono-devel-list mailing list