static int ShapeParagraphFriBidi( filter_t *p_filter, paragraph_t *p_paragraph ) { if( p_paragraph->i_size <= 0 ) { msg_Err( p_filter, "ShapeParagraphFriBidi() invalid parameters. Paragraph size: %d", p_paragraph->i_size ); return VLC_EGENERIC; } FriBidiJoiningType *p_joining_types = malloc( p_paragraph->i_size * sizeof( *p_joining_types ) ); if( !p_joining_types ) return VLC_ENOMEM; fribidi_get_joining_types( p_paragraph->p_code_points, p_paragraph->i_size, p_joining_types ); fribidi_join_arabic( p_paragraph->p_types, p_paragraph->i_size, p_paragraph->p_levels, p_joining_types ); fribidi_shape( FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC, p_paragraph->p_levels, p_paragraph->i_size, p_joining_types, p_paragraph->p_code_points ); free( p_joining_types ); return VLC_SUCCESS; }
bool GlyphString::shapeFriBidi(bool removeInvisibleCharacters) { if (mState != Analyzed) return false; FriBidiJoiningType *joiningTypes = new FriBidiJoiningType[mSize]; fribidi_get_joining_types(mCodePoints, mSize, joiningTypes); fribidi_join_arabic(mTypes, mSize, mLevels, joiningTypes); fribidi_shape(FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC, mLevels, mSize, joiningTypes, mCodePoints); delete[] joiningTypes; loadGlyphImages(); if (removeInvisibleCharacters) { for (int i = 0; i < mSize; ++i) { if (mCodePoints[i] == 0xfeff || mCodePoints[i] == 0x061c || (mCodePoints[i] >= 0x202a && mCodePoints[i] <= 0x202e) || (mCodePoints[i] >= 0x2060 && mCodePoints[i] <= 0x2069) || (mCodePoints[i] >= 0x200b && mCodePoints[i] <= 0x200f)) clearGlyph(i); } } mState = Shaped; return true; }
/** * @internal * Shapes the string ustr according to the bidi properties. * * @param str The string to shape * @param bidi_props the bidi props to shaped according. * @param start the start of the string to shape (offset in bidi_props) * @param len the length of th string. * @return #EINA_TRUE on success, #EINA_FALSE otherwise. */ EAPI Eina_Bool evas_bidi_shape_string(Eina_Unicode *eina_ustr, const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, size_t len) { FriBidiChar *ustr, *base_ustr = NULL; if (!bidi_props) return EINA_FALSE; /* The size of fribidichar is different than eina_unicode, convert */ #ifdef EVAS_FRIBIDI_EINA_UNICODE_UNEQUAL base_ustr = ustr = calloc(len + 1, sizeof(FriBidiChar)); ustr = _evas_bidi_unicode_to_fribidichar(ustr, eina_ustr); #else (void) base_ustr; ustr = (FriBidiChar *) eina_ustr; #endif EvasBiDiJoiningType *join_types = NULL; join_types = (EvasBiDiJoiningType *) malloc(sizeof(EvasBiDiJoiningType) * len); if (!join_types) { #ifdef EVAS_FRIBIDI_EINA_UNICODE_UNEQUAL if (base_ustr) free(base_ustr); #endif return EINA_FALSE; } fribidi_get_joining_types(ustr, len, join_types); fribidi_join_arabic(bidi_props->char_types + start, len, bidi_props->embedding_levels + start, join_types); /* Actually modify the string */ fribidi_shape(FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC, bidi_props->embedding_levels + start, len, join_types, ustr); if (join_types) free(join_types); /* Convert back */ #ifdef EVAS_FRIBIDI_EINA_UNICODE_UNEQUAL _evas_bidi_fribidichar_to_unicode(eina_ustr, ustr); if (base_ustr) free(base_ustr); #endif return EINA_TRUE; }
static int shape_text(AVFilterContext *ctx) { DrawTextContext *s = ctx->priv; uint8_t *tmp; int ret = AVERROR(ENOMEM); static const FriBidiFlags flags = FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC; FriBidiChar *unicodestr = NULL; FriBidiStrIndex len; FriBidiParType direction = FRIBIDI_PAR_LTR; FriBidiStrIndex line_start = 0; FriBidiStrIndex line_end = 0; FriBidiLevel *embedding_levels = NULL; FriBidiArabicProp *ar_props = NULL; FriBidiCharType *bidi_types = NULL; FriBidiStrIndex i,j; len = strlen(s->text); if (!(unicodestr = av_malloc_array(len, sizeof(*unicodestr)))) { goto out; } len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, s->text, len, unicodestr); bidi_types = av_malloc_array(len, sizeof(*bidi_types)); if (!bidi_types) { goto out; } fribidi_get_bidi_types(unicodestr, len, bidi_types); embedding_levels = av_malloc_array(len, sizeof(*embedding_levels)); if (!embedding_levels) { goto out; } if (!fribidi_get_par_embedding_levels(bidi_types, len, &direction, embedding_levels)) { goto out; } ar_props = av_malloc_array(len, sizeof(*ar_props)); if (!ar_props) { goto out; } fribidi_get_joining_types(unicodestr, len, ar_props); fribidi_join_arabic(bidi_types, len, embedding_levels, ar_props); fribidi_shape(flags, embedding_levels, len, ar_props, unicodestr); for (line_end = 0, line_start = 0; line_end < len; line_end++) { if (is_newline(unicodestr[line_end]) || line_end == len - 1) { if (!fribidi_reorder_line(flags, bidi_types, line_end - line_start + 1, line_start, direction, embedding_levels, unicodestr, NULL)) { goto out; } line_start = line_end + 1; } } /* Remove zero-width fill chars put in by libfribidi */ for (i = 0, j = 0; i < len; i++) if (unicodestr[i] != FRIBIDI_CHAR_FILL) unicodestr[j++] = unicodestr[i]; len = j; if (!(tmp = av_realloc(s->text, (len * 4 + 1) * sizeof(*s->text)))) { /* Use len * 4, as a unicode character can be up to 4 bytes in UTF-8 */ goto out; } s->text = tmp; len = fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, unicodestr, len, s->text); ret = 0; out: av_free(unicodestr); av_free(embedding_levels); av_free(ar_props); av_free(bidi_types); return ret; }