@@ -149,6 +149,9 @@ class Reference:
149149 def __init__ (self , id ):
150150 self .id = id
151151
152+ def __repr__ (self ):
153+ return "<Reference %d>" % self .id
154+
152155 def pdfRepr (self ):
153156 return "%d 0 R" % self .id
154157
@@ -167,6 +170,9 @@ def __init__(self, name):
167170 else :
168171 self .name = re .sub (r'[^!-~]' , Name .hexify , name )
169172
173+ def __repr__ (self ):
174+ return "<Name %s>" % self .name
175+
170176 def hexify (match ):
171177 return '#%02x' % ord (match .group ())
172178 hexify = staticmethod (hexify )
@@ -412,7 +418,8 @@ def embedTTF(self, filename):
412418
413419 font = FT2Font (filename )
414420
415- def convert (length , upe = font .units_per_EM , nearest = True ):
421+
422+ def cvt (length , upe = font .units_per_EM , nearest = True ):
416423 "Convert font coordinates to PDF glyph coordinates"
417424 value = length / upe * 1000
418425 if nearest : return round (value )
@@ -434,8 +441,7 @@ def convert(length, upe=font.units_per_EM, nearest=True):
434441 firstchar , lastchar = chars [0 ], chars [- 1 ]
435442
436443 # Get widths
437- widths = [ convert (font .load_char (i , flags = LOAD_NO_SCALE )
438- .horiAdvance )
444+ widths = [ cvt (font .load_char (i , flags = LOAD_NO_SCALE ).horiAdvance )
439445 for i in range (firstchar , lastchar + 1 ) ]
440446 # Remove redundant widths from end and beginning; doing the
441447 # end first helps reduce LastChar, which apparently needs to
@@ -448,21 +454,24 @@ def convert(length, upe=font.units_per_EM, nearest=True):
448454 firstchar += 1
449455 widths .pop (0 )
450456
457+ widthsObject = self .reserveObject ('font widths' )
458+ fontdescObject = self .reserveObject ('font descriptor' )
451459 fontdict = { 'Type' : Name ('Font' ),
452460 'Subtype' : Name ('TrueType' ),
461+ 'Encoding' : Name ('WinAnsiEncoding' ), # ???
453462 'BaseFont' : ps_name ,
454463 'FirstChar' : firstchar ,
455464 'LastChar' : lastchar ,
456- 'Widths' : self .reserveObject ('font widths' ),
457- 'FontDescriptor' :
458- self .reserveObject ('font descriptor' ) }
465+ 'Widths' : widthsObject ,
466+ 'FontDescriptor' : fontdescObject }
459467 # TODO: Encoding?
460468
461469 flags = 0
470+ symbolic = False #ps_name.name in ('Cmsy10', 'Cmmi10', 'Cmex10')
462471 if ff & FIXED_WIDTH : flags |= 1 << 0
463472 if 0 : flags |= 1 << 1 # TODO: serif
464- if 0 : flags |= 1 << 2 # TODO: symbolic
465- else : flags |= 1 << 5 # TODO: nonsymbolic
473+ if symbolic : flags |= 1 << 2
474+ else : flags |= 1 << 5
466475 if sf & ITALIC : flags |= 1 << 6
467476 if 0 : flags |= 1 << 16 # TODO: all caps
468477 if 0 : flags |= 1 << 17 # TODO: small caps
@@ -472,11 +481,11 @@ def convert(length, upe=font.units_per_EM, nearest=True):
472481 'Type' : Name ('FontDescriptor' ),
473482 'FontName' : ps_name ,
474483 'Flags' : flags ,
475- 'FontBBox' : [ convert (x , nearest = False ) for x in font .bbox ],
476- 'Ascent' : convert (font .ascender , nearest = False ),
477- 'Descent' : convert (font .descender , nearest = False ),
478- 'CapHeight' : convert (pclt ['capHeight' ], nearest = False ),
479- 'XHeight' : convert (pclt ['xHeight' ]),
484+ 'FontBBox' : [ cvt (x , nearest = False ) for x in font .bbox ],
485+ 'Ascent' : cvt (font .ascender , nearest = False ),
486+ 'Descent' : cvt (font .descender , nearest = False ),
487+ 'CapHeight' : cvt (pclt ['capHeight' ], nearest = False ),
488+ 'XHeight' : cvt (pclt ['xHeight' ]),
480489 'ItalicAngle' : post ['italicAngle' ][1 ], # ???
481490 'FontFile2' : self .reserveObject ('font file' ),
482491 'MaxWidth' : max (widths + [missingwidth ]),
@@ -490,11 +499,34 @@ def convert(length, upe=font.units_per_EM, nearest=True):
490499 # /FontFile (stream for type 1 font)
491500 # /CharSet (used when subsetting type1 fonts)
492501
502+ # Make an Identity-H encoded CID font for CM fonts? (Doesn't quite work)
503+ if False :
504+ del fontdict ['Widths' ], fontdict ['FontDescriptor' ], \
505+ fontdict ['LastChar' ], fontdict ['FirstChar' ]
506+
507+ fontdict ['Subtype' ] = Name ('Type0' )
508+ fontdict ['Encoding' ] = Name ('Identity-H' )
509+ fontdict2Object = self .reserveObject ('descendant font' )
510+ fontdict ['DescendantFonts' ] = [ fontdict2Object ]
511+ # TODO: fontdict['ToUnicode']
512+ fontdict2 = { 'Type' : Name ('Font' ),
513+ 'Subtype' : Name ('CIDFontType2' ),
514+ 'BaseFont' : ps_name ,
515+ 'W' : widthsObject ,
516+ 'DW' : missingwidth ,
517+ 'CIDSystemInfo' : { 'Registry' : 'Adobe' ,
518+ 'Ordering' : 'Identity' ,
519+ 'Supplement' : 0 },
520+ 'FontDescriptor' : fontdescObject }
521+ self .writeObject (fontdict2Object , fontdict2 )
522+
523+ widths = [ firstchar , widths ]
524+
493525 fontdictObject = self .reserveObject ('font dictionary' )
494526 length1Object = self .reserveObject ('decoded length of a font' )
495527 self .writeObject (fontdictObject , fontdict )
496- self .writeObject (fontdict [ 'Widths' ] , widths )
497- self .writeObject (fontdict [ 'FontDescriptor' ] , descriptor )
528+ self .writeObject (widthsObject , widths )
529+ self .writeObject (fontdescObject , descriptor )
498530 self .currentstream = \
499531 Stream (descriptor ['FontFile2' ].id ,
500532 self .reserveObject ('length of font stream' ),
@@ -809,18 +841,27 @@ def draw_mathtext(self, gc, x, y, s, prop, angle):
809841 for ox , oy , fontname , fontsize , glyph in pswriter :
810842 #print ox, oy, glyph
811843 fontname = fontname .lower ()
812- self ._setup_textpos (x + ox , y + oy , angle , oldx , oldy )
813- oldx , oldy = x + ox , y + oy
844+ a = angle / 180.0 * pi
845+ newx = x + cos (a )* ox - sin (a )* oy
846+ newy = y + sin (a )* ox + cos (a )* oy
847+ self ._setup_textpos (newx , newy , angle , oldx , oldy )
848+ oldx , oldy = newx , newy
814849 if (fontname , fontsize ) != prev_font :
815850 self .file .output (self .file .fontName (fontname ), fontsize ,
816851 Op .selectfont )
817852 prev_font = fontname , fontsize
818- self .file .output (chr (glyph ), Op .show )
853+
854+ #if fontname.endswith('cmsy10.ttf') or \
855+ #fontname.endswith('cmmi10.ttf') or \
856+ #fontname.endswith('cmex10.ttf'):
857+ # string = '\0' + chr(glyph)
858+
859+ string = chr (glyph )
860+ self .file .output (string , Op .show )
819861 self .file .output (Op .end_text )
820862
821863 def draw_text (self , gc , x , y , s , prop , angle , ismath = False ):
822864 # TODO: combine consecutive texts into one BT/ET delimited section
823- # mathtext
824865 # unicode
825866 if ismath : return self .draw_mathtext (gc , x , y , s , prop , angle )
826867 self .check_gc (gc , gc ._rgb )
@@ -838,13 +879,18 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False):
838879 self .file .output (s , Op .show , Op .end_text )
839880
840881 def get_text_width_height (self , s , prop , ismath ):
841- # TODO: mathtext
842882
843- font = self ._get_font_ttf (prop )
844- font .set_text (s , 0.0 )
845- w , h = font .get_width_height ()
846- factor = 1.0 / (self .dpi_factor * 64.0 )
847- return factor * w , factor * h
883+ if ismath :
884+ fontsize = prop .get_size_in_points ()
885+ w , h , pswriter = math_parse_s_pdf (s , self .file .dpi , fontsize )
886+ else :
887+ font = self ._get_font_ttf (prop )
888+ font .set_text (s , 0.0 )
889+ w , h = font .get_width_height ()
890+ factor = 1.0 / (self .dpi_factor * 64.0 )
891+ w *= factor
892+ h *= factor
893+ return w , h
848894
849895 def _get_font_ttf (self , prop ):
850896 font = self .fonts .get (prop )
0 commit comments