[squeak-dev] Re: Text Morph Embedding Broken

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Wed Jan 8 19:10:49 UTC 2014


2014/1/8 Sean P. DeNigris <sean at clipperadams.com>

> Nicolas Cellier wrote
> > For embedded morphs/forms created programmaticaly as you did, we have to
> > decide something...
>
> Just reifying and documenting may be enough. For Pharo, I'm proposing (1)
> an
> update to the TextAnchor class comment and (2):
> Morph>>#asText
>
>         | anchor embedMorphSignal |
>         anchor := TextAnchor new anchoredMorph: self.
>         embedMorphSignal := (Character value: 1) asString. "required by the
> scanner"
>         ^ Text string: embedMorphSignal attribute: anchor.
>
> b.t.w. is "required by the scanner" accurate
>
> Yep, exactly, that's how the scanner loop works.
If you want it, here are a few things I can tell about the scanner and some
recent evolutions:

The scanner processes run after run (a run is a chunk of text with
homogeneous emphasis, like, bold italic, ...).
In each run, the font is set according to current emphasis.
Inside a run, the scanner then compose/displays string chunks separated by
well know special character (space if justified alignment, tab, cr/lf and
(Character value: 1)).
A special action associated to the special character is then processed, and
this composiiton/display loop continues until end of run.
Those special characters and associated actions are stored in
stopConditions which map special character code ->special action (nil if
none).
Note that currently (heritage of ASCII) the special character code are
limited from 0 to 255. There currently cannot be any special wide character.
Two more code are used for two special conditions
- the composition crossed the X boundary (the right margin in latin - we
don't yet support arabic or hebrew right to left).
- the endOfRun was reached
In fact, the two external loops (runs and chunks) are (or can be) fused,
thanks to the #endOfRun actions linked to these EndOfRun special code.

The character by character scanning for stop conditions is performed inside
an internal loop which is very simple and can be generated as a primitive.
This provides great speed up for composing/displaying on slow devices, but
is unfortunately restricted to StrikeFonts and char codes < 256 currently...
This primitive access/mutates some of the scanner states, and thus requires
a specific inst. var. layout which was broken quite some times ago (search
mantis or this mailing list for reference).
It must also have two reserved slots for crossedX and endOfRun conditions
which I previously broke (in order to correct a bug: endOfRun was hikacking
A-macron char code, perventing its display).
Note that some people (including me) thought that having an indirection
stopConditions at: EndOfRun put:#endOfRun was an unecessarily
over-engineered feature.
This was not the original goal : the original goal was to have a primitive,
and indeed the VM cannot easily perform a squeak method, thus the
indirection.
Also the VM cannot easily access Symbols by name - unless we reserve
additional SpecialObjects (oh no!) - thus the two reserved slots.
We restored all these conditions recently with Tim, enabling the primitive
to run again in both Squeak and Pharo.
Tim added the double dispatch things to properly handle other kind of fonts
or WideString by non primitive code.
This should enable using Squeak/Pharo on Pi or other slow devices with
smoother user experience (if restricting to latin1 StrikeFont).

The old TextAnchor code did not play well this logic. It was a hack added a
posteriori, which tried to perform special actions outside the
composition/display loop (during setting of the font).
Unfortunately, this violates some implicit invariants, because some states
are either not yet correctly set, or set twice (like advancing the X
position).
These are the glitches that you can see when inserting a white space in
'foo *bar'.
An unused control Character (value: 1) had been assigned previously for
embedded morph/form before this hack, (late 90s ? early 2000s ?), but maybe
the hack was older after all (use Bob Arning site for exploring old Squeak
changes if you are curious)...

If we really insist on transforming any character code as an anchor, we can
as well try to rewrite the logic to handle TextAnchor specially (as an
isolated run ?), but:
1. this is quite involved: I greatly reduced the number of mutated states
(inst-var) in my recent reviews, but there are still a bit too many
2. this is constrained by the fact that the internal loop must remain
simple in order to be generated.
3. if you change the internal loop logic, then you must allocate a new
primitive # (or you break the property that the interpreter VM supports old
images - we wish to keep it)
4. we miss (non regression) tests - I started some unpublished attempts,
but given that there are many logics in those composition/display, it's
really hard to write good tests. Moreover, I'm not sure that using
MethodWrappers on such kind of low level methods in order to measure
coverage is an easy thing ;).

Another strategy in Pharo is to let things as they are now, and wait for a
better (but you must tell versus which criterion) or at least revisited
Text model...

Last thing, the FreeTypePlugin primitives currently can only compose and
display character by character... This is a pity because it's a huge slow
down !
So if you start Pharo 3.0 on a Pi, please revert to a strike font like
dejaVu sans.
Maybe that's something we could address with moderate effort, if there is
good will and interest.
But what are the mid-term Pharo plans about Text composition/redering? Will
some new 3rd party libraries be used?

Nicolas



> -----
> Cheers,
> Sean
> --
> View this message in context:
> http://forum.world.st/Text-Morph-Embedding-Broken-tp4735055p4735207.html
> Sent from the Squeak - Dev mailing list archive at Nabble.com.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20140108/bc2ef4ce/attachment.htm


More information about the Squeak-dev mailing list