[comp.windows.x] Finding fonts in ATK

mss+@ANDREW.CMU.EDU (Mark Steven Sherman) (03/21/88)

"It turns out to be a bad interaction between buggy
server code and brain-damaged ATK code."

I could dreg up a whole series of related messages from the alpha and beta
times of X that contain the phrase "brain-damaged" but instead, I will just
relate the story and ask for a rational strategy.

In the beginning, calls like XLoadFont and XLoadQueryFont were synchronous,
returning a null pointer if the font was not usuable, e.g., did not exist. Life
was simple and we in fact used your suggestion. A new tape came in the mail and
Xlib kept crapping out. Examination of the problem showed that these calls were
now considered asychronous and always returned immediately with a token for
later use. Of course, when the token was used later, Xlib was unhappy that the
font did not exist. After much nashing of teeth (see introductory remark), the
official word was "you must *know* that your font exists before you start
loading it. If you want to know, use XListFonts. It is simply too slow to
require a synchronous server round trip for loading fonts."

Thus the choice became either using XListFonts or trying to intercept the error
that Xlib came back with. We pleaded for a simple way to intercept such an
error, perhaps a way to make an arbitrary Xlib call synchronous with a return
code (somewhere) that indicated if a problem occurred. Unforutnately, XSynch
would not do the job. We were told how unreasonable we were and that I should
set up a global error handler that would track all of the requests that I had
suspicions about and watch for sequence numbers of replies coming back to
ensure that an operation either succeeded or failed, since "obviously" an error
would require a global strgatey to recover. Besides blowing modularity to hell,
this required us getting into the internals of Xlib which we were assured were
going to change as a natural consequence of evolution. Hence we came to use
XListFont as a first approximation that a font exists (as you especially know
well, our sequence of operations is not atomic, and just because we listed the
font one statement ago, there is no guarantee that the font will be there
during the next statement with the XLoadQuery call -- servers and networks go
down, etc. We thought we were making a reasonable compromise. I will warn you
now: there are several places where we have the same kind of problem. For
example, it is nearly impossible to guarantee that you can read a bitmap from a
window in the presence of window managers. Between the time you verify that it
is present and the time you actually try to read it, the window manager could
have closed the window. Again, it would be nice if we could just make that call
synchronous and handle the error locally, but ...)

Which brings us to the issue of font substitution. There are a number of
questions. First, why do we do font substitution when an unavailable font is
requested? Because our human factors people tell us that people like uniform
fonts, eg., if they can say family F and size S, then we should not arbitrarily
restrict them to whatever bitmaps we have on line (and crap out with "font
unavailable, core dumped), but let them specifiy whatever they want and
sometimes they will get it and sometimes an approximation. Why don't we report
font substitutions? Again, our human factors people tell us that users don't
like such messages coming out at them -- they are confused by something which
they don't want to be bothered with. I have moved that code in and out several
times now. Don't continue to flame at me, it won't help. When your human
factors study shows that it's better to print out a message (for users, not
system installers like us), then something might be done. Note: the Macintosh
does it the same way, although I admit I also hate not knowing when funny
things are happening in my system. Why do we set the fontpath? Because we are
trying to correct a situation when we could not find a font. One of the reasons
why a font might not have been found is that the path was reset by some other
non-cooperating program. We set the path only when a font is not found. So we
try to perform error recovery using guesses as to what happened. We append our
path name to the end of list. How do you recommend programs that are not
officially blessed get their application specific fonts? Or should everyone
have to install their fonts in the one font directory? Or do you want to tell
every user of a random X program, "before you start, type xsetroot -fp
whatever, just do it and take my word for it". Most users around here don't
stand for that. Why do we keep setting the font path so often? Because we
naively hope that if the font wasn't there the first time, it might come back
when a file server returns, network traffic is reduced, whatever the next time
we try -- we could just do the substitution the first time and flag it as
unavailable every other time it is used. Finally, how do we generate names for
the substitiution? Empirically. We try first the exact name, under one of four
different conventions that distributed X fonts come with. We have no control
over the fact that different people chose different ways to name their fonts.
All ATK knows about is a family, a size and a face code. From that it has to
figure out a font name. If X had a standard way to name fonts, we would use it
and be a lot better off. It doesn't and so we have to make our best guess.
Note: if the matching algorithm worked correctly, we should never have an
unavailable font, since we eventually fall back to either variable or fixed,
which comes on the distribution. I admit: I didn't add any code to deal
specifically with possible bugs in the matching algorithm. At some point I
believe the documentation.

I no longer maintain that code and I haven't looked at the latest Xlib
doucmentation, but out of curiousity, is there an easy way to handle a 0-length
font on the client side?

                -Mark

RWS@ZERMATT.LCS.MIT.EDU (Robert Scheifler) (03/25/88)

    Date: Mon, 21 Mar 88 10:24 EST
    From: Mark Steven Sherman <mss+@andrew.cmu>

    In the beginning, calls like XLoadFont and XLoadQueryFont were synchronous,
    returning a null pointer if the font was not usuable, e.g., did not exist.

I didn't see the beginning of this conversation, but as far as I know,
XLoadQueryFont has always been and still is synchronous, returning a
null pointer if the font doesn't exist.  I am thus at a loss to
understand both your gnashing of teeth and your lengthy message.

    I no longer maintain that code and I haven't looked at the latest Xlib
    doucmentation, but out of curiousity, is there an easy way to handle a 0-length
    font on the client side?

I don't understand the question.