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

📄 harfbuzz-buffer.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
字号:
/* * Copyright (C) 1998-2004  David Turner and Werner Lemberg * Copyright (C) 2004,2007  Red Hat, Inc. * * 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. * * Red Hat Author(s): Owen Taylor, Behdad Esfahbod */#include "harfbuzz-impl.h"#include "harfbuzz-buffer-private.h"#include "harfbuzz-gsub-private.h"#include "harfbuzz-gpos-private.h"/* Here is how the buffer works internally: * * There are two string pointers: in_string and out_string.  They * always have same allocated size, but different length and positions. * * As an optimization, both in_string and out_string may point to the * same piece of memory, which is owned by in_string.  This remains the * case as long as: * *   - copy_glyph() is called *   - replace_glyph() is called with inplace=TRUE *   - add_output_glyph() and add_output_glyphs() are not called * * In that case swap(), and copy_glyph(), and replace_glyph() are all * mostly no-op. * * As soon an add_output_glyph[s]() or replace_glyph() with inplace=FALSE is * called, out_string is moved over to an alternate buffer (alt_string), and * its current contents (out_length entries) are copied to the alt buffer. * This should all remain transparent to the user.  swap() then switches * in_string and alt_string.  alt_string is not allocated until its needed, * but after that it's grown with in_string unconditionally. * * The buffer->separate_out boolean keeps status of whether out_string points * to in_string (FALSE) or alt_string (TRUE). *//* Internal API */static HB_Errorhb_buffer_ensure( HB_Buffer buffer,		   HB_UInt   size ){  HB_UInt new_allocated = buffer->allocated;  if (size > new_allocated)    {      HB_Error error;      while (size > new_allocated)	new_allocated += (new_allocated >> 1) + 8;            if ( buffer->positions )        {	  if ( REALLOC_ARRAY( buffer->positions, new_allocated, HB_PositionRec ) )	    return error;	}      if ( REALLOC_ARRAY( buffer->in_string, new_allocated, HB_GlyphItemRec ) )	return error;      if ( buffer->separate_out )        {	  if ( REALLOC_ARRAY( buffer->alt_string, new_allocated, HB_GlyphItemRec ) )	    return error;	  buffer->out_string = buffer->alt_string;	}      else        {	  buffer->out_string = buffer->in_string;	  if ( buffer->alt_string )	    {	      if ( REALLOC_ARRAY( buffer->alt_string, new_allocated, HB_GlyphItemRec ) )		return error;	    }	}      buffer->allocated = new_allocated;    }  return HB_Err_Ok;}static HB_Errorhb_buffer_duplicate_out_buffer( HB_Buffer buffer ){  if ( !buffer->alt_string )    {      HB_Error error;      if ( ALLOC_ARRAY( buffer->alt_string, buffer->allocated, HB_GlyphItemRec ) )	return error;    }  buffer->out_string = buffer->alt_string;  memcpy( buffer->out_string, buffer->in_string, buffer->out_length * sizeof (buffer->out_string[0]) );  buffer->separate_out = TRUE;  return HB_Err_Ok;}/* Public API */HB_Errorhb_buffer_new( HB_Buffer *pbuffer ){  HB_Buffer buffer;  HB_Error error;    if ( ALLOC( buffer, sizeof( HB_BufferRec ) ) )    return error;  buffer->allocated = 0;  buffer->in_string = NULL;  buffer->alt_string = NULL;  buffer->positions = NULL;  hb_buffer_clear( buffer );  *pbuffer = buffer;  return HB_Err_Ok;}voidhb_buffer_free( HB_Buffer buffer ){  FREE( buffer->in_string );  FREE( buffer->alt_string );  buffer->out_string = NULL;  FREE( buffer->positions );  FREE( buffer );}voidhb_buffer_clear( HB_Buffer buffer ){  buffer->in_length = 0;  buffer->out_length = 0;  buffer->in_pos = 0;  buffer->out_pos = 0;  buffer->out_string = buffer->in_string;  buffer->separate_out = FALSE;  buffer->max_ligID = 0;}HB_Errorhb_buffer_add_glyph( HB_Buffer buffer,		      HB_UInt   glyph_index,		      HB_UInt   properties,		      HB_UInt   cluster ){  HB_Error error;  HB_GlyphItem glyph;    error = hb_buffer_ensure( buffer, buffer->in_length + 1 );  if ( error )    return error;  glyph = &buffer->in_string[buffer->in_length];  glyph->gindex = glyph_index;  glyph->properties = properties;  glyph->cluster = cluster;  glyph->component = 0;  glyph->ligID = 0;  glyph->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN;    buffer->in_length++;  return HB_Err_Ok;}/* HarfBuzz-Internal API */HB_INTERNAL void_hb_buffer_clear_output( HB_Buffer buffer ){  buffer->out_length = 0;  buffer->out_pos = 0;  buffer->out_string = buffer->in_string;  buffer->separate_out = FALSE;}HB_INTERNAL HB_Error_hb_buffer_clear_positions( HB_Buffer buffer ){  if ( !buffer->positions )    {      HB_Error error;      if ( ALLOC_ARRAY( buffer->positions, buffer->allocated, HB_PositionRec ) )	return error;    }  memset (buffer->positions, 0, sizeof (buffer->positions[0]) * buffer->in_length);  return HB_Err_Ok;}HB_INTERNAL void_hb_buffer_swap( HB_Buffer buffer ){  HB_GlyphItem tmp_string;  int tmp_length;  int tmp_pos;  if ( buffer->separate_out )    {      tmp_string = buffer->in_string;      buffer->in_string = buffer->out_string;      buffer->out_string = tmp_string;      buffer->alt_string = buffer->out_string;    }  tmp_length = buffer->in_length;  buffer->in_length = buffer->out_length;  buffer->out_length = tmp_length;  tmp_pos = buffer->in_pos;  buffer->in_pos = buffer->out_pos;  buffer->out_pos = tmp_pos;}/* The following function copies `num_out' elements from `glyph_data'   to `buffer->out_string', advancing the in array pointer in the structure   by `num_in' elements, and the out array pointer by `num_out' elements.   Finally, it sets the `length' field of `out' equal to   `pos' of the `out' structure.   If `component' is 0xFFFF, the component value from buffer->in_pos   will copied `num_out' times, otherwise `component' itself will   be used to fill the `component' fields.   If `ligID' is 0xFFFF, the ligID value from buffer->in_pos   will copied `num_out' times, otherwise `ligID' itself will   be used to fill the `ligID' fields.   The properties for all replacement glyphs are taken   from the glyph at position `buffer->in_pos'.   The cluster value for the glyph at position buffer->in_pos is used   for all replacement glyphs */HB_INTERNAL HB_Error_hb_buffer_add_output_glyphs( HB_Buffer  buffer,			      HB_UShort  num_in,			      HB_UShort  num_out,			      HB_UShort *glyph_data,			      HB_UShort  component,			      HB_UShort  ligID ){  HB_Error  error;  HB_UShort i;  HB_UInt properties;  HB_UInt cluster;  error = hb_buffer_ensure( buffer, buffer->out_pos + num_out );  if ( error )    return error;  if ( !buffer->separate_out )    {      error = hb_buffer_duplicate_out_buffer( buffer );      if ( error )	return error;    }  properties = buffer->in_string[buffer->in_pos].properties;  cluster = buffer->in_string[buffer->in_pos].cluster;  if ( component == 0xFFFF )    component = buffer->in_string[buffer->in_pos].component;  if ( ligID == 0xFFFF )    ligID = buffer->in_string[buffer->in_pos].ligID;  for ( i = 0; i < num_out; i++ )  {    HB_GlyphItem item = &buffer->out_string[buffer->out_pos + i];    item->gindex = glyph_data[i];    item->properties = properties;    item->cluster = cluster;    item->component = component;    item->ligID = ligID;    item->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN;  }  buffer->in_pos  += num_in;  buffer->out_pos += num_out;  buffer->out_length = buffer->out_pos;  return HB_Err_Ok;}HB_INTERNAL HB_Error_hb_buffer_add_output_glyph( HB_Buffer buffer,			     HB_UInt   glyph_index,			     HB_UShort component,			     HB_UShort ligID ){  HB_UShort glyph_data =  glyph_index;  return _hb_buffer_add_output_glyphs ( buffer, 1, 1,					&glyph_data, component, ligID );}HB_INTERNAL HB_Error_hb_buffer_copy_output_glyph ( HB_Buffer buffer ){    HB_Error  error;  error = hb_buffer_ensure( buffer, buffer->out_pos + 1 );  if ( error )    return error;    if ( buffer->separate_out )    {      buffer->out_string[buffer->out_pos] = buffer->in_string[buffer->in_pos];    }  buffer->in_pos++;  buffer->out_pos++;  buffer->out_length = buffer->out_pos;  return HB_Err_Ok;}HB_INTERNAL HB_Error_hb_buffer_replace_output_glyph( HB_Buffer buffer,				 HB_UInt   glyph_index,				 HB_Bool   inplace ){  HB_Error error;  if ( inplace )    {      error = _hb_buffer_copy_output_glyph ( buffer );      if ( error )	return error;      buffer->out_string[buffer->out_pos-1].gindex = glyph_index;    }  else    {      return _hb_buffer_add_output_glyph( buffer, glyph_index, 0xFFFF, 0xFFFF );    }  return HB_Err_Ok;}HB_INTERNAL HB_UShort_hb_buffer_allocate_ligid( HB_Buffer buffer ){  buffer->max_ligID++;  if (HB_UNLIKELY (buffer->max_ligID == 0))    buffer->max_ligID++;  return buffer->max_ligID;}

⌨️ 快捷键说明

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