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; }
/* 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); }