Esempio n. 1
0
hb_bool_t
hb_ot_layout_language_find_feature (hb_face_t    *face,
                                    hb_tag_t      table_tag,
                                    unsigned int  script_index,
                                    unsigned int  language_index,
                                    hb_tag_t      feature_tag,
                                    unsigned int *feature_index)
{
  ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
  const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);

  unsigned int num_features = l.get_feature_count ();
  for (unsigned int i = 0; i < num_features; i++) {
    unsigned int f_index = l.get_feature_index (i);

    if (feature_tag == g.get_feature_tag (f_index)) {
      if (feature_index) *feature_index = f_index;
      return true;
    }
  }

  if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX;
  return false;
}
Esempio n. 2
0
hb_bool_t
hb_ot_layout_table_find_script (hb_face_t    *face,
                                hb_tag_t      table_tag,
                                hb_tag_t      script_tag,
                                unsigned int *script_index)
{
  ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);

  if (g.find_script_index (script_tag, script_index))
    return true;

  /* try finding 'DFLT' */
  if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index))
    return false;

  /* try with 'dflt'; MS site has had typos and many fonts use it now :(.
   * including many versions of DejaVu Sans Mono! */
  if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index))
    return false;

  /* try with 'latn'; some old fonts put their features there even though
     they're really trying to support Thai, for example :( */
  if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index))
    return false;

  if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
  return false;
}
Esempio n. 3
0
hb_bool_t
hb_ot_layout_table_choose_script (hb_face_t      *face,
                                  hb_tag_t        table_tag,
                                  const hb_tag_t *script_tags,
                                  unsigned int   *script_index,
                                  hb_tag_t       *chosen_script)
{
  ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);

  while (*script_tags)
  {
    if (g.find_script_index (*script_tags, script_index)) {
      if (chosen_script)
        *chosen_script = *script_tags;
      return true;
    }
    script_tags++;
  }

  /* try finding 'DFLT' */
  if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) {
    if (chosen_script)
      *chosen_script = HB_OT_TAG_DEFAULT_SCRIPT;
    return false;
  }

  /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
  if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) {
    if (chosen_script)
      *chosen_script = HB_OT_TAG_DEFAULT_LANGUAGE;
    return false;
  }

  /* try with 'latn'; some old fonts put their features there even though
     they're really trying to support Thai, for example :( */
  if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index)) {
    if (chosen_script)
      *chosen_script = HB_OT_TAG_LATIN_SCRIPT;
    return false;
  }

  if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
  if (chosen_script)
    *chosen_script = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
  return false;
}
Esempio n. 4
0
bool
hb_buffer_t::enlarge (unsigned int size)
{
  if (unlikely (in_error))
    return false;
  if (unlikely (size > max_len))
  {
    in_error = true;
    return false;
  }

  unsigned int new_allocated = allocated;
  hb_glyph_position_t *new_pos = NULL;
  hb_glyph_info_t *new_info = NULL;
  bool separate_out = out_info != info;

  if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (info[0]))))
    goto done;

  while (size >= new_allocated)
    new_allocated += (new_allocated >> 1) + 32;

  ASSERT_STATIC (sizeof (info[0]) == sizeof (pos[0]));
  if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (info[0]))))
    goto done;

  new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0]));
  new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0]));

