Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] position of first baseline? #105

Closed
frankrolf opened this issue May 23, 2017 · 15 comments
Closed

[question] position of first baseline? #105

frankrolf opened this issue May 23, 2017 · 15 comments
Labels

Comments

@frankrolf
Copy link
Contributor

In a text box, how does DrawBot specify the position of the first baseline for a given font?
I am currently working on a script that layers different fonts, and need to calculate the baseline offset – unfortunately that’s trickier than expected.

A common assumption is just subtracting the hhea.ascent value from the top of the text frame, but it’s not that simple – especially in fonts where hhea.ascent + |hhea.descent| != 1000.

Here is my test data (for simplicity’s sake, font size = UPM = 1000):

    # SourceSansPro-Bold
    # head.yMax: 1009
    # hhea.ascent: 984
    # hhea.descent: -273
    # hhea.lineGap: 0
    # baseline is 855 below top of text frame

    # SourceSerifPro-Light
    # head.yMax: 976
    # hhea.ascent: 1036
    # hhea.descent: -335
    # hhea.lineGap: 0
    # baseline is 850 below top of text frame

    # MyriadPro-Light
    # head.yMax: 935
    # hhea.ascent: 750
    # hhea.descent: -250
    # hhea.lineGap: 200
    # baseline is 750 below top of text frame

This may have been solved by @petrvanblokland – I assume pageBot can deal with baselines?

@frankrolf
Copy link
Contributor Author

This may or may not be related with #52

@frankrolf
Copy link
Contributor Author

frankrolf commented May 23, 2017

I stumbled upon textBoxBaselines, but something seems to be broken:

box = (0, 0, 1000, 1000)
print textBoxBaselines('whatever', box)

Traceback (most recent call last):
  File "<untitled>", line 8, in <module>
  File "drawBot/drawBotDrawingTools.pyc", line 1716, in textBoxBaselines
AttributeError: 'DrawBotDrawingTool' object has no attribute '_getPathForFrameSetter'

@petrvanblokland
Copy link
Sponsor

petrvanblokland commented May 23, 2017 via email

@frankrolf
Copy link
Contributor Author

Thanks Petr – the sample was filtered out (by Github I assume), but maybe you can email it privately? (or post here?)

@petrvanblokland
Copy link
Sponsor

Here it is.
testFSBaselineCalculation2.py.zip

@frankrolf
Copy link
Contributor Author

frankrolf commented May 24, 2017

Unfortunately that trick only works for a very small subset of fonts, Times among them.

import random as rnd

height = width = 1000
t = "hello world "
point_size = 100
line_height = point_size * 1.2
y_value = 500

font_names = ['Times']
font_names.extend(rnd.sample(installedFonts(), 9))

for font_name in font_names:
    newPage(width, height)

    fs_font_name_label = FormattedString(
        font_name,
        font=font_name,
        fontSize=point_size/2,
        lineHeight=line_height
    )

    fs_single = FormattedString(
        t,
        font=font_name,
        fontSize=point_size,
        lineHeight=line_height
    )

    font(font_name)
    fontSize(point_size)
    lineHeight(line_height)

    print font_name
    print fs_single.fontLineHeight()
    print fs_single.fontDescender()
    print

    text(fs_single, (0, y_value))

    r = (100, 0, 1000, y_value + fontLineHeight() + fontDescender())
    label_rect = (100, height-200, width-200, 200)

    fs_multiline = FormattedString(
        t * 10,
        font=font_name,
    fontSize=point_size)

    textBox(fs_font_name_label, label_rect)
    textBox(fs_multiline, r)

    strokeWidth(.2)
    stroke(0, 0 ,1)

    line((0, y_value), (1000, y_value))

    stroke(1, 0, 0)
    fill(None)
    rect(*r)

baseline.pdf

@petrvanblokland
Copy link
Sponsor

petrvanblokland commented May 24, 2017 via email

@typemytype
Copy link
Owner

DrawBot does not do any calculations to retrieve the position of the first line. That's all CoreText. DrawBot just draws glyph runs at a specific position.

This document should describe how CoreText is using the different 'typographical' terms: https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/TypoFeatures/TextSystemFeatures.html


the textBoxBaselines bug should be already solved. What version did you test in?

@typemytype
Copy link
Owner

but you can calculate the pos super precise :)

(but textBoxBaselines has to work :)

import random as rnd

point_size = 100
line_height = 50

t = "Hello World"
x, y = 68, 672

font_names = ['Times']
font_names.extend(rnd.sample(installedFonts(), 9))

boxWidth, boxHeight = 800, 500

for font_name in font_names:
    newPage(1000, 1000)
    
    single = FormattedString()
    single.font(font_name, point_size)
    single.lineHeight(line_height)
    single += font_name
    text(single, (x, y))
    
    
    multi = FormattedString()
    multi.font(font_name, point_size)
    multi.lineHeight(line_height)
    multi += t * 100
    
    box = (x+ 100, 
        y-boxHeight, 
        boxWidth, 
        boxHeight)
    
    # get the pos of the first line
    startX, startY = textBoxBaselines(multi, box)[0]
    # move the box back towards that first line
    save()
    translate(0, y-startY)
    textBox(multi, box)
    restore()
    
    save()
    stroke(1, 0, 0)
    fill(None)
    rect(*box)
    restore()

@frankrolf
Copy link
Contributor Author

Thank you Frederik. So what’s needed to make textBoxBaselines work?

Traceback (most recent call last):
  File "<untitled>", line 35, in <module>
  File "drawBot/drawBotDrawingTools.pyc", line 1716, in textBoxBaselines
AttributeError: 'DrawBotDrawingTool' object has no attribute '_getPathForFrameSetter'

@typemytype
Copy link
Owner

Maybe I have to push a new update... will check

@frankrolf
Copy link
Contributor Author

Does not work in 3.97 yet.
This reminder comment was encouraged by Frederik sitting next to me.

@typemytype
Copy link
Owner

this should work in the latest versions...

@justvanrossum
Copy link
Collaborator

@frankrolf, can this be closed?

@frankrolf
Copy link
Contributor Author

This can indeed be closed.
Thanks for making textBoxBaselines work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants