Esempio n. 1
0
def compileOTF(ufo, outlineCompilerClass=OutlineOTFCompiler,
               featureCompilerClass=FeatureCompiler, mtiFeaFiles=None,
               kernWriterClass=KernFeatureWriter, markWriterClass=MarkFeatureWriter,
               glyphOrder=None, useProductionNames=True, optimizeCFF=True,
               roundTolerance=None):
    """Create FontTools CFF font from a UFO.

    *optimizeCFF* sets whether the CFF table should be subroutinized.

    *roundTolerance* (float) controls the rounding of point coordinates.
      It is defined as the maximum absolute difference between the original
      float and the rounded integer value.
      By default, all floats are rounded to integer (tolerance 0.5); a value
      of 0 completely disables rounding; values in between only round floats
      which are close to their integral part within the tolerated range.
    """

    outlineCompiler = outlineCompilerClass(
        ufo, glyphOrder, roundTolerance=roundTolerance)
    otf = outlineCompiler.compile()

    featureCompiler = featureCompilerClass(
        ufo, otf, kernWriterClass=kernWriterClass, markWriterClass=markWriterClass,
        mtiFeaFiles=mtiFeaFiles)
    featureCompiler.compile()

    postProcessor = PostProcessor(otf, ufo)
    otf = postProcessor.process(useProductionNames, optimizeCFF)

    return otf
Esempio n. 2
0
def compileTTF(ufo,
               outlineCompilerClass=OutlineTTFCompiler,
               featureCompilerClass=FeatureCompiler,
               kernWriterClass=KernFeatureWriter,
               markWriterClass=MarkFeatureWriter,
               glyphOrder=None,
               useProductionNames=True,
               convertCubics=True,
               cubicConversionError=None):
    """Create FontTools TrueType font from a UFO.

    *convertCubics* and *cubicConversionError* specify how the conversion from cubic
    to quadratic curves should be handled.
    """
    outlineCompiler = outlineCompilerClass(ufo, glyphOrder, convertCubics,
                                           cubicConversionError)
    otf = outlineCompiler.compile()

    featureCompiler = featureCompilerClass(ufo,
                                           otf,
                                           kernWriterClass=kernWriterClass,
                                           markWriterClass=markWriterClass,
                                           mtiFeatures=_getMtiFeatures(ufo))
    featureCompiler.compile()

    postProcessor = PostProcessor(otf, ufo)
    otf = postProcessor.process(useProductionNames)

    return otf
Esempio n. 3
0
def compileVariableTTF(
    designSpaceDoc,
    preProcessorClass=TTFInterpolatablePreProcessor,
    outlineCompilerClass=OutlineTTFCompiler,
    featureCompilerClass=None,
    featureWriters=None,
    glyphOrder=None,
    useProductionNames=None,
    cubicConversionError=None,
    reverseDirection=True,
    excludeVariationTables=(),
    optimizeGvar=True,
    flattenComponents=False,
    inplace=False,
    debugFeatureFile=None,
    notdefGlyph=None,
):
    """Create FontTools TrueType variable font from the DesignSpaceDocument UFO sources
    with interpolatable outlines, using fontTools.varLib.build.

    *optimizeGvar*, if set to False, will not perform IUP optimization on the
      generated 'gvar' table.

    *excludeVariationTables* is a list of sfnt table tags (str) that is passed on
      to fontTools.varLib.build, to skip building some variation tables.

    The rest of the arguments works the same as in the other compile functions.

    Returns a new variable TTFont object.
    """
    baseUfo = getDefaultMasterFont(designSpaceDoc)

    ttfDesignSpace = compileInterpolatableTTFsFromDS(
        designSpaceDoc,
        preProcessorClass=preProcessorClass,
        outlineCompilerClass=outlineCompilerClass,
        featureCompilerClass=featureCompilerClass,
        featureWriters=featureWriters,
        glyphOrder=glyphOrder,
        useProductionNames=False,  # will rename glyphs after varfont is built
        cubicConversionError=cubicConversionError,
        reverseDirection=reverseDirection,
        flattenComponents=flattenComponents,
        inplace=inplace,
        debugFeatureFile=debugFeatureFile,
        notdefGlyph=notdefGlyph,
    )

    logger.info("Building variable TTF font")

    varfont = varLib.build(ttfDesignSpace,
                           exclude=excludeVariationTables,
                           optimize=optimizeGvar)[0]

    postProcessor = PostProcessor(varfont, baseUfo)
    varfont = postProcessor.process(useProductionNames)

    return varfont
Esempio n. 4
0
def compileTTF(
        ufo,
        preProcessorClass=TTFPreProcessor,
        outlineCompilerClass=OutlineTTFCompiler,
        featureCompilerClass=FeatureCompiler,
        kernWriterClass=None,  # deprecated
        markWriterClass=None,  # deprecated
        featureWriters=None,
        glyphOrder=None,
        useProductionNames=None,
        convertCubics=True,
        cubicConversionError=None,
        reverseDirection=True,
        removeOverlaps=False,
        inplace=False):
    """Create FontTools TrueType font from a UFO.

    *removeOverlaps* performs a union operation on all the glyphs' contours.

    *convertCubics* and *cubicConversionError* specify how the conversion from cubic
    to quadratic curves should be handled.
    """
    preProcessor = preProcessorClass(ufo,
                                     inplace=inplace,
                                     removeOverlaps=removeOverlaps,
                                     convertCubics=convertCubics,
                                     conversionError=cubicConversionError,
                                     reverseDirection=reverseDirection)
    glyphSet = preProcessor.process()

    outlineCompiler = outlineCompilerClass(ufo,
                                           glyphSet=glyphSet,
                                           glyphOrder=glyphOrder)
    otf = outlineCompiler.compile()

    featureWriters = _replaceDeprecatedFeatureWriters(featureWriters,
                                                      kernWriterClass,
                                                      markWriterClass)
    featureCompiler = featureCompilerClass(ufo,
                                           otf,
                                           featureWriters=featureWriters,
                                           mtiFeatures=_getMtiFeatures(ufo))
    featureCompiler.compile()

    postProcessor = PostProcessor(otf, ufo)
    otf = postProcessor.process(useProductionNames)

    return otf
Esempio n. 5
0
def compileVariableCFF2(
        designSpaceDoc,
        preProcessorClass=OTFPreProcessor,
        outlineCompilerClass=OutlineOTFCompiler,
        featureCompilerClass=None,
        featureWriters=None,
        glyphOrder=None,
        useProductionNames=None,
        roundTolerance=None,
        excludeVariationTables=(),
        inplace=False,
        debugFeatureFile=None,
):
    """Create FontTools CFF2 variable font from the DesignSpaceDocument UFO sources
    with interpolatable outlines, using fontTools.varLib.build.

    *excludeVariationTables* is a list of sfnt table tags (str) that is passed on
      to fontTools.varLib.build, to skip building some variation tables.

    The rest of the arguments works the same as in the other compile functions.

    Returns a new variable TTFont object.
    """
    baseUfo = getDefaultMasterFont(designSpaceDoc)

    otfDesignSpace = compileInterpolatableOTFsFromDS(
        designSpaceDoc,
        preProcessorClass=preProcessorClass,
        outlineCompilerClass=outlineCompilerClass,
        featureCompilerClass=featureCompilerClass,
        featureWriters=featureWriters,
        glyphOrder=glyphOrder,
        useProductionNames=False,  # will rename glyphs after varfont is built
        roundTolerance=roundTolerance,
        inplace=inplace,
        debugFeatureFile=debugFeatureFile,
    )

    logger.info("Building variable CFF2 font")

    varfont = varLib.build(otfDesignSpace, exclude=excludeVariationTables)[0]

    postProcessor = PostProcessor(varfont, baseUfo)
    varfont = postProcessor.process(useProductionNames)

    return varfont
Esempio n. 6
0
def compileInterpolatableTTFs(ufos,
                              preProcessorClass=TTFInterpolatablePreProcessor,
                              outlineCompilerClass=OutlineTTFCompiler,
                              featureCompilerClass=FeatureCompiler,
                              featureWriters=None,
                              glyphOrder=None,
                              useProductionNames=None,
                              cubicConversionError=None,
                              reverseDirection=True,
                              inplace=False):
    """Create FontTools TrueType fonts from a list of UFOs with interpolatable
    outlines. Cubic curves are converted compatibly to quadratic curves using
    the Cu2Qu conversion algorithm.

    Return an iterator object that yields a TTFont instance for each UFO.
    """
    preProcessor = preProcessorClass(ufos,
                                     inplace=inplace,
                                     conversionError=cubicConversionError,
                                     reverseDirection=reverseDirection)
    glyphSets = preProcessor.process()

    for ufo, glyphSet in zip(ufos, glyphSets):
        outlineCompiler = outlineCompilerClass(ufo,
                                               glyphSet=glyphSet,
                                               glyphOrder=glyphOrder)
        ttf = outlineCompiler.compile()

        featureCompiler = featureCompilerClass(
            ufo,
            ttf,
            featureWriters=featureWriters,
            mtiFeatures=_getMtiFeatures(ufo))
        featureCompiler.compile()

        postProcessor = PostProcessor(ttf, ufo)
        ttf = postProcessor.process(useProductionNames)

        yield ttf
Esempio n. 7
0
def compileOTF(
    ufo,
    preProcessorClass=OTFPreProcessor,
    outlineCompilerClass=OutlineOTFCompiler,
    featureCompilerClass=None,
    featureWriters=None,
    glyphOrder=None,
    useProductionNames=None,
    optimizeCFF=CFFOptimization.SUBROUTINIZE,
    roundTolerance=None,
    removeOverlaps=False,
    overlapsBackend=None,
    inplace=False,
    layerName=None,
    skipExportGlyphs=None,
    _tables=None,
):
    """Create FontTools CFF font from a UFO.

    *removeOverlaps* performs a union operation on all the glyphs' contours.

    *optimizeCFF* (int) defines whether the CFF charstrings should be
      specialized and subroutinized. By default both optimization are enabled.
      A value of 0 disables both; 1 only enables the specialization; 2 (default)
      does both specialization and subroutinization.

    *roundTolerance* (float) controls the rounding of point coordinates.
      It is defined as the maximum absolute difference between the original
      float and the rounded integer value.
      By default, all floats are rounded to integer (tolerance 0.5); a value
      of 0 completely disables rounding; values in between only round floats
      which are close to their integral part within the tolerated range.

    *featureWriters* argument is a list of BaseFeatureWriter subclasses or
      pre-initialized instances. Features will be written by each feature
      writer in the given order. If featureWriters is None, the default
      feature writers [KernFeatureWriter, MarkFeatureWriter] are used.

    *useProductionNames* renames glyphs in TrueType 'post' or OpenType 'CFF '
      tables based on the 'public.postscriptNames' mapping in the UFO lib,
      if present. Otherwise, uniXXXX names are generated from the glyphs'
      unicode values. The default value (None) will first check if the UFO lib
      has the 'com.github.googlei18n.ufo2ft.useProductionNames' key. If this
      is missing or True (default), the glyphs are renamed. Set to False
      to keep the original names.

    **inplace** (bool) specifies whether the filters should modify the input
      UFO's glyphs, a copy should be made first.

    *layerName* specifies which layer should be compiled. When compiling something
    other than the default layer, feature compilation is skipped.

    *skipExportGlyphs* is a list or set of glyph names to not be exported to the
    final font. If these glyphs are used as components in any other glyph, those
    components get decomposed. If the parameter is not passed in, the UFO's
    "public.skipExportGlyphs" lib key will be consulted. If it doesn't exist,
    all glyphs are exported. UFO groups and kerning will be pruned of skipped
    glyphs.
    """
    logger.info("Pre-processing glyphs")

    if skipExportGlyphs is None:
        skipExportGlyphs = ufo.lib.get("public.skipExportGlyphs", [])

    preProcessor = preProcessorClass(
        ufo,
        inplace=inplace,
        removeOverlaps=removeOverlaps,
        overlapsBackend=overlapsBackend,
        layerName=layerName,
        skipExportGlyphs=skipExportGlyphs,
    )
    glyphSet = preProcessor.process()

    logger.info("Building OpenType tables")
    optimizeCFF = CFFOptimization(optimizeCFF)
    outlineCompiler = outlineCompilerClass(
        ufo,
        glyphSet=glyphSet,
        glyphOrder=glyphOrder,
        roundTolerance=roundTolerance,
        optimizeCFF=optimizeCFF >= CFFOptimization.SPECIALIZE,
        tables=_tables,
    )
    otf = outlineCompiler.compile()

    # Only the default layer is likely to have all glyphs used in feature code.
    if layerName is None:
        compileFeatures(
            ufo,
            otf,
            glyphSet=glyphSet,
            featureWriters=featureWriters,
            featureCompilerClass=featureCompilerClass,
        )

    postProcessor = PostProcessor(otf, ufo, glyphSet=glyphSet)
    otf = postProcessor.process(
        useProductionNames,
        optimizeCFF=optimizeCFF >= CFFOptimization.SUBROUTINIZE)

    return otf
