lout-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Margin kerning


From: Jeff Kingston
Subject: Re: Margin kerning
Date: Tue, 22 Mar 2005 09:04:15 +1100

> Margin kerning somewhat stroke me so I'm really curious
> how this could be achieved with Lout.  Jeff, could you
> tell us what you had in mind?

I don't believe I ever said that margin kerning was easy.
I said that hanging punctuation was easy, and it is.  All
you have to do is define versions of the `` and '' symbols
that have zero width, with the marks at the right and left
ends respectively.  For example:

    def "```" { @OneCol { |0io `` ^|0io } }
    def "'''" { @OneCol { |0io ''  |0io } }

should do it.

I'm not a fan of hanging punctuation.  Margin kerning
is quite interesting though and should be easy enough
in a system (such as Nonpareil will be) that does
kerning between arbitrary objects, by calculation, as
opposed to current systems, which as far as I know
all take kerning information from font files, and so
are quite limited in what they can kern (e.g. they
can't kern two characters from different fonts).

Curiously enough, just at the moment I am working
on the part of Nonpareil that precalculates these
kinds of things so that the user does not have to
wait forever while they are done at startup.  It
involves an initializing run that does a lot of
standard calculations (fonts, hyphenation tables,
character attribute tables etc.) then saves a
snapshot of memory into a file, so that on ordinary
runs the program can just dump this file into memory
and carry on from where the initializing run left off.

I'm tearing my hair out over it because of the
pointer swizzling problem: when you read the
file back in, all the pointers to other objects
are wrong by the same unknown offset.  It's
difficult to know whether some object fields are
pointers or not (e.g. in class list{x}, the
head field has type x, which being generic is
sometimes a pointer and sometimes not).  I
thought at first this information could be
passed as compile-time constants, but then
I discovered that object creations *within*
generic classes require calculation of this
info at runtime, and I don'r know how to do that.
I looked at mmap() but it's Unix-specific (or
is it?  Does anyone know whether Windows has mmap?).
I've also thought of a truly bizarre scheme in
which I run the initialization code twice and
compare the results object by object.  Any
fields where the two values differ, one
being a pointer into the memory allocated
during the first initialize, and the other
being a pointer into the memory allocated
during the second initialize, needs swizzling.
But can I be sure that the two runs will be
identical?  In particular, do floating point
operations always give the same answer, or
is there nondeterminism in the last bit or two?
(I'm not worried about the time this will
take, because it only happens on the initializing
run.)

Any suggestions for how to get a fast startup
by any means at all; or any information about
the questions above; will be gratefully accepted.

Jeff

ps I'm not willing to pay the price of an
indirect reference on each function access.
I believe Smalltalk implementations do that
and it simplifies a lot of things, such as
memory compaction.  But the most important
things in Nonpareil are speed, speed, and
speed, and everything else has to conform
to those three goals.  Sorry, that was
object access, not function access.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]