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

📄 otlcommn.c

📁 下载来的一个看图软件的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************//*                                                                         *//*  otlcommn.c                                                             *//*                                                                         *//*    OpenType layout support, common tables (body).                       *//*                                                                         *//*  Copyright 2002 by                                                      *//*  David Turner, Robert Wilhelm, and Werner Lemberg.                      *//*                                                                         *//*  This file is part of the FreeType project, and may only be used,       *//*  modified, and distributed under the terms of the FreeType project      *//*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     *//*  this file you indicate that you have read the license and              *//*  understand and accept it fully.                                        *//*                                                                         *//***************************************************************************/#include "otlayout.h" /*************************************************************************/ /*************************************************************************/ /*****                                                               *****/ /*****                       COVERAGE TABLE                          *****/ /*****                                                               *****/ /*************************************************************************/ /*************************************************************************/  OTL_LOCALDEF( void )  otl_coverage_validate( OTL_Bytes      table,                         OTL_Validator  valid )  {    OTL_Bytes  p;    OTL_UInt   format;    if ( table + 4 > valid->limit )      OTL_INVALID_TOO_SHORT;    format = OTL_NEXT_USHORT( p );    switch ( format )    {    case 1:      {        OTL_UInt  count = OTL_NEXT_USHORT( p );        if ( p + count * 2 >= valid->limit )          OTL_INVALID_TOO_SHORT;        /* XXX: check glyph indices */      }      break;    case 2:      {        OTL_UInt  n, num_ranges = OTL_NEXT_USHORT( p );        OTL_UInt  start, end, start_cover, total = 0, last = 0;        if ( p + num_ranges * 6 >= valid->limit )          OTL_INVALID_TOO_SHORT;        for ( n = 0; n < num_ranges; n++ )        {          start       = OTL_NEXT_USHORT( p );          end         = OTL_NEXT_USHORT( p );          start_cover = OTL_NEXT_USHORT( p );          if ( start > end || start_cover != total )            OTL_INVALID_DATA;          if ( n > 0 && start <= last )            OTL_INVALID_DATA;          total += end - start + 1;          last   = end;        }      }      break;    default:      OTL_INVALID_FORMAT;    }  }  OTL_LOCALDEF( OTL_UInt )  otl_coverage_get_count( OTL_Bytes  table )  {    OTL_Bytes  p      = table;    OTL_UInt   format = OTL_NEXT_USHORT( p );    OTL_UInt   count  = OTL_NEXT_USHORT( p );    OTL_UInt   result = 0;    switch ( format )    {    case 1:      return count;    case 2:      {        OTL_UInt  start, end;        for ( ; count > 0; count-- )        {          start = OTL_NEXT_USHORT( p );          end   = OTL_NEXT_USHORT( p );          p    += 2;                    /* skip start_index */          result += end - start + 1;        }      }      break;    default:      ;    }    return result;  }  OTL_LOCALDEF( OTL_Int )  otl_coverage_get_index( OTL_Bytes  table,                          OTL_UInt   glyph_index )  {    OTL_Bytes  p      = table;    OTL_UInt   format = OTL_NEXT_USHORT( p );    OTL_UInt   count  = OTL_NEXT_USHORT( p );    switch ( format )    {    case 1:      {        OTL_UInt  min = 0, max = count, mid, gindex;        table += 4;        while ( min < max )        {          mid    = ( min + max ) >> 1;          p      = table + 2 * mid;          gindex = OTL_PEEK_USHORT( p );          if ( glyph_index == gindex )            return (OTL_Int)mid;          if ( glyph_index < gindex )            max = mid;          else            min = mid + 1;        }      }      break;    case 2:      {        OTL_UInt  min = 0, max = count, mid;        OTL_UInt  start, end, delta, start_cover;        table += 4;        while ( min < max )        {          mid    = ( min + max ) >> 1;          p      = table + 6 * mid;          start  = OTL_NEXT_USHORT( p );          end    = OTL_NEXT_USHORT( p );          if ( glyph_index < start )            max = mid;          else if ( glyph_index > end )            min = mid + 1;          else            return (OTL_Int)( glyph_index + OTL_NEXT_USHORT( p ) - start );        }      }      break;    default:      ;    }    return -1;  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                  CLASS DEFINITION TABLE                       *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  OTL_LOCALDEF( void )  otl_class_definition_validate( OTL_Bytes      table,                                 OTL_Validator  valid )  {    OTL_Bytes  p = table;    OTL_UInt   format;    if ( p + 4 > valid->limit )      OTL_INVALID_TOO_SHORT;    format = OTL_NEXT_USHORT( p );    switch ( format )    {    case 1:      {        OTL_UInt  count, start = OTL_NEXT_USHORT( p );        if ( p + 2 > valid->limit )          OTL_INVALID_TOO_SHORT;        count = OTL_NEXT_USHORT( p );        if ( p + count * 2 > valid->limit )          OTL_INVALID_TOO_SHORT;        /* XXX: check glyph indices */      }      break;    case 2:      {        OTL_UInt  n, num_ranges = OTL_NEXT_USHORT( p );        OTL_UInt  start, end, value, last = 0;        if ( p + num_ranges * 6 > valid->limit )          OTL_INVALID_TOO_SHORT;        for ( n = 0; n < num_ranges; n++ )        {          start = OTL_NEXT_USHORT( p );          end   = OTL_NEXT_USHORT( p );          value = OTL_NEXT_USHORT( p );  /* ignored */          if ( start > end || ( n > 0 && start <= last ) )            OTL_INVALID_DATA;          last = end;        }      }      break;    default:      OTL_INVALID_FORMAT;    }  }  OTL_LOCALDEF( OTL_UInt )  otl_class_definition_get_value( OTL_Bytes  table,                                  OTL_UInt   glyph_index )  {    OTL_Bytes  p      = table;    OTL_UInt   format = OTL_NEXT_USHORT( p );    switch ( format )    {    case 1:      {        OTL_UInt  start = OTL_NEXT_USHORT( p );        OTL_UInt  count = OTL_NEXT_USHORT( p );        OTL_UInt  idx   = (OTL_UInt)( glyph_index - start );        if ( idx < count )        {          p += 2 * idx;          return OTL_PEEK_USHORT( p );        }      }      break;    case 2:      {        OTL_UInt  count = OTL_NEXT_USHORT( p );        OTL_UInt  min = 0, max = count, mid, gindex;        table += 4;        while ( min < max )        {          mid   = ( min + max ) >> 1;          p     = table + 6 * mid;          start = OTL_NEXT_USHORT( p );          end   = OTL_NEXT_USHORT( p );          if ( glyph_index < start )            max = mid;          else if ( glyph_index > end )            min = mid + 1;          else            return OTL_PEEK_USHORT( p );        }      }      break;    default:      ;    }    return 0;  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                      DEVICE TABLE                             *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  OTL_LOCALDEF( void )  otl_device_table_validate( OTL_Bytes      table,                             OTL_Validator  valid )  {    OTL_Bytes  p = table;    OTL_UInt   start, end, count, format, count;    if ( p + 8 > valid->limit )      OTL_INVALID_TOO_SHORT;    start  = OTL_NEXT_USHORT( p );    end    = OTL_NEXT_USHORT( p );    format = OTL_NEXT_USHORT( p );    if ( format < 1 || format > 3 || end < start )      OTL_INVALID_DATA;    count = (OTL_UInt)( end - start + 1 );    if ( p + ( ( 1 << format ) * count ) / 8 > valid->limit )      OTL_INVALID_TOO_SHORT;  }  OTL_LOCALDEF( OTL_UInt )  otl_device_table_get_start( OTL_Bytes  table )  {    OTL_Bytes  p = table;    return OTL_PEEK_USHORT( p );  }  OTL_LOCALDEF( OTL_UInt )  otl_device_table_get_end( OTL_Bytes  table )  {    OTL_Bytes  p = table + 2;    return OTL_PEEK_USHORT( p );  }  OTL_LOCALDEF( OTL_Int )  otl_device_table_get_delta( OTL_Bytes  table,                              OTL_UInt   size )  {    OTL_Bytes  p = table;    OTL_Int    result = 0;    OTL_UInt   start, end, format, idx, value;    start  = OTL_NEXT_USHORT( p );    end    = OTL_NEXT_USHORT( p );    format = OTL_NEXT_USHORT( p );    if ( size >= start && size <= end )    {      /* we could do that with clever bit operations, but a switch is */      /* much simpler to understand and maintain                      */      /*                                                              */      switch ( format )      {      case 1:        idx    = (OTL_UInt)( ( size - start ) * 2 );        p     += idx / 16;        value  = OTL_PEEK_USHORT( p );        shift  = idx & 15;        result = (OTL_Short)( value << shift ) >> ( 14 - shift );        break;      case 2:        idx    = (OTL_UInt)( ( size - start ) * 4 );        p     += idx / 16;        value  = OTL_PEEK_USHORT( p );        shift  = idx & 15;        result = (OTL_Short)( value << shift ) >> ( 12 - shift );        break;      case 3:        idx    = (OTL_UInt)( ( size - start ) * 8 );        p     += idx / 16;        value  = OTL_PEEK_USHORT( p );        shift  = idx & 15;        result = (OTL_Short)( value << shift ) >> ( 8 - shift );        break;      default:        ;      }    }    return result;  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                      LOOKUP LISTS                             *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  OTL_LOCALDEF( void )  otl_lookup_validate( OTL_Bytes      table,                       OTL_Validator  valid )  {    OTL_Bytes  p = table;    OTL_UInt   num_tables;    if ( table + 6 > valid->limit )      OTL_INVALID_TOO_SHORT;    p += 4;    num_tables = OTL_NEXT_USHORT( p );    if ( p + num_tables * 2 > valid->limit )      OTL_INVALID_TOO_SHORT;    for ( ; num_tables > 0; num_tables-- )    {      offset = OTL_NEXT_USHORT( p );      if ( table + offset >= valid->limit )        OTL_INVALID_OFFSET;    }    /* XXX: check sub-tables? */  }  OTL_LOCALDEF( OTL_UInt )  otl_lookup_get_count( OTL_Bytes  table )  {    OTL_Bytes  p = table + 4;    return OTL_PEEK_USHORT( p );  }

⌨️ 快捷键说明

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