/[freetype]/freetype2/src/sfnt/ttcmap.c
ViewVC logotype

Diff of /freetype2/src/sfnt/ttcmap.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.57 by olvaffe, Tue Nov 29 11:27:51 2005 UTC revision 1.58 by olvaffe, Tue Nov 29 11:32:53 2005 UTC
# Line 625  Line 625 
625    
626  #ifdef TT_CONFIG_CMAP_FORMAT_4  #ifdef TT_CONFIG_CMAP_FORMAT_4
627    
 #define  OPT_CMAP4  
   
 #ifdef OPT_CMAP4  
   
628    typedef struct  TT_CMap4Rec_    typedef struct  TT_CMap4Rec_
629    {    {
630      TT_CMapRec  cmap;      TT_CMapRec  cmap;
     FT_UInt32   old_charcode;   /* old charcode */  
631      FT_UInt32   cur_charcode;   /* current charcode */      FT_UInt32   cur_charcode;   /* current charcode */
632      FT_UInt     cur_gindex;     /* current glyph index */      FT_UInt     cur_gindex;     /* current glyph index */
633    
     FT_UInt     table_length;  
634      FT_UInt     num_ranges;      FT_UInt     num_ranges;
635      FT_UInt     cur_range;      FT_UInt     cur_range;
636      FT_UInt     cur_start;      FT_UInt     cur_start;
# Line 656  Line 650 
650    
651      cmap->cmap.data    = table;      cmap->cmap.data    = table;
652    
     p                  = table + 2;  
     cmap->table_length = FT_PEEK_USHORT( p );  
   
653      p                  = table + 6;      p                  = table + 6;
654      cmap->num_ranges   = FT_PEEK_USHORT( p ) >> 1;      cmap->num_ranges   = FT_PEEK_USHORT( p ) >> 1;
655      cmap->cur_range    = cmap->num_ranges;      cmap->cur_charcode = 0xFFFFFFFFUL;
     cmap->old_charcode = 0xFFFFFFFFUL;  
     cmap->cur_charcode = 0;  
656      cmap->cur_gindex   = 0;      cmap->cur_gindex   = 0;
657    
658      return SFNT_Err_Ok;      return SFNT_Err_Ok;
# Line 707  Line 696 
696        range_index++;        range_index++;
697      }      }
698    
     cmap->old_charcode = 0xFFFFFFFFUL;  
     cmap->cur_charcode = 0;  
     cmap->cur_gindex   = 0;  
     cmap->cur_range    = num_ranges;  
699      return -1;      return -1;
700    }    }
701    
702    
703      /* find the index of the charcode next to cmap->cur_charcode; */
704      /* caller should call tt_cmap4_set_range with proper range    */
705      /* before calling this function                               */
706      /*                                                            */
707    static void    static void
708    tt_cmap4_next( TT_CMap4  cmap )    tt_cmap4_next( TT_CMap4  cmap )
709    {    {
710      FT_UInt  charcode   = cmap->cur_charcode + 1;      FT_UInt  charcode;
711        
712    
713        if ( cmap->cur_charcode >= 0xFFFFUL )
714          goto Fail;
715    
716        charcode = cmap->cur_charcode + 1;
717    
718      cmap->old_charcode = cmap->cur_charcode;      if ( charcode < cmap->cur_start )
719          charcode = cmap->cur_start;
720    
721      for ( ;; )      for ( ;; )
722      {      {
# Line 775  Line 770 
770        if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 )        if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 )
771          break;          break;
772    
773        charcode = cmap->cur_start;        if ( charcode < cmap->cur_start )
774            charcode = cmap->cur_start;
775      }      }
   }  
776    
777      Fail:
778    static void      cmap->cur_charcode = 0xFFFFFFFFUL;
779    tt_cmap4_reset( TT_CMap4  cmap,      cmap->cur_gindex   = 0;
                   FT_UInt   code,  
                   FT_UInt   range_index )  
   {  
     if ( tt_cmap4_set_range( cmap, range_index ) >= 0 )  
     {  
       cmap->cur_charcode = code;  
       tt_cmap4_next( cmap );  
     }  
780    }    }
781    
 #endif /* OPT_CMAP4 */  
   
   
