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

📄 harfbuzz-gdef.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1998-2004  David Turner and Werner Lemberg * Copyright (C) 2006  Behdad Esfahbod * *  This is part of HarfBuzz, an OpenType Layout engine library. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */#include "harfbuzz-impl.h"#include "harfbuzz-gdef-private.h"#include "harfbuzz-open-private.h"static HB_Error  Load_AttachList( HB_AttachList*  al,				  HB_Stream        stream );static HB_Error  Load_LigCaretList( HB_LigCaretList*  lcl,				    HB_Stream          stream );static void  Free_AttachList( HB_AttachList*  al );static void  Free_LigCaretList( HB_LigCaretList*  lcl );static void  Free_NewGlyphClasses( HB_GDEFHeader*  gdef );/* GDEF glyph classes */#define UNCLASSIFIED_GLYPH  0#define SIMPLE_GLYPH        1#define LIGATURE_GLYPH      2#define MARK_GLYPH          3#define COMPONENT_GLYPH     4HB_Error  HB_New_GDEF_Table( HB_GDEFHeader** retptr ){  HB_Error         error;  HB_GDEFHeader*  gdef;  if ( !retptr )    return ERR(HB_Err_Invalid_Argument);  if ( ALLOC( gdef, sizeof( *gdef ) ) )    return error;  gdef->GlyphClassDef.loaded = FALSE;  gdef->AttachList.loaded = FALSE;  gdef->LigCaretList.loaded = FALSE;  gdef->MarkAttachClassDef_offset = 0;  gdef->MarkAttachClassDef.loaded = FALSE;  gdef->LastGlyph = 0;  gdef->NewGlyphClasses = NULL;  *retptr = gdef;  return HB_Err_Ok;}HB_Error  HB_Load_GDEF_Table( HB_Font          font,			      HB_GDEFHeader** retptr ){  HB_Error         error;  HB_Stream        stream = font->stream;  HB_UInt         cur_offset, new_offset, base_offset;  HB_GDEFHeader*  gdef;  if ( !retptr )    return ERR(HB_Err_Invalid_Argument);  if ( GOTO_Table( TTAG_GDEF ) )    return error;  if (( error = HB_New_GDEF_Table ( &gdef ) ))    return error;  base_offset = FILE_Pos();  /* skip version */  if ( FILE_Seek( base_offset + 4L ) ||       ACCESS_Frame( 2L ) )    goto Fail0;  new_offset = GET_UShort();  FORGET_Frame();  /* all GDEF subtables are optional */  if ( new_offset )  {    new_offset += base_offset;    /* only classes 1-4 are allowed here */    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||	 ( error = _HB_OPEN_Load_ClassDefinition( &gdef->GlyphClassDef, 5,					 stream ) ) != HB_Err_Ok )      goto Fail0;    (void)FILE_Seek( cur_offset );  }  if ( ACCESS_Frame( 2L ) )    goto Fail1;  new_offset = GET_UShort();  FORGET_Frame();  if ( new_offset )  {    new_offset += base_offset;    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||	 ( error = Load_AttachList( &gdef->AttachList,				    stream ) ) != HB_Err_Ok )      goto Fail1;    (void)FILE_Seek( cur_offset );  }  if ( ACCESS_Frame( 2L ) )    goto Fail2;  new_offset = GET_UShort();  FORGET_Frame();  if ( new_offset )  {    new_offset += base_offset;    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||	 ( error = Load_LigCaretList( &gdef->LigCaretList,				      stream ) ) != HB_Err_Ok )      goto Fail2;    (void)FILE_Seek( cur_offset );  }  /* OpenType 1.2 has introduced the `MarkAttachClassDef' field.  We     first have to scan the LookupFlag values to find out whether we     must load it or not.  Here we only store the offset of the table. */  if ( ACCESS_Frame( 2L ) )    goto Fail3;  new_offset = GET_UShort();  FORGET_Frame();  if ( new_offset )    gdef->MarkAttachClassDef_offset = new_offset + base_offset;  else    gdef->MarkAttachClassDef_offset = 0;  *retptr = gdef;  return HB_Err_Ok;Fail3:  Free_LigCaretList( &gdef->LigCaretList );  Fail2:  Free_AttachList( &gdef->AttachList );Fail1:  _HB_OPEN_Free_ClassDefinition( &gdef->GlyphClassDef );Fail0:  FREE( gdef );  return error;}HB_Error  HB_Done_GDEF_Table ( HB_GDEFHeader* gdef ) {  Free_LigCaretList( &gdef->LigCaretList );  Free_AttachList( &gdef->AttachList );  _HB_OPEN_Free_ClassDefinition( &gdef->GlyphClassDef );  _HB_OPEN_Free_ClassDefinition( &gdef->MarkAttachClassDef );    Free_NewGlyphClasses( gdef );  FREE( gdef );  return HB_Err_Ok;}/******************************* * AttachList related functions *******************************//* AttachPoint */static HB_Error  Load_AttachPoint( HB_AttachPoint*  ap,				   HB_Stream         stream ){  HB_Error  error;  HB_UShort   n, count;  HB_UShort*  pi;  if ( ACCESS_Frame( 2L ) )    return error;  count = ap->PointCount = GET_UShort();  FORGET_Frame();  ap->PointIndex = NULL;  if ( count )  {    if ( ALLOC_ARRAY( ap->PointIndex, count, HB_UShort ) )      return error;    pi = ap->PointIndex;    if ( ACCESS_Frame( count * 2L ) )    {      FREE( pi );      return error;    }    for ( n = 0; n < count; n++ )      pi[n] = GET_UShort();    FORGET_Frame();  }  return HB_Err_Ok;}static void  Free_AttachPoint( HB_AttachPoint*  ap ){  FREE( ap->PointIndex );}/* AttachList */static HB_Error  Load_AttachList( HB_AttachList*  al,				  HB_Stream        stream ){  HB_Error  error;  HB_UShort         n, m, count;  HB_UInt          cur_offset, new_offset, base_offset;  HB_AttachPoint*  ap;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  new_offset = GET_UShort() + base_offset;  FORGET_Frame();  cur_offset = FILE_Pos();  if ( FILE_Seek( new_offset ) ||       ( error = _HB_OPEN_Load_Coverage( &al->Coverage, stream ) ) != HB_Err_Ok )    return error;  (void)FILE_Seek( cur_offset );  if ( ACCESS_Frame( 2L ) )    goto Fail2;  count = al->GlyphCount = GET_UShort();  FORGET_Frame();  al->AttachPoint = NULL;  if ( ALLOC_ARRAY( al->AttachPoint, count, HB_AttachPoint ) )    goto Fail2;  ap = al->AttachPoint;  for ( n = 0; n < count; n++ )  {    if ( ACCESS_Frame( 2L ) )      goto Fail1;    new_offset = GET_UShort() + base_offset;    FORGET_Frame();    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||	 ( error = Load_AttachPoint( &ap[n], stream ) ) != HB_Err_Ok )      goto Fail1;    (void)FILE_Seek( cur_offset );  }  al->loaded = TRUE;  return HB_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )    Free_AttachPoint( &ap[m] );  FREE( ap );Fail2:  _HB_OPEN_Free_Coverage( &al->Coverage );  return error;}static void  Free_AttachList( HB_AttachList*  al ){  HB_UShort         n, count;  HB_AttachPoint*  ap;  if ( !al->loaded )    return;  if ( al->AttachPoint )  {    count = al->GlyphCount;    ap    = al->AttachPoint;    for ( n = 0; n < count; n++ )      Free_AttachPoint( &ap[n] );    FREE( ap );  }  _HB_OPEN_Free_Coverage( &al->Coverage );}/********************************* * LigCaretList related functions *********************************//* CaretValueFormat1 *//* CaretValueFormat2 *//* CaretValueFormat3 *//* CaretValueFormat4 */static HB_Error  Load_CaretValue( HB_CaretValue*  cv,				  HB_Stream        stream ){  HB_Error  error;  HB_UInt cur_offset, new_offset, base_offset;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  cv->CaretValueFormat = GET_UShort();  FORGET_Frame();  switch ( cv->CaretValueFormat )  {  case 1:    if ( ACCESS_Frame( 2L ) )      return error;    cv->cvf.cvf1.Coordinate = GET_Short();    FORGET_Frame();    break;  case 2:    if ( ACCESS_Frame( 2L ) )      return error;    cv->cvf.cvf2.CaretValuePoint = GET_UShort();    FORGET_Frame();    break;  case 3:    if ( ACCESS_Frame( 4L ) )      return error;    cv->cvf.cvf3.Coordinate = GET_Short();    new_offset = GET_UShort() + base_offset;    FORGET_Frame();    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||	 ( error = _HB_OPEN_Load_Device( &cv->cvf.cvf3.Device,				stream ) ) != HB_Err_Ok )      return error;    (void)FILE_Seek( cur_offset );    break;  case 4:    if ( ACCESS_Frame( 2L ) )      return error;    cv->cvf.cvf4.IdCaretValue = GET_UShort();    FORGET_Frame();    break;  default:    return ERR(HB_Err_Invalid_SubTable_Format);  }  return HB_Err_Ok;}static void  Free_CaretValue( HB_CaretValue*  cv ){  if ( cv->CaretValueFormat == 3 )    _HB_OPEN_Free_Device( &cv->cvf.cvf3.Device );}/* LigGlyph */static HB_Error  Load_LigGlyph( HB_LigGlyph*  lg,				HB_Stream      stream ){  HB_Error  error;  HB_UShort        n, m, count;  HB_UInt         cur_offset, new_offset, base_offset;  HB_CaretValue*  cv;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  count = lg->CaretCount = GET_UShort();  FORGET_Frame();  lg->CaretValue = NULL;  if ( ALLOC_ARRAY( lg->CaretValue, count, HB_CaretValue ) )    return error;  cv = lg->CaretValue;  for ( n = 0; n < count; n++ )  {    if ( ACCESS_Frame( 2L ) )      goto Fail;    new_offset = GET_UShort() + base_offset;    FORGET_Frame();    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||	 ( error = Load_CaretValue( &cv[n], stream ) ) != HB_Err_Ok )      goto Fail;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail:  for ( m = 0; m < n; m++ )    Free_CaretValue( &cv[m] );  FREE( cv );  return error;}static void  Free_LigGlyph( HB_LigGlyph*  lg ){  HB_UShort        n, count;  HB_CaretValue*  cv;  if ( lg->CaretValue )  {    count = lg->CaretCount;    cv    = lg->CaretValue;    for ( n = 0; n < count; n++ )      Free_CaretValue( &cv[n] );    FREE( cv );  }}/* LigCaretList */static HB_Error  Load_LigCaretList( HB_LigCaretList*  lcl,				    HB_Stream          stream ){  HB_Error  error;  HB_UShort      m, n, count;  HB_UInt       cur_offset, new_offset, base_offset;  HB_LigGlyph*  lg;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  new_offset = GET_UShort() + base_offset;  FORGET_Frame();  cur_offset = FILE_Pos();  if ( FILE_Seek( new_offset ) ||       ( error = _HB_OPEN_Load_Coverage( &lcl->Coverage, stream ) ) != HB_Err_Ok )    return error;  (void)FILE_Seek( cur_offset );  if ( ACCESS_Frame( 2L ) )    goto Fail2;  count = lcl->LigGlyphCount = GET_UShort();  FORGET_Frame();  lcl->LigGlyph = NULL;  if ( ALLOC_ARRAY( lcl->LigGlyph, count, HB_LigGlyph ) )    goto Fail2;  lg = lcl->LigGlyph;  for ( n = 0; n < count; n++ )  {

⌨️ 快捷键说明

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