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

📄 harfbuzz-open.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 2 页
字号:
  HB_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 = ERR(HB_Err_Invalid_SubTable);      goto Fail;    }  }  FORGET_Frame();  return HB_Err_Ok;Fail:  FREE( cf2->RangeRecord );  return error;}static void  Free_Coverage2( HB_CoverageFormat2*  cf2 ){  FREE( cf2->RangeRecord );}HB_INTERNAL HB_Error_HB_OPEN_Load_Coverage( HB_Coverage* c,			HB_Stream    stream ){  HB_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 ERR(HB_Err_Invalid_SubTable_Format);  }  return HB_Err_Ok;               /* never reached */}HB_INTERNAL void_HB_OPEN_Free_Coverage( HB_Coverage* c ){  switch ( c->CoverageFormat )  {  case 1:  Free_Coverage1( &c->cf.cf1 ); break;  case 2:  Free_Coverage2( &c->cf.cf2 ); break;  default:					 break;  }}static HB_Error  Coverage_Index1( HB_CoverageFormat1*  cf1,				  HB_UShort             glyphID,				  HB_UShort*            index ){  HB_UShort min, max, new_min, new_max, middle;  HB_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 HB_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 HB_Error  Coverage_Index2( HB_CoverageFormat2*  cf2,				  HB_UShort             glyphID,				  HB_UShort*            index ){  HB_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 HB_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;}HB_INTERNAL HB_Error_HB_OPEN_Coverage_Index( HB_Coverage* c,			 HB_UShort    glyphID,			 HB_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 ERR(HB_Err_Invalid_SubTable_Format);  }  return HB_Err_Ok;               /* never reached */}/************************************* * Class Definition related functions *************************************//* ClassDefFormat1 */static HB_Error  Load_ClassDef1( HB_ClassDefinition*  cd,				 HB_UShort             limit,				 HB_Stream             stream ){  HB_Error   error;  HB_UShort             n, count;  HB_UShort*            cva;  HB_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 ERR(HB_Err_Invalid_SubTable);  cdf1->ClassValueArray = NULL;  if ( ALLOC_ARRAY( cdf1->ClassValueArray, count, HB_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 = ERR(HB_Err_Invalid_SubTable);      goto Fail;    }    d[cva[n]] = TRUE;  }  FORGET_Frame();  return HB_Err_Ok;Fail:  FREE( cva );  return error;}static void  Free_ClassDef1( HB_ClassDefFormat1*  cdf1 ){  FREE( cdf1->ClassValueArray );}/* ClassDefFormat2 */static HB_Error  Load_ClassDef2( HB_ClassDefinition*  cd,				 HB_UShort             limit,				 HB_Stream             stream ){  HB_Error   error;  HB_UShort              n, count;  HB_ClassRangeRecord*  crr;  HB_Bool*               d;  HB_ClassDefFormat2*   cdf2;  cdf2 = &cd->cd.cd2;  if ( ACCESS_Frame( 2L ) )    return error;  count = GET_UShort();  cdf2->ClassRangeCount = 0; /* zero for now.  we fill with the number of good entries later */  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 )    {      /* XXX       * Corrupt entry.  Skip it.       * This is hit by Nafees Nastaliq font for example       */       n--;       count--;    }    else      d[crr[n].Class] = TRUE;  }  FORGET_Frame();  cdf2->ClassRangeCount = count;  return HB_Err_Ok;Fail:  FREE( crr );  return error;}static void  Free_ClassDef2( HB_ClassDefFormat2*  cdf2 ){  FREE( cdf2->ClassRangeRecord );}/* ClassDefinition */HB_INTERNAL HB_Error_HB_OPEN_Load_ClassDefinition( HB_ClassDefinition* cd,			       HB_UShort           limit,			       HB_Stream           stream ){  HB_Error   error;  if ( ALLOC_ARRAY( cd->Defined, limit, HB_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 = ERR(HB_Err_Invalid_SubTable_Format);	break;  }  if ( error )    goto Fail;  cd->loaded = TRUE;  return HB_Err_Ok;Fail:  FREE( cd->Defined );  return error;}static HB_Error_HB_OPEN_Load_EmptyClassDefinition( HB_ClassDefinition*  cd ){  HB_Error   error;  if ( ALLOC_ARRAY( cd->Defined, 1, HB_Bool ) )    return error;  cd->ClassFormat = 1; /* Meaningless */  cd->Defined[0] = FALSE;  if ( ALLOC_ARRAY( cd->cd.cd1.ClassValueArray, 1, HB_UShort ) )    goto Fail;  return HB_Err_Ok;Fail:  FREE( cd->Defined );  return error;}HB_INTERNAL HB_Error_HB_OPEN_Load_EmptyOrClassDefinition( HB_ClassDefinition* cd,				      HB_UShort           limit,				      HB_UInt            class_offset,				      HB_UInt            base_offset,				      HB_Stream           stream ){  HB_Error error;  HB_UInt               cur_offset;  cur_offset = FILE_Pos();  if ( class_offset )    {      if ( !FILE_Seek( class_offset + base_offset ) )	error = _HB_OPEN_Load_ClassDefinition( cd, limit, stream );    }  else     error = _HB_OPEN_Load_EmptyClassDefinition ( cd );  if (error == HB_Err_Ok)    (void)FILE_Seek( cur_offset ); /* Changes error as a side-effect */  return error;}HB_INTERNAL void_HB_OPEN_Free_ClassDefinition( HB_ClassDefinition*  cd ){  if ( !cd->loaded )    return;  FREE( cd->Defined );  switch ( cd->ClassFormat )  {  case 1:  Free_ClassDef1( &cd->cd.cd1 ); break;  case 2:  Free_ClassDef2( &cd->cd.cd2 ); break;  default:				  break;  }}static HB_Error  Get_Class1( HB_ClassDefFormat1*  cdf1,			     HB_UShort             glyphID,			     HB_UShort*            klass,			     HB_UShort*            index ){  HB_UShort*  cva = cdf1->ClassValueArray;  if ( index )    *index = 0;  if ( glyphID >= cdf1->StartGlyph &&       glyphID < cdf1->StartGlyph + cdf1->GlyphCount )  {    *klass = cva[glyphID - cdf1->StartGlyph];    return HB_Err_Ok;  }  else  {    *klass = 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 HB_Error  Get_Class2( HB_ClassDefFormat2*  cdf2,			     HB_UShort             glyphID,			     HB_UShort*            klass,			     HB_UShort*            index ){  HB_Error               error = HB_Err_Ok;  HB_UShort              min, max, new_min, new_max, middle;  HB_ClassRangeRecord*  crr = cdf2->ClassRangeRecord;  /* binary search */  if ( cdf2->ClassRangeCount == 0 )    {      *klass = 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 )    {      *klass = crr[middle].Class;      error  = HB_Err_Ok;      break;    }    else if ( glyphID < crr[middle].Start )    {      if ( middle == min )      {	*klass = 0;	error  = HB_Err_Not_Covered;	break;      }      new_max = middle - 1;    }    else    {      if ( middle == max )      {	*klass = 0;	error  = HB_Err_Not_Covered;	break;      }      new_min = middle + 1;    }  } while ( min < max );  if ( index )    *index = middle;  return error;}HB_INTERNAL HB_Error_HB_OPEN_Get_Class( HB_ClassDefinition* cd,		    HB_UShort           glyphID,		    HB_UShort*          klass,		    HB_UShort*          index ){  switch ( cd->ClassFormat )  {  case 1:  return Get_Class1( &cd->cd.cd1, glyphID, klass, index );  case 2:  return Get_Class2( &cd->cd.cd2, glyphID, klass, index );  default: return ERR(HB_Err_Invalid_SubTable_Format);  }  return HB_Err_Ok;               /* never reached */}/*************************** * Device related functions ***************************/HB_INTERNAL HB_Error_HB_OPEN_Load_Device( HB_Device* d,		      HB_Stream  stream ){  HB_Error   error;  HB_UShort   n, count;  HB_UShort*  dv;  if ( ACCESS_Frame( 6L ) )    return error;  d->StartSize   = GET_UShort();  d->EndSize     = GET_UShort();  d->DeltaFormat = GET_UShort();  FORGET_Frame();  d->DeltaValue = NULL;  if ( d->StartSize > d->EndSize ||       d->DeltaFormat == 0 || d->DeltaFormat > 3 )    {      /* XXX       * I've seen fontforge generate DeltaFormat == 0.       * Just return Ok and let the NULL DeltaValue disable       * this table.       */      return HB_Err_Ok;    }  count = ( ( d->EndSize - d->StartSize + 1 ) >>	      ( 4 - d->DeltaFormat ) ) + 1;  if ( ALLOC_ARRAY( d->DeltaValue, count, HB_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 HB_Err_Ok;}HB_INTERNAL void_HB_OPEN_Free_Device( HB_Device* d ){  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                                    */HB_INTERNAL HB_Error_HB_OPEN_Get_Device( HB_Device* d,		     HB_UShort  size,		     HB_Short*  value ){  HB_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 = (HB_Short)( bits & mask );    /* conversion to a signed value */    if ( *value >= ( ( mask + 1 ) >> 1 ) )      *value -= mask + 1;    return HB_Err_Ok;  }  else  {    *value = 0;    return HB_Err_Not_Covered;  }}/* END */

⌨️ 快捷键说明

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