Esempio n. 8
0
def compileInterpolatableTTFs(
    ufos,
    preProcessorClass=TTFInterpolatablePreProcessor,
    outlineCompilerClass=OutlineTTFCompiler,
    featureCompilerClass=None,
    featureWriters=None,
    glyphOrder=None,
    useProductionNames=None,
    cubicConversionError=None,
    reverseDirection=True,
    inplace=False,
    layerNames=None,
    skipExportGlyphs=None,
):
    """Create FontTools TrueType fonts from a list of UFOs with interpolatable
    outlines. Cubic curves are converted compatibly to quadratic curves using
    the Cu2Qu conversion algorithm.

    Return an iterator object that yields a TTFont instance for each UFO.

    *layerNames* refers to the layer names to use glyphs from in the order of
    the UFOs in *ufos*. By default, this is a list of `[None]` times the number
    of UFOs, i.e. using the default layer from all the UFOs.

    When the layerName is not None for a given UFO, the corresponding TTFont object
    will contain only a minimum set of tables ("head", "hmtx", "glyf", "loca", "maxp",
    "post" and "vmtx"), and no OpenType layout tables.

    *skipExportGlyphs* is a list or set of glyph names to not be exported to the
    final font. If these glyphs are used as components in any other glyph, those
    components get decomposed. If the parameter is not passed in, the union of
    all UFO's "public.skipExportGlyphs" lib keys will be used. If they don't
    exist, all glyphs are exported. UFO groups and kerning will be pruned of
    skipped glyphs.
    """
    from ufo2ft.util import _LazyFontName

    if layerNames is None:
        layerNames = [None] * len(ufos)
    assert len(ufos) == len(layerNames)

    if skipExportGlyphs is None:
        skipExportGlyphs = set()
        for ufo in ufos:
            skipExportGlyphs.update(ufo.lib.get("public.skipExportGlyphs", []))

    logger.info("Pre-processing glyphs")
    preProcessor = preProcessorClass(
        ufos,
        inplace=inplace,
        conversionError=cubicConversionError,
        reverseDirection=reverseDirection,
        layerNames=layerNames,
        skipExportGlyphs=skipExportGlyphs,
    )
    glyphSets = preProcessor.process()

    for ufo, glyphSet, layerName in zip(ufos, glyphSets, layerNames):
        fontName = _LazyFontName(ufo)
        if layerName is not None:
            logger.info("Building OpenType tables for %s-%s", fontName,
                        layerName)
        else:
            logger.info("Building OpenType tables for %s", fontName)

        outlineCompiler = outlineCompilerClass(
            ufo,
            glyphSet=glyphSet,
            glyphOrder=glyphOrder,
            tables=SPARSE_TTF_MASTER_TABLES if layerName else None,
        )
        ttf = outlineCompiler.compile()

        # Only the default layer is likely to have all glyphs used in feature
        # code.
        if layerName is None:
            compileFeatures(
                ufo,
                ttf,
                glyphSet=glyphSet,
                featureWriters=featureWriters,
                featureCompilerClass=featureCompilerClass,
            )

        postProcessor = PostProcessor(ttf, ufo, glyphSet=glyphSet)
        ttf = postProcessor.process(useProductionNames)

        if layerName is not None:
            # for sparse masters (i.e. containing only a subset of the glyphs), we
            # need to include the post table in order to store glyph names, so that
            # fontTools.varLib can interpolate glyphs with same name across masters.
            # However we want to prevent the underlinePosition/underlineThickness
            # fields in such sparse masters to be included when computing the deltas
            # for the MVAR table. Thus, we set them to this unlikely, limit value
            # (-36768) which is a signal varLib should ignore them when building MVAR.
            ttf["post"].underlinePosition = -0x8000
            ttf["post"].underlineThickness = -0x8000

        yield ttf
