Atlas - SDL_fribidi.c

Home / ext / SDL / src / core / unix Lines: 2 | Size: 5792 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "SDL_internal.h" 22 23#ifdef HAVE_FRIBIDI_H 24 25#include "SDL_fribidi.h" 26 27#ifdef SDL_FRIBIDI_DYNAMIC 28SDL_ELF_NOTE_DLOPEN( 29 "fribidi", 30 "Bidirectional text support", 31 SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, 32 SDL_FRIBIDI_DYNAMIC 33) 34#endif 35 36SDL_FriBidi *SDL_FriBidi_Create(void) 37{ 38 SDL_FriBidi *fribidi; 39 40 fribidi = (SDL_FriBidi *)SDL_malloc(sizeof(SDL_FriBidi)); 41 if (!fribidi) { 42 return NULL; 43 } 44 45#ifdef SDL_FRIBIDI_DYNAMIC 46 #define SDL_FRIBIDI_LOAD_SYM(x, n, t) x = ((t)SDL_LoadFunction(fribidi->lib, n)); if (!x) { SDL_UnloadObject(fribidi->lib); SDL_free(fribidi); return NULL; } 47 48 fribidi->lib = SDL_LoadObject(SDL_FRIBIDI_DYNAMIC); 49 if (!fribidi->lib) { 50 SDL_free(fribidi); 51 return NULL; 52 } 53 54 SDL_FRIBIDI_LOAD_SYM(fribidi->unicode_to_charset, "fribidi_unicode_to_charset", SDL_FriBidiUnicodeToCharset); 55 SDL_FRIBIDI_LOAD_SYM(fribidi->charset_to_unicode, "fribidi_charset_to_unicode", SDL_FriBidiCharsetToUnicode); 56 SDL_FRIBIDI_LOAD_SYM(fribidi->get_bidi_types, "fribidi_get_bidi_types", SDL_FriBidiGetBidiTypes); 57 SDL_FRIBIDI_LOAD_SYM(fribidi->get_par_direction, "fribidi_get_par_direction", SDL_FriBidiGetParDirection); 58 SDL_FRIBIDI_LOAD_SYM(fribidi->get_par_embedding_levels, "fribidi_get_par_embedding_levels", SDL_FriBidiGetParEmbeddingLevels); 59 SDL_FRIBIDI_LOAD_SYM(fribidi->get_joining_types, "fribidi_get_joining_types", SDL_FriBidiGetJoiningTypes); 60 SDL_FRIBIDI_LOAD_SYM(fribidi->join_arabic, "fribidi_join_arabic", SDL_FriBidiJoinArabic); 61 SDL_FRIBIDI_LOAD_SYM(fribidi->shape, "fribidi_shape", SDL_FriBidiShape); 62 SDL_FRIBIDI_LOAD_SYM(fribidi->reorder_line, "fribidi_reorder_line", SDL_FriBidiReorderLine); 63#else 64 fribidi->unicode_to_charset = fribidi_unicode_to_charset; 65 fribidi->charset_to_unicode = fribidi_charset_to_unicode; 66 fribidi->get_bidi_types = fribidi_get_bidi_types; 67 fribidi->get_par_direction = fribidi_get_par_direction; 68 fribidi->get_par_embedding_levels = fribidi_get_par_embedding_levels; 69 fribidi->get_joining_types = fribidi_get_joining_types; 70 fribidi->join_arabic = fribidi_join_arabic; 71 fribidi->shape = fribidi_shape; 72 fribidi->reorder_line = fribidi_reorder_line; 73#endif 74 75 return fribidi; 76} 77 78char *SDL_FriBidi_Process(SDL_FriBidi *fribidi, char *utf8, ssize_t utf8_len, bool shaping, FriBidiParType *out_par_type) 79{ 80 FriBidiCharType *types; 81 FriBidiLevel *levels; 82 FriBidiArabicProp *props; 83 FriBidiChar *str; 84 char *result; 85 FriBidiStrIndex len; 86 FriBidiLevel max_level; 87 FriBidiLevel start; 88 FriBidiLevel end; 89 FriBidiParType direction; 90 FriBidiParType str_direction; 91 unsigned int i; 92 unsigned int c; 93 94 if (!fribidi || !utf8) { 95 return NULL; 96 } 97 98 /* Convert to UTF32 */ 99 if (utf8_len < 0) { 100 utf8_len = SDL_strlen(utf8); 101 } 102 str = SDL_calloc(SDL_utf8strnlen(utf8, utf8_len), sizeof(FriBidiChar)); 103 len = fribidi->charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, utf8, utf8_len, str); 104 105 /* Setup various BIDI structures */ 106 direction = FRIBIDI_PAR_LTR; 107 types = NULL; 108 levels = NULL; 109 props = SDL_calloc(len + 1, sizeof(FriBidiArabicProp)); 110 levels = SDL_calloc(len + 1, sizeof(FriBidiLevel)); 111 types = SDL_calloc(len + 1, sizeof(FriBidiCharType)); 112 113 /* Shape */ 114 fribidi->get_bidi_types(str, len, types); 115 str_direction = fribidi->get_par_direction(types, len); 116 max_level = fribidi->get_par_embedding_levels(types, len, &direction, levels); 117 if (shaping) { 118 fribidi->get_joining_types(str, len, props); 119 fribidi->join_arabic(types, len, levels, props); 120 fribidi->shape(FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC, levels, len, props, str); 121 } 122 123 /* BIDI */ 124 for (end = 0, start = 0; end < len; end++) { 125 if (str[end] == '\n' || str[end] == '\r' || str[end] == '\f' || str[end] == '\v' || end == len - 1) { 126 max_level = fribidi->reorder_line(FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC, types, end - start + 1, start, direction, levels, str, NULL); 127 start = end + 1; 128 } 129 } 130 131 /* Silence warning */ 132 (void)max_level; 133 134 /* Remove fillers */ 135 for (i = 0, c = 0; i < len; i++) { 136 if (str[i] != FRIBIDI_CHAR_FILL) { 137 str[c++] = str[i]; 138 } 139 } 140 len = c; 141 142 /* Convert back to UTF8 */ 143 result = SDL_malloc(len * 4 + 1); 144 fribidi->unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, str, len, result); 145 146 /* Cleanup */ 147 SDL_free(levels); 148 SDL_free(props); 149 SDL_free(types); 150 151 /* Return */ 152 if (out_par_type) { 153 *out_par_type = str_direction; 154 } 155 return result; 156} 157 158void SDL_FriBidi_Destroy(SDL_FriBidi *fribidi) 159{ 160 if (!fribidi) { 161 return; 162 } 163 164#ifdef SDL_FRIBIDI_DYNAMIC 165 SDL_UnloadObject(fribidi->lib); 166#endif 167 168 SDL_free(fribidi); 169} 170 171#endif 172
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.