done:
  if (unlikely (!new_pos || !new_info))
    in_error = true;

  if (likely (new_pos))
    pos = new_pos;

  if (likely (new_info))
    info = new_info;

  out_info = separate_out ? (hb_glyph_info_t *) pos : info;
  if (likely (!in_error))
    allocated = new_allocated;

  return likely (!in_error);
}
Esempio n. 5
0
hb_bool_t
hb_ot_layout_script_find_language (hb_face_t    *face,
                                   hb_tag_t      table_tag,
                                   unsigned int  script_index,
                                   hb_tag_t      language_tag,
                                   unsigned int *language_index)
{
  ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX);
  const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);

  if (s.find_lang_sys_index (language_tag, language_index))
    return true;

  /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
  if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index))
    return false;

  if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
  return false;
}
Esempio n. 6
0
hb_bool_t
hb_ot_layout_table_find_feature (hb_face_t    *face,
                                 hb_tag_t      table_tag,
                                 hb_tag_t      feature_tag,
                                 unsigned int *feature_index)
{
  ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);

  unsigned int num_features = g.get_feature_count ();
  for (unsigned int i = 0; i < num_features; i++)
  {
    if (feature_tag == g.get_feature_tag (i)) {
      if (feature_index) *feature_index = i;
      return true;
    }
  }

  if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX;
  return false;
}
Esempio n. 7
0
unsigned int
hb_ot_layout_language_get_feature_tags (hb_face_t    *face,
                                        hb_tag_t      table_tag,
                                        unsigned int  script_index,
                                        unsigned int  language_index,
                                        unsigned int  start_offset,
                                        unsigned int *feature_count /* IN/OUT */,
                                        hb_tag_t     *feature_tags /* OUT */)
{
  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
  const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);

  ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t));
  unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsigned int *) feature_tags);

  if (feature_tags) {
    unsigned int count = *feature_count;
    for (unsigned int i = 0; i < count; i++)
      feature_tags[i] = g.get_feature_tag ((unsigned int) feature_tags[i]);
  }

  return ret;
}
Esempio n. 8
0
bool utTextureLoadKTX( const char *data, int size, utTextureInfo* info )
{
	ASSERT_STATIC( sizeof( KTXHeader ) == 64 );

	info->_surfaces = NULL;

	memcpy( &ktxHeader, data, 64 );

	// Check header
	if( memcmp(ktxHeader.identifier, ktxIdentifier, 12) !=0 )
	{
		Modules::log().writeError( "Invalid KTX header" );
		return false;
	}
	
	// Store properties
    info->_width = ktxHeader.pixelWidth;
    info->_height = ktxHeader.pixelHeight;
	info->_depth = 1;
    info->_format = utTextureFormats::Unknown;
	info->_mipCount = ktxHeader.numberOfMipmapLevels;

	// Get texture type
	if( ktxHeader.numberOfFaces > 1 )
	{
		if( ktxHeader.numberOfFaces != 6 )
		{
			Modules::log().writeError( "Wrong number of cube texture faces (should be 6)" );
			return false;
		}
		else
		{
			info->_type = utTextureTypes::TexCube;
		}
	}
	else if( ktxHeader.pixelDepth > 1 )
	{
		info->_depth = ktxHeader.pixelDepth;
		info->_type = utTextureTypes::Tex3D;
	}
	else
		info->_type = utTextureTypes::Tex2D;
	
	// Texture arrays are not supported yet
	if( ktxHeader.numberOfArrayElements > 1 )
	{
		Modules::log().writeWarning( "Texture Arrays not supported. using first array element only" );
	}

	// Get pixel format
	switch( ktxHeader.glInternalFormat )
	{
		case GL_RGB8:
			info->_format = utTextureFormats::RGB8;
			break;
		case GL_RGBA8:
			info->_format = utTextureFormats::BGRA8;
			break;
		case GL_BGRA:
			info->_format = utTextureFormats::BGRA8;
			break;
		case GL_RGBA16F:
			info->_format = utTextureFormats::RGBA16F;
			break;
		case GL_RGBA32F:
			info->_format = utTextureFormats::RGBA32F;
			break;
		case GL_COMPRESSED_RGBA_S3TC_DXT1:
			info->_format = utTextureFormats::DXT1;
			break;
		case GL_COMPRESSED_RGBA_S3TC_DXT3:
			info->_format = utTextureFormats::DXT3;
			break;
		case GL_COMPRESSED_RGBA_S3TC_DXT5:
			info->_format = utTextureFormats::DXT5;
			break;
		case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
			info->_format = utTextureFormats::PVRTCI_2BPP;
			break;
		case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
			info->_format = utTextureFormats::PVRTCI_A2BPP;
			break;
		case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
			info->_format = utTextureFormats::PVRTCI_4BPP;
			break;
		case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
			info->_format = utTextureFormats::PVRTCI_A4BPP;
			break;
		case GL_ETC1_RGB8_OES:
			info->_format = utTextureFormats::ETC1;
			break;
	}
	
	if( info->_format == utTextureFormats::Unknown )
	{
		Modules::log().writeError( "Unsupported KTX pixel format" );
		return false;
	}

	info->_sliceCount = info->_type == utTextureTypes::TexCube ? 6 : 1;
	unsigned char *pixels = (unsigned char *)(data + 128);

	uint32 surfaceIndex = 0;
	info->_surfaceCount = info->_sliceCount * info->_mipCount;
	info->_surfaces = new utTextureSurfaceInfo[info->_surfaceCount];

	int width = info->_width, height = info->_height, depth = info->_depth;

	for( uint32 i = 0; i < info->_mipCount; ++i )
	{
		size_t mipSize =  calcTextureSize( info->_format, width, height, depth );
		if( pixels + mipSize > (unsigned char *)data + size )
		{
			Modules::log().writeError( "Corrupt KTX" );
			return false;
		}
		
		for( uint32 j = 0; j < ktxHeader.numberOfArrayElements; ++j )
		{
			for( uint32 k = 0; k < ktxHeader.numberOfFaces; ++k )
			{
				if ( j == 0)
				{	// using only first element of array now
					utTextureSurfaceInfo& surface = info->_surfaces[surfaceIndex++];
					surface._mip = i;
					surface._slice = k;
					surface._data = pixels;
					surface._size = (uint32)mipSize;
				}
					
				pixels += mipSize;
			}
		}
		if( width > 1 ) width >>= 1;
		if( height > 1 ) height >>= 1;
		if( depth > 1 ) depth >>= 1;
	}

	ASSERT( pixels == (unsigned char *)data + size );
	return true;
}
Esempio n. 9
0
bool utTextureLoadPVR( const char* data, uint32 size, utTextureInfo* info)
{
	// Load pvr
    ASSERT_STATIC( sizeof( PVRHeader ) == 52 );

	info->_surfaces = NULL;

	memcpy( &pvrHeader, data, 52 );

    // Store properties
    info->_width = pvrHeader.dwWidth;
    info->_height = pvrHeader.dwHeight;
	info->_depth = 1;
    info->_format = utTextureFormats::Unknown;
	info->_mipCount = pvrHeader.dwMipMapCount;

    // Get texture type
    if( pvrHeader.dwNumFaces == 6 )
    {
		info->_type = utTextureTypes::TexCube;
    }
    else
    {
		info->_type = utTextureTypes::Tex2D;
    }

    // Get pixel format
	if (pvrHeader.dwPixelFormatHigh == 0 )
	{
		switch(pvrHeader.dwPixelFormatLow)
		{
		case ePVRTPF_PVRTCI_2bpp_RGBA:
			info->_format = utTextureFormats::PVRTCI_A2BPP;
			break;
		case ePVRTPF_PVRTCI_4bpp_RGBA:
			info->_format = utTextureFormats::PVRTCI_A4BPP;
			break;
		case ePVRTPF_DXT1:
			info->_format = utTextureFormats::DXT1;
			break;
		case ePVRTPF_DXT3:
			info->_format = utTextureFormats::DXT3;
			break;
		case ePVRTPF_DXT5:
			info->_format = utTextureFormats::DXT5;
			break;
		case ePVRTPF_PVRTCI_2bpp_RGB:
			info->_format = utTextureFormats::PVRTCI_2BPP;
			break;
		case ePVRTPF_PVRTCI_4bpp_RGB:
			info->_format = utTextureFormats::PVRTCI_4BPP;
			break;
		case ePVRTPF_ETC1:
			info->_format = utTextureFormats::ETC1;
			break;
		}
	}

	if( info->_format == utTextureFormats::Unknown )
	{
		Modules().log().writeError( "Unsupported PVR pixel format" );
		return false;
	}

    // Upload texture subresources
    info->_sliceCount = info->_type == utTextureTypes::TexCube ? 6 : 1;
    unsigned char *pixels = (unsigned char *)(data + 52);

	uint32 surfaceIndex = 0;
	info->_surfaceCount = info->_sliceCount * info->_mipCount;
	info->_surfaces = new utTextureSurfaceInfo[info->_surfaceCount];

    for( uint32 i = 0; i < info->_sliceCount; ++i )
    {
        int width = pvrHeader.dwWidth, height = pvrHeader.dwHeight;

        for( uint32 j = 0; j < info->_mipCount; ++j )
        {
			size_t mipSize =  calcTextureSize( info->_format, width, height, 1 );
            if( pixels + mipSize > (unsigned char *)data + size )
 			{
				Modules::log().writeError( "Corrupt PVR" );
				return false;
			}

			utTextureSurfaceInfo& surface = info->_surfaces[surfaceIndex++];
			surface._mip = j;
			surface._slice = i;
			surface._data = pixels;
			surface._size = (uint32)mipSize;

            pixels += mipSize;
            if( width > 1 ) width >>= 1;
            if( height > 1 ) height >>= 1;
        }
    }

    ASSERT( pixels == (unsigned char *)data + size);
	return true;
}