20
20
from io import BytesIO
21
21
22
22
import numpy as np
23
+
24
+ import freetypy as ft
25
+
23
26
from matplotlib .externals .six import unichr
24
27
25
28
39
42
from matplotlib .afm import AFM
40
43
import matplotlib .type1font as type1font
41
44
import matplotlib .dviread as dviread
42
- from matplotlib .ft2font import (FIXED_WIDTH , ITALIC , LOAD_NO_SCALE ,
43
- LOAD_NO_HINTING , KERNING_UNFITTED )
44
45
from matplotlib .mathtext import MathTextParser
45
46
from matplotlib .transforms import Affine2D , BboxBase
46
47
from matplotlib .path import Path
@@ -757,16 +758,16 @@ def createType1Descriptor(self, t1font, fontfile):
757
758
if 0 :
758
759
flags |= 1 << 18
759
760
760
- ft2font = get_font (fontfile )
761
+ font = get_font (fontfile )
761
762
762
763
descriptor = {
763
764
'Type' : Name ('FontDescriptor' ),
764
765
'FontName' : Name (t1font .prop ['FontName' ]),
765
766
'Flags' : flags ,
766
- 'FontBBox' : ft2font .bbox ,
767
+ 'FontBBox' : font .bbox ,
767
768
'ItalicAngle' : italic_angle ,
768
- 'Ascent' : ft2font .ascender ,
769
- 'Descent' : ft2font .descender ,
769
+ 'Ascent' : font .ascender ,
770
+ 'Descent' : font .descender ,
770
771
'CapHeight' : 1000 , # TODO: find this out
771
772
'XHeight' : 500 , # TODO: this one too
772
773
'FontFile' : fontfileObject ,
@@ -820,7 +821,7 @@ def embedTTF(self, filename, characters):
820
821
font = get_font (filename )
821
822
fonttype = rcParams ['pdf.fonttype' ]
822
823
823
- def cvt (length , upe = font .units_per_EM , nearest = True ):
824
+ def cvt (length , upe = font .units_per_em , nearest = True ):
824
825
"Convert font coordinates to PDF glyph coordinates"
825
826
value = length / upe * 1000
826
827
if nearest :
@@ -840,7 +841,7 @@ def embedTTFType3(font, characters, descriptor):
840
841
charprocsObject = self .reserveObject ('character procs' )
841
842
differencesArray = []
842
843
firstchar , lastchar = 0 , 255
843
- bbox = [cvt (x , nearest = False ) for x in font .bbox ]
844
+ bbox = [cvt (x * 64.0 , nearest = False ) for x in font .bbox ]
844
845
845
846
fontdict = {
846
847
'Type' : Name ('Font' ),
@@ -861,20 +862,16 @@ def embedTTFType3(font, characters, descriptor):
861
862
862
863
# Make the "Widths" array
863
864
from encodings import cp1252
864
- # The "decoding_map" was changed
865
- # to a "decoding_table" as of Python 2.5.
866
- if hasattr (cp1252 , 'decoding_map' ):
867
- def decode_char (charcode ):
868
- return cp1252 .decoding_map [charcode ] or 0
869
- else :
870
- def decode_char (charcode ):
871
- return ord (cp1252 .decoding_table [charcode ])
865
+
866
+ def decode_char (charcode ):
867
+ return ord (cp1252 .decoding_table [charcode ])
872
868
873
869
def get_char_width (charcode ):
874
870
s = decode_char (charcode )
875
- width = font .load_char (
876
- s , flags = LOAD_NO_SCALE | LOAD_NO_HINTING ).horiAdvance
877
- return cvt (width )
871
+ glyph = font .load_char_unicode (
872
+ s , load_flags = ft .LOAD .NO_SCALE | ft .LOAD .NO_HINTING )
873
+ width = glyph .linear_hori_advance
874
+ return cvt (width * 64.0 * 2 )
878
875
879
876
widths = [get_char_width (charcode )
880
877
for charcode in range (firstchar , lastchar + 1 )]
@@ -886,11 +883,10 @@ def get_char_width(charcode):
886
883
glyph_ids = []
887
884
differences = []
888
885
multi_byte_chars = set ()
889
- for c in characters :
890
- ccode = c
891
- gind = font .get_char_index (ccode )
886
+ for ccode in characters :
887
+ gind = font .get_char_index_unicode (ccode )
892
888
glyph_ids .append (gind )
893
- glyph_name = font .get_glyph_name ( gind )
889
+ glyph_name = font .get_char_name ( ccode )
894
890
if ccode <= 255 :
895
891
differences .append ((ccode , glyph_name ))
896
892
else :
@@ -1000,11 +996,10 @@ def embedTTFType42(font, characters, descriptor):
1000
996
cid_to_gid_map = ['\u0000 ' ] * 65536
1001
997
widths = []
1002
998
max_ccode = 0
1003
- for c in characters :
1004
- ccode = c
1005
- gind = font .get_char_index (ccode )
1006
- glyph = font .load_char (ccode , flags = LOAD_NO_HINTING )
1007
- widths .append ((ccode , glyph .horiAdvance / 6 ))
999
+ for ccode in characters :
1000
+ gind = font .get_char_index_unicode (ccode )
1001
+ glyph = font .load_char_unicode (ccode , load_flags = ft .LOAD .NO_HINTING )
1002
+ widths .append ((ccode , glyph .linear_hori_advance * 64. ))
1008
1003
if ccode < 65536 :
1009
1004
cid_to_gid_map [ccode ] = unichr (gind )
1010
1005
max_ccode = max (ccode , max_ccode )
@@ -1064,31 +1059,30 @@ def embedTTFType42(font, characters, descriptor):
1064
1059
# Beginning of main embedTTF function...
1065
1060
1066
1061
# You are lost in a maze of TrueType tables, all different...
1067
- sfnt = font .get_sfnt ()
1068
- try :
1069
- ps_name = sfnt [(1 , 0 , 0 , 6 )].decode ('macroman' ) # Macintosh scheme
1070
- except KeyError :
1071
- # Microsoft scheme:
1072
- ps_name = sfnt [(3 , 1 , 0x0409 , 6 )].decode ('utf-16be' )
1073
- # (see freetype/ttnameid.h)
1074
- ps_name = ps_name .encode ('ascii' , 'replace' )
1062
+ ps_name = font .get_postscript_name ()
1075
1063
ps_name = Name (ps_name )
1076
- pclt = font .get_sfnt_table ('pclt' ) or {'capHeight' : 0 , 'xHeight' : 0 }
1077
- post = font .get_sfnt_table ('post' ) or {'italicAngle' : (0 , 0 )}
1064
+ if hasattr (font , 'tt_pclt' ):
1065
+ pclt = font .tt_pclt
1066
+ else :
1067
+ pclt = Bunch (cap_height = 0 , x_height = 0 )
1068
+ if hasattr (font , 'tt_postscript' ):
1069
+ post = font .tt_postscript
1070
+ else :
1071
+ post = Bunch (italicAngle = 0 )
1078
1072
ff = font .face_flags
1079
1073
sf = font .style_flags
1080
1074
1081
1075
flags = 0
1082
1076
symbolic = False # ps_name.name in ('Cmsy10', 'Cmmi10', 'Cmex10')
1083
- if ff & FIXED_WIDTH :
1077
+ if ff & ft . FACE_FLAG . FIXED_WIDTH :
1084
1078
flags |= 1 << 0
1085
1079
if 0 : # TODO: serif
1086
1080
flags |= 1 << 1
1087
1081
if symbolic :
1088
1082
flags |= 1 << 2
1089
1083
else :
1090
1084
flags |= 1 << 5
1091
- if sf & ITALIC :
1085
+ if sf & ft . STYLE_FLAG . ITALIC :
1092
1086
flags |= 1 << 6
1093
1087
if 0 : # TODO: all caps
1094
1088
flags |= 1 << 16
@@ -1104,9 +1098,9 @@ def embedTTFType42(font, characters, descriptor):
1104
1098
'FontBBox' : [cvt (x , nearest = False ) for x in font .bbox ],
1105
1099
'Ascent' : cvt (font .ascender , nearest = False ),
1106
1100
'Descent' : cvt (font .descender , nearest = False ),
1107
- 'CapHeight' : cvt (pclt [ 'capHeight' ] , nearest = False ),
1108
- 'XHeight' : cvt (pclt [ 'xHeight' ] ),
1109
- 'ItalicAngle' : post [ 'italicAngle' ][ 1 ] , # ???
1101
+ 'CapHeight' : cvt (pclt . cap_height , nearest = False ),
1102
+ 'XHeight' : cvt (pclt . x_height ),
1103
+ 'ItalicAngle' : post . italic_angle , # ???
1110
1104
'StemV' : 0 # ???
1111
1105
}
1112
1106
@@ -1570,7 +1564,7 @@ def track_characters(self, font, s):
1570
1564
if isinstance (font , six .string_types ):
1571
1565
fname = font
1572
1566
else :
1573
- fname = font .fname
1567
+ fname = font .filename
1574
1568
realpath , stat_key = get_realpath_and_stat (fname )
1575
1569
used_characters = self .file .used_characters .setdefault (
1576
1570
stat_key , (realpath , set ()))
@@ -1959,13 +1953,13 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
1959
1953
else :
1960
1954
font = self ._get_font_ttf (prop )
1961
1955
self .track_characters (font , s )
1962
- font . set_text ( s , 0.0 , flags = LOAD_NO_HINTING )
1956
+ layout = ft . Layout ( font , s , load_flags = ft . LOAD . NO_HINTING )
1963
1957
1964
1958
fonttype = rcParams ['pdf.fonttype' ]
1965
1959
1966
1960
# We can't subset all OpenType fonts, so switch to Type 42
1967
1961
# in that case.
1968
- if is_opentype_cff_font (font .fname ):
1962
+ if is_opentype_cff_font (font .filename ):
1969
1963
fonttype = 42
1970
1964
1971
1965
def check_simple_method (s ):
@@ -2037,30 +2031,30 @@ def draw_text_woven(chunks):
2037
2031
lastgind = None
2038
2032
for c in chunk :
2039
2033
ccode = ord (c )
2040
- gind = font .get_char_index (ccode )
2034
+ gind = font .get_char_index_unicode (ccode )
2041
2035
if gind is not None :
2042
2036
if mode == 2 and chunk_type == 2 :
2043
- glyph_name = font .get_glyph_name ( gind )
2037
+ glyph_name = font .get_char_name ( ccode )
2044
2038
self .file .output (Op .gsave )
2045
2039
self .file .output (0.001 * fontsize , 0 ,
2046
2040
0 , 0.001 * fontsize ,
2047
2041
newx , 0 , Op .concat_matrix )
2048
2042
name = self .file ._get_xobject_symbol_name (
2049
- font .fname , glyph_name )
2043
+ font .filename , glyph_name )
2050
2044
self .file .output (Name (name ), Op .use_xobject )
2051
2045
self .file .output (Op .grestore )
2052
2046
2053
2047
# Move the pointer based on the character width
2054
2048
# and kerning
2055
- glyph = font .load_char (ccode ,
2056
- flags = LOAD_NO_HINTING )
2049
+ # glyph = font.load_char_unicode(ccode, flags=ft.LOAD.NO_HINTING)
2057
2050
if lastgind is not None :
2058
2051
kern = font .get_kerning (
2059
- lastgind , gind , KERNING_UNFITTED )
2052
+ lastgind , gind , ft . KERNING . UNFITTED ). x
2060
2053
else :
2061
2054
kern = 0
2062
2055
lastgind = gind
2063
- newx += kern / 64.0 + glyph .linearHoriAdvance / 65536.0
2056
+ glyph = font .load_glyph (gind , load_flags = ft .LOAD .NO_HINTING )
2057
+ newx += kern + glyph .linear_hori_advance
2064
2058
2065
2059
if mode == 1 :
2066
2060
self .file .output (Op .end_text )
@@ -2094,13 +2088,10 @@ def get_text_width_height_descent(self, s, prop, ismath):
2094
2088
d *= scale / 1000
2095
2089
else :
2096
2090
font = self ._get_font_ttf (prop )
2097
- font .set_text (s , 0.0 , flags = LOAD_NO_HINTING )
2098
- w , h = font .get_width_height ()
2099
- scale = (1.0 / 64.0 )
2100
- w *= scale
2101
- h *= scale
2102
- d = font .get_descent ()
2103
- d *= scale
2091
+ layout = ft .Layout (font , s , load_flags = ft .LOAD .NO_HINTING )
2092
+ w = layout .ink_bbox .width
2093
+ h = layout .ink_bbox .height
2094
+ d = layout .ink_bbox .y_min
2104
2095
return w , h , d
2105
2096
2106
2097
def _get_font_afm (self , prop ):
@@ -2124,8 +2115,8 @@ def _get_font_afm(self, prop):
2124
2115
def _get_font_ttf (self , prop ):
2125
2116
filename = findfont (prop )
2126
2117
font = get_font (filename )
2127
- font .clear ()
2128
- font . set_size ( prop . get_size_in_points () , 72 )
2118
+ font .set_char_size ( prop . get_size_in_points (), prop . get_size_in_points (),
2119
+ 72 , 72 )
2129
2120
return font
2130
2121
2131
2122
def flipy (self ):
0 commit comments