// Missing glyphs run constructor. Core Text will not generate a run of missing glyphs, instead falling back on // glyphs from LastResort. We want to use the primary font's missing glyph in order to match the fast text code path. void ComplexTextController::ComplexTextRun::createTextRunFromFontDataCoreText(bool ltr) { m_coreTextIndicesVector.reserveInitialCapacity(m_stringLength); unsigned r = 0; while (r < m_stringLength) { m_coreTextIndicesVector.uncheckedAppend(r); if (U_IS_SURROGATE(m_characters[r])) { ASSERT(r + 1 < m_stringLength); ASSERT(U_IS_SURROGATE_LEAD(m_characters[r])); ASSERT(U_IS_TRAIL(m_characters[r + 1])); r += 2; } else r++; } m_glyphCount = m_coreTextIndicesVector.size(); if (!ltr) { for (unsigned r = 0, end = m_glyphCount - 1; r < m_glyphCount / 2; ++r, --end) std::swap(m_coreTextIndicesVector[r], m_coreTextIndicesVector[end]); } m_coreTextIndices = m_coreTextIndicesVector.data(); // Synthesize a run of missing glyphs. m_glyphsVector.fill(0, m_glyphCount); m_glyphs = m_glyphsVector.data(); m_advancesVector.fill(CGSizeMake(m_fontData->widthForGlyph(0), 0), m_glyphCount); m_advances = m_advancesVector.data(); }
// Missing glyphs run constructor. Core Text will not generate a run of missing glyphs, instead falling back on // glyphs from LastResort. We want to use the primary font's missing glyph in order to match the fast text code path. CoreTextController::CoreTextRun::CoreTextRun(const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr) : m_fontData(fontData) , m_characters(characters) , m_stringLocation(stringLocation) , m_stringLength(stringLength) { Vector<CFIndex, 16> indices; unsigned r = 0; while (r < stringLength) { indices.append(r); if (U_IS_SURROGATE(characters[r])) { ASSERT(r + 1 < stringLength); ASSERT(U_IS_SURROGATE_LEAD(characters[r])); ASSERT(U_IS_TRAIL(characters[r + 1])); r += 2; } else r++; } m_glyphCount = indices.size(); if (!ltr) { for (unsigned r = 0, end = m_glyphCount - 1; r < m_glyphCount / 2; ++r, --end) std::swap(indices[r], indices[end]); } m_indicesData.adoptCF(CFDataCreateMutable(kCFAllocatorDefault, m_glyphCount * sizeof(CFIndex))); CFDataAppendBytes(m_indicesData.get(), reinterpret_cast<const UInt8*>(indices.data()), m_glyphCount * sizeof(CFIndex)); m_indices = reinterpret_cast<const CFIndex*>(CFDataGetBytePtr(m_indicesData.get())); }
static bool shouldUseCoreText(UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) { if (fontData->platformData().isCompositeFontReference()) return true; // CoreText doesn't have vertical glyphs of surrogate pair characters. // Therefore, we should not use CoreText, but this always returns horizontal glyphs. // FIXME: We should use vertical glyphs. https://code.google.com/p/chromium/issues/detail?id=340173 if (bufferLength >= 2 && U_IS_SURROGATE(buffer[0]) && fontData->hasVerticalGlyphs()) { ASSERT(U_IS_SURROGATE_LEAD(buffer[0])); ASSERT(U_IS_TRAIL(buffer[1])); return false; } if (fontData->platformData().widthVariant() != RegularWidth || fontData->hasVerticalGlyphs()) { // Ideographs don't have a vertical variant or width variants. for (unsigned i = 0; i < bufferLength; ++i) { if (!Character::isCJKIdeograph(buffer[i])) return true; } } return false; }
int icu_bidi_runs(lua_State *L) { size_t input_l; const char* input = luaL_checklstring(L, 1, &input_l); const char* direction = luaL_checkstring(L, 2); UChar *input_as_uchar; int32_t l; utf8_to_uchar(input, input_l, input_as_uchar, l); UBiDiLevel paraLevel = 0; if (strncasecmp(direction, "RTL", 3) == 0) { paraLevel = 1; } /* Now let's bidi! */ UBiDi* bidi = ubidi_open(); UErrorCode err = U_ZERO_ERROR; ubidi_setPara(bidi, input_as_uchar, l, paraLevel, NULL, &err); if (!U_SUCCESS(err)) { free(input_as_uchar); ubidi_close(bidi); return luaL_error(L, "Error in bidi %s", u_errorName(err)); } int count = ubidi_countRuns(bidi,&err); int start, length; lua_checkstack(L,count); for (int i=0; i < count; i++) { UBiDiDirection dir = ubidi_getVisualRun(bidi, i, &start, &length); lua_newtable(L); // Convert back to UTF8... int32_t l3 = 0; char* possibleOutbuf = malloc(4*length); if(!possibleOutbuf) { return luaL_error(L, "Couldn't malloc"); } u_strToUTF8(possibleOutbuf, 4 * length, &l3, input_as_uchar+start, length, &err); if (!U_SUCCESS(err)) { free(possibleOutbuf); return luaL_error(L, "Bidi run too big? %s", u_errorName(err)); } lua_pushstring(L, "run"); lua_pushstring(L, possibleOutbuf); free(possibleOutbuf); lua_settable(L, -3); lua_pushstring(L, "start"); int32_t new_start = start; // Length/start is given in terms of UTF16 codepoints. // But we want a count of Unicode characters. This means // surrogate pairs need to be counted as 1. for (int j=0; j< start; j++) { if (U_IS_TRAIL(*(input_as_uchar+j))) new_start--; } lua_pushinteger(L, new_start); lua_settable(L, -3); lua_pushstring(L, "length"); for (int j=start; j< start+length; j++) { if (U_IS_TRAIL(*(input_as_uchar+j))) length--; } lua_pushinteger(L, length); lua_settable(L, -3); lua_pushstring(L, "dir"); lua_pushstring(L, dir == UBIDI_RTL ? "RTL" : "LTR"); lua_settable(L, -3); lua_pushstring(L, "level"); lua_pushinteger(L, ubidi_getLevelAt(bidi, start)); lua_settable(L, -3); } free(input_as_uchar); ubidi_close(bidi); return count; }