782    
783    FT_CALLBACK_DEF( FT_Error )    FT_CALLBACK_DEF( FT_Error )
784    tt_cmap4_validate( FT_Byte*      table,    tt_cmap4_validate( FT_Byte*      table,
# Line 807  Line 791 
791      FT_Error  error = SFNT_Err_Ok;      FT_Error  error = SFNT_Err_Ok;
792    
793    
     /* in certain fonts, the `length' field is invalid and goes */  
     /* out of bound.  We try to correct this here...            */  
794      if ( length < 16 )      if ( length < 16 )
795        FT_INVALID_TOO_SHORT;        FT_INVALID_TOO_SHORT;
796    
797        /* in certain fonts, the `length' field is invalid and goes */
798        /* out of bound.  We try to correct this here...            */
799      if ( table + length > valid->limit )      if ( table + length > valid->limit )
800      {      {
801        if ( valid->level >= FT_VALIDATE_TIGHT )        if ( valid->level >= FT_VALIDATE_TIGHT )
# Line 832  Line 816 
816    
817      num_segs /= 2;      num_segs /= 2;
818    
819        if ( length < 16 + num_segs * 2 * 4 )
820          FT_INVALID_TOO_SHORT;
821    
822      /* check the search parameters - even though we never use them */      /* check the search parameters - even though we never use them */
823      /*                                                             */      /*                                                             */
824      if ( valid->level >= FT_VALIDATE_PARANOID )      if ( valid->level >= FT_VALIDATE_PARANOID )
# Line 863  Line 850 
850      offsets   = deltas  + num_segs * 2;      offsets   = deltas  + num_segs * 2;
851      glyph_ids = offsets + num_segs * 2;      glyph_ids = offsets + num_segs * 2;
852    
     if ( glyph_ids > table + length )  
       FT_INVALID_TOO_SHORT;  
   
853      /* check last segment, its end count must be FFFF */      /* check last segment, its end count must be FFFF */
854      if ( valid->level >= FT_VALIDATE_PARANOID )      if ( valid->level >= FT_VALIDATE_PARANOID )
855      {      {
# Line 874  Line 858 
858          FT_INVALID_DATA;          FT_INVALID_DATA;
859      }      }
860    
     /* check that segments are sorted in increasing order and do not */  
     /* overlap; check also the offsets                               */  
861      {      {
862        FT_UInt  start, end, last = 0, offset, n;        FT_UInt  start, end, offset, n;
863          FT_UInt  last_start = 0, last_end = 0;
864        FT_Int   delta;        FT_Int   delta;
865    
866    
# Line 899  Line 882 
882          /* unfortunately, some popular Asian fonts present overlapping */          /* unfortunately, some popular Asian fonts present overlapping */
883          /* ranges in their charmaps                                    */          /* ranges in their charmaps                                    */
884          /*                                                             */          /*                                                             */
885          if ( n > 0 && start <= last )          if ( start <= last_end && n > 0 )
886          {          {
887            if ( valid->level >= FT_VALIDATE_TIGHT )            if ( valid->level >= FT_VALIDATE_TIGHT )
888              FT_INVALID_DATA;              FT_INVALID_DATA;
889            else            else
890              error = SFNT_Err_Invalid_CharMap_Format;            {
891                /* allow overlapping segments, provided their start points */
892                /* and end points, respectively, are in ascending order.   */
893                /*                                                         */
894                if ( last_start > start || last_end > end )
895                  error |= TT_CMAP_FLAG_UNSORTED;
896                else
897                  error |= TT_CMAP_FLAG_OVERLAPPED;
898              }
899          }          }
900    
901          if ( offset && offset != 0xFFFFU )          if ( offset && offset != 0xFFFFU )
# Line 955  Line 946 
946              FT_INVALID_DATA;              FT_INVALID_DATA;
947          }          }
948    
949          last = end;          last_start = start;
950            last_end = end;
951        }        }
952      }      }
953    
# Line 963  Line 955 
955    }    }
956    
957    
958    FT_CALLBACK_DEF( FT_UInt )    static FT_UInt
959    tt_cmap4_char_index( TT_CMap    cmap,    tt_cmap4_char_map_linear( TT_CMap   cmap,
960                         FT_UInt32  char_code )                              FT_UInt*  pcharcode,
961    {                              FT_Bool   next )
962      FT_Byte*  table  = cmap->data;    {
963      FT_UInt   result = 0;      FT_UInt    num_segs2, start, end, offset;
964        FT_Int     delta;
965        FT_UInt    i, num_segs;
966        FT_UInt32  charcode = *pcharcode;
967        FT_UInt    gindex    = 0;
968        FT_Byte*   p;
969    
970    
971      if ( char_code < 0x10000UL )      p = cmap->data + 6;
972      {      num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
       FT_UInt   idx, num_segs2;  
       FT_Int    delta;  
       FT_UInt   code = (FT_UInt)char_code;  
       FT_Byte*  p;  
973    
974        p         = table + 6;      num_segs = num_segs2 >> 1;
       num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );  /* be paranoid! */  
   
       if ( !cmap->unsorted )  
       {  
         /* Some fonts have more than 170 segments in their charmaps! */  
         /* We changed this function to use a more efficient binary   */  
         /* search for improving performance                          */  
         FT_UInt  min = 0;  
         FT_UInt  max = num_segs2 >> 1;  
         FT_UInt  mid, start, end, offset;  
975    
976        if ( !num_segs )
977          return 0;
978    
979          while ( min < max )      if ( next )
980          {        charcode++;
           mid   = ( min + max ) >> 1;  
           p     = table + 14 + mid * 2;  
           end   = TT_NEXT_USHORT( p );  
           p    += num_segs2;  
           start = TT_PEEK_USHORT( p);  
   
           if ( code < start )  
             max = mid;  
           else if ( code > end )  
             min = mid + 1;  
           else  
           {  
             /* we found the segment */  
             idx = code;  
981    
982              p += num_segs2;      /* linear search */
983              delta = TT_PEEK_SHORT( p );      for ( ; charcode <= 0xFFFFU; charcode++ )
984        {
985          FT_Byte*  q;
986          
987    
988              p += num_segs2;        p = cmap->data + 14;               /* ends table   */
989              offset = TT_PEEK_USHORT( p );        q = cmap->data + 16 + num_segs2;   /* starts table */
990    
991              if ( offset == 0xFFFFU )        for ( i = 0; i < num_segs; i++ )
992                goto Exit;        {
993            end   = TT_NEXT_USHORT( p );
994            start = TT_NEXT_USHORT( q );
995    
996              if ( offset != 0 )          if ( charcode >= start && charcode <= end )
997              {          {
998                p  += offset + 2 * ( idx - start );            p       = q - 2 + num_segs2;
999                idx = TT_PEEK_USHORT( p );            delta   = TT_PEEK_SHORT( p );
1000              }            p      += num_segs2;
1001              offset  = TT_PEEK_USHORT( p );
1002    
1003              if ( idx != 0 )            if ( offset == 0xFFFFU )
1004                result = (FT_UInt)( idx + delta ) & 0xFFFFU;              continue;
1005    
1006              goto Exit;            if ( offset )
1007              {
1008                p += offset + ( charcode - start ) * 2;
1009                gindex = TT_PEEK_USHORT( p );
1010                if ( gindex != 0 )
1011                  gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;
1012            }            }
1013              else
1014                gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU;
1015    
1016              break;
1017          }          }
1018        }        }
       else  
       {  
         FT_UInt   n;  
         FT_Byte*  q;  
1019    
1020          if ( !next || gindex )
1021            break;
1022        }
1023    
1024          p = table + 14;               /* ends table   */      if ( next && gindex )
1025          q = table + 16 + num_segs2;   /* starts table */        *pcharcode = charcode;
1026    
1027        return gindex;
1028      }
1029    
         for ( n = 0; n < num_segs2; n += 2 )  
         {  
           FT_UInt  end   = TT_NEXT_USHORT( p );  
           FT_UInt  start = TT_NEXT_USHORT( q );  
           FT_UInt  offset;  
1030    
1031      static FT_UInt
1032      tt_cmap4_char_map_binary( TT_CMap     cmap,
1033                                FT_UInt*    pcharcode,
1034                                FT_Bool     next )
1035      {
1036        FT_UInt   num_segs2, start, end, offset;
1037        FT_Int    delta;
1038        FT_UInt   max, min, mid, num_segs;
1039        FT_UInt   charcode = *pcharcode;
1040        FT_UInt   gindex    = 0;
1041        FT_Byte*  p;
1042        
1043    
1044            if ( code < start )      p = cmap->data + 6;
1045              break;      num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
1046    
1047            if ( code <= end )      num_segs = num_segs2 >> 1;
           {  
             idx = code;  
1048    
1049              p = q + num_segs2 - 2;      if ( !num_segs )
1050              delta = TT_PEEK_SHORT( p );        return 0;
             p += num_segs2;  
             offset = TT_PEEK_USHORT( p );  
1051    
1052              if ( offset == 0xFFFFU )      if ( next )
1053                goto Exit;        charcode++;
1054    
1055              if ( offset != 0 )      min = 0;
1056              {      max = num_segs;
               p  += offset + 2 * ( idx - start );  
               idx = TT_PEEK_USHORT( p );  
             }  
1057    
1058              if ( idx != 0 )      /* binary search */
1059                result = (FT_UInt)( idx + delta ) & 0xFFFFU;      while ( min < max )
1060            }      {
1061          }        mid    = ( min + max ) >> 1;
1062        }        p      = cmap->data + 14 + mid * 2;
1063      }        end    = TT_PEEK_USHORT( p );
1064          p     += 2 + num_segs2;
1065          start  = TT_PEEK_USHORT( p );
1066    
1067    Exit:        if ( charcode < start )
1068      return result;          max = mid;
1069    }        else if ( charcode > end )
1070            min = mid + 1;
1071          else
1072          {
1073            p      += num_segs2;
1074            delta   = TT_PEEK_SHORT( p );
1075            p      += num_segs2;
1076            offset  = TT_PEEK_USHORT( p );
1077    
1078            /* find the first segment containing `charcode' */
1079            if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPED )
1080            {
1081              FT_UInt  i;
1082    
   FT_CALLBACK_DEF( FT_UInt )  
   tt_cmap4_char_next( TT_CMap     cmap,  
                       FT_UInt32  *pchar_code )  
   {  
     FT_Byte*   table     = cmap->data;  
     FT_UInt32  result    = 0;  
     FT_UInt    gindex    = 0;  
     FT_UInt32  char_code = *pchar_code;  
     FT_Byte*   p;  
     FT_UInt    code, num_segs2;  
1083    
1084              /* call the current segment `max' */
1085              max = mid;
1086    
1087      if ( char_code >= 0xFFFFUL )            if ( offset == 0xFFFFU )
1088        goto Exit;              mid = max + 1;
1089    
1090  #ifdef OPT_CMAP4            /* find in segments before the current segment */
1091        {            for ( i = max ; i > 0; i-- )
1092          TT_CMap4  cmap4 = (TT_CMap4)cmap;            {
1093                FT_UInt  prev_end;
1094    
1095    
1096          if ( char_code == cmap4->old_charcode )              p = cmap->data + 14 + ( i - 1 ) * 2;
1097          {              prev_end = TT_PEEK_USHORT( p );
           result = cmap4->cur_charcode;  
           gindex = cmap4->cur_gindex;  
           if ( result != 0 )  
           {  
             tt_cmap4_next( cmap4 );  
             goto Exit;  
           }  
         }  
       }  
 #endif /* OPT_CMAP4 */  
1098    
1099      code      = (FT_UInt)char_code + 1;              if ( charcode > prev_end )
1100      p         = table + 6;                break;
     num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); /* ensure even-ness */  
   
     if ( !cmap->unsorted )  
     {  
       for (;;)  
       {  
         /* Some fonts have more than 170 segments in their charmaps! */  
         /* We changed this function to use a more efficient binary   */  
         /* search                                                    */  
         FT_UInt  offset;  
         FT_Int   delta;  
         FT_UInt  min = 0;  
         FT_UInt  max = num_segs2 >> 1;  
         FT_UInt  mid, start, end;  
         FT_UInt  hi;  
   
   
         /* we begin by finding the segment which end is  
            closer to our code point */  
         hi = max + 1;  
         while ( min < max )  
         {  
           mid = ( min + max ) >> 1;  
           p   = table + 14 + mid * 2;  
           end = TT_PEEK_USHORT( p );  
1101    
1102            if ( end < code )              end     = prev_end;
1103              min = mid + 1;              p      += 2 + num_segs2;
1104            else              start   = TT_PEEK_USHORT( p );
1105            {              p      += num_segs2;
1106              hi  = mid;              delta   = TT_PEEK_SHORT( p );
1107              max = mid;              p      += num_segs2;
1108                offset  = TT_PEEK_USHORT( p );
1109    
1110                if ( offset != 0xFFFFU )
1111                  mid = i - 1;
1112            }            }
         }  
1113    
1114          if ( hi > max )            /* no luck */
1115          {            if ( mid == max + 1 )
1116            /* the point is behind the last segment;            {
1117               we will exit right now */              if ( i != max )
1118            goto Exit;              {
1119          }                p       = cmap->data + 14 + max * 2;
1120                  end     = TT_PEEK_USHORT( p );
1121                  p      += 2 + num_segs2;
1122                  start   = TT_PEEK_USHORT( p );
1123                  p      += num_segs2;
1124                  delta   = TT_PEEK_SHORT( p );
1125                  p      += num_segs2;
1126                  offset  = TT_PEEK_USHORT( p );
1127                }
1128    
1129          p   = table + 14 + hi * 2;              mid = max;
         end = TT_PEEK_USHORT( p );  
1130    
1131          p    += 2 + num_segs2;              /* find in segments after the current segment */
1132          start = TT_PEEK_USHORT( p );              for ( i = max + 1; i < num_segs; i++ )
1133                {
1134                  FT_UInt  next_end, next_start;
1135    
         if ( code < start )  
           code = start;  
1136    
1137          p    += num_segs2;                p           = cmap->data + 14 + i * 2;
1138          delta = TT_PEEK_USHORT( p );                next_end    = TT_PEEK_USHORT( p );
1139                  p          += 2 + num_segs2;
1140                  next_start  = TT_PEEK_USHORT( p );
1141    
1142                  if ( charcode < next_start )
1143                    break;
1144    
1145                  end     = next_end;
1146                  start   = next_start;
1147                  p      += num_segs2;
1148                  delta   = TT_PEEK_SHORT( p );
1149                  p      += num_segs2;
1150                  offset  = TT_PEEK_USHORT( p );
1151    
1152          p     += num_segs2;                if ( offset != 0xFFFFU )
1153          offset = TT_PEEK_USHORT( p );                  mid = i;
1154                }
1155                i--;
1156    
1157          if ( offset != 0 && offset != 0xFFFFU )              /* still no luck */
1158          {              if ( mid == max )
           /* parse the glyph ids array for non-zero index */  
           p += offset + ( code - start ) * 2;  
           while ( code <= end )  
           {  
             gindex = TT_NEXT_USHORT( p );  
             if ( gindex != 0 )  
1159              {              {
1160                gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;                mid = i;
1161                if ( gindex != 0 )  
1162                {                break;
                 result = code;  
 #ifdef OPT_CMAP4  
                 tt_cmap4_reset( (TT_CMap4)cmap, code, hi );  
 #endif  
                 goto Exit;  
               }  
1163              }              }
1164              code++;            }
1165    
1166              /* end, start, delta and offset are for the i'th segment */
1167              if ( mid != i )
1168              {
1169                p       = cmap->data + 14 + mid * 2;
1170                end     = TT_PEEK_USHORT( p );
1171                p      += 2 + num_segs2;
1172                start   = TT_PEEK_USHORT( p );
1173                p      += num_segs2;
1174                delta   = TT_PEEK_SHORT( p );
1175                p      += num_segs2;
1176                offset  = TT_PEEK_USHORT( p );
1177            }            }
1178          }          }
1179          else if ( offset == 0xFFFFU )          else
1180          {          {
1181            /* an offset of 0xFFFF means an empty segment in certain fonts! */            if ( offset == 0xFFFFU )
1182            code = end + 1;              break;
1183          }          }
1184          else  /* offset == 0 */  
1185            if ( offset )
1186          {          {
1187            gindex = (FT_UInt)( code + delta ) & 0xFFFFU;            p += offset + ( charcode - start ) * 2;
1188              gindex = TT_PEEK_USHORT( p );
1189            if ( gindex != 0 )            if ( gindex != 0 )
1190            {              gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;
             result = code;  
 #ifdef OPT_CMAP4  
             tt_cmap4_reset( (TT_CMap4)cmap, code, hi );  
 #endif  
             goto Exit;  
           }  
           code++;  
1191          }          }
1192            else
1193              gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU;
1194    
1195            break;
1196        }        }
1197      }      }
1198      else  
1199        if ( next )
1200      {      {
1201        for ( ;; )        TT_CMap4  cmap4 = (TT_CMap4)cmap;
       {  
         FT_UInt   offset, n;  
         FT_Int    delta;  
         FT_Byte*  q;  
1202    
1203    
1204          p = table + 14;              /* ends table  */        /* if `charcode' is not in any segment, then `mid' is */
1205          q = table + 16 + num_segs2;  /* starts table */        /* the segment nearest to `charcode'                  */
1206          /*                                                    */
1207    
1208          for ( n = 0; n < num_segs2; n += 2 )        if ( charcode > end )
1209          {
1210            mid++;
1211            if ( mid == num_segs )
1212              return 0;
1213          }
1214    
1215          if ( tt_cmap4_set_range( cmap4, mid ) )
1216          {
1217            if ( gindex )
1218              *pcharcode = charcode;
1219          }
1220          else
1221          {
1222            cmap4->cur_charcode = charcode;
1223    
1224            if ( gindex )
1225              cmap4->cur_gindex = gindex;
1226            else
1227          {          {
1228            FT_UInt  end   = TT_NEXT_USHORT( p );            cmap4->cur_charcode = charcode;
1229            FT_UInt  start = TT_NEXT_USHORT( q );            tt_cmap4_next( cmap4 );
1230              gindex = cmap4->cur_gindex;
1231            }
1232    
1233            if ( gindex )
1234              *pcharcode = cmap4->cur_charcode;
1235          }
1236        }
1237    
1238            if ( code < start )      return gindex;
1239              code = start;    }
1240    
           if ( code <= end )  
           {  
             p = q + num_segs2 - 2;  
             delta = TT_PEEK_SHORT( p );  
             p += num_segs2;  
             offset = TT_PEEK_USHORT( p );  
1241    
1242              if ( offset != 0 && offset != 0xFFFFU )    FT_CALLBACK_DEF( FT_UInt )
1243              {    tt_cmap4_char_index( TT_CMap    cmap,
1244                /* parse the glyph ids array for non-0 index */                         FT_UInt32  char_code )
1245                p += offset + ( code - start ) * 2;    {
1246                while ( code <= end )      if ( char_code >= 0x10000U )
1247                {        return 0;
                 gindex = TT_NEXT_USHORT( p );  
                 if ( gindex != 0 )  
                 {  
                   gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;  
                   if ( gindex != 0 )  
                     break;  
                 }  
                 code++;  
               }  
             }  
             else if ( offset == 0xFFFFU )  
             {  
               /* an offset of 0xFFFF means an empty glyph in certain fonts! */  
               code = end;  
               break;  
             }  
             else  
               gindex = (FT_UInt)( code + delta ) & 0xFFFFU;  
1248    
1249              if ( gindex == 0 )      if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
1250                break;        return tt_cmap4_char_map_linear( cmap, &char_code, 0 );
1251        else
1252          return tt_cmap4_char_map_binary( cmap, &char_code, 0 );
1253      }
1254    
1255    
1256      FT_CALLBACK_DEF( FT_UInt )
1257      tt_cmap4_char_next( TT_CMap     cmap,
1258                          FT_UInt32  *pchar_code )
1259      {
1260        FT_UInt  gindex;
1261    
1262    
1263        if ( *pchar_code >= 0xFFFFU )
1264          return 0;
1265    
1266        if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
1267          gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 );
1268        else
1269        {
1270          TT_CMap4  cmap4 = (TT_CMap4)cmap;
1271    
             result = code;  
             goto Exit;  
           }  
         }  
         /* loop to next trial charcode */  
         if ( code >= 0xFFFFU )  
           break;  
1272    
1273          code++;        /* no need to search */
1274          if ( *pchar_code == cmap4->cur_charcode )
1275          {
1276            tt_cmap4_next( cmap4 );
1277            gindex = cmap4->cur_gindex;
1278            if ( gindex )
1279              *pchar_code = cmap4->cur_charcode;
1280        }        }
1281          else
1282            gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 );
1283      }      }
1284    
   Exit:  
     *pchar_code = result;  
