bool SimpleFontData::canRenderCombiningCharacterSequence( const UChar* characters, size_t length) const { if (!m_combiningCharacterSequenceSupport) m_combiningCharacterSequenceSupport = adoptPtr(new HashMap<String, bool>); WTF::HashMap<String, bool>::AddResult addResult = m_combiningCharacterSequenceSupport->add(String(characters, length), false); if (!addResult.isNewEntry) return addResult.storedValue->value; UErrorCode error = U_ZERO_ERROR; Vector<UChar, 4> normalizedCharacters(length); int32_t normalizedLength = unorm_normalize(characters, length, UNORM_NFC, UNORM_UNICODE_3_2, &normalizedCharacters[0], length, &error); // Can't render if we have an error or no composition occurred. if (U_FAILURE(error) || (static_cast<size_t>(normalizedLength) == length)) return false; SkPaint paint; m_platformData.setupPaint(&paint); paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); if (paint.textToGlyphs(&normalizedCharacters[0], normalizedLength * 2, 0)) { addResult.storedValue->value = true; return true; } return false; }
bool SimpleFontData::canRenderCombiningCharacterSequence(const UChar* characters, size_t length) const { if (!m_combiningCharacterSequenceSupport) m_combiningCharacterSequenceSupport = adoptPtr(new HashMap<String, bool>); WTF::HashMap<String, bool>::AddResult addResult = m_combiningCharacterSequenceSupport->add(String(characters, length), false); if (!addResult.isNewEntry) return addResult.iterator->value; UErrorCode error = U_ZERO_ERROR; Vector<UChar, 4> normalizedCharacters(length); int32_t normalizedLength = unorm_normalize(characters, length, UNORM_NFC, UNORM_UNICODE_3_2, &normalizedCharacters[0], length, &error); // Can't render if we have an error or no composition occurred. if (U_FAILURE(error) || (static_cast<size_t>(normalizedLength) == length)) return false; FT_Face face = cairo_ft_scaled_font_lock_face(m_platformData.scaledFont()); if (!face) return false; if (FcFreeTypeCharIndex(face, normalizedCharacters[0])) addResult.iterator->value = true; cairo_ft_scaled_font_unlock_face(m_platformData.scaledFont()); return addResult.iterator->value; }
bool SimpleFontData::canRenderCombiningCharacterSequence(const UChar* characters, size_t length) const { if (!m_combiningCharacterSequenceSupport) m_combiningCharacterSequenceSupport = adoptPtr(new HashMap<String, bool>); WTF::HashMap<String, bool>::AddResult addResult = m_combiningCharacterSequenceSupport->add(String(characters, length), false); if (!addResult.isNewEntry) return addResult.iterator->value; UErrorCode error = U_ZERO_ERROR; Vector<UChar, 4> normalizedCharacters(length); int32_t normalizedLength = unorm_normalize(characters, length, UNORM_NFC, UNORM_UNICODE_3_2, &normalizedCharacters[0], length, &error); if (U_FAILURE(error)) return false; int position = 0; while (position < normalizedLength) { UChar32 character; int nextPosition = position; U16_NEXT(normalizedCharacters, nextPosition, normalizedLength, character); if (!u_hasBinaryProperty(character, UCHAR_DEFAULT_IGNORABLE_CODE_POINT)) { FS_USHORT glyph = FS_map_char(m_platformData.font(), static_cast<FS_ULONG>(character)); if (!glyph) return false; } position = nextPosition; } addResult.iterator->value = true; return true; }
static const SimpleFontData* fontDataForCombiningCharacterSequence(const Font* font, const UChar* characters, size_t length) { UErrorCode error = U_ZERO_ERROR; Vector<UChar, 4> normalizedCharacters(length); int32_t normalizedLength = unorm_normalize(characters, length, UNORM_NFC, UNORM_UNICODE_3_2, &normalizedCharacters[0], length, &error); // Should fallback if we have an error or no composition occurred. if (U_FAILURE(error) || (static_cast<size_t>(normalizedLength) == length)) return 0; UChar32 normalizedCharacter; size_t index = 0; U16_NEXT(&normalizedCharacters[0], index, static_cast<size_t>(normalizedLength), normalizedCharacter); return font->glyphDataForCharacter(normalizedCharacter, false).fontData; }