6
6
from __future__ import absolute_import , print_function , unicode_literals
7
7
8
8
# Change the script version when you edit this script:
9
- script_version = "4.15 .0"
9
+ script_version = "4.16 .0"
10
10
11
11
version = "3.2.1"
12
12
projectName = "Nerd Fonts"
@@ -964,6 +964,16 @@ class font_patcher:
964
964
# 0x2592: {'align': 'c', 'valign': 'c', 'stretch': 'xy', 'params': {'dont_copy': box_keep}},
965
965
# 0x2593: {'align': 'c', 'valign': 'c', 'stretch': 'xy', 'params': {'dont_copy': box_keep}},
966
966
}
967
+ SYM_ATTR_PROGRESS = {
968
+ 'default' : {'align' : 'c' , 'valign' : 'c' , 'stretch' : '^pa1!' , 'params' : {'overlap' : - 0.03 , 'careful' : True }}, # Cirles
969
+ # All the squares:
970
+ 0xee00 : {'align' : 'r' , 'valign' : 'c' , 'stretch' : '^xy' , 'params' : {'overlap' : 0.05 , 'careful' : True }},
971
+ 0xee01 : {'align' : 'c' , 'valign' : 'c' , 'stretch' : '^xy' , 'params' : {'overlap' : 0.10 , 'careful' : True }},
972
+ 0xee02 : {'align' : 'l' , 'valign' : 'c' , 'stretch' : '^xy' , 'params' : {'overlap' : 0.05 , 'careful' : True }},
973
+ 0xee03 : {'align' : 'r' , 'valign' : 'c' , 'stretch' : '^xy' , 'params' : {'overlap' : 0.05 , 'careful' : True }},
974
+ 0xee04 : {'align' : 'c' , 'valign' : 'c' , 'stretch' : '^xy' , 'params' : {'overlap' : 0.10 , 'careful' : True }},
975
+ 0xee05 : {'align' : 'l' , 'valign' : 'c' , 'stretch' : '^xy' , 'params' : {'overlap' : 0.05 , 'careful' : True }},
976
+ }
967
977
CUSTOM_ATTR = {
968
978
# previous custom scaling => do not touch the icons
969
979
# 'default': {'align': 'c', 'valign': '', 'stretch': '', 'params': {}}
@@ -983,9 +993,9 @@ class font_patcher:
983
993
# Shifting in addition to scaling can be selected too (see below).
984
994
# - ScaleGroups:
985
995
# Here you specify a group of glyphs that should be handled together
986
- # with the same scaling and shifting. The basis for it is a 'combined
987
- # bounding box' of all glyphs in that group. All glyphs are handled as
988
- # if they fill that combined bounding box.
996
+ # with the same scaling and shifting (see bottom) . The basis for it is
997
+ # a 'combined bounding box' of all glyphs in that group. All glyphs are
998
+ # handled as if they fill that combined bounding box.
989
999
# (- ScaleGroupsVert: Removed with this commit)
990
1000
#
991
1001
# The ScaleGlyph method: You set 'ScaleGlyph' to the unicode of the reference glyph.
@@ -1002,7 +1012,7 @@ class font_patcher:
1002
1012
#
1003
1013
# For the ScaleGroup method you define any number groups of glyphs and each group is
1004
1014
# handled separately. The combined bounding box of all glyphs in the group is determined
1005
- # and based on that the scale and shift for all the glyphs in the group.
1015
+ # and based on that the scale and shift (see bottom) for all the glyphs in the group.
1006
1016
# You define the groups as value of 'ScaleGroups'.
1007
1017
# It is a List of: ((lists of glyph codes) or (ranges of glyph codes))
1008
1018
# 'ScaleGroups': [
@@ -1013,15 +1023,21 @@ class font_patcher:
1013
1023
# See prepareScaleRules() for some more details.
1014
1024
# For historic reasons ScaleGroups is sometimes called 'new method' and ScaleGlyph 'old'.
1015
1025
# The codepoints mentioned here are symbol-font-codepoints.
1016
-
1017
- BOX_SCALE_LIST = {'ScaleGroups' : [
1026
+ #
1027
+ # Shifting:
1028
+ # If we have a combined bounding box stored in a range, that
1029
+ # box is used to align all symbols in the range identically.
1030
+ # - If the symbol font is proportinal only the v alignment is synced.
1031
+ # - If the symbol font is monospaced v and h alignemnts are synced.
1032
+ # To make sure the behavior is as expected you are required to set a ShiftMode property
1033
+ # accordingly. It just checks, you can not (!) select what is done with that property.
1034
+
1035
+ BOX_SCALE_LIST = {'ShiftMode' : 'xy' , 'ScaleGroups' : [
1018
1036
[* range (0x2500 , 0x2570 + 1 ), * range (0x2574 , 0x257f + 1 )], # box drawing
1019
1037
range (0x2571 , 0x2573 + 1 ), # diagonals
1020
- [* range (0x2580 , 0x2590 + 1 ), 0x2594 , 0x2595 ], # blocks
1021
- range (0x2591 , 0x2593 + 1 ), # greys
1022
- range (0x2594 , 0x259f + 1 ), # quards (Note: quard 2597 in Hack is wrong, scales like block!)
1038
+ range (0x2580 , 0x259f + 1 ), # blocks and greys (greys are less tall originally, so overlap will be less)
1023
1039
]}
1024
- CODI_SCALE_LIST = {'ScaleGroups' : [
1040
+ CODI_SCALE_LIST = {'ShiftMode' : 'xy' , ' ScaleGroups' : [
1025
1041
[0xea61 , 0xeb13 ], # lightbulb
1026
1042
range (0xeab4 , 0xeab7 + 1 ), # chevrons
1027
1043
[0xea7d , * range (0xea99 , 0xeaa1 + 1 ), 0xebcb ], # arrows
@@ -1033,7 +1049,7 @@ class font_patcher:
1033
1049
range (0xebd5 , 0xebd7 + 1 ), # compasses
1034
1050
]}
1035
1051
DEVI_SCALE_LIST = None
1036
- FONTA_SCALE_LIST = {'ScaleGroups' : [
1052
+ FONTA_SCALE_LIST = {'ShiftMode' : '' , ' ScaleGroups' : [
1037
1053
[0xf005 , 0xf006 , 0xf089 ], # star, star empty, half star
1038
1054
range (0xf026 , 0xf028 + 1 ), # volume off, down, up
1039
1055
range (0xf02b , 0xf02c + 1 ), # tag, tags
@@ -1054,11 +1070,11 @@ class font_patcher:
1054
1070
range (0xf221 , 0xf22d + 1 ), # gender or so
1055
1071
range (0xf255 , 0xf25b + 1 ), # hand symbols
1056
1072
]}
1057
- HEAVY_SCALE_LIST = {'ScaleGlyph' : 0x2771 , # widest bracket, horizontally
1073
+ HEAVY_SCALE_LIST = {'ShiftMode' : 'y' , ' ScaleGlyph' : 0x2771 , # widest bracket, horizontally
1058
1074
'GlyphsToScale' : [
1059
1075
(0x276c , 0x2771 ) # all
1060
1076
]}
1061
- OCTI_SCALE_LIST = {'ScaleGroups' : [
1077
+ OCTI_SCALE_LIST = {'ShiftMode' : '' , ' ScaleGroups' : [
1062
1078
[* range (0xf03d , 0xf040 + 1 ), 0xf019 , 0xf030 , 0xf04a , 0xf051 , 0xf071 , 0xf08c ], # arrows
1063
1079
[0xF0E7 , # Smily and ...
1064
1080
0xf044 , 0xf05a , 0xf05b , 0xf0aa , # triangles
@@ -1070,7 +1086,11 @@ class font_patcher:
1070
1086
range (0xf2c2 , 0xf2c5 + 1 ), # move to
1071
1087
[0xf07b , 0xf0a1 , 0xf0d6 , 0xf306 ], # bookmarks
1072
1088
]}
1073
- WEATH_SCALE_LIST = {'ScaleGroups' : [
1089
+ PROGR_SCALE_LIST = {'ShiftMode' : 'xy' , 'ScaleGroups' : [
1090
+ range (0xedff , 0xee05 + 1 ), # boxes... with helper glyph for Y padding
1091
+ range (0xee06 , 0xee0b + 1 ), # circles
1092
+ ]}
1093
+ WEATH_SCALE_LIST = {'ShiftMode' : '' , 'ScaleGroups' : [
1074
1094
[0xf03c , 0xf042 , 0xf045 ], # degree signs
1075
1095
[0xf043 , 0xf044 , 0xf048 , 0xf04b , 0xf04c , 0xf04d , 0xf057 , 0xf058 , 0xf087 , 0xf088 ], # arrows
1076
1096
range (0xf053 , 0xf055 + 1 ), # thermometers
@@ -1104,6 +1124,7 @@ class font_patcher:
1104
1124
{'Enabled' : True , 'Name' : "Seti-UI + Custom" , 'Filename' : "original-source.otf" , 'Exact' : False , 'SymStart' : 0xE4FA , 'SymEnd' : 0xE5FF , 'SrcStart' : 0xE5FA , 'ScaleRules' : None , 'Attributes' : SYM_ATTR_DEFAULT },
1105
1125
{'Enabled' : True , 'Name' : "Heavy Angle Brackets" , 'Filename' : "extraglyphs.sfd" , 'Exact' : True , 'SymStart' : 0x276C , 'SymEnd' : 0x2771 , 'SrcStart' : None , 'ScaleRules' : HEAVY_SCALE_LIST , 'Attributes' : SYM_ATTR_HEAVYBRACKETS },
1106
1126
{'Enabled' : box_enabled , 'Name' : "Box Drawing" , 'Filename' : "extraglyphs.sfd" , 'Exact' : True , 'SymStart' : 0x2500 , 'SymEnd' : 0x259F , 'SrcStart' : None , 'ScaleRules' : BOX_SCALE_LIST , 'Attributes' : SYM_ATTR_BOX },
1127
+ {'Enabled' : True , 'Name' : "Progress Indicators" , 'Filename' : "extraglyphs.sfd" , 'Exact' : True , 'SymStart' : 0xEE00 , 'SymEnd' : 0xEE0B , 'SrcStart' : None , 'ScaleRules' : PROGR_SCALE_LIST , 'Attributes' : SYM_ATTR_PROGRESS },
1107
1128
{'Enabled' : True , 'Name' : "Devicons" , 'Filename' : "devicons/devicons.ttf" , 'Exact' : False , 'SymStart' : 0xE600 , 'SymEnd' : 0xE7E3 , 'SrcStart' : 0xE700 , 'ScaleRules' : DEVI_SCALE_LIST , 'Attributes' : SYM_ATTR_DEFAULT },
1108
1129
{'Enabled' : self .args .powerline , 'Name' : "Powerline Symbols" , 'Filename' : "powerline-symbols/PowerlineSymbols.otf" , 'Exact' : True , 'SymStart' : 0xE0A0 , 'SymEnd' : 0xE0A2 , 'SrcStart' : None , 'ScaleRules' : None , 'Attributes' : SYM_ATTR_POWERLINE },
1109
1130
{'Enabled' : self .args .powerline , 'Name' : "Powerline Symbols" , 'Filename' : "powerline-symbols/PowerlineSymbols.otf" , 'Exact' : True , 'SymStart' : 0xE0B0 , 'SymEnd' : 0xE0B3 , 'SrcStart' : None , 'ScaleRules' : None , 'Attributes' : SYM_ATTR_POWERLINE },
@@ -1344,25 +1365,29 @@ class font_patcher:
1344
1365
return 1
1345
1366
return 2
1346
1367
1347
- def get_scale_factors (self , sym_dim , stretch ):
1368
+ def get_scale_factors (self , sym_dim , stretch , overlap = None ):
1348
1369
""" Get scale in x and y as tuple """
1349
1370
# It is possible to have empty glyphs, so we need to skip those.
1350
1371
if not sym_dim ['width' ] or not sym_dim ['height' ]:
1351
1372
return (1.0 , 1.0 )
1352
1373
1353
1374
target_width = self .font_dim ['width' ] * self .get_target_width (stretch )
1375
+ if overlap :
1376
+ target_width += self .font_dim ['width' ] * overlap
1354
1377
scale_ratio_x = target_width / sym_dim ['width' ]
1355
1378
1356
1379
# font_dim['height'] represents total line height, keep our symbols sized based upon font's em
1357
1380
# Use the font_dim['height'] only for explicit 'y' scaling (not 'pa')
1358
1381
target_height = self .font_dim ['height' ] if '^' in stretch else self .font_dim ['iconheight' ]
1359
1382
target_height *= 1.0 - self .font_dim ['ypadding' ]
1383
+ if overlap :
1384
+ target_height *= 1.0 + min (0.01 , overlap ) # never aggressive vertical overlap
1360
1385
scale_ratio_y = target_height / sym_dim ['height' ]
1361
1386
1362
1387
if 'pa' in stretch :
1363
1388
# We want to preserve x/y aspect ratio, so find biggest scale factor that allows symbol to fit
1364
1389
scale_ratio_x = min (scale_ratio_x , scale_ratio_y )
1365
- if not self .args .single and not '!' in stretch :
1390
+ if not self .args .single and not '!' in stretch and not overlap :
1366
1391
# non monospaced fonts just scale down on 'pa', not up
1367
1392
scale_ratio_x = min (scale_ratio_x , 1.0 )
1368
1393
scale_ratio_y = scale_ratio_x
@@ -1502,25 +1527,26 @@ class font_patcher:
1502
1527
1503
1528
# Prepare symbol glyph dimensions
1504
1529
sym_dim = get_glyph_dimensions (self .sourceFont [currentSourceFontGlyph ])
1530
+ overlap = sym_attr ['params' ].get ('overlap' )
1531
+ if overlap and ypadding :
1532
+ logger .critical ("Conflicting params: overlap and ypadding" )
1533
+ sys .exit (1 )
1534
+
1505
1535
if glyph_scale_data is not None :
1506
1536
if glyph_scale_data [1 ] is not None :
1507
1537
sym_dim = glyph_scale_data [1 ] # Use combined bounding box
1508
- (scale_ratio_x , scale_ratio_y ) = self .get_scale_factors (sym_dim , stretch )
1538
+ (scale_ratio_x , scale_ratio_y ) = self .get_scale_factors (sym_dim , stretch , overlap )
1509
1539
else :
1510
1540
# This is roughly alike get_scale_factors(glyph_scale_data[1], 'pa')
1511
1541
# Except we do not have glyph_scale_data[1] always...
1512
1542
(scale_ratio_x , scale_ratio_y ) = (glyph_scale_data [0 ], glyph_scale_data [0 ])
1543
+ if overlap :
1544
+ scale_ratio_x *= 1.0 + (self .font_dim ['width' ] / (sym_dim ['width' ] * scale_ratio_x )) * overlap
1545
+ y_overlap = min (0.01 , overlap ) # never aggressive vertical overlap
1546
+ scale_ratio_y *= 1.0 + (self .font_dim ['height' ] / (sym_dim ['height' ] * scale_ratio_y )) * y_overlap
1513
1547
else :
1514
- (scale_ratio_x , scale_ratio_y ) = self .get_scale_factors (sym_dim , stretch )
1548
+ (scale_ratio_x , scale_ratio_y ) = self .get_scale_factors (sym_dim , stretch , overlap )
1515
1549
1516
- overlap = sym_attr ['params' ].get ('overlap' )
1517
- if overlap and ypadding :
1518
- logger .critical ("Conflicting params: overlap and ypadding" )
1519
- sys .exit (1 )
1520
- if overlap :
1521
- scale_ratio_x *= 1.0 + (self .font_dim ['width' ] / (sym_dim ['width' ] * scale_ratio_x )) * overlap
1522
- y_overlap = min (0.01 , overlap ) # never aggressive vertical overlap
1523
- scale_ratio_y *= 1.0 + (self .font_dim ['height' ] / (sym_dim ['height' ] * scale_ratio_y )) * y_overlap
1524
1550
1525
1551
# Size in x to size in y ratio limit (to prevent over-wide glyphs)
1526
1552
xy_ratio_max = sym_attr ['params' ].get ('xy-ratio' )
@@ -1567,15 +1593,17 @@ class font_patcher:
1567
1593
elif sym_attr ['align' ] == 'r' :
1568
1594
# Right align
1569
1595
x_align_distance += self .font_dim ['width' ] * self .get_target_width (stretch ) - sym_dim ['width' ]
1570
- # If symbol glyph is wider than target font cell, just left-align
1571
- x_align_distance = max (self .font_dim ['xmin' ] - sym_dim ['xmin' ], x_align_distance )
1596
+ if not overlap :
1597
+ # If symbol glyph is wider than target font cell, just left-align
1598
+ x_align_distance = max (self .font_dim ['xmin' ] - sym_dim ['xmin' ], x_align_distance )
1572
1599
1573
1600
if overlap :
1574
1601
overlap_width = self .font_dim ['width' ] * overlap
1575
1602
if sym_attr ['align' ] == 'l' :
1576
1603
x_align_distance -= overlap_width
1577
1604
elif sym_attr ['align' ] == 'c' :
1578
- if overlap_width > 0 :
1605
+ # center aligned keeps being center aligned even with overlap
1606
+ if overlap_width < 0 and self .args .nonmono and sym_dim ['advance' ] is None : # Keep positive bearing due to negative overlap (propo)
1579
1607
x_align_distance -= overlap_width / 2
1580
1608
elif sym_attr ['align' ] == 'r' and not self .args .nonmono :
1581
1609
# Check and correct overlap; it can go wrong if we have a xy-ratio limit
@@ -1609,7 +1637,7 @@ class font_patcher:
1609
1637
else :
1610
1638
width = sym_dim ['width' ]
1611
1639
# If we have overlap we need to subtract that to keep/get negative bearings
1612
- if overlap and ( sym_attr [ 'align' ] == 'l' or sym_attr [ 'align' ] == 'r' ) :
1640
+ if overlap :
1613
1641
width -= overlap_width
1614
1642
# Fontforge handles the width change like this:
1615
1643
# - Keep existing left_side_bearing
@@ -1707,11 +1735,21 @@ class font_patcher:
1707
1735
scaleRules ['bbdims' ] = []
1708
1736
if 'ScaleGroups' not in scaleRules :
1709
1737
scaleRules ['ScaleGroups' ] = []
1738
+
1739
+ mode = scaleRules ['ShiftMode' ] # Mode is only documentary
1710
1740
for group in scaleRules ['ScaleGroups' ]:
1711
1741
sym_dim = get_multiglyph_boundingBox ([ symbolFont [g ] if g in symbolFont else None for g in group ], destGlyph )
1712
1742
scale = self .get_scale_factors (sym_dim , stretch )[0 ]
1713
1743
scaleRules ['scales' ].append (scale )
1714
1744
scaleRules ['bbdims' ].append (sym_dim )
1745
+ if (mode ):
1746
+ if ('x' in mode ) != (sym_dim ['advance' ] is not None ):
1747
+ d = '0x{:X} - 0x{:X}' .format (group [0 ], group [- 1 ])
1748
+ if ('x' in mode ) :
1749
+ logger .critical ("Scaling in group %s is expected to do horizonal shifts but can not" , d )
1750
+ else :
1751
+ logger .critical ("Scaling in group %s is expected to not do horizonal shifts but will" , d )
1752
+ sys .exit (1 )
1715
1753
1716
1754
if 'ScaleGlyph' in scaleRules :
1717
1755
# Rewrite to equivalent ScaleGroup
0 commit comments