1285      return gindex;      return gindex;
1286    }    }
1287    
# Line 1305  Line 1303 
1303    const TT_CMap_ClassRec  tt_cmap4_class_rec =    const TT_CMap_ClassRec  tt_cmap4_class_rec =
1304    {    {
1305      {      {
 #ifdef OPT_CMAP4  
1306        sizeof ( TT_CMap4Rec ),        sizeof ( TT_CMap4Rec ),
1307        (FT_CMap_InitFunc)     tt_cmap4_init,        (FT_CMap_InitFunc)     tt_cmap4_init,
 #else  
       sizeof ( TT_CMapRec ),  
       (FT_CMap_InitFunc)     tt_cmap_init,  
 #endif  
1308        (FT_CMap_DoneFunc)     NULL,        (FT_CMap_DoneFunc)     NULL,
1309        (FT_CMap_CharIndexFunc)tt_cmap4_char_index,        (FT_CMap_CharIndexFunc)tt_cmap4_char_index,
1310        (FT_CMap_CharNextFunc) tt_cmap4_char_next        (FT_CMap_CharNextFunc) tt_cmap4_char_next
# Line 2300  Line 2293 
2293    
2294              if ( valid.validator.error == 0 )              if ( valid.validator.error == 0 )
2295              {              {
2296                (void)FT_CMap_New( (FT_CMap_Class)clazz, cmap, &charmap, NULL );                FT_CMap  ttcmap;
2297    
2298                /* it is simpler to directly set the `unsorted' flag instead */  
2299                /* of adding a parameter to FT_CMap_New                      */                if ( !FT_CMap_New( (FT_CMap_Class)clazz, cmap, &charmap, &ttcmap ) )
2300                ((TT_CMap)(face->root.charmaps                {
2301                            [face->root.num_charmaps - 1]))->unsorted =                  /* it is simpler to directly set `flags' than adding */
2302                  FT_BOOL( error );                  /* a parameter to FT_CMap_New                        */
2303                    ((TT_CMap)ttcmap)->flags = (FT_Int)error;
2304                  }
2305              }              }
2306              else              else
2307              {              {

Legend:
Removed from v.1.57  
changed lines
  Added in v.1.58

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26