Last Comment Bug 299943 - refactor letter-spacing
: refactor letter-spacing
Status: NEW
:
Product: Core
Classification: Components
Component: Layout: Text (show other bugs)
: Trunk
: All All
: P2 normal with 7 votes (vote)
: Future
Assigned To: Nobody; OK to take it and work on it
:
Mentors:
Depends on: 164700 333659
Blocks: 102016 125390 css2.1-tests 722284 919281
  Show dependency treegraph
 
Reported: 2005-07-07 07:32 PDT by Masayuki Nakano [:masayuki] (Mozilla Japan)
Modified: 2016-05-26 08:11 PDT (History)
14 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
testcase (1.85 KB, text/html)
2006-03-09 09:51 PST, Masayuki Nakano [:masayuki] (Mozilla Japan)
no flags Details
Patch v0.1 (4.63 KB, patch)
2010-04-08 01:25 PDT, Masayuki Nakano [:masayuki] (Mozilla Japan)
no flags Details | Diff | Review

Description Masayuki Nakano [:masayuki] (Mozilla Japan) 2005-07-07 07:32:37 PDT
extra spaces of letter-spacing should be applied half on each side of the
character. But the spacing must not be applied at the beginning or at the end of
a line.

It is specified by CSS3 text module(but that is WD).
http://www.w3.org/TR/2005/WD-css3-text-20050627/#letter-spacing

Spec says:
> Spacing should be applied half on each side of the grapheme cluster. Spacing
> must not be applied at the beginning or at the end of a line.

But we don't support grapheme cluster yet. See bug 229896.
We should implement by character, not grapheme cluster.
Comment 1 fantasai 2005-07-11 21:56:47 PDT
Note: The grapheme cluster stuff may be affected by smontagu's work in 297074.
Comment 2 rbs 2005-07-11 23:09:48 PDT
I still don't see much benefit from the "half" spacing thing. It instead seems
so far that it creates more complications/ambiguities to outweigh any benefit it
might have.
Comment 3 fantasai 2005-08-16 01:11:09 PDT
The purpose is to make it so that letter-spacing applied to an inline element
will result in half-spacing before and after the element, not no spacing before
and full spacing afterward. Whether it's actually implemented as half on each
side of each character is not relevant.

I'll try to clarify this in the next draft.
Comment 4 Masayuki Nakano [:masayuki] (Mozilla Japan) 2005-08-17 03:17:39 PDT
> Whether it's actually implemented as half on each
> side of each character is not relevant.

If we implement to add extra space as half on each side of each character,
we get "natural" interface for text selection.
Currently, if a text has large letter-spacing, we cannot select from center of a
character to center of another character.

i.e.,

Curreytly:

|a    |b    |c    |d    |
       ^-----^  <- Drag this range, we can select b only.

If adding space as half on each sides on each character:

|  a  |  b  |  c  |  d  |
         ^-----^  <- Drag this range, we can select b and c.
Comment 5 Masayuki Nakano [:masayuki] (Mozilla Japan) 2006-03-09 08:54:23 PST
fantasai:

> The purpose is to make it so that letter-spacing applied to an inline element
> will result in half-spacing before and after the element, not no spacing before
> and full spacing afterward.

Don't you change this idea? I'll work on this soon. If you have another suggestions, please tell me.
Comment 6 Masayuki Nakano [:masayuki] (Mozilla Japan) 2006-03-09 09:51:12 PST
Created attachment 214571 [details]
testcase

I have a question on this test case. If an inline image is existing(img element or object element), should we add full-width extra space around these characters?
I.e.,

'ab<img>cd'

is rendered:

'a  b  <img>  c  d'
      ^     ^
instead of:

'a  b <img> c  d'

? I think that it's natural. But I think that this makes bad performance. Because when layout time, we cannot know that we succeed in loading of the image... We should not use this layout for performance (and keeping simple code).
Comment 7 fantasai 2006-03-09 19:58:50 PST
> Don't you change this idea?

Sorry, I don't understand the question...

>  If an inline image is existing (img element or object element), should we add
> full-width extra space around these characters?

That's a really good question, but I don't know how to answer it. :/
I guess you can implement it however is easier, and I will mark it as an issue
in the next CSS3 Text draft.
Comment 8 Masayuki Nakano [:masayuki] (Mozilla Japan) 2006-03-09 20:18:55 PST
(In reply to comment #7)
> > Don't you change this idea?
> 
> Sorry, I don't understand the question...
My question is that your idea of comment 3 is changed or not changed still now.
I.e., if you changed your mind, please tell me latest your opinion.

> >  If an inline image is existing (img element or object element), should we add
> > full-width extra space around these characters?
> 
> That's a really good question, but I don't know how to answer it. :/
> I guess you can implement it however is easier, and I will mark it as an issue
> in the next CSS3 Text draft.

Maybe it's not easy on nsTextFrame. However, I don't know that it's not easy on image frame too.
Comment 9 fantasai 2006-03-09 22:13:51 PST
Give me a few days to go dig around in the library. Apparently German used to use letter-spacing for emphasis, and I want to see what they did at the edges of the words (which would correspond to what we should do at the edges of elements).
Comment 10 Simon Montagu :smontagu 2006-03-09 23:19:18 PST
I own German books from the beginning of the last century, and also Hebrew books printed in Germany from the same period that use the same convention. Inter-word spacing does not seem to be affected. (I can attach scans or send them off-line, whichever you would prefer).
Comment 11 fantasai 2006-03-11 22:14:10 PST
I think I've got the definition worked out, although I'd still be interested in seeing your scans. :) Attaching them to the bug report should be fine.

Applying the letter-spacing to spaces within the letter-spaced element is well
established implementation-wise, so that can't change. But the behavior at
element boundaries is inconsistent, so we can spec that to be consistent and
reasonable.

Here's what I've drafted so far:

  | At element boundaries, the letter spacing is given by and rendered within
  | the innermost element that contains the boundary.
  | 
  | For example, given the markup
  |
  |   <P>a<LS>b<Z>cd</Z><Y>ef</Y></LS>g</P>
  |
  | and the style sheet
  |
  |   LS { letter-spacing: 1em; }
  |   Z { letter-spacing: 0.3em; }
  |   Y { letter-spacing: 0.4em; }
  |
  | The spacing would be
  |
  |   a[0]b[1em]c[0.3em]d[1em]e[0.4em]f[0]g

Masayuki, I believe that would address your concern with images. Boundaries
are handled as, I believe, they ideally should be. And given that definition,
it doesn't matter how the letter-spacing is actually applied. Splitting it to
either side would, as you pointed out, result in a more natural selection UI.
In that case you'd have to not put any space at the start and end of the inline
and put double space next to each child inline. But as far as CSS layout is
concerned, selection UI is out-of-scope.

Word-spacing would be given, naturally, by the word separator's parent inline.
Word-spacing has to be split on either side of the character, though, because
some word separators are visible.

Is this ok?
Comment 12 Masayuki Nakano [:masayuki] (Mozilla Japan) 2006-03-12 07:52:52 PST
Yeah, thanks for the comment.

Your idea will make simple layout code, the nsTextFrames will be created as following:

> a[0]b[1em]c[0.3em]d[1em]e[0.4em]f[0]g

+-+-+     +---------+     +---------+-+
|a|b|[1em]|c[0.3em]d|[1em]|e[0.4em]f|g|
+-+-+     +---------+     +---------+-+

But this way has some problems on Gecko.
1. the selection background is separated by the letter-spacing between nsTextFrames.
2. the text-decoration on quirks mode is separated by the letter-spacing between nsTextFrames.

I.e., we need to create following frames:

+-+------+--------------+------------+-+
|a|b[1em]|c[0.3em]d[1em]|e[0.4em]f[0]|g|
+-+------+--------------+------------+-+

I'll try to fix this problem on next week.
Comment 13 Masayuki Nakano [:masayuki] (Mozilla Japan) 2006-03-12 07:58:26 PST
And there is a question.
Doesn't the letter-spacing of end of line appear, right?
Comment 14 Masayuki Nakano [:masayuki] (Mozilla Japan) 2006-03-12 08:17:24 PST
Oops. We have a problem.

> <P>a<LS>b<Z>cd</Z><Y>ef</Y></LS>g</P>
> LS { letter-spacing: 1em; }
> Z { letter-spacing: 0.3em; text-decoration: underline; }
> Y { letter-spacing: 0.4em; }

Should we render as:

a[0]b[1em]c[0.3em]d[1em]e[0.4em]f[0]g
          ~~~~~~~~~
? If so, we cannot use following approach.
> +-+------+--------------+------------+-+
> |a|b[1em]|c[0.3em]d[1em]|e[0.4em]f[0]|g|
> +-+------+--------------+------------+-+

This is very bad for quirks mode...
Comment 15 Masayuki Nakano [:masayuki] (Mozilla Japan) 2006-03-12 10:31:08 PST
And...

Should we render:

<p style="letter-spacing: 1em;">ab<img/>cd</p>

as

a[1em]b[1em]<img/>[1em]c[1em]d

? Or

a[1em]b<img/>c[1em]d

?
Comment 16 Masayuki Nakano [:masayuki] (Mozilla Japan) 2006-03-12 10:36:24 PST
FYI: I think we should not set space around <img/>, <button/>, <input/> and <object/>. Becuase page authors can use 'margin' for these elements.
Comment 17 Masayuki Nakano [:masayuki] (Mozilla Japan) 2006-03-12 10:58:32 PST
My comment 16 may not be correct.

example:

<p>ab<img alt="cd"/>ef</p>
p{ letter-spacing: 1em; }
img{ margin: 1em; }

In this case, if the image is loaded:

a[1em]b[1em]<img/>[1em]e[1em]f

but if the image is not loaded:

a[1em]b[1em][1em]c[1em]d[1em][1em]e[1em]f
       ^^^^^^^^^^       ^^^^^^^^^^

Maybe, we should apply letter-spacing to edge of inline replaced elements.
Comment 18 fantasai 2006-03-12 11:03:07 PST
> Doesn't the letter-spacing of end of line appear, right?

No letter-spacing at the beginning or end of a line.

> Should we render as:
> a[0]b[1em]c[0.3em]d[1em]e[0.4em]f[0]g
>           ~~~~~~~~~

Yes.

I would set up frames like this:

+-+------+---------+-----+---------+-+
|a|b[1em]|c[0.3em]d|[1em]|e[0.4em]f|g|
+-+------+---------+-----+---------+-+

Imagine putting backgrounds or borders on the elements.
The hierarchy needs to come out like this:

         +---------+     +---------+
  +------|---------|-----|---------+
+-|------|---------|-----|---------|-+
|a|b[1em]|c[0.3em]d|[1em]|e[0.4em]f|g|


> <p style="letter-spacing: 1em;">ab<img/>cd</p>

That should render as a[1em]b[1em]<img/>[1em]c[1em]d

Although authors could technically set margins on those elements,
I think it makes more sense for them to be spaced out just as everything
else is. It's also more consistent to handle implementation-wise: it
doesn't matter whether the next element is replaced or not, the rendering
is the same within the text frames.
Comment 19 Masayuki Nakano [:masayuki] (Mozilla Japan) 2006-03-12 11:29:18 PST
thanks,

>> Should we render as:
>> a[0]b[1em]c[0.3em]d[1em]e[0.4em]f[0]g
>>           ~~~~~~~~~
> 
> Yes.
> 
> I would set up frames like this:
> 
> +-+------+---------+-----+---------+-+
> |a|b[1em]|c[0.3em]d|[1em]|e[0.4em]f|g|
> +-+------+---------+-----+---------+-+
> 
> Imagine putting backgrounds or borders on the elements.
> The hierarchy needs to come out like this:
> 
>          +---------+     +---------+
>   +------|---------|-----|---------+
> +-|------|---------|-----|---------|-+
> |a|b[1em]|c[0.3em]d|[1em]|e[0.4em]f|g|

