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

📄 harfbuzz-open.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-open-private.h"/*************************** * Script related functions ***************************//* LangSys */static HB_Error  Load_LangSys( HB_LangSys*  ls,			       HB_Stream     stream ){  HB_Error   error;  HB_UShort  n, count;  HB_UShort* fi;  if ( ACCESS_Frame( 6L ) )    return error;  ls->LookupOrderOffset    = GET_UShort();    /* should be 0 */  ls->ReqFeatureIndex      = GET_UShort();  count = ls->FeatureCount = GET_UShort();  FORGET_Frame();  ls->FeatureIndex = NULL;  if ( ALLOC_ARRAY( ls->FeatureIndex, count, HB_UShort ) )    return error;  if ( ACCESS_Frame( count * 2L ) )  {    FREE( ls->FeatureIndex );    return error;  }  fi = ls->FeatureIndex;  for ( n = 0; n < count; n++ )    fi[n] = GET_UShort();  FORGET_Frame();  return HB_Err_Ok;}static void  Free_LangSys( HB_LangSys*  ls ){  FREE( ls->FeatureIndex );}/* Script */static HB_Error  Load_Script( HB_ScriptTable*  s,			      HB_Stream    stream ){  HB_Error   error;  HB_UShort  n, m, count;  HB_UInt   cur_offset, new_offset, base_offset;  HB_LangSysRecord*  lsr;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  new_offset = GET_UShort() + base_offset;  FORGET_Frame();  if ( new_offset != base_offset )        /* not a NULL offset */  {    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||	 ( error = Load_LangSys( &s->DefaultLangSys,				 stream ) ) != HB_Err_Ok )      return error;    (void)FILE_Seek( cur_offset );  }  else  {    /* we create a DefaultLangSys table with no entries */    s->DefaultLangSys.LookupOrderOffset = 0;    s->DefaultLangSys.ReqFeatureIndex   = 0xFFFF;    s->DefaultLangSys.FeatureCount      = 0;    s->DefaultLangSys.FeatureIndex      = NULL;  }  if ( ACCESS_Frame( 2L ) )    goto Fail2;  count = s->LangSysCount = GET_UShort();  /* safety check; otherwise the official handling of TrueType Open     fonts won't work */  if ( s->LangSysCount == 0 && s->DefaultLangSys.FeatureCount == 0 )  {    error = HB_Err_Not_Covered;    goto Fail2;  }  FORGET_Frame();  s->LangSysRecord = NULL;  if ( ALLOC_ARRAY( s->LangSysRecord, count, HB_LangSysRecord ) )    goto Fail2;  lsr = s->LangSysRecord;  for ( n = 0; n < count; n++ )  {    if ( ACCESS_Frame( 6L ) )      goto Fail1;    lsr[n].LangSysTag = GET_ULong();    new_offset = GET_UShort() + base_offset;    FORGET_Frame();    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||	 ( error = Load_LangSys( &lsr[n].LangSys, stream ) ) != HB_Err_Ok )      goto Fail1;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )    Free_LangSys( &lsr[m].LangSys );  FREE( s->LangSysRecord );Fail2:  Free_LangSys( &s->DefaultLangSys );  return error;}static void  Free_Script( HB_ScriptTable*  s ){  HB_UShort           n, count;  HB_LangSysRecord*  lsr;  Free_LangSys( &s->DefaultLangSys );  if ( s->LangSysRecord )  {    count = s->LangSysCount;    lsr   = s->LangSysRecord;    for ( n = 0; n < count; n++ )      Free_LangSys( &lsr[n].LangSys );    FREE( lsr );  }}/* ScriptList */HB_INTERNAL HB_Error_HB_OPEN_Load_ScriptList( HB_ScriptList* sl,			  HB_Stream      stream ){  HB_Error   error;  HB_UShort          n, script_count;  HB_UInt           cur_offset, new_offset, base_offset;  HB_ScriptRecord*  sr;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  script_count = GET_UShort();  FORGET_Frame();  sl->ScriptRecord = NULL;  if ( ALLOC_ARRAY( sl->ScriptRecord, script_count, HB_ScriptRecord ) )    return error;  sr = sl->ScriptRecord;  sl->ScriptCount= 0;  for ( n = 0; n < script_count; n++ )  {    if ( ACCESS_Frame( 6L ) )      goto Fail;    sr[sl->ScriptCount].ScriptTag = GET_ULong();    new_offset = GET_UShort() + base_offset;    FORGET_Frame();    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) )      goto Fail;    error = Load_Script( &sr[sl->ScriptCount].Script, stream );    if ( error == HB_Err_Ok )      sl->ScriptCount += 1;    else if ( error != HB_Err_Not_Covered )      goto Fail;    (void)FILE_Seek( cur_offset );  }  /* Empty tables are harmless and generated by fontforge.   * See http://bugzilla.gnome.org/show_bug.cgi?id=347073   */#if 0  if ( sl->ScriptCount == 0 )  {    error = ERR(HB_Err_Invalid_SubTable);    goto Fail;  }#endif    return HB_Err_Ok;Fail:  for ( n = 0; n < sl->ScriptCount; n++ )    Free_Script( &sr[n].Script );  FREE( sl->ScriptRecord );  return error;}HB_INTERNAL void_HB_OPEN_Free_ScriptList( HB_ScriptList* sl ){  HB_UShort          n, count;  HB_ScriptRecord*  sr;  if ( sl->ScriptRecord )  {    count = sl->ScriptCount;    sr    = sl->ScriptRecord;    for ( n = 0; n < count; n++ )      Free_Script( &sr[n].Script );    FREE( sr );  }}/********************************* * Feature List related functions *********************************//* Feature */static HB_Error  Load_Feature( HB_Feature*  f,			       HB_Stream     stream ){  HB_Error   error;  HB_UShort   n, count;  HB_UShort*  lli;  if ( ACCESS_Frame( 4L ) )    return error;  f->FeatureParams           = GET_UShort();    /* should be 0 */  count = f->LookupListCount = GET_UShort();  FORGET_Frame();  f->LookupListIndex = NULL;  if ( ALLOC_ARRAY( f->LookupListIndex, count, HB_UShort ) )    return error;  lli = f->LookupListIndex;  if ( ACCESS_Frame( count * 2L ) )  {    FREE( f->LookupListIndex );    return error;  }  for ( n = 0; n < count; n++ )    lli[n] = GET_UShort();  FORGET_Frame();  return HB_Err_Ok;}static void  Free_Feature( HB_Feature*  f ){  FREE( f->LookupListIndex );}/* FeatureList */HB_INTERNAL HB_Error_HB_OPEN_Load_FeatureList( HB_FeatureList* fl,			   HB_Stream       stream ){  HB_Error   error;  HB_UShort           n, m, count;  HB_UInt            cur_offset, new_offset, base_offset;  HB_FeatureRecord*  fr;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  count = fl->FeatureCount = GET_UShort();  FORGET_Frame();  fl->FeatureRecord = NULL;  if ( ALLOC_ARRAY( fl->FeatureRecord, count, HB_FeatureRecord ) )    return error;  if ( ALLOC_ARRAY( fl->ApplyOrder, count, HB_UShort ) )    goto Fail2;    fl->ApplyCount = 0;  fr = fl->FeatureRecord;  for ( n = 0; n < count; n++ )  {    if ( ACCESS_Frame( 6L ) )      goto Fail1;    fr[n].FeatureTag = GET_ULong();    new_offset = GET_UShort() + base_offset;    FORGET_Frame();    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||	 ( error = Load_Feature( &fr[n].Feature, stream ) ) != HB_Err_Ok )      goto Fail1;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )    Free_Feature( &fr[m].Feature );  FREE( fl->ApplyOrder );Fail2:  FREE( fl->FeatureRecord );  return error;}HB_INTERNAL void_HB_OPEN_Free_FeatureList( HB_FeatureList*  fl ){  HB_UShort           n, count;  HB_FeatureRecord*  fr;  if ( fl->FeatureRecord )  {    count = fl->FeatureCount;    fr    = fl->FeatureRecord;    for ( n = 0; n < count; n++ )      Free_Feature( &fr[n].Feature );    FREE( fr );  }    FREE( fl->ApplyOrder );}/******************************** * Lookup List related functions ********************************//* the subroutines of the following two functions are defined in   ftxgsub.c and ftxgpos.c respectively                          *//* SubTable */static HB_Error  Load_SubTable( HB_SubTable*  st,				HB_Stream     stream,				HB_Type       table_type,				HB_UShort     lookup_type ){  if ( table_type == HB_Type_GSUB )    return _HB_GSUB_Load_SubTable ( &st->st.gsub, stream, lookup_type );  else    return _HB_GPOS_Load_SubTable ( &st->st.gpos, stream, lookup_type );}static void  Free_SubTable( HB_SubTable*  st,			    HB_Type       table_type,			    HB_UShort     lookup_type ){  if ( table_type == HB_Type_GSUB )    _HB_GSUB_Free_SubTable ( &st->st.gsub, lookup_type );  else    _HB_GPOS_Free_SubTable ( &st->st.gpos, lookup_type );}/* Lookup */static HB_Error  Load_Lookup( HB_Lookup*   l,			      HB_Stream     stream,			      HB_Type      type ){  HB_Error   error;  HB_UShort      n, m, count;  HB_UInt       cur_offset, new_offset, base_offset;  HB_SubTable*  st;  HB_Bool        is_extension = FALSE;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 6L ) )    return error;  l->LookupType            = GET_UShort();  l->LookupFlag            = GET_UShort();  count = l->SubTableCount = GET_UShort();  FORGET_Frame();  l->SubTable = NULL;  if ( ALLOC_ARRAY( l->SubTable, count, HB_SubTable ) )    return error;  st = l->SubTable;  if ( ( type == HB_Type_GSUB && l->LookupType == HB_GSUB_LOOKUP_EXTENSION ) ||       ( type == HB_Type_GPOS && l->LookupType == HB_GPOS_LOOKUP_EXTENSION ) )    is_extension = TRUE;  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 ( is_extension )    {      if ( FILE_Seek( new_offset ) || ACCESS_Frame( 8L ) )	goto Fail;      if (GET_UShort() != 1) /* format should be 1 */	goto Fail;      l->LookupType = GET_UShort();      new_offset += GET_ULong();      FORGET_Frame();    }    if ( FILE_Seek( new_offset ) ||	 ( error = Load_SubTable( &st[n], stream,				  type, l->LookupType ) ) != HB_Err_Ok )      goto Fail;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail:  for ( m = 0; m < n; m++ )    Free_SubTable( &st[m], type, l->LookupType );  FREE( l->SubTable );  return error;}static void  Free_Lookup( HB_Lookup*   l,			  HB_Type      type ){  HB_UShort      n, count;  HB_SubTable*  st;  if ( l->SubTable )  {    count = l->SubTableCount;    st    = l->SubTable;    for ( n = 0; n < count; n++ )      Free_SubTable( &st[n], type, l->LookupType );    FREE( st );  }}/* LookupList */HB_INTERNAL HB_Error_HB_OPEN_Load_LookupList( HB_LookupList* ll,			  HB_Stream      stream,			  HB_Type        type ){  HB_Error   error;  HB_UShort    n, m, count;  HB_UInt     cur_offset, new_offset, base_offset;  HB_Lookup*  l;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  count = ll->LookupCount = GET_UShort();  FORGET_Frame();  ll->Lookup = NULL;  if ( ALLOC_ARRAY( ll->Lookup, count, HB_Lookup ) )    return error;  if ( ALLOC_ARRAY( ll->Properties, count, HB_UInt ) )    goto Fail2;  l = ll->Lookup;  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_Lookup( &l[n], stream, type ) ) != HB_Err_Ok )      goto Fail1;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail1:  FREE( ll->Properties );  for ( m = 0; m < n; m++ )    Free_Lookup( &l[m], type );Fail2:  FREE( ll->Lookup );  return error;}HB_INTERNAL void_HB_OPEN_Free_LookupList( HB_LookupList* ll,			  HB_Type        type ){  HB_UShort    n, count;  HB_Lookup*  l;  FREE( ll->Properties );  if ( ll->Lookup )  {    count = ll->LookupCount;    l     = ll->Lookup;    for ( n = 0; n < count; n++ )      Free_Lookup( &l[n], type );    FREE( l );  }}/***************************** * Coverage related functions *****************************//* CoverageFormat1 */static HB_Error  Load_Coverage1( HB_CoverageFormat1*  cf1,				 HB_Stream             stream ){  HB_Error   error;  HB_UShort  n, count;  HB_UShort* ga;  if ( ACCESS_Frame( 2L ) )    return error;  count = cf1->GlyphCount = GET_UShort();  FORGET_Frame();  cf1->GlyphArray = NULL;  if ( ALLOC_ARRAY( cf1->GlyphArray, count, HB_UShort ) )    return error;  ga = cf1->GlyphArray;  if ( ACCESS_Frame( count * 2L ) )  {    FREE( cf1->GlyphArray );    return error;  }  for ( n = 0; n < count; n++ )    ga[n] = GET_UShort();  FORGET_Frame();  return HB_Err_Ok;}static void  Free_Coverage1( HB_CoverageFormat1*  cf1 ){  FREE( cf1->GlyphArray );}/* CoverageFormat2 */static HB_Error  Load_Coverage2( HB_CoverageFormat2*  cf2,				 HB_Stream             stream ){  HB_Error   error;

⌨️ 快捷键说明

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