示例#1
0
static void get_bidi_levels(FriBidiChar *in,int length,int is_rtl,FriBidiLevel *embed)
{
	FriBidiCharType direction;
	if(is_rtl)
		direction = FRIBIDI_TYPE_RTL;
	else
		direction = FRIBIDI_TYPE_LTR;

	fribidi_log2vis_get_embedding_levels(in,length,&direction,embed);
}
/**
 * pango_log2vis_get_embedding_levels:
 * @text:      the text to itemize.
 * @length:    the number of bytes (not characters) to process, or -1
 *             if @text is nul-terminated and the length should be calculated.
 * @pbase_dir: input base direction, and output resolved direction.
 *
 * This will return the bidirectional embedding levels of the input paragraph
 * as defined by the Unicode Bidirectional Algorithm available at:
 *
 *   http://www.unicode.org/reports/tr9/
 *
 * If the input base direction is a weak direction, the direction of the
 * characters in the text will determine the final resolved direction.
 *
 * Return value: a newly allocated array of embedding levels, one item per
 *               character (not byte), that should be freed using g_free.
 *
 * Since: 1.4
 */
guint8 *
pango_log2vis_get_embedding_levels (const gchar    *text,
				    int             length,
				    PangoDirection *pbase_dir)
{
  FriBidiCharType fribidi_base_dir;
  guint8 *embedding_levels_list;

  switch (*pbase_dir)
    {
    case PANGO_DIRECTION_LTR:
    case PANGO_DIRECTION_TTB_RTL:
      fribidi_base_dir = FRIBIDI_TYPE_L;
      break;
    case PANGO_DIRECTION_RTL:
    case PANGO_DIRECTION_TTB_LTR:
      fribidi_base_dir = FRIBIDI_TYPE_R;
      break;
    case PANGO_DIRECTION_WEAK_RTL:
      fribidi_base_dir = FRIBIDI_TYPE_WR;
      break;
    case PANGO_DIRECTION_WEAK_LTR:
    case PANGO_DIRECTION_NEUTRAL:
    default:
      fribidi_base_dir = FRIBIDI_TYPE_WL;
      break;
    }

#ifdef FRIBIDI_HAVE_UTF8
  {
    if (length < 0)
      length = strlen (text);
    embedding_levels_list = (guint8 *) fribidi_log2vis_get_embedding_levels_new_utf8 (text, length, &fribidi_base_dir);
  }
#else
  {
    gunichar *text_ucs4;
    int n_chars;
    text_ucs4 = g_utf8_to_ucs4_fast (text, length, &n_chars);
    embedding_levels_list = g_new (guint8, n_chars);
    fribidi_log2vis_get_embedding_levels ((FriBidiChar*)text_ucs4, n_chars,
					  &fribidi_base_dir,
					  (FriBidiLevel*)embedding_levels_list);
    g_free (text_ucs4);
  }
#endif

  *pbase_dir = (fribidi_base_dir == FRIBIDI_TYPE_L) ?  PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL;

  return embedding_levels_list;
}
void 
pangolite_log2vis_get_embedding_levels (gunichar       *str,
                                    int            len,
                                    PangoliteDirection *pbase_dir,
                                    guint8         *embedding_level_list)
{
  FriBidiCharType fribidi_base_dir;
  
  fribidi_base_dir = (*pbase_dir == PANGO_DIRECTION_LTR) ?
    FRIBIDI_TYPE_L : FRIBIDI_TYPE_R;
  
  fribidi_log2vis_get_embedding_levels(str, len, &fribidi_base_dir,
                                       embedding_level_list);
  
  *pbase_dir = (fribidi_base_dir == FRIBIDI_TYPE_L) ?  
    PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL;
}
示例#4
0
/* This function marks embedding levels at for text "in",
 * it ignores different tags */
void bidi_tag_tolerant_fribidi_l2v(	FriBidiChar *in,int len,
									int is_heb,
									FriBidiLevel *embed,
									char *is_command)
{
	int in_pos,out_pos,cmd_len,i;
	FriBidiChar *in_tmp;
	FriBidiLevel *embed_tmp,fill_level;
	FriBidiCharType direction;

	if(is_heb)
		direction = FRIBIDI_TYPE_RTL;
	else
		direction = FRIBIDI_TYPE_LTR;
	
	in_tmp=(FriBidiChar*)utl_malloc(sizeof(FriBidiChar)*(len+1));
	embed_tmp=(FriBidiLevel*)utl_malloc(sizeof(FriBidiLevel)*len);
	
	/**********************************************
	 * This is main parser that marks commands    *
	 * across the text i.e. marks non text        *
	 **********************************************/
	bidi_mark_commands(in,len,is_command,is_heb);
	
	/**********************************************/
	/* Copy all the data without tags for fribidi */
	/**********************************************/
	in_pos=0;
	out_pos=0;

	while(in_pos<len) {
		if(is_command[in_pos]){
			in_pos++;
			continue;
		}
		/* Copy to buffer */
		in_tmp[out_pos]=in[in_pos];
		out_pos++;
		in_pos++;
	}
	
	/***************
	 * RUN FRIBIDI *
	 ***************/
	
	/* Note - you must take the new size for firibidi */
	fribidi_log2vis_get_embedding_levels(in_tmp,out_pos,&direction,embed_tmp);

	/****************************************************
	 * Return the tags and fill missing embedding level *
	 ****************************************************/
	in_pos=0;
	out_pos=0;

	while(in_pos<len) {
		if(is_command[in_pos]){
			/* Find the length of the part that 
			 * has a command/tag */
			for(cmd_len=0;in_pos+cmd_len<len;cmd_len++) {
				if(!is_command[cmd_len+in_pos])
					break;
			}
			
			if(in_pos == 0 || in_pos + cmd_len == len){
				/* When we on start/end assume basic direction */
				fill_level = bidi_basic_level(is_heb);
			}
			else {
				/* Fill with minimum on both sides */
				fill_level = min(embed_tmp[out_pos-1],embed_tmp[out_pos]);
			}
			
			for(i=0;i<cmd_len;i++){
				embed[in_pos]=fill_level;
				in_pos++;
			}
			continue;
		}
		/* Retrieve embedding */
		embed[in_pos]=embed_tmp[out_pos];
		out_pos++;
		in_pos++;
	}

	/* Not forget to free */
	utl_free(embed_tmp);
	utl_free(in_tmp);
}