Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Coming up: gradual decrease of script sizes

2 views
Skip to first unread message

Roger B. Sidje

unread,
Feb 19, 2001, 4:40:05 PM2/19/01
to mozilla...@mozilla.org
First the problem:
==================
In many mathml markups, <mtag>base arguments</mtag>, the rendering of the
'base' is expected to be in a normal font-size, whereas the 'arguments'
should appear in a smaller font-size. This is a common functionality to
tags like <msub>, <msup>, <msubsup>, <mover>, <munder>, <munderover>,
<mmultiscripts>, <mroot>. Moreover, the reduction of the font size needs
to happen gradually in a top-down manner within the hierarchies of
sub-expressions; and more importantly, the sizes should not decrease
up to a point where the scripts become unreadably small.

Technically, this scaling effect (downwards or upwards) arises when the
scriptlevel changes (increase or decrease) between a parent and a child.
Whenever the scriptlevel changes, either automatically or by being
explicitly incremented, decremented, or set, the current font size
has to be multiplied by the predefined value of 'scriptsizemultiplier'
to the power of the change in the scriptlevel, and this scaling effect
has to be propagated down the subtrees--with the caveat that the font
size is never allowed to go below the predefined value of 'scriptminsize'
within a sub-expression.

Unfortunately, the Style System knows nothing about this mathml-specific
behavior, and there is no combination of CSS rules that can emulate the
behavior. As a consequence, during frame construction, the Style System
produces style contexts in which the sizes of the fonts are not suitable
for mathml scripting elements.

The existing solution:
======================
To address the problem, the current code resorts to the method
InsertScriptLevelStyleContext(). Here is what the method does.
Consider the initial tree
-- child_0
parent -- child_1
-- child_2

If the scriptlevel of the parent is says, 2, and the scriptlevel of
child_1 is 3, then InsertScriptLevelStyleContext() will insert
3-2 = +1 frame, and change the frame tree so that it looks like:

-- child_0
parent -- wrapperFrame -- child_1
-- child_2

Here, 'wrapperFrame' is a pseudo-frame whose sole purpose is only to
apply the CSS rule "font-size: smaller", thereby reducing the font size
in child_1. If the scriptlevel of child_1 was instead 1, so that 1-2 = -1
was negative, the rule would instead have been "font-size: larger".

Generally therefore, no a priori knowledge of the scriptlevels is needed.
As the scriptlevels become known, InsertScriptLevelStyleContext() repeatedly
adds as many wrapper frames as necessary to decrease or increase the size,
with each wrapper frame being associated to a pseudo-style context in a
one-to-one relationship (this is one of the invariants of the Style System).

In order to prevent the size from becoming unreadably small, a check is first
made in the child frame sub-tree to ensure that its smallest font-size will not
go below 'scriptminsize' after the next insertion of a smaller-type wrapper frame.

Unfortunately, this scheme can require many wrapper frames on pages with many
scripting elements. Moreover, the insertion of wrapper frames happens in a
bottom-up manner. This means that, given for example a_{b_{c}} and depending on
the initial font-size, the font-size of 'c' could end up being the scriptminsize
while 'a' and 'b' stay normal, whereas the expected behavior is that 'a' stays
normal while 'b' and 'c' appear in scriptminsize.

The changed solution
====================
InsertScriptLevelStyleContext() is gone. ReResolveScriptStyle() has been
introduced in conjunction with a number of fixed CSS rules in mathml.css:

[-moz-math-font-size="+1"] {
font-size: 71%;
}
[-moz-math-font-size="+2"] {
font-size: 50%;
}
[-moz-math-font-size="+3"] {
font-size: 36%;
}
[-moz-math-font-size="+4"] {
font-size: 25%;
}
[-moz-math-font-size="+5"] {
font-size: 18%;
}
[-moz-math-font-size="scriptminsize"] {
font-size: 8pt;
}
[-moz-math-font-size="-1"] {
font-size: 141%;
}
[-moz-math-font-size="-2"] {
font-size: 200%;
}
[-moz-math-font-size="-3"] {
font-size: 283%;
}
[-moz-math-font-size="-4"] {
font-size: 400%;
}
[-moz-math-font-size="-5"] {
font-size: 566%;
}

What ReResolveScriptStyle() will do is that, once the <math> subtree is
_fully_ constructed, it will walk the subtree in a top-down manner and then
set, where appropriate, the private attribute -moz-math-font-size="." on mathml
content objects, and ask the Style System to re-resolve the affected mathml
style contexts.

This allows scripting elements to be rendered as expected, with a nice looking
top-down decreasing font-size (a la TeX). But because there is only a finite
number of CSS rules, the scaling effect is bounded -- even though the actual
scriptelevel can internally exceed these bounds (TeX only has three levels, BTW).

Style re-resolutions is very expensive, and the cost is even higher if they have
to be done repeatedly. Knuth once said that he chose $...$ as delimiters for math
expressions because these math expressions expensive to typeset. They are...

While not ideal, ReResolveScriptStyle() produces the desired effects, until
another better solution...

I have some other changes that may help with this hard-to-get performance.
These are widespread changes to remove the numerous "if (!IsOnlyWhiteSpace())"
that are used to skip ignorable whitespace frames throughout the math subtree.
By preventing these frames from being created in the first place inside the
frame construction code, these "if"s can go away - bug 68411.
http://bugzilla.mozilla.org/show_bug.cgi?id=68411
---
RBS

0 new messages