char hb_utf16_script_run_prev(unsigned *num_code_points, HB_ScriptItem *output, const uint16_t *chars, size_t len, ssize_t *iter) { if (*iter == (size_t) -1) return 0; const size_t ending_index = *iter; const uint32_t init_cp = utf16_to_code_point_prev(chars, len, iter); unsigned cps = 1; if (init_cp == HB_InvalidCodePoint) return 0; const HB_Script init_script = code_point_to_script(init_cp); HB_Script current_script = init_script; output->script = init_script; for (;;) { if (*iter < 0) break; const ssize_t prev_iter = *iter; const uint32_t cp = utf16_to_code_point_prev(chars, len, iter); if (cp == HB_InvalidCodePoint) return 0; cps++; const HB_Script script = code_point_to_script(cp); if (script != current_script) { if (current_script == HB_Script_Inherited && init_script == HB_Script_Inherited) { // If we started off as inherited, we take whatever we can find. output->script = script; current_script = script; continue; } else if (script == HB_Script_Inherited) { /* BEGIN android-changed We apply the same fix for Chrome to Android. Chrome team will talk with upsteam about it. Just assume that whatever follows this combining character is within the same script. This is incorrect if you had language1 + combining char + language 2, but that is rare and this code is suspicious anyway. END android-changed */ continue; } else { *iter = prev_iter; cps--; break; } } } if (output->script == HB_Script_Inherited) output->script = HB_Script_Common; output->pos = *iter + 1; output->length = ending_index - *iter; if (num_code_points) *num_code_points = cps; return 1; }
char hb_utf16_script_run_next(unsigned *num_code_points, HB_ScriptItem *output, const uint16_t *chars, size_t len, ssize_t *iter) { if (*iter == len) return 0; output->pos = *iter; const uint32_t init_cp = utf16_to_code_point(chars, len, iter); unsigned cps = 1; if (init_cp == HB_InvalidCodePoint) return 0; const HB_Script init_script = code_point_to_script(init_cp); HB_Script current_script = init_script; output->script = init_script; for (;;) { if (*iter == len) break; const ssize_t prev_iter = *iter; const uint32_t cp = utf16_to_code_point(chars, len, iter); if (cp == HB_InvalidCodePoint) return 0; cps++; const HB_Script script = code_point_to_script(cp); if (script != current_script) { /* BEGIN android-changed The condition was not correct by doing "a == b == constant" END android-changed */ if (current_script == HB_Script_Inherited && init_script == HB_Script_Inherited) { // If we started off as inherited, we take whatever we can find. output->script = script; current_script = script; continue; } else if (script == HB_Script_Inherited) { continue; } else { *iter = prev_iter; cps--; break; } } } if (output->script == HB_Script_Inherited) output->script = HB_Script_Common; output->length = *iter - output->pos; if (num_code_points) *num_code_points = cps; return 1; }
char hb_utf16_script_run_prev(unsigned *num_code_points, HB_ScriptItem *output, const uint16_t *chars, size_t len, ssize_t *iter) { if (*iter == (size_t) -1) return 0; const size_t ending_index = *iter; const uint32_t init_cp = utf16_to_code_point_prev(chars, len, iter); unsigned cps = 1; if (init_cp == HB_InvalidCodePoint) return 0; const HB_Script init_script = code_point_to_script(init_cp); HB_Script current_script = init_script; output->script = init_script; for (;;) { if (*iter < 0) break; const ssize_t prev_iter = *iter; const uint32_t cp = utf16_to_code_point_prev(chars, len, iter); if (cp == HB_InvalidCodePoint) return 0; cps++; const HB_Script script = code_point_to_script(cp); if (script != current_script) { if (current_script == HB_Script_Inherited && init_script == HB_Script_Inherited) { // If we started off as inherited, we take whatever we can find. output->script = script; current_script = script; continue; } else if (script == HB_Script_Inherited) { current_script = script; continue; } else { *iter = prev_iter; cps--; break; } } } if (output->script == HB_Script_Inherited) output->script = HB_Script_Common; output->pos = *iter + 1; output->length = ending_index - *iter; if (num_code_points) *num_code_points = cps; return 1; }
int PalFont_RenderText( void *aContext, unsigned int *aBitmap, int aBitmapWidth, int aBitmapHeight, const char *text, int textIndex, int textLength, int *aPen_x, int *aPen_y, PalFont_BBox_t*aBBox, int resetBox ) { ft_Context_t *ftContext = FT_CONTEXT( aContext ); HarfBuzz_t aHarfBuzz; int err = 0; uint16_t str[ MAX_CHARS ]; int i; int nChars; int isArabic = 0; int savePenX, savePenY; /* firstly convert to UTF-16 in str */ for ( i = 0; i < MAX_CHARS; i++ ) { int aCharCode = getNextUnicodeFromUTF8( ( unsigned char ** )&text ); if ( aCharCode == 0 ) { break; } str[ i ] = aCharCode; } /* we cant handle more than MAX_CHARS */ if ( i == MAX_CHARS ) { return -1; } /* add termination, not sure if needed */ str[ i ] = '\0'; nChars = i; /* do we have any Arabic? */ for ( i = 0; i < nChars; i++ ) { if ( code_point_to_script( str[ i ] ) == HB_Script_Arabic ) { isArabic = 1; break; } } /* if we do then reverse any runs of Latin */ if ( isArabic != 0 ) { int j; for ( j = 0 ; j < nChars; ) { /* set i to the start of latin */ for ( i = j; i < nChars; i++ ) { if ( isLatin( str[ i ] ) != 0 ) { break; } } /* set j to the end of latin + 1 */ for ( j = i; j < nChars; j++ ) { if ( isLatin( str[ j ] ) == 0 ) { break; } } reverse_text( str, i, j - i ); } } err = Utf16_To_Harfbuzz( aContext, str, nChars, &aHarfBuzz ); if ( err != 0 ) { return err; } if ( aPen_x != NULL ) { savePenX = *aPen_x; } if ( aPen_y != NULL ) { savePenY = *aPen_y; } err = PalFont_RenderHarfBuzz( ftContext, aBitmap, aBitmapWidth, aBitmapHeight, &aHarfBuzz, textIndex, textLength, aPen_x, aPen_y, aBBox, resetBox, isArabic, 0 ); if ( err != 0 ) { return err; } if ( ( ftContext->m_Synth & SynthTwoColor ) != 0 ) { resetBox = 0; if ( aPen_x != NULL ) { *aPen_x = savePenX; } if ( aPen_y != NULL ) { *aPen_y = savePenY; } err = PalFont_RenderHarfBuzz( ftContext, aBitmap, aBitmapWidth, aBitmapHeight, &aHarfBuzz, textIndex, textLength, aPen_x, aPen_y, aBBox, resetBox, isArabic, 1 ); if ( err != 0 ) { return err; } } return 0; }
//pointless proxy HB_Script charScript(uint cp) { return code_point_to_script(cp); }