Skip to content

Right-to-left problem with "mark" GPOS #24

@andyclymer

Description

@andyclymer

A student of mine found a problem in the FeaturePreview.roboFontExt that I traced back to Compositor, but I'm a little bit lost with how to fix it — the handling of GPOS mark positioning doesn't seem to be working properly when the text is right-to-left.

Here's an example as I visualize the problem in DrawBot using Noto Sans Hebrew as a sample font:

image

The green text is in a normal text box in DrawBot, and the marks are positioned correctly, as a control. The red text is when rightToLeft is True, the direction is correct but the positioning is off by one base character. The purple text shows that when the text is processed in the incorrect order the mark positioning is correct.

I'm also attaching my DrawBot script below if it helps with testing the problem, and I'm testing with the latest release of Noto which can be found here: https://www.google.com/get/noto/

from compositor import Font as cFont
from fontTools.pens.cocoaPen import CocoaPen

size(200, 200)

fontPath = "./NotoSansHebrew-Medium.ttf"

def drawRecords(glyphRecords):
    for record in glyphRecords:
        save()
        translate(record.xPlacement, record.yPlacement)
        glyph = f[record.glyphName]
        pen = CocoaPen(f)
        glyph.draw(pen)
        path = BezierPath()
        drawPath(pen.path)
        restore()
        translate(glyph.width)
        

# Green text in a text box,
# Correct positioning

font("Lucida Grande")
fontSize(8)
fill(0)
text("In a text box", (10, 150))

font(fontPath)
fontSize(30)
fill(0, 0.5, 0, 1)
text("בַּיִת", (100, 150)) # oooh, this line looks weird but it works



# Red text with Compositor
# rightToLeft set to True
# Correct direction, incorrect mark positioning

font("Lucida Grande")
fontSize(8)
fill(0)
text("rightToLeft = True", (10, 100))

fill(0.75, 0, 0, 1)

save()
scale(0.05, 0.05)
translate(2000, 2000)
f = cFont(fontPath)
glyphRecords = f.process(u"בַּיִת", script="hebr", rightToLeft=True)
drawRecords(glyphRecords)
restore()

# Purple text with Compositor
# rightToLeft = False
# Incorrect direction, but correct mark positioning

font("Lucida Grande")
fontSize(8)
fill(0)
text("rightToLeft = False", (10, 50))

fill(0.5, 0, 0.5, 1)

save()
scale(0.05, 0.05)
translate(2000, 1000)
f = cFont(fontPath)
glyphRecords = f.process(u"בַּיִת", script="hebr", rightToLeft=False)
drawRecords(glyphRecords)
restore()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions