Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1"""Module to get fontwidth.""" 

2import os 

3import json 

4import numpy as np 

5from io import open 

6import pandas as pd 

7 

8 

9def abs_path(): 

10 """Retutn absolute path.""" 

11 return os.path.dirname(os.path.abspath(__file__)) 

12 

13 

14def fontwidth(string, font='sans-serif'): 

15 """Function: Returns the px width of a string assuming a base size of 16px.""" 

16 _fontwidth = json.load(open(os.path.join(abs_path(), 'fonts.json'), encoding='utf-8')) 

17 codes_len = 127 

18 default_width = 32 

19 default_width_idx = 120 

20 for _fontrow in _fontwidth: 

21 _fontrow['widths'] = pd.np.array(_fontrow['widths'], dtype=float) 

22 _fontrow['widths'] = pd.np.insert(_fontrow['widths'], 0, np.zeros(default_width)) 

23 

24 # Add the first font stack at the end, making it the default 

25 _fontwidth.append(_fontwidth[0]) 

26 # Convert all characters to ASCII codes. Treat Unicode as single char 

27 codes = pd.np.fromstring(string.encode('ascii', 'replace'), dtype=pd.np.uint8) 

28 # Drop everything that's out of bounds. We'll adjust for them later 

29 valid = codes[codes < codes_len] 

30 # Get the font 

31 for row in _fontwidth: 31 ↛ 35line 31 didn't jump to line 35, because the loop on line 31 didn't complete

32 if font in row['family']: 32 ↛ 31line 32 didn't jump to line 31, because the condition on line 32 was never false

33 break 

34 # Compute and return the width, defaulting unknowns to 'x' (char 120) 

35 widths = row['widths'] 

36 return widths[valid].sum() + widths[default_width_idx] * (len(codes) - len(valid))