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

fonttools subset performance #2147

Closed
Jijun opened this issue Jan 14, 2021 · 1 comment
Closed

fonttools subset performance #2147

Jijun opened this issue Jan 14, 2021 · 1 comment

Comments

@Jijun
Copy link

Jijun commented Jan 14, 2021

hi,
i want use fonttools to subbset our chinese truetype fonts, but i found it is so slowly for realtime web request.
the flavor are woff and woff2 for webpage。some code snippets as below:

from fontTools.subset import Options, Subsetter
from fontTools.ttLib import TTFont
import io

drop_tables_extra = ['GSUB', 'prep', 'vhea', 'vmtx', 'FFTM', 'GDEF', 'GPOS', 'kern', 'hdmx', 'VDMX', 'LTSH', 'DSIG', 'EBLC', 'EBDT', 'morx', 'mort']

from enum import Enum
class TTFormat(str, Enum):
    woff = "woff"
    woff2 = "woff2"
    ttf = "ttf"
fontDir='/tmp'
def subset_font(fontFamily: str, text : str, format : TTFormat):
    
    fontPath = f"{fontDir}/{fontFamily}.ttf"
    options = Options()
    options.flavor = format
    #options.desubroutinize = True
    options.hinting = False
    options.drop_tables += drop_tables_extra
    try:
        font = TTFont(fontPath, recalcTimestamp=False, lazy=False)
        subset_font = font
        if format ==TTFormat.woff or format == TTFormat.woff2:
            subset_font.flavor = format
            
        subsetter = Subsetter(options = options)
        subsetter.populate(text = text)
        subsetter.subset(subset_font)

        return subset_font
    except FileNotFoundError:
        pass
    except AssertionError:
        pass
    return None

if __name__ == '__main__' :
    font = subset_font('fangzheng_ktjt', 'Javatest', 'woff2')
    if font:
        buf = io.BytesIO()
        font.save(buf)
        buf.seek(0)
        print(buf)
        font.close()

so i use cProfile to find the problem.

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000   19.195   19.195 FontService.py:22(subset_font)
        1    0.000    0.000   19.192   19.192 __init__.py:2720(subset)
    26/18    0.000    0.000   19.166    1.065 ttFont.py:369(__getitem__)
        1    0.000    0.000   19.163   19.163 __init__.py:2500(_prune_pre_subset)
        1    0.030    0.030   19.157   19.157 _g_l_y_f.py:57(decompile)
     8107    0.040    0.000   19.059    0.002 _g_l_y_f.py:531(expand)
     8100    1.156    0.000   18.909    0.002 _g_l_y_f.py:692(decompileCoordinates)
  3628674    3.245    0.000   12.489    0.000 _g_l_y_f.py:1452(_checkFloat)
  2419116    1.784    0.000   10.414    0.000 _g_l_y_f.py:1482(__setitem__)
  7257349    4.079    0.000    8.544    0.000 {built-in method builtins.any}
     8100    0.558    0.000    5.778    0.001 _g_l_y_f.py:1517(relativeToAbsolute)
     8100    0.016    0.000    5.044    0.001 _g_l_y_f.py:1464(zeros)
     8100    0.011    0.000    5.028    0.001 _g_l_y_f.py:1435(__init__)
     8100    0.486    0.000    5.017    0.001 _g_l_y_f.py:1504(extend)
 10886022    2.074    0.000    2.906    0.000 _g_l_y_f.py:1458(<genexpr>)
 10886022    1.558    0.000    1.558    0.000 _g_l_y_f.py:1455(<genexpr>)
     8100    1.156    0.000    1.537    0.000 _g_l_y_f.py:746(decompileCoordinatesRaw)
 10974219    1.227    0.000    1.227    0.000 {built-in method builtins.isinstance}
  3628674    0.700    0.000    0.700    0.000 _g_l_y_f.py:1443(isFloat)
  1209558    0.379    0.000    0.379    0.000 {method 'extend' of 'array.array' objects}
  1209566    0.233    0.000    0.325    0.000 py23.py:65(byteord)
  1217658    0.173    0.000    0.173    0.000 _g_l_y_f.py:744(<genexpr>)
     8129    0.016    0.000    0.103    0.000 sstruct.py:101(unpack2)

you can see some truetype check use most of the time.

anyone know how to optimze it? thanks.
fangzheng_ktjt.ttf.zip
.

@justvanrossum
Copy link
Collaborator

I would suggest to try hb-subset instead (part of the HarfBuzz project). (I haven't used it myself, and I'm assuming it has similar functionality, yet it's written in C++, so should be a lot faster.)

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

No branches or pull requests

3 participants