xref: /inferno-os/libfreetype/cffload.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 /***************************************************************************/
2 /*                                                                         */
3 /*  cffload.c                                                              */
4 /*                                                                         */
5 /*    OpenType and CFF data/program tables loader (body).                  */
6 /*                                                                         */
7 /*  Copyright 1996-2001, 2002 by                                           */
8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9 /*                                                                         */
10 /*  This file is part of the FreeType project, and may only be used,       */
11 /*  modified, and distributed under the terms of the FreeType project      */
12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13 /*  this file you indicate that you have read the license and              */
14 /*  understand and accept it fully.                                        */
15 /*                                                                         */
16 /***************************************************************************/
17 
18 
19 #include <ft2build.h>
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_OBJECTS_H
22 #include FT_INTERNAL_STREAM_H
23 #include FT_INTERNAL_POSTSCRIPT_NAMES_H
24 #include FT_TRUETYPE_TAGS_H
25 
26 #include "cffload.h"
27 #include "cffparse.h"
28 
29 #include "cfferrs.h"
30 
31 
32 #if 1
33   static const FT_UShort  cff_isoadobe_charset[229] =
34   {
35     0,
36     1,
37     2,
38     3,
39     4,
40     5,
41     6,
42     7,
43     8,
44     9,
45     10,
46     11,
47     12,
48     13,
49     14,
50     15,
51     16,
52     17,
53     18,
54     19,
55     20,
56     21,
57     22,
58     23,
59     24,
60     25,
61     26,
62     27,
63     28,
64     29,
65     30,
66     31,
67     32,
68     33,
69     34,
70     35,
71     36,
72     37,
73     38,
74     39,
75     40,
76     41,
77     42,
78     43,
79     44,
80     45,
81     46,
82     47,
83     48,
84     49,
85     50,
86     51,
87     52,
88     53,
89     54,
90     55,
91     56,
92     57,
93     58,
94     59,
95     60,
96     61,
97     62,
98     63,
99     64,
100     65,
101     66,
102     67,
103     68,
104     69,
105     70,
106     71,
107     72,
108     73,
109     74,
110     75,
111     76,
112     77,
113     78,
114     79,
115     80,
116     81,
117     82,
118     83,
119     84,
120     85,
121     86,
122     87,
123     88,
124     89,
125     90,
126     91,
127     92,
128     93,
129     94,
130     95,
131     96,
132     97,
133     98,
134     99,
135     100,
136     101,
137     102,
138     103,
139     104,
140     105,
141     106,
142     107,
143     108,
144     109,
145     110,
146     111,
147     112,
148     113,
149     114,
150     115,
151     116,
152     117,
153     118,
154     119,
155     120,
156     121,
157     122,
158     123,
159     124,
160     125,
161     126,
162     127,
163     128,
164     129,
165     130,
166     131,
167     132,
168     133,
169     134,
170     135,
171     136,
172     137,
173     138,
174     139,
175     140,
176     141,
177     142,
178     143,
179     144,
180     145,
181     146,
182     147,
183     148,
184     149,
185     150,
186     151,
187     152,
188     153,
189     154,
190     155,
191     156,
192     157,
193     158,
194     159,
195     160,
196     161,
197     162,
198     163,
199     164,
200     165,
201     166,
202     167,
203     168,
204     169,
205     170,
206     171,
207     172,
208     173,
209     174,
210     175,
211     176,
212     177,
213     178,
214     179,
215     180,
216     181,
217     182,
218     183,
219     184,
220     185,
221     186,
222     187,
223     188,
224     189,
225     190,
226     191,
227     192,
228     193,
229     194,
230     195,
231     196,
232     197,
233     198,
234     199,
235     200,
236     201,
237     202,
238     203,
239     204,
240     205,
241     206,
242     207,
243     208,
244     209,
245     210,
246     211,
247     212,
248     213,
249     214,
250     215,
251     216,
252     217,
253     218,
254     219,
255     220,
256     221,
257     222,
258     223,
259     224,
260     225,
261     226,
262     227,
263     228
264   };
265 
266   static const FT_UShort  cff_expert_charset[166] =
267   {
268     0,
269     1,
270     229,
271     230,
272     231,
273     232,
274     233,
275     234,
276     235,
277     236,
278     237,
279     238,
280     13,
281     14,
282     15,
283     99,
284     239,
285     240,
286     241,
287     242,
288     243,
289     244,
290     245,
291     246,
292     247,
293     248,
294     27,
295     28,
296     249,
297     250,
298     251,
299     252,
300     253,
301     254,
302     255,
303     256,
304     257,
305     258,
306     259,
307     260,
308     261,
309     262,
310     263,
311     264,
312     265,
313     266,
314     109,
315     110,
316     267,
317     268,
318     269,
319     270,
320     271,
321     272,
322     273,
323     274,
324     275,
325     276,
326     277,
327     278,
328     279,
329     280,
330     281,
331     282,
332     283,
333     284,
334     285,
335     286,
336     287,
337     288,
338     289,
339     290,
340     291,
341     292,
342     293,
343     294,
344     295,
345     296,
346     297,
347     298,
348     299,
349     300,
350     301,
351     302,
352     303,
353     304,
354     305,
355     306,
356     307,
357     308,
358     309,
359     310,
360     311,
361     312,
362     313,
363     314,
364     315,
365     316,
366     317,
367     318,
368     158,
369     155,
370     163,
371     319,
372     320,
373     321,
374     322,
375     323,
376     324,
377     325,
378     326,
379     150,
380     164,
381     169,
382     327,
383     328,
384     329,
385     330,
386     331,
387     332,
388     333,
389     334,
390     335,
391     336,
392     337,
393     338,
394     339,
395     340,
396     341,
397     342,
398     343,
399     344,
400     345,
401     346,
402     347,
403     348,
404     349,
405     350,
406     351,
407     352,
408     353,
409     354,
410     355,
411     356,
412     357,
413     358,
414     359,
415     360,
416     361,
417     362,
418     363,
419     364,
420     365,
421     366,
422     367,
423     368,
424     369,
425     370,
426     371,
427     372,
428     373,
429     374,
430     375,
431     376,
432     377,
433     378
434   };
435 
436   static const FT_UShort  cff_expertsubset_charset[87] =
437   {
438     0,
439     1,
440     231,
441     232,
442     235,
443     236,
444     237,
445     238,
446     13,
447     14,
448     15,
449     99,
450     239,
451     240,
452     241,
453     242,
454     243,
455     244,
456     245,
457     246,
458     247,
459     248,
460     27,
461     28,
462     249,
463     250,
464     251,
465     253,
466     254,
467     255,
468     256,
469     257,
470     258,
471     259,
472     260,
473     261,
474     262,
475     263,
476     264,
477     265,
478     266,
479     109,
480     110,
481     267,
482     268,
483     269,
484     270,
485     272,
486     300,
487     301,
488     302,
489     305,
490     314,
491     315,
492     158,
493     155,
494     163,
495     320,
496     321,
497     322,
498     323,
499     324,
500     325,
501     326,
502     150,
503     164,
504     169,
505     327,
506     328,
507     329,
508     330,
509     331,
510     332,
511     333,
512     334,
513     335,
514     336,
515     337,
516     338,
517     339,
518     340,
519     341,
520     342,
521     343,
522     344,
523     345,
524     346
525   };
526 
527   static const FT_UShort  cff_standard_encoding[256] =
528   {
529     0,
530     0,
531     0,
532     0,
533     0,
534     0,
535     0,
536     0,
537     0,
538     0,
539     0,
540     0,
541     0,
542     0,
543     0,
544     0,
545     0,
546     0,
547     0,
548     0,
549     0,
550     0,
551     0,
552     0,
553     0,
554     0,
555     0,
556     0,
557     0,
558     0,
559     0,
560     0,
561     1,
562     2,
563     3,
564     4,
565     5,
566     6,
567     7,
568     8,
569     9,
570     10,
571     11,
572     12,
573     13,
574     14,
575     15,
576     16,
577     17,
578     18,
579     19,
580     20,
581     21,
582     22,
583     23,
584     24,
585     25,
586     26,
587     27,
588     28,
589     29,
590     30,
591     31,
592     32,
593     33,
594     34,
595     35,
596     36,
597     37,
598     38,
599     39,
600     40,
601     41,
602     42,
603     43,
604     44,
605     45,
606     46,
607     47,
608     48,
609     49,
610     50,
611     51,
612     52,
613     53,
614     54,
615     55,
616     56,
617     57,
618     58,
619     59,
620     60,
621     61,
622     62,
623     63,
624     64,
625     65,
626     66,
627     67,
628     68,
629     69,
630     70,
631     71,
632     72,
633     73,
634     74,
635     75,
636     76,
637     77,
638     78,
639     79,
640     80,
641     81,
642     82,
643     83,
644     84,
645     85,
646     86,
647     87,
648     88,
649     89,
650     90,
651     91,
652     92,
653     93,
654     94,
655     95,
656     0,
657     0,
658     0,
659     0,
660     0,
661     0,
662     0,
663     0,
664     0,
665     0,
666     0,
667     0,
668     0,
669     0,
670     0,
671     0,
672     0,
673     0,
674     0,
675     0,
676     0,
677     0,
678     0,
679     0,
680     0,
681     0,
682     0,
683     0,
684     0,
685     0,
686     0,
687     0,
688     0,
689     0,
690     96,
691     97,
692     98,
693     99,
694     100,
695     101,
696     102,
697     103,
698     104,
699     105,
700     106,
701     107,
702     108,
703     109,
704     110,
705     0,
706     111,
707     112,
708     113,
709     114,
710     0,
711     115,
712     116,
713     117,
714     118,
715     119,
716     120,
717     121,
718     122,
719     0,
720     123,
721     0,
722     124,
723     125,
724     126,
725     127,
726     128,
727     129,
728     130,
729     131,
730     0,
731     132,
732     133,
733     0,
734     134,
735     135,
736     136,
737     137,
738     0,
739     0,
740     0,
741     0,
742     0,
743     0,
744     0,
745     0,
746     0,
747     0,
748     0,
749     0,
750     0,
751     0,
752     0,
753     0,
754     138,
755     0,
756     139,
757     0,
758     0,
759     0,
760     0,
761     140,
762     141,
763     142,
764     143,
765     0,
766     0,
767     0,
768     0,
769     0,
770     144,
771     0,
772     0,
773     0,
774     145,
775     0,
776     0,
777     146,
778     147,
779     148,
780     149,
781     0,
782     0,
783     0,
784     0
785   };
786 
787   static const FT_UShort  cff_expert_encoding[256] =
788   {
789     0,
790     0,
791     0,
792     0,
793     0,
794     0,
795     0,
796     0,
797     0,
798     0,
799     0,
800     0,
801     0,
802     0,
803     0,
804     0,
805     0,
806     0,
807     0,
808     0,
809     0,
810     0,
811     0,
812     0,
813     0,
814     0,
815     0,
816     0,
817     0,
818     0,
819     0,
820     0,
821     1,
822     229,
823     230,
824     0,
825     231,
826     232,
827     233,
828     234,
829     235,
830     236,
831     237,
832     238,
833     13,
834     14,
835     15,
836     99,
837     239,
838     240,
839     241,
840     242,
841     243,
842     244,
843     245,
844     246,
845     247,
846     248,
847     27,
848     28,
849     249,
850     250,
851     251,
852     252,
853     0,
854     253,
855     254,
856     255,
857     256,
858     257,
859     0,
860     0,
861     0,
862     258,
863     0,
864     0,
865     259,
866     260,
867     261,
868     262,
869     0,
870     0,
871     263,
872     264,
873     265,
874     0,
875     266,
876     109,
877     110,
878     267,
879     268,
880     269,
881     0,
882     270,
883     271,
884     272,
885     273,
886     274,
887     275,
888     276,
889     277,
890     278,
891     279,
892     280,
893     281,
894     282,
895     283,
896     284,
897     285,
898     286,
899     287,
900     288,
901     289,
902     290,
903     291,
904     292,
905     293,
906     294,
907     295,
908     296,
909     297,
910     298,
911     299,
912     300,
913     301,
914     302,
915     303,
916     0,
917     0,
918     0,
919     0,
920     0,
921     0,
922     0,
923     0,
924     0,
925     0,
926     0,
927     0,
928     0,
929     0,
930     0,
931     0,
932     0,
933     0,
934     0,
935     0,
936     0,
937     0,
938     0,
939     0,
940     0,
941     0,
942     0,
943     0,
944     0,
945     0,
946     0,
947     0,
948     0,
949     0,
950     304,
951     305,
952     306,
953     0,
954     0,
955     307,
956     308,
957     309,
958     310,
959     311,
960     0,
961     312,
962     0,
963     0,
964     312,
965     0,
966     0,
967     314,
968     315,
969     0,
970     0,
971     316,
972     317,
973     318,
974     0,
975     0,
976     0,
977     158,
978     155,
979     163,
980     319,
981     320,
982     321,
983     322,
984     323,
985     324,
986     325,
987     0,
988     0,
989     326,
990     150,
991     164,
992     169,
993     327,
994     328,
995     329,
996     330,
997     331,
998     332,
999     333,
1000     334,
1001     335,
1002     336,
1003     337,
1004     338,
1005     339,
1006     340,
1007     341,
1008     342,
1009     343,
1010     344,
1011     345,
1012     346,
1013     347,
1014     348,
1015     349,
1016     350,
1017     351,
1018     352,
1019     353,
1020     354,
1021     355,
1022     356,
1023     357,
1024     358,
1025     359,
1026     360,
1027     361,
1028     362,
1029     363,
1030     364,
1031     365,
1032     366,
1033     367,
1034     368,
1035     369,
1036     370,
1037     371,
1038     372,
1039     373,
1040     374,
1041     375,
1042     376,
1043     377,
1044     378
1045   };
1046 #endif
1047 
1048 
1049   FT_LOCAL_DEF( FT_UShort )
cff_get_standard_encoding(FT_UInt charcode)1050   cff_get_standard_encoding( FT_UInt  charcode )
1051   {
1052     return  (FT_UShort)(charcode < 256 ? cff_standard_encoding[charcode] : 0);
1053   }
1054 
1055 
1056   /*************************************************************************/
1057   /*                                                                       */
1058   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
1059   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
1060   /* messages during execution.                                            */
1061   /*                                                                       */
1062 #undef  FT_COMPONENT
1063 #define FT_COMPONENT  trace_cffload
1064 
1065 
1066   /* read a CFF offset from memory */
1067   static FT_ULong
cff_get_offset(FT_Byte * p,FT_Byte off_size)1068   cff_get_offset( FT_Byte*  p,
1069                   FT_Byte   off_size )
1070   {
1071     FT_ULong  result;
1072 
1073 
1074     for ( result = 0; off_size > 0; off_size-- )
1075     {
1076       result <<= 8;
1077       result  |= *p++;
1078     }
1079 
1080     return result;
1081   }
1082 
1083 
1084   static FT_Error
cff_new_index(CFF_Index idx,FT_Stream stream,FT_Bool load)1085   cff_new_index( CFF_Index  idx,
1086                  FT_Stream  stream,
1087                  FT_Bool    load )
1088   {
1089     FT_Error   error;
1090     FT_Memory  memory = stream->memory;
1091     FT_UShort  count;
1092 
1093 
1094     FT_MEM_ZERO( idx, sizeof ( *idx ) );
1095 
1096     idx->stream = stream;
1097     if ( !FT_READ_USHORT( count ) &&
1098          count > 0             )
1099     {
1100       FT_Byte*   p;
1101       FT_Byte    offsize;
1102       FT_ULong   data_size;
1103       FT_ULong*  poff;
1104 
1105 
1106       /* there is at least one element; read the offset size,           */
1107       /* then access the offset table to compute the index's total size */
1108       if ( FT_READ_BYTE( offsize ) )
1109         goto Exit;
1110 
1111       idx->stream   = stream;
1112       idx->count    = count;
1113       idx->off_size = offsize;
1114       data_size     = (FT_ULong)( count + 1 ) * offsize;
1115 
1116       if ( FT_NEW_ARRAY( idx->offsets, count + 1 ) ||
1117            FT_FRAME_ENTER( data_size )             )
1118         goto Exit;
1119 
1120       poff = idx->offsets;
1121       p    = (FT_Byte*)stream->cursor;
1122 
1123       for ( ; (FT_Short)count >= 0; count-- )
1124       {
1125         poff[0] = cff_get_offset( p, offsize );
1126         poff++;
1127         p += offsize;
1128       }
1129 
1130       FT_FRAME_EXIT();
1131 
1132       idx->data_offset = FT_STREAM_POS();
1133       data_size        = poff[-1] - 1;
1134 
1135       if ( load )
1136       {
1137         /* load the data */
1138         if ( FT_FRAME_EXTRACT( data_size, idx->bytes ) )
1139           goto Exit;
1140       }
1141       else
1142       {
1143         /* skip the data */
1144         if ( FT_STREAM_SKIP( data_size ) )
1145           goto Exit;
1146       }
1147     }
1148 
1149   Exit:
1150     if ( error )
1151       FT_FREE( idx->offsets );
1152 
1153     return error;
1154   }
1155 
1156 
1157   static void
cff_done_index(CFF_Index idx)1158   cff_done_index( CFF_Index  idx )
1159   {
1160     if ( idx->stream )
1161     {
1162       FT_Stream  stream = idx->stream;
1163       FT_Memory  memory = stream->memory;
1164 
1165 
1166       if ( idx->bytes )
1167         FT_FRAME_RELEASE( idx->bytes );
1168 
1169       FT_FREE( idx->offsets );
1170       FT_MEM_ZERO( idx, sizeof ( *idx ) );
1171     }
1172   }
1173 
1174 
1175  /* allocate a table containing pointers to an index's elements */
1176   static FT_Error
cff_index_get_pointers(CFF_Index idx,FT_Byte *** table)1177   cff_index_get_pointers( CFF_Index   idx,
1178                           FT_Byte***  table )
1179   {
1180     FT_Error   error  = 0;
1181     FT_Memory  memory = idx->stream->memory;
1182     FT_ULong   n, offset, old_offset;
1183     FT_Byte**  t;
1184 
1185 
1186     *table = 0;
1187 
1188     if ( idx->count > 0 && !FT_NEW_ARRAY( t, idx->count + 1 ) )
1189     {
1190       old_offset = 1;
1191       for ( n = 0; n <= idx->count; n++ )
1192       {
1193         offset = idx->offsets[n];
1194         if ( !offset )
1195           offset = old_offset;
1196 
1197         t[n] = idx->bytes + offset - 1;
1198 
1199         old_offset = offset;
1200       }
1201       *table = t;
1202     }
1203 
1204     return error;
1205   }
1206 
1207 
1208   FT_LOCAL_DEF( FT_Error )
cff_index_access_element(CFF_Index idx,FT_UInt element,FT_Byte ** pbytes,FT_ULong * pbyte_len)1209   cff_index_access_element( CFF_Index  idx,
1210                             FT_UInt    element,
1211                             FT_Byte**  pbytes,
1212                             FT_ULong*  pbyte_len )
1213   {
1214     FT_Error  error = 0;
1215 
1216 
1217     if ( idx && idx->count > element )
1218     {
1219       /* compute start and end offsets */
1220       FT_ULong  off1, off2 = 0;
1221 
1222 
1223       off1 = idx->offsets[element];
1224       if ( off1 )
1225       {
1226         do
1227         {
1228           element++;
1229           off2 = idx->offsets[element];
1230 
1231         } while ( off2 == 0 && element < idx->count );
1232 
1233         if ( !off2 )
1234           off1 = 0;
1235       }
1236 
1237       /* access element */
1238       if ( off1 )
1239       {
1240         *pbyte_len = off2 - off1;
1241 
1242         if ( idx->bytes )
1243         {
1244           /* this index was completely loaded in memory, that's easy */
1245           *pbytes = idx->bytes + off1 - 1;
1246         }
1247         else
1248         {
1249           /* this index is still on disk/file, access it through a frame */
1250           FT_Stream  stream = idx->stream;
1251 
1252 
1253           if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
1254                FT_FRAME_EXTRACT( off2 - off1, *pbytes )      )
1255             goto Exit;
1256         }
1257       }
1258       else
1259       {
1260         /* empty index element */
1261         *pbytes    = 0;
1262         *pbyte_len = 0;
1263       }
1264     }
1265     else
1266       error = CFF_Err_Invalid_Argument;
1267 
1268   Exit:
1269     return error;
1270   }
1271 
1272 
1273   FT_LOCAL_DEF( void )
cff_index_forget_element(CFF_Index idx,FT_Byte ** pbytes)1274   cff_index_forget_element( CFF_Index  idx,
1275                             FT_Byte**  pbytes )
1276   {
1277     if ( idx->bytes == 0 )
1278     {
1279       FT_Stream  stream = idx->stream;
1280 
1281 
1282       FT_FRAME_RELEASE( *pbytes );
1283     }
1284   }
1285 
1286 
1287   FT_LOCAL_DEF( FT_String* )
cff_index_get_name(CFF_Index idx,FT_UInt element)1288   cff_index_get_name( CFF_Index  idx,
1289                       FT_UInt    element )
1290   {
1291     FT_Memory   memory = idx->stream->memory;
1292     FT_Byte*    bytes;
1293     FT_ULong    byte_len;
1294     FT_Error    error;
1295     FT_String*  name = 0;
1296 
1297 
1298     error = cff_index_access_element( idx, element, &bytes, &byte_len );
1299     if ( error )
1300       goto Exit;
1301 
1302     if ( !FT_ALLOC( name, byte_len + 1 ) )
1303     {
1304       FT_MEM_COPY( name, bytes, byte_len );
1305       name[byte_len] = 0;
1306     }
1307     cff_index_forget_element( idx, &bytes );
1308 
1309   Exit:
1310     return name;
1311   }
1312 
1313 
1314   FT_LOCAL_DEF( FT_String* )
cff_index_get_sid_string(CFF_Index idx,FT_UInt sid,PSNames_Service psnames_service)1315   cff_index_get_sid_string( CFF_Index        idx,
1316                             FT_UInt          sid,
1317                             PSNames_Service  psnames_service )
1318   {
1319     /* if it is not a standard string, return it */
1320     if ( sid > 390 )
1321       return cff_index_get_name( idx, sid - 391 );
1322 
1323     /* that's a standard string, fetch a copy from the PSName module */
1324     {
1325       FT_String*   name       = 0;
1326       const char*  adobe_name = psnames_service->adobe_std_strings( sid );
1327       FT_UInt      len;
1328 
1329 
1330       if ( adobe_name )
1331       {
1332         FT_Memory  memory = idx->stream->memory;
1333         FT_Error   error;
1334 
1335 
1336         len = (FT_UInt)ft_strlen( adobe_name );
1337         if ( !FT_ALLOC( name, len + 1 ) )
1338         {
1339           FT_MEM_COPY( name, adobe_name, len );
1340           name[len] = 0;
1341         }
1342 
1343         FT_UNUSED( error );
1344       }
1345 
1346       return name;
1347     }
1348   }
1349 
1350 
1351   /*************************************************************************/
1352   /*************************************************************************/
1353   /***                                                                   ***/
1354   /***   FD Select table support                                         ***/
1355   /***                                                                   ***/
1356   /*************************************************************************/
1357   /*************************************************************************/
1358 
1359 
1360   static void
CFF_Done_FD_Select(CFF_FDSelect fdselect,FT_Stream stream)1361   CFF_Done_FD_Select( CFF_FDSelect  fdselect,
1362                       FT_Stream     stream )
1363   {
1364     if ( fdselect->data )
1365       FT_FRAME_RELEASE( fdselect->data );
1366 
1367     fdselect->data_size   = 0;
1368     fdselect->format      = 0;
1369     fdselect->range_count = 0;
1370   }
1371 
1372 
1373   static FT_Error
CFF_Load_FD_Select(CFF_FDSelect fdselect,FT_UInt num_glyphs,FT_Stream stream,FT_ULong offset)1374   CFF_Load_FD_Select( CFF_FDSelect  fdselect,
1375                       FT_UInt       num_glyphs,
1376                       FT_Stream     stream,
1377                       FT_ULong      offset )
1378   {
1379     FT_Error  error;
1380     FT_Byte   format;
1381     FT_UInt   num_ranges;
1382 
1383 
1384     /* read format */
1385     if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
1386       goto Exit;
1387 
1388     fdselect->format      = format;
1389     fdselect->cache_count = 0;   /* clear cache */
1390 
1391     switch ( format )
1392     {
1393     case 0:     /* format 0, that's simple */
1394       fdselect->data_size = num_glyphs;
1395       goto Load_Data;
1396 
1397     case 3:     /* format 3, a tad more complex */
1398       if ( FT_READ_USHORT( num_ranges ) )
1399         goto Exit;
1400 
1401       fdselect->data_size = num_ranges * 3 + 2;
1402 
1403     Load_Data:
1404       if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
1405         goto Exit;
1406       break;
1407 
1408     default:    /* hmm... that's wrong */
1409       error = CFF_Err_Invalid_File_Format;
1410     }
1411 
1412   Exit:
1413     return error;
1414   }
1415 
1416 
1417   FT_LOCAL_DEF( FT_Byte )
cff_fd_select_get(CFF_FDSelect fdselect,FT_UInt glyph_index)1418   cff_fd_select_get( CFF_FDSelect  fdselect,
1419                      FT_UInt       glyph_index )
1420   {
1421     FT_Byte  fd = 0;
1422 
1423 
1424     switch ( fdselect->format )
1425     {
1426     case 0:
1427       fd = fdselect->data[glyph_index];
1428       break;
1429 
1430     case 3:
1431       /* first, compare to cache */
1432       if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
1433                         fdselect->cache_count )
1434       {
1435         fd = fdselect->cache_fd;
1436         break;
1437       }
1438 
1439       /* then, lookup the ranges array */
1440       {
1441         FT_Byte*  p       = fdselect->data;
1442         FT_Byte*  p_limit = p + fdselect->data_size;
1443         FT_Byte   fd2;
1444         FT_UInt   first, limit;
1445 
1446 
1447         first = FT_NEXT_USHORT( p );
1448         do
1449         {
1450           if ( glyph_index < first )
1451             break;
1452 
1453           fd2   = *p++;
1454           limit = FT_NEXT_USHORT( p );
1455 
1456           if ( glyph_index < limit )
1457           {
1458             fd = fd2;
1459 
1460             /* update cache */
1461             fdselect->cache_first = first;
1462             fdselect->cache_count = limit-first;
1463             fdselect->cache_fd    = fd2;
1464             break;
1465           }
1466           first = limit;
1467 
1468         } while ( p < p_limit );
1469       }
1470       break;
1471 
1472     default:
1473       ;
1474     }
1475 
1476     return fd;
1477   }
1478 
1479 
1480   /*************************************************************************/
1481   /*************************************************************************/
1482   /***                                                                   ***/
1483   /***   CFF font support                                                ***/
1484   /***                                                                   ***/
1485   /*************************************************************************/
1486   /*************************************************************************/
1487 
1488   static void
cff_charset_done(CFF_Charset charset,FT_Stream stream)1489   cff_charset_done( CFF_Charset  charset,
1490                     FT_Stream    stream )
1491   {
1492     FT_Memory  memory = stream->memory;
1493 
1494 
1495     FT_FREE( charset->sids );
1496     charset->format = 0;
1497     charset->offset = 0;
1498   }
1499 
1500 
1501   static FT_Error
cff_charset_load(CFF_Charset charset,FT_UInt num_glyphs,FT_Stream stream,FT_ULong base_offset,FT_ULong offset)1502   cff_charset_load( CFF_Charset  charset,
1503                     FT_UInt      num_glyphs,
1504                     FT_Stream    stream,
1505                     FT_ULong     base_offset,
1506                     FT_ULong     offset )
1507   {
1508     FT_Memory  memory     = stream->memory;
1509     FT_Error   error      = 0;
1510     FT_UShort  glyph_sid;
1511 
1512 
1513     /* If the the offset is greater than 2, we have to parse the */
1514     /* charset table.                                            */
1515     if ( offset > 2 )
1516     {
1517       FT_UInt  j;
1518 
1519 
1520       charset->offset = base_offset + offset;
1521 
1522       /* Get the format of the table. */
1523       if ( FT_STREAM_SEEK( charset->offset ) ||
1524            FT_READ_BYTE( charset->format )   )
1525         goto Exit;
1526 
1527       /* Allocate memory for sids. */
1528       if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
1529         goto Exit;
1530 
1531       /* assign the .notdef glyph */
1532       charset->sids[0] = 0;
1533 
1534       switch ( charset->format )
1535       {
1536       case 0:
1537         if ( num_glyphs > 0 )
1538         {
1539           if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
1540             goto Exit;
1541 
1542           for ( j = 1; j < num_glyphs; j++ )
1543             charset->sids[j] = FT_GET_USHORT();
1544 
1545           FT_FRAME_EXIT();
1546         }
1547         break;
1548 
1549       case 1:
1550       case 2:
1551         {
1552           FT_UInt  nleft;
1553           FT_UInt  i;
1554 
1555 
1556           j = 1;
1557 
1558           while ( j < num_glyphs )
1559           {
1560 
1561             /* Read the first glyph sid of the range. */
1562             if ( FT_READ_USHORT( glyph_sid ) )
1563               goto Exit;
1564 
1565             /* Read the number of glyphs in the range.  */
1566             if ( charset->format == 2 )
1567             {
1568               if ( FT_READ_USHORT( nleft ) )
1569                 goto Exit;
1570             }
1571             else
1572             {
1573               if ( FT_READ_BYTE( nleft ) )
1574                 goto Exit;
1575             }
1576 
1577             /* Fill in the range of sids -- `nleft + 1' glyphs. */
1578             for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
1579               charset->sids[j] = glyph_sid;
1580           }
1581         }
1582         break;
1583 
1584       default:
1585         FT_ERROR(( "cff_charset_load: invalid table format!\n" ));
1586         error = CFF_Err_Invalid_File_Format;
1587         goto Exit;
1588       }
1589     }
1590     else
1591     {
1592       /* Parse default tables corresponding to offset == 0, 1, or 2.  */
1593       /* CFF specification intimates the following:                   */
1594       /*                                                              */
1595       /* In order to use a predefined charset, the following must be  */
1596       /* true: The charset constructed for the glyphs in the font's   */
1597       /* charstrings dictionary must match the predefined charset in  */
1598       /* the first num_glyphs, and hence must match the predefined    */
1599       /* charset *exactly*.                                           */
1600 
1601       charset->offset = offset;  /* record charset type */
1602 
1603       switch ( (FT_UInt)offset )
1604       {
1605       case 0:
1606         if ( num_glyphs != 229 )
1607         {
1608           FT_ERROR(("cff_charset_load: implicit charset not equal to\n"
1609                     "predefined charset (Adobe ISO-Latin)!\n" ));
1610           error = CFF_Err_Invalid_File_Format;
1611           goto Exit;
1612         }
1613 
1614         /* Allocate memory for sids. */
1615         if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
1616           goto Exit;
1617 
1618         /* Copy the predefined charset into the allocated memory. */
1619         FT_MEM_COPY( charset->sids, cff_isoadobe_charset,
1620                      num_glyphs * sizeof ( FT_UShort ) );
1621 
1622         break;
1623 
1624       case 1:
1625         if ( num_glyphs != 166 )
1626         {
1627           FT_ERROR(( "cff_charset_load: implicit charset not equal to\n"
1628                      "predefined charset (Adobe Expert)!\n" ));
1629           error = CFF_Err_Invalid_File_Format;
1630           goto Exit;
1631         }
1632 
1633         /* Allocate memory for sids. */
1634         if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
1635           goto Exit;
1636 
1637         /* Copy the predefined charset into the allocated memory.     */
1638         FT_MEM_COPY( charset->sids, cff_expert_charset,
1639                      num_glyphs * sizeof ( FT_UShort ) );
1640 
1641         break;
1642 
1643       case 2:
1644         if ( num_glyphs != 87 )
1645         {
1646           FT_ERROR(( "cff_charset_load: implicit charset not equal to\n"
1647                      "predefined charset (Adobe Expert Subset)!\n" ));
1648           error = CFF_Err_Invalid_File_Format;
1649           goto Exit;
1650         }
1651 
1652         /* Allocate memory for sids. */
1653         if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
1654           goto Exit;
1655 
1656         /* Copy the predefined charset into the allocated memory.     */
1657         FT_MEM_COPY( charset->sids, cff_expertsubset_charset,
1658                      num_glyphs * sizeof ( FT_UShort ) );
1659 
1660         break;
1661 
1662       default:
1663         error = CFF_Err_Invalid_File_Format;
1664         goto Exit;
1665       }
1666     }
1667 
1668   Exit:
1669 
1670     /* Clean up if there was an error. */
1671     if ( error )
1672       if ( charset->sids )
1673       {
1674         FT_FREE( charset->sids );
1675         charset->format = 0;
1676         charset->offset = 0;
1677         charset->sids   = 0;
1678       }
1679 
1680     return error;
1681   }
1682 
1683 
1684 
1685   static void
cff_encoding_done(CFF_Encoding encoding)1686   cff_encoding_done( CFF_Encoding  encoding )
1687   {
1688     encoding->format = 0;
1689     encoding->offset = 0;
1690     encoding->count  = 0;
1691   }
1692 
1693 
1694 
1695   static FT_Error
cff_encoding_load(CFF_Encoding encoding,CFF_Charset charset,FT_UInt num_glyphs,FT_Stream stream,FT_ULong base_offset,FT_ULong offset)1696   cff_encoding_load( CFF_Encoding  encoding,
1697                      CFF_Charset   charset,
1698                      FT_UInt       num_glyphs,
1699                      FT_Stream     stream,
1700                      FT_ULong      base_offset,
1701                      FT_ULong      offset )
1702   {
1703     FT_Error    error  = 0;
1704     FT_UInt     count;
1705     FT_UInt     j;
1706     FT_UShort   glyph_sid;
1707     FT_UInt     glyph_code;
1708 
1709 
1710     /* Check for charset->sids.  If we do not have this, we fail. */
1711     if ( !charset->sids )
1712     {
1713       error = CFF_Err_Invalid_File_Format;
1714       goto Exit;
1715     }
1716 
1717     /* Zero out the code to gid/sid mappings. */
1718     for ( j = 0; j < 256; j++ )
1719     {
1720       encoding->sids [j] = 0;
1721       encoding->codes[j] = 0;
1722     }
1723 
1724     /* Note: The encoding table in a CFF font is indexed by glyph index,  */
1725     /* where the first encoded glyph index is 1.  Hence, we read the char */
1726     /* code (`glyph_code') at index j and make the assignment:            */
1727     /*                                                                    */
1728     /*    encoding->codes[glyph_code] = j + 1                             */
1729     /*                                                                    */
1730     /* We also make the assignment:                                       */
1731     /*                                                                    */
1732     /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */
1733     /*                                                                    */
1734     /* This gives us both a code to GID and a code to SID mapping.        */
1735 
1736     if ( offset > 1 )
1737     {
1738 
1739       encoding->offset = base_offset + offset;
1740 
1741       /* we need to parse the table to determine its size */
1742       if ( FT_STREAM_SEEK( encoding->offset ) ||
1743            FT_READ_BYTE( encoding->format )   ||
1744            FT_READ_BYTE( count )              )
1745         goto Exit;
1746 
1747       encoding->count = count + 1;
1748 
1749       switch ( encoding->format & 0x7F )
1750       {
1751       case 0:
1752         {
1753           FT_Byte*  p;
1754 
1755 
1756           if ( FT_FRAME_ENTER( count ) )
1757             goto Exit;
1758 
1759           p = (FT_Byte*)stream->cursor;
1760 
1761           for ( j = 1; j <= count; j++ )
1762           {
1763             glyph_code = *p++;
1764 
1765             /* Make sure j is not too big. */
1766             if ( (FT_UInt) glyph_code < num_glyphs )
1767             {
1768               /* Assign code to GID mapping. */
1769               encoding->codes[glyph_code] = (FT_UShort)j;
1770 
1771               /* Assign code to SID mapping. */
1772               encoding->sids[glyph_code] = charset->sids[j];
1773             }
1774           }
1775 
1776           FT_FRAME_EXIT();
1777         }
1778         break;
1779 
1780       case 1:
1781         {
1782           FT_Byte  nleft;
1783           FT_UInt  i = 1;
1784           FT_UInt  k;
1785 
1786 
1787           /* Parse the Format1 ranges. */
1788           for ( j = 0;  j < count; j++, i += nleft )
1789           {
1790             /* Read the first glyph code of the range. */
1791             if ( FT_READ_BYTE( glyph_code ) )
1792               goto Exit;
1793 
1794             /* Read the number of codes in the range. */
1795             if ( FT_READ_BYTE( nleft ) )
1796               goto Exit;
1797 
1798             /* Increment nleft, so we read `nleft + 1' codes/sids. */
1799             nleft++;
1800 
1801             /* Fill in the range of codes/sids. */
1802             for ( k = i; k < nleft + i; k++, glyph_code++ )
1803             {
1804               /* Make sure k is not too big. */
1805               if ( k < num_glyphs && glyph_code < 256 )
1806               {
1807                 /* Assign code to GID mapping. */
1808                 encoding->codes[glyph_code] = (FT_UShort)k;
1809 
1810                 /* Assign code to SID mapping. */
1811                 encoding->sids[glyph_code] = charset->sids[k];
1812               }
1813             }
1814           }
1815         }
1816         break;
1817 
1818       default:
1819         FT_ERROR(( "cff_encoding_load: invalid table format!\n" ));
1820         error = CFF_Err_Invalid_File_Format;
1821         goto Exit;
1822       }
1823 
1824       /* Parse supplemental encodings, if any. */
1825       if ( encoding->format & 0x80 )
1826       {
1827         FT_UInt  gindex;
1828 
1829 
1830         /* count supplements */
1831         if ( FT_READ_BYTE( count ) )
1832           goto Exit;
1833 
1834         for ( j = 0; j < count; j++ )
1835         {
1836           /* Read supplemental glyph code. */
1837           if ( FT_READ_BYTE( glyph_code ) )
1838             goto Exit;
1839 
1840           /* Read the SID associated with this glyph code. */
1841           if ( FT_READ_USHORT( glyph_sid ) )
1842             goto Exit;
1843 
1844           /* Assign code to SID mapping. */
1845           encoding->sids[glyph_code] = glyph_sid;
1846 
1847           /* First, lookup GID which has been assigned to */
1848           /* SID glyph_sid.                               */
1849           for ( gindex = 0; gindex < num_glyphs; gindex++ )
1850           {
1851             if ( charset->sids[gindex] == glyph_sid )
1852             {
1853               encoding->codes[glyph_code] = (FT_UShort) gindex;
1854               break;
1855             }
1856           }
1857         }
1858       }
1859     }
1860     else
1861     {
1862       FT_UInt i;
1863 
1864 
1865       /* We take into account the fact a CFF font can use a predefined  */
1866       /* encoding without containing all of the glyphs encoded by this  */
1867       /* encoding (see the note at the end of section 12 in the CFF     */
1868       /* specification).                                                */
1869 
1870       encoding->count = 256;
1871 
1872       switch ( (FT_UInt)offset )
1873       {
1874       case 0:
1875         /* First, copy the code to SID mapping. */
1876         FT_MEM_COPY( encoding->sids, cff_standard_encoding,
1877                      256 * sizeof ( FT_UShort ) );
1878 
1879         goto Populate;
1880 
1881       case 1:
1882         /* First, copy the code to SID mapping. */
1883         FT_MEM_COPY( encoding->sids, cff_expert_encoding,
1884                      256 * sizeof ( FT_UShort ) );
1885 
1886       Populate:
1887         /* Construct code to GID mapping from code to SID mapping */
1888         /* and charset.                                           */
1889         for ( j = 0; j < 256; j++ )
1890         {
1891           /* If j is encoded, find the GID for it. */
1892           if ( encoding->sids[j] )
1893           {
1894             for ( i = 1; i < num_glyphs; i++ )
1895               /* We matched, so break. */
1896               if ( charset->sids[i] == encoding->sids[j] )
1897                 break;
1898 
1899             /* i will be equal to num_glyphs if we exited the above */
1900             /* loop without a match.  In this case, we also have to */
1901             /* fix the code to SID mapping.                         */
1902             if ( i == num_glyphs )
1903             {
1904               encoding->codes[j] = 0;
1905               encoding->sids [j] = 0;
1906             }
1907             else
1908               encoding->codes[j] = (FT_UShort)i;
1909           }
1910         }
1911         break;
1912 
1913       default:
1914         FT_ERROR(( "cff_encoding_load: invalid table format!\n" ));
1915         error = CFF_Err_Invalid_File_Format;
1916         goto Exit;
1917       }
1918     }
1919 
1920   Exit:
1921 
1922     /* Clean up if there was an error. */
1923     return error;
1924   }
1925 
1926 
1927   static FT_Error
cff_subfont_load(CFF_SubFont font,CFF_Index idx,FT_UInt font_index,FT_Stream stream,FT_ULong base_offset)1928   cff_subfont_load( CFF_SubFont  font,
1929                     CFF_Index    idx,
1930                     FT_UInt      font_index,
1931                     FT_Stream    stream,
1932                     FT_ULong     base_offset )
1933   {
1934     FT_Error         error;
1935     CFF_ParserRec    parser;
1936     FT_Byte*         dict;
1937     FT_ULong         dict_len;
1938     CFF_FontRecDict  top  = &font->font_dict;
1939     CFF_Private      priv = &font->private_dict;
1940 
1941 
1942     cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict );
1943 
1944     /* set defaults */
1945     FT_MEM_ZERO( top, sizeof ( *top ) );
1946 
1947     top->underline_position  = -100;
1948     top->underline_thickness = 50;
1949     top->charstring_type     = 2;
1950     top->font_matrix.xx      = 0x10000L;
1951     top->font_matrix.yy      = 0x10000L;
1952     top->cid_count           = 8720;
1953 
1954     error = cff_index_access_element( idx, font_index, &dict, &dict_len ) ||
1955             cff_parser_run( &parser, dict, dict + dict_len );
1956 
1957     cff_index_forget_element( idx, &dict );
1958 
1959     if ( error )
1960       goto Exit;
1961 
1962     /* if it is a CID font, we stop there */
1963     if ( top->cid_registry )
1964       goto Exit;
1965 
1966     /* parse the private dictionary, if any */
1967     if ( top->private_offset && top->private_size )
1968     {
1969       /* set defaults */
1970       FT_MEM_ZERO( priv, sizeof ( *priv ) );
1971 
1972       priv->blue_shift       = 7;
1973       priv->blue_fuzz        = 1;
1974       priv->lenIV            = -1;
1975       priv->expansion_factor = (FT_Fixed)0.06 * 0x10000L;
1976       priv->blue_scale       = (FT_Fixed)0.039625 * 0x10000L;
1977 
1978       cff_parser_init( &parser, CFF_CODE_PRIVATE, priv );
1979 
1980       if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
1981            FT_FRAME_ENTER( font->font_dict.private_size )                 )
1982         goto Exit;
1983 
1984       error = cff_parser_run( &parser,
1985                               (FT_Byte*)stream->cursor,
1986                               (FT_Byte*)stream->limit );
1987       FT_FRAME_EXIT();
1988       if ( error )
1989         goto Exit;
1990     }
1991 
1992     /* read the local subrs, if any */
1993     if ( priv->local_subrs_offset )
1994     {
1995       if ( FT_STREAM_SEEK( base_offset + top->private_offset +
1996                            priv->local_subrs_offset ) )
1997         goto Exit;
1998 
1999       error = cff_new_index( &font->local_subrs_index, stream, 1 );
2000       if ( error )
2001         goto Exit;
2002 
2003       font->num_local_subrs = font->local_subrs_index.count;
2004       error = cff_index_get_pointers( &font->local_subrs_index,
2005                                       &font->local_subrs );
2006       if ( error )
2007         goto Exit;
2008     }
2009 
2010   Exit:
2011     return error;
2012   }
2013 
2014 
2015   static void
cff_subfont_done(FT_Memory memory,CFF_SubFont subfont)2016   cff_subfont_done( FT_Memory    memory,
2017                     CFF_SubFont  subfont )
2018   {
2019     if ( subfont )
2020     {
2021       cff_done_index( &subfont->local_subrs_index );
2022       FT_FREE( subfont->local_subrs );
2023     }
2024   }
2025 
2026 
2027   FT_LOCAL_DEF( FT_Error )
cff_font_load(FT_Stream stream,FT_Int face_index,CFF_Font font)2028   cff_font_load( FT_Stream  stream,
2029                  FT_Int     face_index,
2030                  CFF_Font   font )
2031   {
2032     static const FT_Frame_Field  cff_header_fields[] =
2033     {
2034 #undef  FT_STRUCTURE
2035 #define FT_STRUCTURE  CFF_FontRec
2036 
2037       FT_FRAME_START( 4 ),
2038         FT_FRAME_BYTE( version_major ),
2039         FT_FRAME_BYTE( version_minor ),
2040         FT_FRAME_BYTE( header_size ),
2041         FT_FRAME_BYTE( absolute_offsize ),
2042       FT_FRAME_END
2043     };
2044 
2045     FT_Error         error;
2046     FT_Memory        memory = stream->memory;
2047     FT_ULong         base_offset;
2048     CFF_FontRecDict  dict;
2049 
2050     FT_ZERO( font );
2051 
2052     font->stream = stream;
2053     font->memory = memory;
2054     dict         = &font->top_font.font_dict;
2055     base_offset  = FT_STREAM_POS();
2056 
2057     /* read CFF font header */
2058     if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
2059       goto Exit;
2060 
2061     /* check format */
2062     if ( font->version_major   != 1 ||
2063          font->header_size      < 4 ||
2064          font->absolute_offsize > 4 )
2065     {
2066       FT_TRACE2(( "[not a CFF font header!]\n" ));
2067       error = CFF_Err_Unknown_File_Format;
2068       goto Exit;
2069     }
2070 
2071     /* skip the rest of the header */
2072     if ( FT_STREAM_SKIP( font->header_size - 4 ) )
2073       goto Exit;
2074 
2075     /* read the name, top dict, string and global subrs index */
2076     if ( FT_SET_ERROR( cff_new_index( &font->name_index,         stream, 0 )) ||
2077          FT_SET_ERROR( cff_new_index( &font->font_dict_index,    stream, 0 )) ||
2078          FT_SET_ERROR( cff_new_index( &font->string_index,       stream, 0 )) ||
2079          FT_SET_ERROR( cff_new_index( &font->global_subrs_index, stream, 1 )) )
2080       goto Exit;
2081 
2082     /* well, we don't really forget the `disabled' fonts... */
2083     font->num_faces = font->name_index.count;
2084     if ( face_index >= (FT_Int)font->num_faces )
2085     {
2086       FT_ERROR(( "cff_font_load: incorrect face index = %d\n",
2087                  face_index ));
2088       error = CFF_Err_Invalid_Argument;
2089     }
2090 
2091     /* in case of a font format check, simply exit now */
2092     if ( face_index < 0 )
2093       goto Exit;
2094 
2095     /* now, parse the top-level font dictionary */
2096     error = cff_subfont_load( &font->top_font,
2097                               &font->font_dict_index,
2098                               face_index,
2099                               stream,
2100                               base_offset );
2101     if ( error )
2102       goto Exit;
2103 
2104     /* now, check for a CID font */
2105     if ( dict->cid_registry )
2106     {
2107       CFF_IndexRec  fd_index;
2108       CFF_SubFont   sub;
2109       FT_UInt       idx;
2110 
2111 
2112       /* this is a CID-keyed font, we must now allocate a table of */
2113       /* sub-fonts, then load each of them separately              */
2114       if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
2115         goto Exit;
2116 
2117       error = cff_new_index( &fd_index, stream, 0 );
2118       if ( error )
2119         goto Exit;
2120 
2121       if ( fd_index.count > CFF_MAX_CID_FONTS )
2122       {
2123         FT_ERROR(( "cff_font_load: FD array too large in CID font\n" ));
2124         goto Fail_CID;
2125       }
2126 
2127       /* allocate & read each font dict independently */
2128       font->num_subfonts = fd_index.count;
2129       if ( FT_NEW_ARRAY( sub, fd_index.count ) )
2130         goto Fail_CID;
2131 
2132       /* setup pointer table */
2133       for ( idx = 0; idx < fd_index.count; idx++ )
2134         font->subfonts[idx] = sub + idx;
2135 
2136       /* now load each sub font independently */
2137       for ( idx = 0; idx < fd_index.count; idx++ )
2138       {
2139         sub = font->subfonts[idx];
2140         error = cff_subfont_load( sub, &fd_index, idx,
2141                                   stream, base_offset );
2142         if ( error )
2143           goto Fail_CID;
2144       }
2145 
2146       /* now load the FD Select array */
2147       error = CFF_Load_FD_Select( &font->fd_select,
2148                                   (FT_UInt)dict->cid_count,
2149                                   stream,
2150                                   base_offset + dict->cid_fd_select_offset );
2151 
2152     Fail_CID:
2153       cff_done_index( &fd_index );
2154 
2155       if ( error )
2156         goto Exit;
2157     }
2158     else
2159       font->num_subfonts = 0;
2160 
2161     /* read the charstrings index now */
2162     if ( dict->charstrings_offset == 0 )
2163     {
2164       FT_ERROR(( "cff_font_load: no charstrings offset!\n" ));
2165       error = CFF_Err_Unknown_File_Format;
2166       goto Exit;
2167     }
2168 
2169     if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
2170       goto Exit;
2171 
2172     error = cff_new_index( &font->charstrings_index, stream, 0 );
2173     if ( error )
2174       goto Exit;
2175 
2176     /* explicit the global subrs */
2177     font->num_global_subrs = font->global_subrs_index.count;
2178     font->num_glyphs       = font->charstrings_index.count;
2179 
2180     error = cff_index_get_pointers( &font->global_subrs_index,
2181                                     &font->global_subrs ) ;
2182 
2183     if ( error )
2184       goto Exit;
2185 
2186     /* read the Charset and Encoding tables when available */
2187     if ( font->num_glyphs > 0 )
2188     {
2189       error = cff_charset_load( &font->charset, font->num_glyphs, stream,
2190                               base_offset, dict->charset_offset );
2191       if ( error )
2192         goto Exit;
2193 
2194       error = cff_encoding_load( &font->encoding,
2195                                  &font->charset,
2196                                  font->num_glyphs,
2197                                  stream,
2198                                  base_offset,
2199                                  dict->encoding_offset );
2200       if ( error )
2201         goto Exit;
2202     }
2203 
2204     /* get the font name */
2205     font->font_name = cff_index_get_name( &font->name_index, face_index );
2206 
2207   Exit:
2208     return error;
2209   }
2210 
2211 
2212   FT_LOCAL_DEF( void )
cff_font_done(CFF_Font font)2213   cff_font_done( CFF_Font  font )
2214   {
2215     FT_Memory  memory = font->memory;
2216     FT_UInt    idx;
2217 
2218 
2219     cff_done_index( &font->global_subrs_index );
2220     cff_done_index( &font->string_index );
2221     cff_done_index( &font->font_dict_index );
2222     cff_done_index( &font->name_index );
2223     cff_done_index( &font->charstrings_index );
2224 
2225     /* release font dictionaries, but only if working with */
2226     /* a CID keyed CFF font                                */
2227     if ( font->num_subfonts > 0 )
2228     {
2229       for ( idx = 0; idx < font->num_subfonts; idx++ )
2230         cff_subfont_done( memory, font->subfonts[idx] );
2231 
2232       FT_FREE( font->subfonts );
2233     }
2234 
2235     cff_encoding_done( &font->encoding );
2236     cff_charset_done( &font->charset, font->stream );
2237 
2238     cff_subfont_done( memory, &font->top_font );
2239 
2240     CFF_Done_FD_Select( &font->fd_select, font->stream );
2241 
2242     FT_FREE( font->global_subrs );
2243     FT_FREE( font->font_name );
2244   }
2245 
2246 
2247 /* END */
2248