@@ -4507,11 +4507,21 @@ var Type1Parser = function type1Parser() {
4507
4507
return args ;
4508
4508
}
4509
4509
4510
+ // Remove the same number of args from the stack that are in the args
4511
+ // parameter. Args should be built from breakUpArgs().
4512
+ function popArgs (stack , args ) {
4513
+ for (var i = 0 , ii = args .length ; i < ii ; i ++) {
4514
+ for (var j = 0 , jj = args [i ].arg .length ; j < jj ; j ++) {
4515
+ stack .pop ();
4516
+ }
4517
+ }
4518
+ }
4519
+
4510
4520
function decodeCharString (array ) {
4511
4521
var charstring = [];
4512
4522
var lsb = 0 ;
4513
4523
var width = 0 ;
4514
- var flexState = 0 ;
4524
+ var flexing = false ;
4515
4525
4516
4526
var value = '';
4517
4527
var count = array .length ;
@@ -4595,27 +4605,60 @@ var Type1Parser = function type1Parser() {
4595
4605
continue ;
4596
4606
} else if (value == 10 ) { // callsubr
4597
4607
if (charstring [charstring .length - 1 ] < 3 ) { // subr #0..2
4608
+ // XXX: According to the spec if flex or hinting is not used then
4609
+ // subroutines 0-3 can actually be anything defined by the font,
4610
+ // so we really shouldn't be doing flex here but when
4611
+ // callothersubr 0-2 is used. There hasn't been a real world
4612
+ // example of this yet so we'll keep doing it here.
4598
4613
var subrNumber = charstring .pop ();
4599
4614
switch (subrNumber ) {
4600
4615
case 1 :
4601
- flexState = 1 ; // prepare for flex coordinates
4602
- break ;
4603
- case 2 :
4604
- flexState = 2 ; // flex in progress
4616
+ flexing = true ; // prepare for flex coordinates
4605
4617
break ;
4606
4618
case 0 :
4607
- // type2 flex command does not need final coords
4608
- charstring .push ('exch' , 'drop' , 'exch' , 'drop' );
4609
- charstring .push ('flex' );
4610
- flexState = 0 ;
4619
+ var flexArgs = breakUpArgs (charstring , 17 );
4620
+ popArgs (charstring , flexArgs );
4621
+
4622
+ charstring .push (
4623
+ flexArgs [2 ].value + flexArgs [0 ].value , // bcp1x + rpx
4624
+ flexArgs [3 ].value + flexArgs [1 ].value , // bcp1y + rpy
4625
+ flexArgs [4 ].value , // bcp2x
4626
+ flexArgs [5 ].value , // bcp2y
4627
+ flexArgs [6 ].value , // p2x
4628
+ flexArgs [7 ].value , // p2y
4629
+ flexArgs [8 ].value , // bcp3x
4630
+ flexArgs [9 ].value , // bcp3y
4631
+ flexArgs [10 ].value , // bcp4x
4632
+ flexArgs [11 ].value , // bcp4y
4633
+ flexArgs [12 ].value , // p3x
4634
+ flexArgs [13 ].value , // p3y
4635
+ flexArgs [14 ].value , // flexDepth
4636
+ // 15 = finalx unused by flex
4637
+ // 16 = finaly unused by flex
4638
+ 'flex'
4639
+ );
4640
+
4641
+ flexing = false ;
4611
4642
break ;
4612
4643
}
4613
4644
continue ;
4614
4645
}
4615
- } else if (value == 21 && flexState > 0 ) {
4616
- if (flexState > 1 )
4617
- continue ; // ignoring rmoveto
4618
- value = 5 ; // first segment replacing with rlineto
4646
+ } else if (value == 21 && flexing ) { // rmoveto
4647
+ continue ; // ignoring rmoveto
4648
+ } else if (value == 22 && flexing ) { // hmoveto
4649
+ // Add the dy for flex.
4650
+ charstring .push (0 );
4651
+ continue ; // ignoring hmoveto
4652
+ } else if (value == 4 && flexing ) { // vmoveto
4653
+ // Add the dx for flex and but also swap the values so they are the
4654
+ // right order.
4655
+ var vArgs = breakUpArgs (charstring , 1 );
4656
+ popArgs (charstring , vArgs );
4657
+ charstring .push (0 );
4658
+ for (var t = 0 , tt = vArgs [0 ].arg .length ; t < tt ; t ++) {
4659
+ charstring .push (vArgs [0 ].arg [t ]);
4660
+ }
4661
+ continue ; // ignoring vmoveto
4619
4662
} else if (!HINTING_ENABLED && (value == 1 || value == 3 )) {
4620
4663
charstring .push ('drop' , 'drop' );
4621
4664
continue ;
@@ -5191,6 +5234,17 @@ Type1Font.prototype = {
5191
5234
},
5192
5235
5193
5236
wrap : function Type1Font_wrap (name , glyphs , charstrings , subrs , properties ) {
5237
+ var comp = new CFFCompiler ();
5238
+ // TODO: remove this function after refactoring wrap to use the CFFCompiler.
5239
+ function encodeNumber (num ) {
5240
+ var val = comp .encodeNumber (num );
5241
+ var ret = '';
5242
+ for (var i = 0 ; i < val .length ; i ++) {
5243
+ ret += String .fromCharCode (val [i ]);
5244
+ }
5245
+ return ret ;
5246
+ }
5247
+
5194
5248
var fields = {
5195
5249
// major version, minor version, header size, offset size
5196
5250
'header' : '\x01\x00\x04\x04' ,
@@ -5210,7 +5264,7 @@ Type1Font.prototype = {
5210
5264
5211
5265
var boundingBox = properties .bbox ;
5212
5266
for (var i = 0 , ii = boundingBox .length ; i < ii ; i ++)
5213
- dict += self . encodeNumber (boundingBox [i ]);
5267
+ dict += encodeNumber (boundingBox [i ]);
5214
5268
dict += '\x05' ; // FontBBox;
5215
5269
5216
5270
var offset = fields .header .length +
@@ -5298,11 +5352,10 @@ Type1Font.prototype = {
5298
5352
var value = properties .privateData [field ];
5299
5353
5300
5354
if (isArray (value )) {
5301
- data += self .encodeNumber (value [0 ]);
5302
- for (var i = 1 , ii = value .length ; i < ii ; i ++)
5303
- data += self .encodeNumber (value [i ] - value [i - 1 ]);
5355
+ for (var i = 0 , ii = value .length ; i < ii ; i ++)
5356
+ data += encodeNumber (value [i ]);
5304
5357
} else {
5305
- data += self . encodeNumber (value );
5358
+ data += encodeNumber (value );
5306
5359
}
5307
5360
data += fieldMap [field ];
5308
5361
}
0 commit comments