On Thu, Mar 20, 2003 at 02:59:04PM +0000, John Levon wrote:
> > Not more than once per redraw.
> 
> OK,  what is your magical solution to the inset update problem. With
> details please ...

Simple: There is no inset update problem as there won't be an inset update.

Handling an LFUN just changes the structure of the doc, the postion of the
cursor, whatever. It does not care about visual appearance at all.

If the handling is finished, we do a full redraw. [Later we might be a bit
more clever, but not now]. The full redraw consists of two phases. In
each phase the document tree is traversed in full and each phase carries
some "information object" containing objects like current font, current
textwidth etc.

The first phase is the "metrics calculation". Each container (inset,
main text,...) adjusts the information object according to its needs (i.e.
a minipage would change the textwidth) and calls metrics() with this
information object on each of its children recursively. If this is
finished, the sizes of the children are known and the container itself can
compute its own size. Row breaking etc. would happen here. Afterwards it
saves this newly computed size in its local "cache".

Example:

        void MathFracInset::metrics(MathMetricsInfo & mi) const
        {
                // this locally changes fontsize, clean up on destruction of dummy
                MathFracChanger dummy(mi.base);
                // determine size of two children (numerator and denominator)
                cell(0).metrics(mi);
                cell(1).metrics(mi);
                // compute our own size
                dim_.w = max(cell(0).width(), cell(1).width()) + 2;
                dim_.a = cell(0).height() + 2 + 5;
                dim_.d = cell(1).height() + 2 - 5;
        }

In the second phase, we go down the tree again passing another "information
object" around, containing an actual painter object and a position. Again,
apply local changes. Using the precomputed sizes we are able to tell the
childeren where to start their drawing. Tell them to do so. Then do our own
drawing. Undo local changes to the information object. Return.

Example:

        void MathFracInset::draw(MathPainterInfo & pi, int x, int y) const
        {
                int m = x + width() / 2;
                // this locally changes fontsize, clean up on destruction of dummy
                MathFracChanger dummy(pi.base);
                cell(0).draw(pi, m - cell(0).width() / 2, y - cell(0).descent() - 2 - 
5);
                cell(1).draw(pi, m - cell(1).width() / 2, y + cell(1).ascent()  + 2 - 
5);
                if (!atop_)
                        pi.pain.line(x + 1, y - 5, x + width() - 2, y - 5, 
LColor::math);
        }



Andre'

-- 
Those who desire to give up Freedom in order to gain Security,
will not have, nor do they deserve, either one. (T. Jefferson)

Reply via email to