EAPI char * evas_common_encoding_unicode_to_utf8(const Eina_Unicode *uni, int *_len) { char *buf; const Eina_Unicode *uind; char *ind; int ulen, len; ulen = eina_unicode_strlen(uni); buf = (char *) calloc(ulen + 1, EVAS_ENCODING_UTF8_BYTES_PER_CHAR); len = 0; for (uind = uni, ind = buf ; *uind ; uind++) { if (*uind <= 0x7F) /* 1 byte char */ { *ind++ = *uind; len += 1; } else if (*uind <= 0x7FF) /* 2 byte char */ { *ind++ = 0xC0 | (unsigned char) (*uind >> 6); *ind++ = 0x80 | (unsigned char) (*uind & 0x3F); len += 2; } else if (*uind <= 0xFFFF) /* 3 byte char */
EAPI char * eina_unicode_unicode_to_utf8(const Eina_Unicode *uni, int *_len) { char *buf; const Eina_Unicode *uind; char *ind; int ulen, len; EINA_SAFETY_ON_NULL_RETURN_VAL(uni, NULL); ulen = eina_unicode_strlen(uni); buf = (char *) calloc(ulen + 1, EINA_UNICODE_UTF8_BYTES_PER_CHAR); len = 0; for (uind = uni, ind = buf ; *uind ; uind++) { if (*uind <= 0x7F) /* 1 byte char */ { *ind++ = *uind; len += 1; } else if (*uind <= 0x7FF) /* 2 byte char */ { *ind++ = 0xC0 | (unsigned char) (*uind >> 6); *ind++ = 0x80 | (unsigned char) (*uind & 0x3F); len += 2; } else if (*uind <= 0xFFFF) /* 3 byte char */
EAPI Eina_Unicode * eina_unicode_escape(const Eina_Unicode *str) { Eina_Unicode *s2, *d; const Eina_Unicode *s; EINA_SAFETY_ON_NULL_RETURN_VAL(str, NULL); s2 = malloc((eina_unicode_strlen(str) * 2) + 1); if (!s2) return NULL; for (s = str, d = s2; *s != 0; s++, d++) { if ((*s == ' ') || (*s == '\\') || (*s == '\'')) { *d = '\\'; d++; } *d = *s; } *d = 0; return s2; }
EAPI Eina_Unicode * eina_unicode_strdup(const Eina_Unicode *text) { size_t len; EINA_SAFETY_ON_NULL_RETURN_VAL(text, NULL); len = eina_unicode_strlen(text); return eina_unicode_strndup(text, len); }
/** * @brief Same as the standard strdup just with Eina_Unicode instead of char. */ EAPI Eina_Unicode *eina_unicode_strdup(const Eina_Unicode * text) { Eina_Unicode *ustr; int len; len = eina_unicode_strlen(text); ustr = (Eina_Unicode *) calloc(len + 1, sizeof(Eina_Unicode)); memcpy(ustr, text, len * sizeof(Eina_Unicode)); return ustr; }
/** * @internal * Allocates bidi properties according to ustr. First checks to see if the * passed has rtl chars, if not, it returns NULL. * * Assumes all the segment_idxs are either -1 or legal, and > 0 indexes. * Also assumes that the characters at the override points are of weak/neutral * bidi type, otherwise unexpected results may occur. * * @param ustr The string to update according to. * @param len The length of the string * @param segment_idxs A -1 terminated array of points to start a new bidi analysis at (used for section high level bidi overrides). - NULL means none. * @return returns allocated paragraph props on success, NULL otherwise. */ Evas_BiDi_Paragraph_Props * evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr, size_t len, int *segment_idxs) { Evas_BiDi_Paragraph_Props *bidi_props = NULL; EvasBiDiCharType *char_types = NULL; EvasBiDiLevel *embedding_levels = NULL; const FriBidiChar *ustr; FriBidiChar *base_ustr = NULL; if (!eina_ustr) return NULL; if (!evas_bidi_is_rtl_str(eina_ustr)) /* No need to handle bidi */ { len = -1; goto cleanup; } len = eina_unicode_strlen(eina_ustr); /* The size of fribidichar s different than eina_unicode, convert */ #ifdef EVAS_FRIBIDI_EINA_UNICODE_UNEQUAL base_ustr = calloc(len + 1, sizeof(FriBidiChar)); base_ustr = _evas_bidi_unicode_to_fribidichar(base_ustr, eina_ustr); ustr = base_ustr; #else ustr = (const FriBidiChar *) eina_ustr; #endif bidi_props = evas_bidi_paragraph_props_new(); /* Prep work for reordering */ char_types = (EvasBiDiCharType *) malloc(sizeof(EvasBiDiCharType) * len); if (!char_types) { len = -2; goto cleanup; } fribidi_get_bidi_types(ustr, len, char_types); embedding_levels = (EvasBiDiLevel *)malloc(sizeof(EvasBiDiLevel) * len); if (!embedding_levels) { len = -2; goto cleanup; } if (segment_idxs) { size_t pos = 0; int *itr; EvasBiDiLevel base_level = 0; EvasBiDiParType direction; for (itr = segment_idxs ; *itr > 0 ; itr++) { direction = EVAS_BIDI_PARAGRAPH_NEUTRAL; if (!fribidi_get_par_embedding_levels(char_types + pos, *itr - pos, &direction, embedding_levels + pos)) { len = -2; goto cleanup; } /* Only on the first run */ if (itr == segment_idxs) { bidi_props->direction = direction; /* adjust base_level to be 1 for rtl paragraphs, and 0 for * ltr paragraphs. */ base_level = EVAS_BIDI_PARAGRAPH_DIRECTION_IS_RTL(bidi_props) ? 1 : 0; } /* We want those chars at the override points to be on the base * level and we also remove -2 cause we later increment them, * just for simpler code paths */ embedding_levels[*itr] = base_level - 2; pos = *itr + 1; } direction = EVAS_BIDI_PARAGRAPH_NEUTRAL; if (!fribidi_get_par_embedding_levels(char_types + pos, len - pos, &direction, embedding_levels + pos)) { len = -2; goto cleanup; } /* Increment all levels by 2 to emulate embedding. */ { EvasBiDiLevel *bitr = embedding_levels, *end; end = bitr + len; for ( ; bitr < end ; bitr++) { *bitr += 2; } } } else { if (!fribidi_get_par_embedding_levels(char_types, len, &bidi_props->direction, embedding_levels)) { len = -2; goto cleanup; } } /* clean up */ if (bidi_props->embedding_levels) { free(bidi_props->embedding_levels); } bidi_props->embedding_levels = embedding_levels; /* clean up */ if (bidi_props->char_types) { free(bidi_props->char_types); } bidi_props->char_types = char_types; if (base_ustr) free(base_ustr); return bidi_props; /* Cleanup */ cleanup: if (char_types) free(char_types); if (embedding_levels) free(embedding_levels); if (base_ustr) free(base_ustr); if (bidi_props) evas_bidi_paragraph_props_unref(bidi_props); /* Clean up the bidi props */ return NULL; }
/** * @brief Retrieve an instance of a string for use in a program. * * @param str The NULL terminated string to retrieve an instance of. * @return A pointer to an instance of the string on success. * @c NULL on failure. * * This function retrieves an instance of @p str. If @p str is * @c NULL, then @c NULL is returned. If @p str is already stored, it * is just returned and its reference counter is increased. Otherwise * it is added to the strings to be searched and a duplicated string * of @p str is returned. * * The string @p str must be NULL terminated ('@\0') and its full * length will be used. To use part of the string or non-null * terminated, use eina_stringshare_add_length() instead. * * @see eina_ustringshare_add_length() */ EAPI const Eina_Unicode *eina_ustringshare_add(const Eina_Unicode * str) { int slen = (str) ? (int) eina_unicode_strlen(str) : -1; return eina_ustringshare_add_length(str, slen); }