New linebreaker interface

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

New linebreaker interface

Robert O'Callahan-3
See http://wiki.mozilla.org/Gecko:LineBreakerAPI for a suggestion. The
currently interface is unworkable because it doesn't take account of
complex context; it can't handle Thai reasonably, for example, but
really it couldn't do UAX#14 well either. When we have complex line
breaking to do, the current interface is also inefficient because it can
only return at most one linebreak opportunity per call and it would be
difficult to keep state from one call to the next.

I'm actually thinking seriously of adding this interface to
nsILineBreaker with an implementation based on the current linebreaker
code and then rolling this into the textframe patch. It fits well with
the new textrun construction code, which is already basically
paragraph-at-a-time, and we can store the computed linebreak
opportunities into the textrun, which means some changes to the textrun
API (mostly, simplification). Might as well do this now, I think.

Rob
_______________________________________________
dev-tech-layout mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-layout
Reply | Threaded
Open this post in threaded view
|

Re: New linebreaker interface

Robert O'Callahan-3
I worked on this some more and it seems it would be simpler and more
efficient for linebreaking to operate on transformed text (i.e. after
whitespace compression), because then we don't have to translate
possible break points from DOM offsets to transformed-text offsets to
store and use in the textrun. But we don't keep transformed text around,
so we need a new kind of line breaking interface that is more like a
state machine. Something like this:

/**
 * A receiver of line break data.
 */
class nsILineBreakSink {
public:
  /**
   * Sets the break data for a substring of the associated text chunk.
   * One or more of these calls will be performed; the union of all
   * substrings will cover the entire text chunk. Substrings may overlap
   * (i.e., we may set the break-before state of a character more than
   * once).
   * @param aBreakBefore the break-before states for the characters in
   * the substring.
   */
  void SetBreaks(PRUint32 aStart, PRUint32 aLength,
                 PRPackedBool* aBreakBefore) = 0;
};

/**
 * A line-breaking state machine. You feed text into it via AppendText
 * calls and it computes the possible line breaks. Because break
 * decisions can require a lot of context, the breaks for a piece of
 * text are sometimes not known until later text has been seen (or all
 * text ends). So breaks are returned via a call to SetBreaks on the
 * nsILineBreakSink object passed with each text chunk, which might
 * happen during the corresponding AppendText call, or might happen
 * during a later AppendText call or even a Reset() call.
 */
class nsLineBreaker {
public:
  nsLineBreaker();
  ~nsLineBreaker();

  /**
   * Feed Unicode text into the linebreaker for analysis.
   */
  void AppendText(nsIAtom* aLangGroup, const PRUnichar* aText,
                  PRUint32 aLength,
                  nsILineBreakSink* aSink);
  /**
   * Feed 8-bit text into the linebreaker for analysis.
   */
  void AppendText(nsIAtom* aLangGroup, const unsigned char* aText,
                  PRUint32 aLength,
                  nsILineBreakSink* aSink);
  /**
   * Reset all state. This means the current run has ended; any
   * outstanding calls through nsILineBreakSink are made, and all
   * outstanding references to nsILineBreakSink objects are dropped.
   * After this call, this linebreaker can be reused.
   * This must be called at least once between any call to
   * AppendText() and destroying the object.
   */
  void Reset();
}

Oh yeah --- I also want this to be non-COM and inline-allocatable, so
I'm thinking of putting it content/base instead of intl. The only users
of nsILineBreaker are content, layout and editor so I think this will
work. We can expose a COM-ish wrapper to satisfy non-gklayout consumers.

Rob
_______________________________________________
dev-tech-layout mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-layout
Reply | Threaded
Open this post in threaded view
|

Re: New linebreaker interface

Jonas Sicking
> Oh yeah --- I also want this to be non-COM and inline-allocatable, so
> I'm thinking of putting it content/base instead of intl. The only users
> of nsILineBreaker are content, layout and editor so I think this will
> work. We can expose a COM-ish wrapper to satisfy non-gklayout consumers.

Editor unfortunately isn't part of gklayout, so you may need to use a
COM-ish wrapper for that. As much as I hate to say it, maybe we should
consider moving libeditor into gklayout :(

/ Jonas
_______________________________________________
dev-tech-layout mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-layout
Reply | Threaded
Open this post in threaded view
|

Re: New linebreaker interface

Robert O'Callahan-3
Jonas Sicking wrote:
>> Oh yeah --- I also want this to be non-COM and inline-allocatable, so
>> I'm thinking of putting it content/base instead of intl. The only users
>> of nsILineBreaker are content, layout and editor so I think this will
>> work. We can expose a COM-ish wrapper to satisfy non-gklayout consumers.
>
> Editor unfortunately isn't part of gklayout, so you may need to use a
> COM-ish wrapper for that. As much as I hate to say it, maybe we should
> consider moving libeditor into gklayout :(

Why do you hate to say that? it's a great idea and I think I've
suggested it before :-)

Rob
_______________________________________________
dev-tech-layout mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-layout
Reply | Threaded
Open this post in threaded view
|

Re: New linebreaker interface

Jonas Sicking
Robert O'Callahan wrote:

> Jonas Sicking wrote:
>>> Oh yeah --- I also want this to be non-COM and inline-allocatable, so
>>> I'm thinking of putting it content/base instead of intl. The only users
>>> of nsILineBreaker are content, layout and editor so I think this will
>>> work. We can expose a COM-ish wrapper to satisfy non-gklayout consumers.
>> Editor unfortunately isn't part of gklayout, so you may need to use a
>> COM-ish wrapper for that. As much as I hate to say it, maybe we should
>> consider moving libeditor into gklayout :(
>
> Why do you hate to say that? it's a great idea and I think I've
> suggested it before :-)

Linking gklayout.dll on windows is really painful as is. On my laptop it
can take up to 15 minutes which is more or less a show stopper for me to
do serious development in that environment.

/ Jonas
_______________________________________________
dev-tech-layout mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-layout
Reply | Threaded
Open this post in threaded view
|

Re: New linebreaker interface

Robert O'Callahan-3
Jonas Sicking wrote:
> Linking gklayout.dll on windows is really painful as is. On my laptop it
> can take up to 15 minutes which is more or less a show stopper for me to
> do serious development in that environment.

That sucks, but I'd rather buy developers bigger laptops so our users
can have smaller ones.

Rob
_______________________________________________
dev-tech-layout mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-layout