Features of text composition with different alignments and CharacterBlockScanner

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Features of text composition with different alignments and CharacterBlockScanner

Nicolas Cellier
Currently, the scanner family is wrapping the composition/display on next line when line is too long.
With a single space, the feature is quite simple, a space is then conceptually equal to a cr (and a line feed if you are stuck to the typewriter).
So for example in rightFlush alignment:
- align character before space with right margin
- let character after space lay on next line
- do not materialize any spacing in text selection
selecting before the space let the cursor at upper line, right margin.
selecting after the space let the cursor at lower line, left of next character.

But what if there are two spaces?
Should spacing be materialized before right margin or left of next line?
IMHO, when rightFlush, spacing should be materialized left of next line, by symmetry with leftFlush (in which case they are materialized right of current line).

And what about Centered? And Justified?

Currently CharacterBlockScanner and rightFlush alignment don't play well together.
Even leftFlush doesn't correctly update the cursor position (and I checked that this was already broken before I touched anything).

It's not really amazing, looking at the bunch of states that come onto the playfield:
- spaceCount for adjusting the padding in Justified case
- spaceX for determining the (left) position of last space (or other breakable char)
- lastIndex the index of next character to be processed in the text
- runStopIndex the last index in the text from current position (?) before a change of run (emphasis)
- destX the (left) position for next character to go
- kern & pendingKernX for adjusting spacing of next character (if in same font)
plus all the ones specific for CharacterBlockScanner:
- lastCharacter the last character that was processed
- lastCharacterExtent  its extent
- lastSpaceOrTabExtent the extent of last spce or tab (why?)
- specialWidth if it wasn't a character but an embedded morph

And the number of conditions scattered in the stop conditions:

    ((characterIndex ~= nil
        and: [characterIndex > text size])
            or: [(line last = text size)
                and: [(destY + line lineHeight) < characterPoint y]])

    characterIndex == nil ifFalse: [
        characterIndex > text size ifTrue: [

    characterPoint x <= (destX + (lastCharacterExtent x // 2))
        ifTrue:    [

    lastIndex >= line last
        ifTrue:    [

    (((characterIndex ~~ nil and:
        [runStopIndex < characterIndex and: [runStopIndex < text size]])
            or:    [characterIndex == nil and: [lastIndex < line last]]) or: [
                ((lastIndex < line last)
                and: [((text at: lastIndex) leadingChar ~= (text at: lastIndex+1) leadingChar)
                    and: [lastIndex ~= characterIndex]])])
        ifTrue:    [

    ((lastCharacter = Space and: [alignment = Justified])
        or: [lastCharacter = Tab and: [lastSpaceOrTabExtent notNil]])
        ifTrue: [

    runStopIndex = text size
        ifTrue:    [

    (destX + lastSpaceOrTabExtent x)  >= characterPoint x
        ifTrue: [

    (alignment = Justified and: [self leadingTab not])
        ifTrue:        "imbedded tabs in justified text are weird"
            [

    currentX >= characterPoint x
        ifTrue:
            [

Plus the ones before and after scanning

    (text isEmpty or: [(characterPoint y < destY or: [characterPoint x < destX])
                or: [characterIndex notNil and: [characterIndex < line first]]])
        ifTrue:    [

    characterIndex
        ifNil: [
            (stopCondition ~~ #cr and: [ lastIndex = line last
                and: [ aPoint x > ((characterPoint x) + (lastCharacterExtent x / 2)) ]])
                    ifTrue: [

Of course, a MVC Paragraph does not behave exactly the same.

I cannot really reverse engineer the state machine... It's not our best production.
I can conjecture that:
- characterIndex ~~ nil tests are probably related to the fact that moving cursor position with mouse or with arrow keys does not always result in consistent behavior (the cursor disappear in one case, remain visible in the other)
- testing once for (destX + lastSpaceOrTabExtent x) and the other for (destX + (lastCharacterExtent x // 2)) sounds weird

If you have any advice, reminiscence of bug report, useful comments to explain each and every logic, or anything related in this area, that might be helpful.

Nicolas



Reply | Threaded
Open this post in threaded view
|

Re: Features of text composition with different alignments and CharacterBlockScanner

timrowledge
That is opening a can of very scary worms, with large amounts of super-hot pepper added, and liquorice (I hate it).

My starting point is "let's keep it as simple as possible even if it might be wrong, unless it really annoys us". We can always make it more correct(er)  later(er).

I think the approach generally would be along the lines of 'spaces only count between non-space characters'. Uh, then it gets complicated when a space (or more than one) is at the start of the line. Or at the end. Or in the middle, when there is a tab as well.

OK, so it isn't simple. Bugger.

What *should* damn well be simple is finding some authoritative source to tell us what should happen. This isn't rocket science - it's stuff that has been sorted for centuries by skilled typographers. Somebody, somewhere, has written down the proper thing to do. All we need to do is find it...


tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Strange OpCodes: DUL: Delete Utility Library



Reply | Threaded
Open this post in threaded view
|

Re: Features of text composition with different alignments and CharacterBlockScanner

J. Vuletich (mail lists)
In reply to this post by Nicolas Cellier

Hi Nicolas,

Quoting Nicolas Cellier <[hidden email]>:

Currently, the scanner family is wrapping the composition/display on next line when line is too long.
...

If you have any advice, reminiscence of bug report, useful comments to explain each and every logic, or anything related in this area, that might be helpful.

Nicolas

It might be of use to check in Cuis. Although (or because of) text composition in Cuis is limited to 8bit chars (ISO 8859-15) and StrikeFonts, it uses less code; and I fixed many quirks and bugs, to support the StyledTextEditor. So, it might give some hints.

Cheers,
Juan Vuletich



Reply | Threaded
Open this post in threaded view
|

Re: Features of text composition with different alignments and CharacterBlockScanner

Nicolas Cellier
In reply to this post by timrowledge
tim: are you speaking of heavy metal fonts? Then yes, technology is rock-solid.
These guys had all sort of space width available...
The rules for using the right space can be complex, but we have our own too (padding/kerning).
But concerning CharacterBlockScanner, I'm more on electronic artifacts:
the explicitation of invisible spacing characters when selecting some text...
For rightFlush, the typographers knowledge can also help, but when I think of it, the rules seem obvious to me now:
align right of last char on each line.


2013/9/29 tim Rowledge <[hidden email]>
That is opening a can of very scary worms, with large amounts of super-hot pepper added, and liquorice (I hate it).

My starting point is "let's keep it as simple as possible even if it might be wrong, unless it really annoys us". We can always make it more correct(er)  later(er).

I think the approach generally would be along the lines of 'spaces only count between non-space characters'. Uh, then it gets complicated when a space (or more than one) is at the start of the line. Or at the end. Or in the middle, when there is a tab as well.

OK, so it isn't simple. Bugger.

What *should* damn well be simple is finding some authoritative source to tell us what should happen. This isn't rocket science - it's stuff that has been sorted for centuries by skilled typographers. Somebody, somewhere, has written down the proper thing to do. All we need to do is find it...


tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Strange OpCodes: DUL: Delete Utility Library