Blog Page 3 of 47 (462 posts) :: archive :: feeds

I’m working on a Russian alphabet chart at the moment. Things are mostly in place, with some spacing to do on some of the IPA bits, possibly adding cursive, and then sending the chart to some Russian speakers for proofing. It’s close.

I’ve reorganized my Mormon page, primarily to gather together all of the scripture-related materials into their own pages, like the new Book of Mormon page. I also have a few new related projects in the works, some of which are very exciting. More details later.

From Charles Mann’s 1491:

Almost 150 years before Columbus set sail, a Tartar army besieged the Genoese city of Kaffa. Then the Black Death visited. To the defenders’ joy, their attackers began dying off. But triumph turned to terror when the Tartar khan catapulted the dead bodies of his men over the city walls, deliberately creating an epidemic inside. The Genoese fled Kaffa, leaving it open to the Tartars. But they did not run away fast enough; their ships spread the disease to every port they visited.


Progress on Press has been a bit slower lately. I’ve fixed most of the errors I discovered by running the exported PDFs through the 3-Heights PDF validator. I also refactored the code and reorganized the package per Kenneth Reitz’s advice.

I’ve implemented initial support for embedding subsetted fonts (doing the subsetting via fontTools.subset), and while the fonts (including uninstalled fonts) display fine on my macOS box, the PDFs don’t validate properly and the fonts don’t show at all on iOS, which means the embedding isn’t actually working right. Current suspects include the /Differences array (which I’m not generating properly yet) and the CMap (which I haven’t implemented at all yet). I still have to implement ToUnicode as well, so that copying and pasting does what it should, but I’m fairly certain that isn’t what’s causing the fonts to not embed properly.

I’m also trying to figure out color spaces. In general I believe I want the output to be either DeviceRGB or DeviceCMYK, with some way of specifying an output intent, and also an option for the user to embed an ICC profile if they want. I’m part of the way there.

Anyway, the font stuff is far more complicated than I expected going in, but I’m still making progress, and I’m learning a lot.

A quick update: I was stuck for a while on the Dagh story, but I’ve started spending my lunch hour working on it, and it’s coming together nicely. I should have a complete first draft done soon. (I’ve got 7,000 words on it so far.)

Rather than starting work on Ink with the low-level typesetting engine, I’m thinking it’ll be worthwhile instead to start with a processor that goes through Ink rules and outputs TeX and/or SILE code. More to come later.

Press can now generate PDFs. For example:

from press import Press

with Press('press-demo.pdf', size=Press.LETTER, margin=1*Press.INCH) as p:
    # Top and bottom borders
    p.line(p.page_min_x, p.page_min_y, p.page_max_x, p.page_min_y)
    p.line(p.page_min_x, p.page_max_y, p.page_max_x, p.page_max_y)

    # Rotated colored rectangle
    p.stroke(hsl=(0, 0.5, 0.5))
    p.translate(p.page_min_x + 4*Press.INCH, p.page_max_y - 4*Press.INCH)
    p.rect(0, 0, 2*Press.INCH, 2*Press.INCH)

    # Lines of varying thickness
    p.translate(p.page_min_x + 1*Press.INCH, p.page_min_y + 1*Press.CM)
    for i in range(1, 20):
        p.pen(i / 2)
        p.line(0, 0, 30, 0)
        p.translate(0, 20)

That code generates the following PDF (linked):


I’m working on text/font support now, which is by far the most complicated thing about this project.

Since there isn’t a clean, cross-platform way to select a font via code, I’ve decided to use font maps (inspired by @font-face in CSS):

fontmap = {
    'paths': [ './fonts', '/Library/Fonts', ],
    'Minion Pro': [
        { 'weight': 300, 'italics': False, 'filename': 'MinionPro-Regular.otf', },
        { 'weight': 300, 'italics': True,  'filename': 'MinionPro-It.otf', },
        { 'weight': 600, 'italics': False, 'filename': 'MinionPro-Bold.otf', },
        { 'weight': 600, 'italics': True,  'filename': 'MinionPro-BoldIt.otf', },

with Press('output.pdf', size=Press.LETTER, fontmap=fontmap) as p:
    p.font('Minion Pro', size=24, weight=300, italics=True, dlig=True, smcp=True, tracking=50)
    p.text("This is a test.", 50, 50)

Font maps are admittedly extra work, but they do have some advantages as well: you can use fonts you haven’t installed, for example, and you can specify exactly which font files you want to use. And I can’t see any good way around the lack of a cross-platform font selection mechanism (meaning, a way to pass in ‘Minion Pro’ with specific weight and styles, and get a font filename in return).

Anyway, I’m in the middle of reading the PDF spec on CIDFonts and CMaps. It’s … complicated. It makes my head hurt. But it’ll be awesome when it’s done.