Yes, this is best. But we don't have a frame between 'Z' and 'Y'.
Comment 20 fantasai 2006-03-15 12:05:00 PST
Hm. Do we need one in non-quirks mode?
Comment 21 Masayuki Nakano [:masayuki] (Mozilla Japan) 2006-03-15 23:20:39 PST
(In reply to comment #20)
> Hm. Do we need one in non-quirks mode?
> 

For selection background between inline elements, we need it.
I'm trying to create the empty text frame.
Comment 22 Masayuki Nakano [:masayuki] (Mozilla Japan) 2007-01-20 13:02:21 PST
should fix only on new text frame.
Comment 23 Masayuki Nakano [:masayuki] (Mozilla Japan) 2010-04-08 01:25:43 PDT
Created attachment 437787 [details] [diff] [review]
Patch v0.1

Inserting the spaces to both side of each character except that the left most character and right most character of each line.
Comment 24 David Baron :dbaron: ⌚️UTC-7 (review requests must explain patch) 2010-12-05 13:07:14 PST
Perhaps the way to do what http://www.w3.org/TR/css3-text/#letter-spacing says:
  # Letter-spacing must not be applied at the beginning or at the end of a
  # line. At element boundaries, the letter spacing is given by and rendered
  # within the innermost element that contains the boundary. 
is to handle the spacing within text runs in a different part of the code from the spacing between them.  The spacing within a text run would be based on the style for that text run; the spacing between adjacent text runs could be handled at a higher level.

However, it's still not clear to me how letter-spacing is supposed to behave when there's a replaced element, inline-block, etc., in the middle of a run of text.  This means I'm really not at all sure how the latter half (in the separation described in the previous paragraph) of the code should behave.
Comment 25 David Baron :dbaron: ⌚️UTC-7 (review requests must explain patch) 2012-08-28 11:50:10 PDT
http://dev.w3.org/csswg/css3-text/#letter-spacing is now clear on that issue as well.
Comment 26 David Baron :dbaron: ⌚️UTC-7 (review requests must explain patch) 2012-08-28 11:53:41 PDT
What's hard about implementing the model now described in the spec is that it sometimes requires that the letter-spacing be at a point where there isn't a text frame.  So some of the letter-spacing code will need to be in nsLineLayout.  (And the interaction with bidi is also hard since I think it applies after bidi reordering.)
Comment 27 Duan Yao 2015-03-23 19:09:54 PDT
(In reply to David Baron [:dbaron] ⏰UTC-7 from comment #24)
> 
> However, it's still not clear to me how letter-spacing is supposed to behave
> when there's a replaced element, inline-block, etc., in the middle of a run
> of text.

Hi David Baron,

I wonder how mozilla will implement this in future? I believe some web pages already depend on current firefox and webkit/blink's behavior, i.e. replaced/inline-block never adds letter spacing to the line it lives in. For example, pdf2htmlEX tool (https://github.com/coolwanglu/pdf2htmlEX) uses inline-blocks to properly offset characters, so if a line has non-zero letter-spacing, and browsers change current behavior, the positions of characters all go wrong.

Current spec (http://dev.w3.org/csswg/css-text-3/#letter-spacing-property) says:

  For the purpose of letter-spacing, each consecutive run of atomic inlines (such as images
  and inline blocks) is treated as a single typographic character unit. 

Does it mean
  <div style="letter-spacing:10px">M<img><img>M<div>
Should be rendered as
  M[10px]<img><img>[10px]M

If so, this will definitely break pdf2htmlEX, as it assumes the following rendering behavior:
  M[10px]<img><img>M
Comment 28 Sebastian Zartner [:sebo] 2016-02-03 01:48:51 PST
ni'ing dbaron in regard of comment 27.

Sebastian
Comment 29 David Baron :dbaron: ⌚️UTC-7 (review requests must explain patch) 2016-02-03 01:52:57 PST
(In reply to Duan Yao from comment #27)
> Current spec (http://dev.w3.org/csswg/css-text-3/#letter-spacing-property)
> says:
> 
>   For the purpose of letter-spacing, each consecutive run of atomic inlines
> (such as images
>   and inline blocks) is treated as a single typographic character unit. 
> 
> Does it mean
>   <div style="letter-spacing:10px">M<img><img>M<div>
> Should be rendered as
>   M[10px]<img><img>[10px]M

Yes, that's what is supposed to happen.

> If so, this will definitely break pdf2htmlEX, as it assumes the following
> rendering behavior:
>   M[10px]<img><img>M

Why does it assume that?
Comment 30 Duan Yao 2016-02-06 05:25:49 PST
(In reply to David Baron [:dbaron] ⌚️UTC-8 from comment #29)
> (In reply to Duan Yao from comment #27)
> > Current spec (http://dev.w3.org/csswg/css-text-3/#letter-spacing-property)
> > says:
> > 
> >   For the purpose of letter-spacing, each consecutive run of atomic inlines
> > (such as images
> >   and inline blocks) is treated as a single typographic character unit. 
> > 
> > Does it mean
> >   <div style="letter-spacing:10px">M<img><img>M<div>
> > Should be rendered as
> >   M[10px]<img><img>[10px]M
> 
> Yes, that's what is supposed to happen.
> 
> > If so, this will definitely break pdf2htmlEX, as it assumes the following
> > rendering behavior:
> >   M[10px]<img><img>M
> 
> Why does it assume that?

In PDF, arbitrary offsets can be added between letters, and pdf2htmlEx inserts inline-blocks(empty spans) between letters to emulate such offsets. Because that is the current behavior of browsers, so pdf2htmlEx have to assume that.
Comment 31 Masayuki Nakano [:masayuki] (Mozilla Japan) 2016-05-26 08:11:42 PDT
I don't have time to work on layout. So, I step down from assignee of this bug.

Note You need to log in before you can comment on or make changes to this bug.