Esempio n. 9
0
def compileTTF(
    ufo,
    preProcessorClass=TTFPreProcessor,
    outlineCompilerClass=OutlineTTFCompiler,
    featureCompilerClass=None,
    featureWriters=None,
    glyphOrder=None,
    useProductionNames=None,
    convertCubics=True,
    cubicConversionError=None,
    reverseDirection=True,
    rememberCurveType=True,
    removeOverlaps=False,
    overlapsBackend=None,
    inplace=False,
    layerName=None,
    skipExportGlyphs=None,
):
    """Create FontTools TrueType font from a UFO.

    *removeOverlaps* performs a union operation on all the glyphs' contours.

    *convertCubics* and *cubicConversionError* specify how the conversion from cubic
    to quadratic curves should be handled.

    *layerName* specifies which layer should be compiled. When compiling something
    other than the default layer, feature compilation is skipped.

    *skipExportGlyphs* is a list or set of glyph names to not be exported to the
    final font. If these glyphs are used as components in any other glyph, those
    components get decomposed. If the parameter is not passed in, the UFO's
    "public.skipExportGlyphs" lib key will be consulted. If it doesn't exist,
    all glyphs are exported. UFO groups and kerning will be pruned of skipped
    glyphs.
    """
    logger.info("Pre-processing glyphs")

    if skipExportGlyphs is None:
        skipExportGlyphs = ufo.lib.get("public.skipExportGlyphs", [])

    preProcessor = preProcessorClass(
        ufo,
        inplace=inplace,
        removeOverlaps=removeOverlaps,
        overlapsBackend=overlapsBackend,
        convertCubics=convertCubics,
        conversionError=cubicConversionError,
        reverseDirection=reverseDirection,
        rememberCurveType=rememberCurveType,
        layerName=layerName,
        skipExportGlyphs=skipExportGlyphs,
    )
    glyphSet = preProcessor.process()

    logger.info("Building OpenType tables")
    outlineCompiler = outlineCompilerClass(ufo,
                                           glyphSet=glyphSet,
                                           glyphOrder=glyphOrder)
    otf = outlineCompiler.compile()

    # Only the default layer is likely to have all glyphs used in feature code.
    if layerName is None:
        compileFeatures(
            ufo,
            otf,
            glyphSet=glyphSet,
            featureWriters=featureWriters,
            featureCompilerClass=featureCompilerClass,
        )

    postProcessor = PostProcessor(otf, ufo, glyphSet=glyphSet)
    otf = postProcessor.process(useProductionNames)

    return otf
Esempio n. 10
0
def compileVariableCFF2(
    designSpaceDoc,
    preProcessorClass=OTFPreProcessor,
    outlineCompilerClass=OutlineOTFCompiler,
    featureCompilerClass=None,
    featureWriters=None,
    glyphOrder=None,
    useProductionNames=None,
    roundTolerance=None,
    excludeVariationTables=(),
    inplace=False,
    debugFeatureFile=None,
    optimizeCFF=CFFOptimization.SPECIALIZE,
    notdefGlyph=None,
):
    """Create FontTools CFF2 variable font from the DesignSpaceDocument UFO sources
    with interpolatable outlines, using fontTools.varLib.build.

    *excludeVariationTables* is a list of sfnt table tags (str) that is passed on
      to fontTools.varLib.build, to skip building some variation tables.

    *optimizeCFF* (int) defines whether the CFF charstrings should be
      specialized and subroutinized. 1 (default) only enables the specialization;
      2 (default) does both specialization and subroutinization. The value 0 is supposed
      to disable both optimizations, however it's currently unused, because fontTools
      has some issues generating a VF with non-specialized CFF2 charstrings:
      fonttools/fonttools#1979.
      NOTE: Subroutinization of variable CFF2 requires the "cffsubr" extra requirement.

    The rest of the arguments works the same as in the other compile functions.

    Returns a new variable TTFont object.
    """
    baseUfo = getDefaultMasterFont(designSpaceDoc)

    otfDesignSpace = compileInterpolatableOTFsFromDS(
        designSpaceDoc,
        preProcessorClass=preProcessorClass,
        outlineCompilerClass=outlineCompilerClass,
        featureCompilerClass=featureCompilerClass,
        featureWriters=featureWriters,
        glyphOrder=glyphOrder,
        useProductionNames=False,  # will rename glyphs after varfont is built
        roundTolerance=roundTolerance,
        inplace=inplace,
        debugFeatureFile=debugFeatureFile,
        notdefGlyph=notdefGlyph,
    )

    logger.info("Building variable CFF2 font")

    optimizeCFF = CFFOptimization(optimizeCFF)

    varfont = varLib.build(
        otfDesignSpace,
        exclude=excludeVariationTables,
        # NOTE optimize=False won't change anything until this PR is merged
        # https://github.com/fonttools/fonttools/pull/1979
        optimize=optimizeCFF >= CFFOptimization.SPECIALIZE,
    )[0]

    postProcessor = PostProcessor(varfont, baseUfo)
    varfont = postProcessor.process(
        useProductionNames,
        optimizeCFF=optimizeCFF >= CFFOptimization.SUBROUTINIZE,
    )

    return varfont
