Skip to content
This repository has been archived by the owner on Aug 9, 2023. It is now read-only.

otf2ttf? #47

Open
davelab6 opened this issue Sep 8, 2016 · 9 comments
Open

otf2ttf? #47

davelab6 opened this issue Sep 8, 2016 · 9 comments

Comments

@davelab6
Copy link
Member

davelab6 commented Sep 8, 2016

Has anyone used cu2qu to convert a cff (file.otf) to ttf (file.ttf)?

cu2qu works on Defcon/Robofab Font objects, and thus UFO sources. To convert a OTF to TTF means intermediate conversion to UFO, which I suppose https://github.com/typesupply/extractor may be used for?

BTW, https://github.com/caryll/otfcc seems to offer a straight forward otf2ttf

@behdad
Copy link
Contributor

behdad commented Sep 8, 2016

With the pens, it should be straightforward to convert. @anthrotype

@graphicore
Copy link

BTW, https://github.com/caryll/otfcc seems to offer a straight forward otf2ttf

Here's the package: https://github.com/caryll/otfcc-cubic2quad

It's executed so: otfccdump input.otf | otfcc-c2q | otfccbuild -o output.ttf

Where otfcc-c2q consumes, modifies and outputs the sfnt json serialization of otfccdump. I like the use of unix pipes here.

The script c2q.js has 88 lines and its only relevant dependency https://github.com/fontello/cubic2quad has 303 lines, the latter does the math.

I'm using this right now and it seems to work OK. I did not dig too deep though.

@moyogo
Copy link
Contributor

moyogo commented Sep 9, 2016

All the pieces are there. otfcc is probably much faster.

import sys
from defcon import Font
from extractor import extractUFO
from cu2qu.ufo import font_to_quadratic
from ufo2ft import compileTTF

ufo = Font()
extractUFO(sys.argv[1], ufo)
font_to_quadratic(ufo)
ttf = compileTTF(ufo)
ttf.save(sys.argv[2])

@moyogo
Copy link
Contributor

moyogo commented Sep 9, 2016

Have a look at extractor’s extractOpenTypeGlyphs() and ufo2ft’s OutlineTTFCompiler.setupTable_glyf() if you want to just use a pen and create a glyf table directly without going through a temporary UFO.

@khaledhosny
Copy link

khaledhosny commented Sep 9, 2016

If it is only about converting the glyph outlines, I'd not use the
extractor because it likely to throw out lots of viable information (like
non-kerning font features, even not all ways of OpenType kerning can be
represented in UFO). It shouldn't be hard to just use the pens to create a
new glyf table.

On Fri, Sep 9, 2016, 8:25 AM Denis Moyogo Jacquerye <
[email protected]> wrote:

Have a look at ufo2ft’s outlineOTF. OutlineTTFCompiler.setupTable_glyf()
https://github.com/googlei18n/ufo2ft/blob/8ce57a83460a6e9415fb26f4cbb0b4138f4cfaba/Lib/ufo2ft/outlineOTF.py#L938
if you want to just use a pen and create a glyf table directly without
going through a temporary UFO.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#47 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAFu2iWXFGA7mAeFKs7AyAGWNXGHxLnsks5qoPvhgaJpZM4J4S20
.

@anthrotype
Copy link
Member

I found this in my stash. Maybe we could add it to fonttools Snippets.

from __future__ import print_function, division, absolute_import
import sys
from fontTools.ttLib import TTFont, newTable
from cu2qu.pens import Cu2QuPen
from fontTools.pens.ttGlyphPen import TTGlyphPen


# default approximation error
MAX_ERR = 1.0


def glyphs_to_quadratic(glyphs, max_err, **kwargs):
    quadGlyphs = {}
    for gname in glyphs.keys():
        glyph = glyphs[gname]
        ttPen = TTGlyphPen(glyphs)
        cu2quPen = Cu2QuPen(ttPen, max_err, **kwargs)
        glyph.draw(cu2quPen)
        quadGlyphs[gname] = ttPen.glyph()
    return quadGlyphs


def font_to_ttf(ttFont, max_err, **kwargs):
    glyphOrder = ttFont.getGlyphOrder()

    ttFont["loca"] = newTable("loca")
    ttFont["glyf"] = glyf = newTable("glyf")
    glyf.glyphOrder = glyphOrder
    glyf.glyphs = glyphs_to_quadratic(ttFont.getGlyphSet(), max_err, **kwargs)
    del ttFont["CFF "]

    ttFont["maxp"] = maxp = newTable("maxp")
    maxp.tableVersion = 0b10000
    maxp.maxZones = 1
    maxp.maxTwilightPoints = 0
    maxp.maxStorage = 0
    maxp.maxFunctionDefs = 0
    maxp.maxInstructionDefs = 0
    maxp.maxStackElements = 0
    maxp.maxSizeOfInstructions = 0
    maxp.maxComponentElements = max(
        len(g.components if hasattr(g, 'components') else [])
        for g in glyf.glyphs.values())

    post = ttFont["post"]
    post.formatType = 2.0
    post.extraNames = []
    post.mapping = {}
    post.glyphOrder = glyphOrder

    ttFont.sfntVersion = "\000\001\000\000"


if __name__ == "__main__":
    font = TTFont(sys.argv[1])
    font_to_ttf(font, max_err=MAX_ERR)
    font.save(sys.argv[2])

@behdad
Copy link
Contributor

behdad commented Jan 12, 2017

Yes please, add it!

Typo in maxp version: 0b10000 should be 0x10000 instead, or better, 0x00010000.

@behdad
Copy link
Contributor

behdad commented Jan 12, 2017

Note that for a font like NotoSansCJK that has 65535 glyphs, post table format 2.0 overflows. Trying with format 3.0 now.

@behdad
Copy link
Contributor

behdad commented Jan 12, 2017

Post table format 3.0 worked. I got a NotoSansCJK.ttf file that seems to work.

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

No branches or pull requests

6 participants