What to do about the 'ch' length unit? (Mozilla vendor specific)
(Followup from bug 281972)
The only real internal dependence is:
That is, to wrap a <pre> exactly at the number of characters specified by
WIDTH (or COLS) we need a unit that is based on the width of a character
in the current font.
The problem is that all the relative widths that are font based are
relative the height, not the width:
So, to get rid of this Mozilla vendor unit I see two options.
1. convince the CSS working group that 'ch' is needed
2. remove it and introduce a "nsPreFrame" that looks at the
WIDTH/COLS attr to set its width during reflow (similar to what
It has been proposed:
(I could not find any other emails about it.)
I suppose this is an alternative as well:
3. drop the 'ch' keyword and only use eCSSUnit_Char internally
Or (a variant of (3)) we could rename it to -moz-ch to allow round-tripping.
That said, it's needed to allow the cascade to work correctly, and we should
probably be using it for input and textarea as well for exactly that reason.
I agree with the cascade argument, but input and textarea is using
nsIFontMetrics::GetAveCharWidth() rather than the width of a 'M',
so it's not the same measure. Hm, -moz-avg-ch perhaps?
Given that 'ch' is only intended for use with fixed width fonts at the moment,
I suppose we could change this:
to use nsIFontMetrics::GetAveCharWidth() instead.
I think it's reasonable to expect it to be equal to the width of a 'M' in a
fixed width font, yes?
If so, we can use it for input and textarea too.
Also, I would like length units to be universal, at the moment 'ch' can't
be used to specify 'height' for example (it results in zero height).
So there are two issues here:
1) Should we have an internal "ch" unit that we use for <pre> and <input>? I
think the answer is yes.
2) Should this be accessible from CSS stylesheets (that is, parsed)? I think
the answer here should be "not unless it's a -moz unit".
For the rest, having this work for all lenths could be interesting -- the "ch"
unit depends on the font metrics, which depend on the lang group, which comes
from the "visibility" struct. But we have lengths in the "display" struct,
which makes "display" depend on "visibility". I don't think that's desirable
(and I'm not sure it doesn't introduce a circular dependency). Also, should
"ch" do all the weirdness that nsTextControlFrame does right now for
non-fixed-width fonts? I suspect it should...
If there is a "ch" unit, what will be the impact to characters that is wider
than "M", especially double-byte characters. Consider this:
<pre style="width: 10ch">
Should Mozilla wraps the second line at "五" or "六" (around the tenth charcter
on the first line), or "十" (exactly the tenth character)?
If it is the former case, maybe it should be name "byte" so as to reflect the
fact that it is not counting character-width but byte-width.
> If there is a "ch" unit, what will be the impact to characters that is wider
> than "M"
That's up to the GetAveCharWidth implementation in the relevant nsIFontMetrics.
You can test it using <input size="10">, since that already uses the function.
And yes, this should be counting characters, not bytes.
The algorithm used by text inputs handles both fixed-width and proportional
fonts. Perhaps something like that algorithm would provide a reasonable
definition for 'ch' for all cases?
(In reply to comment #6)
> For the rest, having this work for all lenths could be interesting -- the "ch"
> unit depends on the font metrics, which depend on the lang group, which comes
> from the "visibility" struct. But we have lengths in the "display" struct,
> which makes "display" depend on "visibility". I don't think that's desirable
> (and I'm not sure it doesn't introduce a circular dependency).
Yeah, this is a problem. I've said a few times that the CSS WG should have a
dependency map for computed value calculation. We probably need to do the same,
and make sure that we don't get dependencies across structs.
The rationale for bug 281630 which this bug has been marked as blocking is that
although the default Windows and Linux UI fonts are reasonably similar so that
dialogs designed on one work on the other their aspect ratio and that of the
default Mac UI font differ sufficiently for us to have had to put various hacks
into e.g. the preferences and account manager windows to size them appropriately
which a native "ch" (or whatever) unit would have accomplished automatically.
Of course the bug also affects people who change their UI font to something
sufficiently dissimilar but they've currently just had to live with it.
"CSS3 Values and Units" now includes a 'ch' unit:
Should we morph this bug into a meta bug with dependencies to the bugs that
handles the specific errors?
The width of the "0" (ZERO, U+0030) glyph found in the font for the font size used to render. If the "0" glyph is not found in the font, the average character width may be used.
AddCoord in nsFrame.cpp and GetAbsoluteCoord in nsLayoutUtils.cpp use the width of the "M".
nsTextControlFrame::CalcIntrinsicSize does something more complicated, "for compatibility with IE".
(If my memory is correct, the wording in css3-values is there because it's what the IE folks said IE does. So it might be even more compatible with IE.)
Oh, and nsTextControlFrame::CalcIntrinsicSize also accounts for letter-spacing, which is harder on a unit...
See patches just added to bug 363706 - we could make CalcIntrinsicSize use GetZeroOrAveCharWidth() instead and possibly take out some of the "for IE compatibility" complications.
Isn't this fixed with bug 363706?
Not really, no.