Esempio n. 11
0
def compileTTF(
    ufo,
    preProcessorClass=TTFPreProcessor,
    outlineCompilerClass=OutlineTTFCompiler,
    featureCompilerClass=None,
    featureWriters=None,
    glyphOrder=None,
    useProductionNames=None,
    convertCubics=True,
    cubicConversionError=None,
    reverseDirection=True,
    rememberCurveType=True,
    removeOverlaps=False,
    overlapsBackend=None,
    inplace=False,
    layerName=None,
):
    """Create FontTools TrueType font from a UFO.

    *removeOverlaps* performs a union operation on all the glyphs' contours.

    *convertCubics* and *cubicConversionError* specify how the conversion from cubic
    to quadratic curves should be handled.

    *layerName* specifies which layer should be compiled. When compiling something
    other than the default layer, feature compilation is skipped.
    """
    logger.info("Pre-processing glyphs")
    preProcessor = preProcessorClass(
        ufo,
        inplace=inplace,
        removeOverlaps=removeOverlaps,
        overlapsBackend=overlapsBackend,
        convertCubics=convertCubics,
        conversionError=cubicConversionError,
        reverseDirection=reverseDirection,
        rememberCurveType=rememberCurveType,
        layerName=layerName,
    )
    glyphSet = preProcessor.process()

    logger.info("Building OpenType tables")
    outlineCompiler = outlineCompilerClass(ufo,
                                           glyphSet=glyphSet,
                                           glyphOrder=glyphOrder)
    otf = outlineCompiler.compile()

    # Only the default layer is likely to have all glyphs used in feature code.
    if layerName is None:
        compileFeatures(
            ufo,
            otf,
            glyphSet=glyphSet,
            featureWriters=featureWriters,
            featureCompilerClass=featureCompilerClass,
        )

    postProcessor = PostProcessor(otf, ufo, glyphSet=glyphSet)
    otf = postProcessor.process(useProductionNames)

    return otf
Esempio n. 12
0
def compileOTF(
        ufo,
        preProcessorClass=OTFPreProcessor,
        outlineCompilerClass=OutlineOTFCompiler,
        featureCompilerClass=FeatureCompiler,
        kernWriterClass=None,  # deprecated
        markWriterClass=None,  # deprecated
        featureWriters=None,
        glyphOrder=None,
        useProductionNames=None,
        optimizeCFF=True,
        roundTolerance=None,
        removeOverlaps=False,
        inplace=False):
    """Create FontTools CFF font from a UFO.

    *removeOverlaps* performs a union operation on all the glyphs' contours.

    *optimizeCFF* sets whether the CFF table should be subroutinized.

    *roundTolerance* (float) controls the rounding of point coordinates.
      It is defined as the maximum absolute difference between the original
      float and the rounded integer value.
      By default, all floats are rounded to integer (tolerance 0.5); a value
      of 0 completely disables rounding; values in between only round floats
      which are close to their integral part within the tolerated range.

    *featureWriters* argument is a list of BaseFeatureWriter subclasses or
      pre-initialized instances. Features will be written by each feature
      writer in the given order. If featureWriters is None, the default
      feature writers [KernFeatureWriter, MarkFeatureWriter] are used.

    *useProductionNames* renames glyphs in TrueType 'post' or OpenType 'CFF '
      tables based on the 'public.postscriptNames' mapping in the UFO lib,
      if present. Otherwise, uniXXXX names are generated from the glyphs'
      unicode values. The default value (None) will first check if the UFO lib
      has the 'com.github.googlei18n.ufo2ft.useProductionNames' key. If this
      is missing or True (default), the glyphs are renamed. Set to False
      to keep the original names.
    """
    preProcessor = preProcessorClass(ufo,
                                     inplace=inplace,
                                     removeOverlaps=removeOverlaps)
    glyphSet = preProcessor.process()

    outlineCompiler = outlineCompilerClass(ufo,
                                           glyphSet=glyphSet,
                                           glyphOrder=glyphOrder,
                                           roundTolerance=roundTolerance)
    otf = outlineCompiler.compile()

    featureWriters = _replaceDeprecatedFeatureWriters(featureWriters,
                                                      kernWriterClass,
                                                      markWriterClass)
    featureCompiler = featureCompilerClass(ufo,
                                           otf,
                                           featureWriters=featureWriters,
                                           mtiFeatures=_getMtiFeatures(ufo))
    featureCompiler.compile()

    postProcessor = PostProcessor(otf, ufo)
    otf = postProcessor.process(useProductionNames, optimizeCFF)

    return otf