⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 harfbuzz-open.c

📁 GTK+-2.0源码之pango-1.15.6.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
{  FT_Error   error;  FT_Memory  memory = stream->memory;  FT_UShort         n, count;  HB_RangeRecord*  rr;  if ( ACCESS_Frame( 2L ) )    return error;  count = cf2->RangeCount = GET_UShort();  FORGET_Frame();  cf2->RangeRecord = NULL;  if ( ALLOC_ARRAY( cf2->RangeRecord, count, HB_RangeRecord ) )    return error;  rr = cf2->RangeRecord;  if ( ACCESS_Frame( count * 6L ) )    goto Fail;  for ( n = 0; n < count; n++ )  {    rr[n].Start              = GET_UShort();    rr[n].End                = GET_UShort();    rr[n].StartCoverageIndex = GET_UShort();    /* sanity check; we are limited to 16bit integers */    if ( rr[n].Start > rr[n].End ||	 ( rr[n].End - rr[n].Start + (long)rr[n].StartCoverageIndex ) >=	   0x10000L )    {      error = HB_Err_Invalid_SubTable;      goto Fail;    }  }  FORGET_Frame();  return FT_Err_Ok;Fail:  FREE( cf2->RangeRecord );  return error;}static void  Free_Coverage2( HB_CoverageFormat2*  cf2,			     FT_Memory             memory ){  FREE( cf2->RangeRecord );}FT_Error  _HB_OPEN_Load_Coverage( HB_Coverage*  c,			 FT_Stream      stream ){  FT_Error   error;  if ( ACCESS_Frame( 2L ) )    return error;  c->CoverageFormat = GET_UShort();  FORGET_Frame();  switch ( c->CoverageFormat )  {  case 1:    return Load_Coverage1( &c->cf.cf1, stream );  case 2:    return Load_Coverage2( &c->cf.cf2, stream );  default:    return HB_Err_Invalid_SubTable_Format;  }  return FT_Err_Ok;               /* never reached */}void  _HB_OPEN_Free_Coverage( HB_Coverage*  c,		     FT_Memory      memory ){  switch ( c->CoverageFormat )  {  case 1:    Free_Coverage1( &c->cf.cf1, memory );    break;  case 2:    Free_Coverage2( &c->cf.cf2, memory );    break;  }}static FT_Error  Coverage_Index1( HB_CoverageFormat1*  cf1,				  FT_UShort             glyphID,				  FT_UShort*            index ){  FT_UShort min, max, new_min, new_max, middle;  FT_UShort*  array = cf1->GlyphArray;  /* binary search */  if ( cf1->GlyphCount == 0 )    return HB_Err_Not_Covered;  new_min = 0;  new_max = cf1->GlyphCount - 1;  do  {    min = new_min;    max = new_max;    /* we use (min + max) / 2 = max - (max - min) / 2  to avoid       overflow and rounding errors                             */    middle = max - ( ( max - min ) >> 1 );    if ( glyphID == array[middle] )    {      *index = middle;      return FT_Err_Ok;    }    else if ( glyphID < array[middle] )    {      if ( middle == min )	break;      new_max = middle - 1;    }    else    {      if ( middle == max )	break;      new_min = middle + 1;    }  } while ( min < max );  return HB_Err_Not_Covered;}static FT_Error  Coverage_Index2( HB_CoverageFormat2*  cf2,				  FT_UShort             glyphID,				  FT_UShort*            index ){  FT_UShort         min, max, new_min, new_max, middle;  HB_RangeRecord*  rr = cf2->RangeRecord;  /* binary search */  if ( cf2->RangeCount == 0 )    return HB_Err_Not_Covered;  new_min = 0;  new_max = cf2->RangeCount - 1;  do  {    min = new_min;    max = new_max;    /* we use (min + max) / 2 = max - (max - min) / 2  to avoid       overflow and rounding errors                             */    middle = max - ( ( max - min ) >> 1 );    if ( glyphID >= rr[middle].Start && glyphID <= rr[middle].End )    {      *index = rr[middle].StartCoverageIndex + glyphID - rr[middle].Start;      return FT_Err_Ok;    }    else if ( glyphID < rr[middle].Start )    {      if ( middle == min )	break;      new_max = middle - 1;    }    else    {      if ( middle == max )	break;      new_min = middle + 1;    }  } while ( min < max );  return HB_Err_Not_Covered;}FT_Error  _HB_OPEN_Coverage_Index( HB_Coverage*  c,			  FT_UShort      glyphID,			  FT_UShort*     index ){  switch ( c->CoverageFormat )  {  case 1:    return Coverage_Index1( &c->cf.cf1, glyphID, index );  case 2:    return Coverage_Index2( &c->cf.cf2, glyphID, index );  default:    return HB_Err_Invalid_SubTable_Format;  }  return FT_Err_Ok;               /* never reached */}/************************************* * Class Definition related functions *************************************//* ClassDefFormat1 */static FT_Error  Load_ClassDef1( HB_ClassDefinition*  cd,				 FT_UShort             limit,				 FT_Stream             stream ){  FT_Error   error;  FT_Memory  memory = stream->memory;  FT_UShort             n, count;  FT_UShort*            cva;  FT_Bool*              d;  HB_ClassDefFormat1*  cdf1;  cdf1 = &cd->cd.cd1;  if ( ACCESS_Frame( 4L ) )    return error;  cdf1->StartGlyph         = GET_UShort();  count = cdf1->GlyphCount = GET_UShort();  FORGET_Frame();  /* sanity check; we are limited to 16bit integers */  if ( cdf1->StartGlyph + (long)count >= 0x10000L )    return HB_Err_Invalid_SubTable;  cdf1->ClassValueArray = NULL;  if ( ALLOC_ARRAY( cdf1->ClassValueArray, count, FT_UShort ) )    return error;  d   = cd->Defined;  cva = cdf1->ClassValueArray;  if ( ACCESS_Frame( count * 2L ) )    goto Fail;  for ( n = 0; n < count; n++ )  {    cva[n] = GET_UShort();    if ( cva[n] >= limit )    {      error = HB_Err_Invalid_SubTable;      goto Fail;    }    d[cva[n]] = TRUE;  }  FORGET_Frame();  return FT_Err_Ok;Fail:  FREE( cva );  return error;}static void  Free_ClassDef1( HB_ClassDefFormat1*  cdf1,			     FT_Memory             memory ){  FREE( cdf1->ClassValueArray );}/* ClassDefFormat2 */static FT_Error  Load_ClassDef2( HB_ClassDefinition*  cd,				 FT_UShort             limit,				 FT_Stream             stream ){  FT_Error   error;  FT_Memory  memory = stream->memory;  FT_UShort              n, count;  HB_ClassRangeRecord*  crr;  FT_Bool*               d;  HB_ClassDefFormat2*   cdf2;  cdf2 = &cd->cd.cd2;  if ( ACCESS_Frame( 2L ) )    return error;  count = cdf2->ClassRangeCount = GET_UShort();  FORGET_Frame();  cdf2->ClassRangeRecord = NULL;  if ( ALLOC_ARRAY( cdf2->ClassRangeRecord, count, HB_ClassRangeRecord ) )    return error;  d   = cd->Defined;  crr = cdf2->ClassRangeRecord;  if ( ACCESS_Frame( count * 6L ) )    goto Fail;  for ( n = 0; n < count; n++ )  {    crr[n].Start = GET_UShort();    crr[n].End   = GET_UShort();    crr[n].Class = GET_UShort();    /* sanity check */    if ( crr[n].Start > crr[n].End ||	 crr[n].Class >= limit )    {      error = HB_Err_Invalid_SubTable;      goto Fail;    }    d[crr[n].Class] = TRUE;  }  FORGET_Frame();  return FT_Err_Ok;Fail:  FREE( crr );  return error;}static void  Free_ClassDef2( HB_ClassDefFormat2*  cdf2,			     FT_Memory             memory ){  FREE( cdf2->ClassRangeRecord );}/* ClassDefinition */FT_Error  _HB_OPEN_Load_ClassDefinition( HB_ClassDefinition*  cd,				FT_UShort             limit,				FT_Stream             stream ){  FT_Error   error;  FT_Memory  memory = stream->memory;  if ( ALLOC_ARRAY( cd->Defined, limit, FT_Bool ) )    return error;  if ( ACCESS_Frame( 2L ) )    goto Fail;  cd->ClassFormat = GET_UShort();  FORGET_Frame();  switch ( cd->ClassFormat )  {  case 1:    error = Load_ClassDef1( cd, limit, stream );    break;  case 2:    error = Load_ClassDef2( cd, limit, stream );    break;  default:    error = HB_Err_Invalid_SubTable_Format;    break;  }  if ( error )    goto Fail;  cd->loaded = TRUE;  return FT_Err_Ok;Fail:  FREE( cd->Defined );  return error;}FT_Error  _HB_OPEN_Load_EmptyClassDefinition( HB_ClassDefinition*  cd,				     FT_Stream             stream ){  FT_Error   error;  FT_Memory  memory = stream->memory;  if ( ALLOC_ARRAY( cd->Defined, 1, FT_Bool ) )    return error;  cd->ClassFormat = 1; /* Meaningless */  cd->Defined[0] = FALSE;  if ( ALLOC_ARRAY( cd->cd.cd1.ClassValueArray, 1, FT_UShort ) )    goto Fail;  return FT_Err_Ok;Fail:  FREE( cd->Defined );  return error;}void  _HB_OPEN_Free_ClassDefinition( HB_ClassDefinition*  cd,			    FT_Memory             memory ){  if ( !cd->loaded )    return;  FREE( cd->Defined );  switch ( cd->ClassFormat )  {  case 1:    Free_ClassDef1( &cd->cd.cd1, memory );    break;  case 2:    Free_ClassDef2( &cd->cd.cd2, memory );    break;  }}static FT_Error  Get_Class1( HB_ClassDefFormat1*  cdf1,			     FT_UShort             glyphID,			     FT_UShort*            class,			     FT_UShort*            index ){  FT_UShort*  cva = cdf1->ClassValueArray;  if ( index )    *index = 0;  if ( glyphID >= cdf1->StartGlyph &&       glyphID <= cdf1->StartGlyph + cdf1->GlyphCount )  {    *class = cva[glyphID - cdf1->StartGlyph];    return FT_Err_Ok;  }  else  {    *class = 0;    return HB_Err_Not_Covered;  }}/* we need the index value of the last searched class range record   in case of failure for constructed GDEF tables                  */static FT_Error  Get_Class2( HB_ClassDefFormat2*  cdf2,			     FT_UShort             glyphID,			     FT_UShort*            class,			     FT_UShort*            index ){  FT_Error               error = FT_Err_Ok;  FT_UShort              min, max, new_min, new_max, middle;  HB_ClassRangeRecord*  crr = cdf2->ClassRangeRecord;  /* binary search */  if ( cdf2->ClassRangeCount == 0 )    {      *class = 0;      if ( index )	*index = 0;            return HB_Err_Not_Covered;    }  new_min = 0;  new_max = cdf2->ClassRangeCount - 1;  do  {    min = new_min;    max = new_max;    /* we use (min + max) / 2 = max - (max - min) / 2  to avoid       overflow and rounding errors                             */    middle = max - ( ( max - min ) >> 1 );    if ( glyphID >= crr[middle].Start && glyphID <= crr[middle].End )    {      *class = crr[middle].Class;      error  = FT_Err_Ok;      break;    }    else if ( glyphID < crr[middle].Start )    {      if ( middle == min )      {	*class = 0;	error  = HB_Err_Not_Covered;	break;      }      new_max = middle - 1;    }    else    {      if ( middle == max )      {	*class = 0;	error  = HB_Err_Not_Covered;	break;      }      new_min = middle + 1;    }  } while ( min < max );  if ( index )    *index = middle;  return error;}FT_Error  _HB_OPEN_Get_Class( HB_ClassDefinition*  cd,		     FT_UShort             glyphID,		     FT_UShort*            class,		     FT_UShort*            index ){  switch ( cd->ClassFormat )  {  case 1:    return Get_Class1( &cd->cd.cd1, glyphID, class, index );  case 2:    return Get_Class2( &cd->cd.cd2, glyphID, class, index );  default:    return HB_Err_Invalid_SubTable_Format;  }  return FT_Err_Ok;               /* never reached */}/*************************** * Device related functions ***************************/FT_Error  _HB_OPEN_Load_Device( HB_Device*  d,		       FT_Stream    stream ){  FT_Error   error;  FT_Memory  memory = stream->memory;  FT_UShort   n, count;  FT_UShort*  dv;  if ( ACCESS_Frame( 6L ) )    return error;  d->StartSize   = GET_UShort();  d->EndSize     = GET_UShort();  d->DeltaFormat = GET_UShort();  FORGET_Frame();  if ( d->StartSize > d->EndSize ||       d->DeltaFormat == 0 || d->DeltaFormat > 3 )    return HB_Err_Invalid_SubTable;  d->DeltaValue = NULL;  count = ( ( d->EndSize - d->StartSize + 1 ) >>	      ( 4 - d->DeltaFormat ) ) + 1;  if ( ALLOC_ARRAY( d->DeltaValue, count, FT_UShort ) )    return error;  if ( ACCESS_Frame( count * 2L ) )  {    FREE( d->DeltaValue );    return error;  }  dv = d->DeltaValue;  for ( n = 0; n < count; n++ )    dv[n] = GET_UShort();  FORGET_Frame();  return FT_Err_Ok;}void  _HB_OPEN_Free_Device( HB_Device*  d,		   FT_Memory    memory ){  FREE( d->DeltaValue );}/* Since we have the delta values stored in compressed form, we must   uncompress it now.  To simplify the interface, the function always   returns a meaningful value in `value'; the error is just for   information.			       |                |   format = 1: 0011223344556677|8899101112131415|...			       |                |		    byte 1           byte 2     00: (byte >> 14) & mask     11: (byte >> 12) & mask     ...     mask = 0x0003			       |                |   format = 2: 0000111122223333|4444555566667777|...			       |                |		    byte 1           byte 2     0000: (byte >> 12) & mask     1111: (byte >>  8) & mask     ...     mask = 0x000F			       |                |   format = 3: 0000000011111111|2222222233333333|...			       |                |		    byte 1           byte 2     00000000: (byte >> 8) & mask     11111111: (byte >> 0) & mask     ....     mask = 0x00FF                                    */FT_Error  _HB_OPEN_Get_Device( HB_Device*  d,		      FT_UShort    size,		      FT_Short*    value ){  FT_UShort  byte, bits, mask, f, s;  f = d->DeltaFormat;  if ( d->DeltaValue && size >= d->StartSize && size <= d->EndSize )  {    s    = size - d->StartSize;    byte = d->DeltaValue[s >> ( 4 - f )];    bits = byte >> ( 16 - ( ( s % ( 1 << ( 4 - f ) ) + 1 ) << f ) );    mask = 0xFFFF >> ( 16 - ( 1 << f ) );    *value = (FT_Short)( bits & mask );    /* conversion to a signed value */    if ( *value >= ( ( mask + 1 ) >> 1 ) )      *value -= mask + 1;    return FT_Err_Ok;  }  else  {    *value = 0;    return HB_Err_Not_Covered;  }}/* END */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -