diff --git a/include/minikin/FontFamily.h b/include/minikin/FontFamily.h index aa2e0ac2e4ab1eb4185257d265e4acccf0817707..00130e6f5d0332cf44a2059c833d23de18510d5f 100644 --- a/include/minikin/FontFamily.h +++ b/include/minikin/FontFamily.h @@ -30,6 +30,62 @@ namespace android { class MinikinFont; +// FontLanguage is a compact representation of a bcp-47 language tag. It +// does not capture all possible information, only what directly affects +// font rendering. +class FontLanguage { + friend class FontStyle; + friend class FontLanguages; +public: + FontLanguage() : mBits(0) { } + + // Parse from string + FontLanguage(const char* buf, size_t size); + + bool operator==(const FontLanguage other) const { + return mBits != kUnsupportedLanguage && mBits == other.mBits; + } + operator bool() const { return mBits != 0; } + + bool isUnsupported() const { return mBits == kUnsupportedLanguage; } + bool hasEmojiFlag() const { return isUnsupported() ? false : (mBits & kEmojiFlag); } + + std::string getString() const; + + // 0 = no match, 1 = language matches + int match(const FontLanguage other) const; + +private: + explicit FontLanguage(uint32_t bits) : mBits(bits) { } + + uint32_t bits() const { return mBits; } + + static const uint32_t kUnsupportedLanguage = 0xFFFFFFFFu; + static const uint32_t kBaseLangMask = 0xFFFFFFu; + static const uint32_t kHansFlag = 1u << 24; + static const uint32_t kHantFlag = 1u << 25; + static const uint32_t kEmojiFlag = 1u << 26; + static const uint32_t kScriptMask = kHansFlag | kHantFlag | kEmojiFlag; + uint32_t mBits; +}; + +// A list of zero or more instances of FontLanguage, in the order of +// preference. Used for further resolution of rendering results. +class FontLanguages { +public: + FontLanguages() { mLangs.clear(); } + + // Parse from string, which is a comma-separated list of languages + FontLanguages(const char* buf, size_t size); + + const FontLanguage& operator[](size_t index) const { return mLangs.at(index); } + + size_t size() const { return mLangs.size(); } + +private: + std::vector mLangs; +}; + // FontStyle represents all style information needed to select an actual font // from a collection. The implementation is packed into two 32-bit words // so it can be efficiently copied, embedded in other objects, etc. @@ -102,9 +158,7 @@ class FontFamily : public MinikinRefCounted { public: FontFamily() : mHbFont(nullptr) { } - FontFamily(int variant); - - FontFamily(uint32_t langId, int variant) : mLangId(langId), mVariant(variant), mHbFont(nullptr) { + FontFamily(FontLanguage lang, int variant) : mLang(lang), mVariant(variant), mHbFont(nullptr) { } ~FontFamily(); @@ -115,7 +169,7 @@ public: void addFont(MinikinFont* typeface, FontStyle style); FakedFont getClosestMatch(FontStyle style) const; - uint32_t langId() const { return mLangId; } + FontLanguage lang() const { return mLang; } int variant() const { return mVariant; } // API's for enumerating the fonts in a family. These don't guarantee any particular order @@ -146,7 +200,7 @@ private: MinikinFont* typeface; FontStyle style; }; - uint32_t mLangId; + FontLanguage mLang; int mVariant; std::vector mFonts; diff --git a/libs/minikin/Android.mk b/libs/minikin/Android.mk index 42fdca391938a1b8230d4cab08559f78989fa680..4c945a60c9c8b7085a96bb3dfc123f31e586febd 100644 --- a/libs/minikin/Android.mk +++ b/libs/minikin/Android.mk @@ -21,7 +21,6 @@ minikin_src_files := \ CmapCoverage.cpp \ FontCollection.cpp \ FontFamily.cpp \ - FontLanguage.cpp \ FontLanguageListCache.cpp \ GraphemeBreak.cpp \ HbFaceCache.cpp \ diff --git a/libs/minikin/FontCollection.cpp b/libs/minikin/FontCollection.cpp index 62c70310c064027c56e03c78945bc8f64b18a52d..bba2ef95359f1c6cd44ebe20ce172016c71b8659 100644 --- a/libs/minikin/FontCollection.cpp +++ b/libs/minikin/FontCollection.cpp @@ -22,7 +22,6 @@ #include "unicode/unistr.h" #include "unicode/unorm2.h" -#include "FontLanguage.h" #include "FontLanguageListCache.h" #include "MinikinInternal.h" #include @@ -151,17 +150,14 @@ FontFamily* FontCollection::getFamilyForChar(uint32_t ch, uint32_t vs, // always use it. return family; } - - // TODO use all language in the list. - FontLanguage fontLang = FontLanguageListCache::getById(family->langId())[0]; - int score = lang.match(fontLang) * 2; + int score = lang.match(family->lang()) * 2; if (family->variant() == 0 || family->variant() == variant) { score++; } if (hasVSGlyph) { score += 8; - } else if (((vs == 0xFE0F) && fontLang.hasEmojiFlag()) || - ((vs == 0xFE0E) && !fontLang.hasEmojiFlag())) { + } else if (((vs == 0xFE0F) && family->lang().hasEmojiFlag()) || + ((vs == 0xFE0E) && !family->lang().hasEmojiFlag())) { score += 4; } if (score > bestScore) { diff --git a/libs/minikin/FontFamily.cpp b/libs/minikin/FontFamily.cpp index 14057890281f232cce8af186d4576f8b61075573..76398312406c354185b23f0e80b802b211d946c7 100644 --- a/libs/minikin/FontFamily.cpp +++ b/libs/minikin/FontFamily.cpp @@ -16,6 +16,8 @@ #define LOG_TAG "Minikin" +#include + #include #include #include @@ -26,7 +28,6 @@ #include -#include "FontLanguage.h" #include "FontLanguageListCache.h" #include "HbFaceCache.h" #include "MinikinInternal.h" @@ -40,6 +41,117 @@ using std::vector; namespace android { +// Parse bcp-47 language identifier into internal structure +FontLanguage::FontLanguage(const char* buf, size_t size) { + uint32_t bits = 0; + size_t i; + for (i = 0; i < size; i++) { + uint16_t c = buf[i]; + if (c == '-' || c == '_') break; + } + if (i == 2) { + bits = uint8_t(buf[0]) | (uint8_t(buf[1]) << 8); + } else if (i == 3) { + bits = uint8_t(buf[0]) | (uint8_t(buf[1]) << 8) | (uint8_t(buf[2]) << 16); + } else { + mBits = kUnsupportedLanguage; + // We don't understand anything other than two-letter or three-letter + // language codes, so we skip parsing the rest of the string. + return; + } + size_t next; + for (i++; i < size; i = next + 1) { + for (next = i; next < size; next++) { + uint16_t c = buf[next]; + if (c == '-' || c == '_') break; + } + if (next - i == 4) { + if (buf[i] == 'H' && buf[i+1] == 'a' && buf[i+2] == 'n') { + if (buf[i+3] == 's') { + bits |= kHansFlag; + } else if (buf[i+3] == 't') { + bits |= kHantFlag; + } + } else if (buf[i] == 'Q' && buf[i+1] == 'a' && buf[i+2] == 'a'&& buf[i+3] == 'e') { + bits |= kEmojiFlag; + } + } + // TODO: this might be a good place to infer script from country (zh_TW -> Hant), + // but perhaps it's up to the client to do that, before passing a string. + } + mBits = bits; +} + +std::string FontLanguage::getString() const { + if (mBits == kUnsupportedLanguage) { + return "und"; + } + char buf[16]; + size_t i = 0; + if (mBits & kBaseLangMask) { + buf[i++] = mBits & 0xFFu; + buf[i++] = (mBits >> 8) & 0xFFu; + char third_letter = (mBits >> 16) & 0xFFu; + if (third_letter != 0) buf[i++] = third_letter; + } + if (mBits & kScriptMask) { + if (!i) { + // This should not happen, but as it apparently has, we fill the language code part + // with "und". + buf[i++] = 'u'; + buf[i++] = 'n'; + buf[i++] = 'd'; + } + buf[i++] = '-'; + if (mBits & kEmojiFlag) { + buf[i++] = 'Q'; + buf[i++] = 'a'; + buf[i++] = 'a'; + buf[i++] = 'e'; + } else { + buf[i++] = 'H'; + buf[i++] = 'a'; + buf[i++] = 'n'; + buf[i++] = (mBits & kHansFlag) ? 's' : 't'; + } + } + return std::string(buf, i); +} + +int FontLanguage::match(const FontLanguage other) const { + return *this == other; +} + +FontLanguages::FontLanguages(const char* buf, size_t size) { + std::unordered_set seen; + mLangs.clear(); + const char* bufEnd = buf + size; + const char* lastStart = buf; + bool isLastLang = false; + while (true) { + const char* commaLoc = static_cast( + memchr(lastStart, ',', bufEnd - lastStart)); + if (commaLoc == NULL) { + commaLoc = bufEnd; + isLastLang = true; + } + FontLanguage lang(lastStart, commaLoc - lastStart); + if (isLastLang && mLangs.size() == 0) { + // Make sure the list has at least one member + mLangs.push_back(lang); + return; + } + uint32_t bits = lang.bits(); + if (bits != FontLanguage::kUnsupportedLanguage && seen.count(bits) == 0) { + mLangs.push_back(lang); + if (isLastLang) return; + seen.insert(bits); + } + if (isLastLang) return; + lastStart = commaLoc + 1; + } +} + FontStyle::FontStyle(int variant, int weight, bool italic) : FontStyle(FontLanguageListCache::kEmptyListId, variant, weight, italic) { } @@ -65,9 +177,6 @@ uint32_t FontStyle::pack(int variant, int weight, bool italic) { return (weight & kWeightMask) | (italic ? kItalicMask : 0) | (variant << kVariantShift); } -FontFamily::FontFamily(int variant) : FontFamily(FontLanguageListCache::kEmptyListId, variant) { -} - FontFamily::~FontFamily() { for (size_t i = 0; i < mFonts.size(); i++) { mFonts[i].typeface->UnrefLocked(); @@ -101,8 +210,7 @@ void FontFamily::addFont(MinikinFont* typeface, FontStyle style) { addFontLocked(typeface, style); } -void FontFamily::addFontLocked(MinikinFont* typeface, FontStyle style) { - typeface->RefLocked(); +void FontFamily::addFontLocked(MinikinFont* typeface, FontStyle style) { typeface->RefLocked(); mFonts.push_back(Font(typeface, style)); mCoverageValid = false; } diff --git a/libs/minikin/FontLanguage.cpp b/libs/minikin/FontLanguage.cpp deleted file mode 100644 index 3c12e06c6f126e18ade3123aa497e4497c62bc47..0000000000000000000000000000000000000000 --- a/libs/minikin/FontLanguage.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "Minikin" - -#include "FontLanguage.h" - -#include -#include - -namespace android { - -#define SCRIPT_TAG(c1, c2, c3, c4) \ - ((uint32_t)(c1)) << 24 | ((uint32_t)(c2)) << 16 | ((uint32_t)(c3)) << 8 | ((uint32_t)(c4)) - -// Parse BCP 47 language identifier into internal structure -FontLanguage::FontLanguage(const char* buf, size_t length) : FontLanguage() { - size_t i; - for (i = 0; i < length; i++) { - char c = buf[i]; - if (c == '-' || c == '_') break; - } - if (i == 2 || i == 3) { // only accept two or three letter language code. - mLanguage = buf[0] | (buf[1] << 8) | ((i == 3) ? (buf[2] << 16) : 0); - } else { - // We don't understand anything other than two-letter or three-letter - // language codes, so we skip parsing the rest of the string. - mLanguage = 0ul; - return; - } - - size_t next; - for (i++; i < length; i = next + 1) { - for (next = i; next < length; next++) { - char c = buf[next]; - if (c == '-' || c == '_') break; - } - if (next - i == 4 && 'A' <= buf[i] && buf[i] <= 'Z') { - mScript = SCRIPT_TAG(buf[i], buf[i + 1], buf[i + 2], buf[i + 3]); - } - } - - mSubScriptBits = scriptToSubScriptBits(mScript); -} - -//static -uint8_t FontLanguage::scriptToSubScriptBits(uint32_t script) { - uint8_t subScriptBits = 0u; - switch (script) { - case SCRIPT_TAG('H', 'a', 'n', 'g'): - subScriptBits = kHangulFlag; - break; - case SCRIPT_TAG('H', 'a', 'n', 'i'): - subScriptBits = kHanFlag; - break; - case SCRIPT_TAG('H', 'a', 'n', 's'): - subScriptBits = kHanFlag | kSimplifiedChineseFlag; - break; - case SCRIPT_TAG('H', 'a', 'n', 't'): - subScriptBits = kHanFlag | kTraditionalChineseFlag; - break; - case SCRIPT_TAG('H', 'i', 'r', 'a'): - subScriptBits = kHiraganaFlag; - break; - case SCRIPT_TAG('H', 'r', 'k', 't'): - subScriptBits = kKatakanaFlag | kHiraganaFlag; - break; - case SCRIPT_TAG('J', 'p', 'a', 'n'): - subScriptBits = kHanFlag | kKatakanaFlag | kHiraganaFlag; - break; - case SCRIPT_TAG('K', 'a', 'n', 'a'): - subScriptBits = kKatakanaFlag; - break; - case SCRIPT_TAG('K', 'o', 'r', 'e'): - subScriptBits = kHanFlag | kHangulFlag; - break; - case SCRIPT_TAG('Q', 'a', 'a', 'e'): - subScriptBits = kEmojiFlag; - break; - } - return subScriptBits; -} - -std::string FontLanguage::getString() const { - if (mLanguage == 0ul) { - return "und"; - } - char buf[16]; - size_t i = 0; - buf[i++] = mLanguage & 0xFF ; - buf[i++] = (mLanguage >> 8) & 0xFF; - char third_letter = (mLanguage >> 16) & 0xFF; - if (third_letter != 0) buf[i++] = third_letter; - if (mScript != 0) { - buf[i++] = '-'; - buf[i++] = (mScript >> 24) & 0xFFu; - buf[i++] = (mScript >> 16) & 0xFFu; - buf[i++] = (mScript >> 8) & 0xFFu; - buf[i++] = mScript & 0xFFu; - } - return std::string(buf, i); -} - -bool FontLanguage::isEqualScript(const FontLanguage other) const { - return other.mScript == mScript; -} - -bool FontLanguage::supportsHbScript(hb_script_t script) const { - static_assert(SCRIPT_TAG('J', 'p', 'a', 'n') == HB_TAG('J', 'p', 'a', 'n'), - "The Minikin script and HarfBuzz hb_script_t have different encodings."); - if (script == mScript) return true; - uint8_t requestedBits = scriptToSubScriptBits(script); - return requestedBits != 0 && (mSubScriptBits & requestedBits) == requestedBits; -} - -int FontLanguage::match(const FontLanguage other) const { - // TODO: Use script for matching. - return *this == other; -} - -#undef SCRIPT_TAG -} // namespace android diff --git a/libs/minikin/FontLanguage.h b/libs/minikin/FontLanguage.h deleted file mode 100644 index abe7d13179deb0cc05d5cd061299a9678ce4fd67..0000000000000000000000000000000000000000 --- a/libs/minikin/FontLanguage.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MINIKIN_FONT_LANGUAGE_H -#define MINIKIN_FONT_LANGUAGE_H - -#include -#include - -#include - -namespace android { - -// FontLanguage is a compact representation of a BCP 47 language tag. It -// does not capture all possible information, only what directly affects -// font rendering. -struct FontLanguage { -public: - // Default constructor creates the unsupported language. - FontLanguage() : mScript(0ul), mLanguage(0ul), mSubScriptBits(0ul) {} - - // Parse from string - FontLanguage(const char* buf, size_t length); - - bool operator==(const FontLanguage other) const { - return !isUnsupported() && isEqualScript(other) && isEqualLanguage(other); - } - - bool operator!=(const FontLanguage other) const { - return !(*this == other); - } - - bool isUnsupported() const { return mLanguage == 0ul; } - bool hasEmojiFlag() const { return mSubScriptBits & kEmojiFlag; } - - bool isEqualLanguage(const FontLanguage other) const { return mLanguage == other.mLanguage; } - bool isEqualScript(const FontLanguage other) const; - - // Returns true if this script supports the given script. For example, ja-Jpan supports Hira, - // ja-Hira doesn't support Jpan. - bool supportsHbScript(hb_script_t script) const; - - std::string getString() const; - - // 0 = no match, 1 = language matches - int match(const FontLanguage other) const; - - uint64_t getIdentifier() const { return (uint64_t)mScript << 32 | (uint64_t)mLanguage; } - -private: - // ISO 15924 compliant script code. The 4 chars script code are packed into a 32 bit integer. - uint32_t mScript; - - // ISO 639-1 or ISO 639-2 compliant language code. - // The two or three letter language code is packed into 32 bit integer. - // mLanguage = 0 means the FontLanguage is unsupported. - uint32_t mLanguage; - - // For faster comparing, use 7 bits for specific scripts. - static const uint8_t kEmojiFlag = 1u; - static const uint8_t kHanFlag = 1u << 1; - static const uint8_t kHangulFlag = 1u << 2; - static const uint8_t kHiraganaFlag = 1u << 3; - static const uint8_t kKatakanaFlag = 1u << 4; - static const uint8_t kSimplifiedChineseFlag = 1u << 5; - static const uint8_t kTraditionalChineseFlag = 1u << 6; - uint8_t mSubScriptBits; - - static uint8_t scriptToSubScriptBits(uint32_t script); -}; - -typedef std::vector FontLanguages; - -} // namespace android - -#endif // MINIKIN_FONT_LANGUAGE_H diff --git a/libs/minikin/FontLanguageListCache.cpp b/libs/minikin/FontLanguageListCache.cpp index 2d64998e7a3846f7b9ecb962636599f583a85364..e1c2343ddaacd2beaf7160a14efea0919a9145ec 100644 --- a/libs/minikin/FontLanguageListCache.cpp +++ b/libs/minikin/FontLanguageListCache.cpp @@ -19,92 +19,13 @@ #include "FontLanguageListCache.h" #include -#include -#include #include "MinikinInternal.h" -#include "FontLanguage.h" namespace android { const uint32_t FontLanguageListCache::kEmptyListId; -// Returns the text length of output. -static size_t toLanguageTag(char* output, size_t outSize, const std::string& locale) { - output[0] = '\0'; - if (locale.empty()) { - return 0; - } - - size_t outLength = 0; - UErrorCode uErr = U_ZERO_ERROR; - outLength = uloc_canonicalize(locale.c_str(), output, outSize, &uErr); - if (U_FAILURE(uErr)) { - // unable to build a proper language identifier - ALOGD("uloc_canonicalize(\"%s\") failed: %s", locale.c_str(), u_errorName(uErr)); - output[0] = '\0'; - return 0; - } - - // Preserve "und" and "und-****" since uloc_addLikelySubtags changes "und" to "en-Latn-US". - if (strncmp(output, "und", 3) == 0 && - (outLength == 3 || (outLength == 8 && output[3] == '_'))) { - return outLength; - } - - char likelyChars[ULOC_FULLNAME_CAPACITY]; - uErr = U_ZERO_ERROR; - uloc_addLikelySubtags(output, likelyChars, ULOC_FULLNAME_CAPACITY, &uErr); - if (U_FAILURE(uErr)) { - // unable to build a proper language identifier - ALOGD("uloc_addLikelySubtags(\"%s\") failed: %s", output, u_errorName(uErr)); - output[0] = '\0'; - return 0; - } - - uErr = U_ZERO_ERROR; - outLength = uloc_toLanguageTag(likelyChars, output, outSize, FALSE, &uErr); - if (U_FAILURE(uErr)) { - // unable to build a proper language identifier - ALOGD("uloc_toLanguageTag(\"%s\") failed: %s", likelyChars, u_errorName(uErr)); - output[0] = '\0'; - return 0; - } -#ifdef VERBOSE_DEBUG - ALOGD("ICU normalized '%s' to '%s'", locale.c_str(), output); -#endif - return outLength; -} - -static FontLanguages constructFontLanguages(const std::string& input) { - FontLanguages result; - size_t currentIdx = 0; - size_t commaLoc = 0; - char langTag[ULOC_FULLNAME_CAPACITY]; - std::unordered_set seen; - std::string locale(input.size(), 0); - - while ((commaLoc = input.find_first_of(',', currentIdx)) != std::string::npos) { - locale.assign(input, currentIdx, commaLoc - currentIdx); - currentIdx = commaLoc + 1; - size_t length = toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, locale); - FontLanguage lang(langTag, length); - uint64_t identifier = lang.getIdentifier(); - if (!lang.isUnsupported() && seen.count(identifier) == 0) { - result.push_back(lang); - seen.insert(identifier); - } - } - locale.assign(input, currentIdx, input.size() - currentIdx); - size_t length = toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, locale); - FontLanguage lang(langTag, length); - uint64_t identifier = lang.getIdentifier(); - if (!lang.isUnsupported() && seen.count(identifier) == 0) { - result.push_back(lang); - } - return result; -} - // static uint32_t FontLanguageListCache::getId(const std::string& languages) { FontLanguageListCache* inst = FontLanguageListCache::getInstance(); @@ -116,11 +37,7 @@ uint32_t FontLanguageListCache::getId(const std::string& languages) { // Given language list is not in cache. Insert it and return newly assigned ID. const uint32_t nextId = inst->mLanguageLists.size(); - FontLanguages fontLanguages = constructFontLanguages(languages); - if (fontLanguages.empty()) { - return kEmptyListId; - } - inst->mLanguageLists.push_back(fontLanguages); + inst->mLanguageLists.push_back(FontLanguages(languages.c_str(), languages.size())); inst->mLanguageListLookupTable.insert(std::make_pair(languages, nextId)); return nextId; } @@ -139,9 +56,8 @@ FontLanguageListCache* FontLanguageListCache::getInstance() { if (instance == nullptr) { instance = new FontLanguageListCache(); - // Insert an empty language list for mapping default language list to kEmptyListId. - // The default language list has only one FontLanguage and it is the unsupported language. - instance->mLanguageLists.push_back(FontLanguages({FontLanguage()})); + // Insert an empty language list for mapping empty language list to kEmptyListId. + instance->mLanguageLists.push_back(FontLanguages()); instance->mLanguageListLookupTable.insert(std::make_pair("", kEmptyListId)); } return instance; diff --git a/libs/minikin/FontLanguageListCache.h b/libs/minikin/FontLanguageListCache.h index c961882f0a87572cdcded21ddbb5b5405cfca044..7d627b562e3640ca2a2a2e2386163a9e86b75058 100644 --- a/libs/minikin/FontLanguageListCache.h +++ b/libs/minikin/FontLanguageListCache.h @@ -20,7 +20,6 @@ #include #include -#include "FontLanguage.h" namespace android { diff --git a/libs/minikin/Layout.cpp b/libs/minikin/Layout.cpp index 2e206a20fc317b530ed6220d77691fbfbf5bab36..af5e6fe75a7392437f362646a6c1b93551c74676 100644 --- a/libs/minikin/Layout.cpp +++ b/libs/minikin/Layout.cpp @@ -34,7 +34,6 @@ #include #include -#include "FontLanguage.h" #include "FontLanguageListCache.h" #include "LayoutUtils.h" #include "HbFaceCache.h" @@ -747,15 +746,9 @@ void Layout::doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t const FontLanguages& langList = FontLanguageListCache::getById(ctx->style.getLanguageListId()); if (langList.size() != 0) { - const FontLanguage* hbLanguage = &langList[0]; - for (size_t i = 0; i < langList.size(); ++i) { - if (langList[i].supportsHbScript(script)) { - hbLanguage = &langList[i]; - break; - } - } - hb_buffer_set_language(buffer, - hb_language_from_string(hbLanguage->getString().c_str(), -1)); + // TODO: use all languages in langList. + string lang = langList[0].getString(); + hb_buffer_set_language(buffer, hb_language_from_string(lang.c_str(), -1)); } hb_buffer_add_utf16(buffer, buf, bufSize, srunstart + start, srunend - srunstart); if (ctx->paint.hyphenEdit.hasHyphen() && srunend > srunstart) { diff --git a/tests/FontCollectionItemizeTest.cpp b/tests/FontCollectionItemizeTest.cpp index cf9b704efa214b485c604e24bea64bef89a7a5bc..85d76afccb85f172ec83c3dbca660c6be6223ba3 100644 --- a/tests/FontCollectionItemizeTest.cpp +++ b/tests/FontCollectionItemizeTest.cpp @@ -16,9 +16,7 @@ #include -#include "FontLanguage.h" #include "FontTestUtils.h" -#include "ICUTestBase.h" #include "MinikinFontForTest.h" #include "UnicodeUtils.h" @@ -44,8 +42,6 @@ const char kColorEmojiFont[] = kTestFontDir "ColorEmojiFont.ttf"; const char kTextEmojiFont[] = kTestFontDir "TextEmojiFont.ttf"; const char kMixedEmojiFont[] = kTestFontDir "ColorTextMixedEmojiFont.ttf"; -typedef ICUTestBase FontCollectionItemizeTest; - // Utility function for calling itemize function. void itemize(FontCollection* collection, const char* str, FontStyle style, std::vector* result) { @@ -64,7 +60,7 @@ const std::string& getFontPath(const FontCollection::Run& run) { return ((MinikinFontForTest*)run.fakedFont.font)->fontPath(); } -TEST_F(FontCollectionItemizeTest, itemize_latin) { +TEST(FontCollectionItemizeTest, itemize_latin) { std::unique_ptr collection = getFontCollection(kTestFontDir, kItemizeFontXml); std::vector runs; @@ -134,7 +130,7 @@ TEST_F(FontCollectionItemizeTest, itemize_latin) { EXPECT_FALSE(runs[0].fakedFont.fakery.isFakeItalic()); } -TEST_F(FontCollectionItemizeTest, itemize_emoji) { +TEST(FontCollectionItemizeTest, itemize_emoji) { std::unique_ptr collection = getFontCollection(kTestFontDir, kItemizeFontXml); std::vector runs; @@ -195,7 +191,7 @@ TEST_F(FontCollectionItemizeTest, itemize_emoji) { EXPECT_FALSE(runs[1].fakedFont.fakery.isFakeItalic()); } -TEST_F(FontCollectionItemizeTest, itemize_non_latin) { +TEST(FontCollectionItemizeTest, itemize_non_latin) { std::unique_ptr collection = getFontCollection(kTestFontDir, kItemizeFontXml); std::vector runs; @@ -284,7 +280,7 @@ TEST_F(FontCollectionItemizeTest, itemize_non_latin) { EXPECT_FALSE(runs[0].fakedFont.fakery.isFakeItalic()); } -TEST_F(FontCollectionItemizeTest, itemize_mixed) { +TEST(FontCollectionItemizeTest, itemize_mixed) { std::unique_ptr collection = getFontCollection(kTestFontDir, kItemizeFontXml); std::vector runs; @@ -323,7 +319,7 @@ TEST_F(FontCollectionItemizeTest, itemize_mixed) { EXPECT_FALSE(runs[4].fakedFont.fakery.isFakeItalic()); } -TEST_F(FontCollectionItemizeTest, itemize_variationSelector) { +TEST(FontCollectionItemizeTest, itemize_variationSelector) { std::unique_ptr collection = getFontCollection(kTestFontDir, kItemizeFontXml); std::vector runs; @@ -462,7 +458,7 @@ TEST_F(FontCollectionItemizeTest, itemize_variationSelector) { EXPECT_EQ(kLatinFont, getFontPath(runs[0])); } -TEST_F(FontCollectionItemizeTest, itemize_variationSelectorSupplement) { +TEST(FontCollectionItemizeTest, itemize_variationSelectorSupplement) { std::unique_ptr collection = getFontCollection(kTestFontDir, kItemizeFontXml); std::vector runs; @@ -587,7 +583,7 @@ TEST_F(FontCollectionItemizeTest, itemize_variationSelectorSupplement) { EXPECT_TRUE(runs[0].fakedFont.font == nullptr || kLatinFont == getFontPath(runs[0])); } -TEST_F(FontCollectionItemizeTest, itemize_no_crash) { +TEST(FontCollectionItemizeTest, itemize_no_crash) { std::unique_ptr collection = getFontCollection(kTestFontDir, kItemizeFontXml); std::vector runs; @@ -611,7 +607,7 @@ TEST_F(FontCollectionItemizeTest, itemize_no_crash) { itemize(collection.get(), "U+FE00 U+302D U+E0100", FontStyle(), &runs); } -TEST_F(FontCollectionItemizeTest, itemize_fakery) { +TEST(FontCollectionItemizeTest, itemize_fakery) { std::unique_ptr collection = getFontCollection(kTestFontDir, kItemizeFontXml); std::vector runs; @@ -651,18 +647,18 @@ TEST_F(FontCollectionItemizeTest, itemize_fakery) { EXPECT_TRUE(runs[0].fakedFont.fakery.isFakeItalic()); } -TEST_F(FontCollectionItemizeTest, itemize_vs_sequence_but_no_base_char) { +TEST(FontCollectionItemizeTest, itemize_vs_sequence_but_no_base_char) { // kVSTestFont supports U+717D U+FE02 but doesn't support U+717D. // kVSTestFont should be selected for U+717D U+FE02 even if it does not support the base code // point. const std::string kVSTestFont = kTestFontDir "VarioationSelectorTest-Regular.ttf"; std::vector families; - FontFamily* family1 = new FontFamily(android::VARIANT_DEFAULT); + FontFamily* family1 = new FontFamily(FontLanguage(), android::VARIANT_DEFAULT); family1->addFont(new MinikinFontForTest(kLatinFont)); families.push_back(family1); - FontFamily* family2 = new FontFamily(android::VARIANT_DEFAULT); + FontFamily* family2 = new FontFamily(FontLanguage(), android::VARIANT_DEFAULT); family2->addFont(new MinikinFontForTest(kVSTestFont)); families.push_back(family2); @@ -680,7 +676,7 @@ TEST_F(FontCollectionItemizeTest, itemize_vs_sequence_but_no_base_char) { family2->Unref(); } -TEST_F(FontCollectionItemizeTest, itemize_emojiSelection) { +TEST(FontCollectionItemizeTest, itemize_emojiSelection) { std::unique_ptr collection = getFontCollection(kTestFontDir, kEmojiXmlFile); std::vector runs; @@ -752,7 +748,7 @@ TEST_F(FontCollectionItemizeTest, itemize_emojiSelection) { EXPECT_TRUE(runs[0].fakedFont.font == NULL || kNoGlyphFont == getFontPath(runs[0])); } -TEST_F(FontCollectionItemizeTest, itemize_emojiSelection_withFE0E) { +TEST(FontCollectionItemizeTest, itemize_emojiSelection_withFE0E) { std::unique_ptr collection = getFontCollection(kTestFontDir, kEmojiXmlFile); std::vector runs; @@ -834,7 +830,7 @@ TEST_F(FontCollectionItemizeTest, itemize_emojiSelection_withFE0E) { EXPECT_EQ(kMixedEmojiFont, getFontPath(runs[0])); } -TEST_F(FontCollectionItemizeTest, itemize_emojiSelection_withFE0F) { +TEST(FontCollectionItemizeTest, itemize_emojiSelection_withFE0F) { std::unique_ptr collection = getFontCollection(kTestFontDir, kEmojiXmlFile); std::vector runs; diff --git a/tests/FontFamilyTest.cpp b/tests/FontFamilyTest.cpp index ac7616fada35ba16305cd4465d99d4eb91baafe0..fc44e6c63695ca913519fad358eb22b96b66b9e3 100644 --- a/tests/FontFamilyTest.cpp +++ b/tests/FontFamilyTest.cpp @@ -17,261 +17,74 @@ #include #include - -#include - #include "FontLanguageListCache.h" -#include "ICUTestBase.h" #include "MinikinFontForTest.h" #include "MinikinInternal.h" namespace android { -typedef ICUTestBase FontLanguagesTest; -typedef ICUTestBase FontLanguageTest; - -static FontLanguages createFontLanguages(const std::string& input) { - uint32_t langId = FontLanguageListCache::getId(input); - return FontLanguageListCache::getById(langId); -} - -static FontLanguage createFontLanguage(const std::string& input) { - uint32_t langId = FontLanguageListCache::getId(input); - return FontLanguageListCache::getById(langId)[0]; -} - -TEST_F(FontLanguageTest, basicTests) { - FontLanguage defaultLang; - FontLanguage emptyLang("", 0); - FontLanguage english = createFontLanguage("en"); - FontLanguage french = createFontLanguage("fr"); - FontLanguage und = createFontLanguage("und"); - FontLanguage undQaae = createFontLanguage("und-Qaae"); - - EXPECT_EQ(english, english); - EXPECT_EQ(french, french); - - EXPECT_TRUE(defaultLang != defaultLang); - EXPECT_TRUE(emptyLang != emptyLang); - EXPECT_TRUE(defaultLang != emptyLang); - EXPECT_TRUE(defaultLang != und); - EXPECT_TRUE(emptyLang != und); - EXPECT_TRUE(english != defaultLang); - EXPECT_TRUE(english != emptyLang); - EXPECT_TRUE(english != french); - EXPECT_TRUE(english != undQaae); - EXPECT_TRUE(und != undQaae); - EXPECT_TRUE(english != und); - - EXPECT_TRUE(defaultLang.isUnsupported()); - EXPECT_TRUE(emptyLang.isUnsupported()); - - EXPECT_FALSE(english.isUnsupported()); - EXPECT_FALSE(french.isUnsupported()); - EXPECT_FALSE(und.isUnsupported()); - EXPECT_FALSE(undQaae.isUnsupported()); -} - -TEST_F(FontLanguageTest, getStringTest) { - EXPECT_EQ("en-Latn", createFontLanguage("en").getString()); - EXPECT_EQ("en-Latn", createFontLanguage("en-Latn").getString()); - - // Capitalized language code or lowercased script should be normalized. - EXPECT_EQ("en-Latn", createFontLanguage("EN-LATN").getString()); - EXPECT_EQ("en-Latn", createFontLanguage("EN-latn").getString()); - EXPECT_EQ("en-Latn", createFontLanguage("en-latn").getString()); - - // Invalid script should be kept. - EXPECT_EQ("en-Xyzt", createFontLanguage("en-xyzt").getString()); - - EXPECT_EQ("en-Latn", createFontLanguage("en-Latn-US").getString()); - EXPECT_EQ("ja-Jpan", createFontLanguage("ja").getString()); - EXPECT_EQ("und", createFontLanguage("und").getString()); - EXPECT_EQ("und", createFontLanguage("UND").getString()); - EXPECT_EQ("und", createFontLanguage("Und").getString()); - EXPECT_EQ("und-Qaae", createFontLanguage("und-Qaae").getString()); - EXPECT_EQ("und-Qaae", createFontLanguage("Und-QAAE").getString()); - EXPECT_EQ("und-Qaae", createFontLanguage("Und-qaae").getString()); - - EXPECT_EQ("de-Latn", createFontLanguage("de-1901").getString()); - - // This is not a necessary desired behavior, just known behavior. - EXPECT_EQ("en-Latn", createFontLanguage("und-Abcdefgh").getString()); -} - -TEST_F(FontLanguageTest, ScriptEqualTest) { - EXPECT_TRUE(createFontLanguage("en").isEqualScript(createFontLanguage("en"))); - EXPECT_TRUE(createFontLanguage("en-Latn").isEqualScript(createFontLanguage("en"))); - EXPECT_TRUE(createFontLanguage("jp-Latn").isEqualScript(createFontLanguage("en-Latn"))); - EXPECT_TRUE(createFontLanguage("en-Jpan").isEqualScript(createFontLanguage("en-Jpan"))); - - EXPECT_FALSE(createFontLanguage("en-Jpan").isEqualScript(createFontLanguage("en-Hira"))); - EXPECT_FALSE(createFontLanguage("en-Jpan").isEqualScript(createFontLanguage("en-Hani"))); -} - -TEST_F(FontLanguageTest, ScriptMatchTest) { - const bool SUPPORTED = true; - const bool NOT_SUPPORTED = false; - - struct TestCase { - const std::string baseScript; - const std::string requestedScript; - bool isSupported; - } testCases[] = { - // Same scripts - { "en-Latn", "Latn", SUPPORTED }, - { "ja-Jpan", "Jpan", SUPPORTED }, - { "ja-Hira", "Hira", SUPPORTED }, - { "ja-Kana", "Kana", SUPPORTED }, - { "ja-Hrkt", "Hrkt", SUPPORTED }, - { "zh-Hans", "Hans", SUPPORTED }, - { "zh-Hant", "Hant", SUPPORTED }, - { "zh-Hani", "Hani", SUPPORTED }, - { "ko-Kore", "Kore", SUPPORTED }, - { "ko-Hang", "Hang", SUPPORTED }, - - // Japanese supports Hiragana, Katakanara, etc. - { "ja-Jpan", "Hira", SUPPORTED }, - { "ja-Jpan", "Kana", SUPPORTED }, - { "ja-Jpan", "Hrkt", SUPPORTED }, - { "ja-Hrkt", "Hira", SUPPORTED }, - { "ja-Hrkt", "Kana", SUPPORTED }, - - // Chinese supports Han. - { "zh-Hans", "Hani", SUPPORTED }, - { "zh-Hant", "Hani", SUPPORTED }, - - // Korean supports Hangul. - { "ko-Kore", "Hang", SUPPORTED }, - - // Different scripts - { "ja-Jpan", "Latn", NOT_SUPPORTED }, - { "en-Latn", "Jpan", NOT_SUPPORTED }, - { "ja-Jpan", "Hant", NOT_SUPPORTED }, - { "zh-Hant", "Jpan", NOT_SUPPORTED }, - { "ja-Jpan", "Hans", NOT_SUPPORTED }, - { "zh-Hans", "Jpan", NOT_SUPPORTED }, - { "ja-Jpan", "Kore", NOT_SUPPORTED }, - { "ko-Kore", "Jpan", NOT_SUPPORTED }, - { "zh-Hans", "Hant", NOT_SUPPORTED }, - { "zh-Hant", "Hans", NOT_SUPPORTED }, - { "zh-Hans", "Kore", NOT_SUPPORTED }, - { "ko-Kore", "Hans", NOT_SUPPORTED }, - { "zh-Hant", "Kore", NOT_SUPPORTED }, - { "ko-Kore", "Hant", NOT_SUPPORTED }, - - // Hiragana doesn't support Japanese, etc. - { "ja-Hira", "Jpan", NOT_SUPPORTED }, - { "ja-Kana", "Jpan", NOT_SUPPORTED }, - { "ja-Hrkt", "Jpan", NOT_SUPPORTED }, - { "ja-Hani", "Jpan", NOT_SUPPORTED }, - { "ja-Hira", "Hrkt", NOT_SUPPORTED }, - { "ja-Kana", "Hrkt", NOT_SUPPORTED }, - { "ja-Hani", "Hrkt", NOT_SUPPORTED }, - { "ja-Hani", "Hira", NOT_SUPPORTED }, - { "ja-Hani", "Kana", NOT_SUPPORTED }, - - // Kanji doesn't support Chinese, etc. - { "zh-Hani", "Hant", NOT_SUPPORTED }, - { "zh-Hani", "Hans", NOT_SUPPORTED }, - - // Hangul doesn't support Korean, etc. - { "ko-Hang", "Kore", NOT_SUPPORTED }, - { "ko-Hani", "Kore", NOT_SUPPORTED }, - { "ko-Hani", "Hang", NOT_SUPPORTED }, - { "ko-Hang", "Hani", NOT_SUPPORTED }, - }; - - for (auto testCase : testCases) { - hb_script_t script = hb_script_from_iso15924_tag( - HB_TAG(testCase.requestedScript[0], testCase.requestedScript[1], - testCase.requestedScript[2], testCase.requestedScript[3])); - if (testCase.isSupported) { - EXPECT_TRUE( - createFontLanguage(testCase.baseScript).supportsHbScript(script)) - << testCase.baseScript << " should support " << testCase.requestedScript; - } else { - EXPECT_FALSE( - createFontLanguage(testCase.baseScript).supportsHbScript(script)) - << testCase.baseScript << " shouldn't support " << testCase.requestedScript; - } - } -} - -TEST_F(FontLanguagesTest, basicTests) { +TEST(FontLanguagesTest, basicTests) { FontLanguages emptyLangs; EXPECT_EQ(0u, emptyLangs.size()); - FontLanguage english = createFontLanguage("en"); - FontLanguages singletonLangs = createFontLanguages("en"); + FontLanguage english("en", 2); + FontLanguages singletonLangs("en", 2); EXPECT_EQ(1u, singletonLangs.size()); EXPECT_EQ(english, singletonLangs[0]); - FontLanguage french = createFontLanguage("fr"); - FontLanguages twoLangs = createFontLanguages("en,fr"); + FontLanguage french("fr", 2); + FontLanguages twoLangs("en,fr", 5); EXPECT_EQ(2u, twoLangs.size()); EXPECT_EQ(english, twoLangs[0]); EXPECT_EQ(french, twoLangs[1]); } -TEST_F(FontLanguagesTest, unsupportedLanguageTests) { - FontLanguage unsupportedLang = createFontLanguage("abcd"); +TEST(FontLanguagesTest, unsupportedLanguageTests) { + FontLanguage unsupportedLang("x-example", 9); ASSERT_TRUE(unsupportedLang.isUnsupported()); - FontLanguages oneUnsupported = createFontLanguages("abcd-example"); + FontLanguages oneUnsupported("x-example", 9); EXPECT_EQ(1u, oneUnsupported.size()); EXPECT_TRUE(oneUnsupported[0].isUnsupported()); - FontLanguages twoUnsupporteds = createFontLanguages("abcd-example,abcd-example"); + FontLanguages twoUnsupporteds("x-example,x-example", 19); EXPECT_EQ(1u, twoUnsupporteds.size()); EXPECT_TRUE(twoUnsupporteds[0].isUnsupported()); - FontLanguage english = createFontLanguage("en"); - FontLanguages firstUnsupported = createFontLanguages("abcd-example,en"); + FontLanguage english("en", 2); + FontLanguages firstUnsupported("x-example,en", 12); EXPECT_EQ(1u, firstUnsupported.size()); EXPECT_EQ(english, firstUnsupported[0]); - FontLanguages lastUnsupported = createFontLanguages("en,abcd-example"); + FontLanguages lastUnsupported("en,x-example", 12); EXPECT_EQ(1u, lastUnsupported.size()); EXPECT_EQ(english, lastUnsupported[0]); } -TEST_F(FontLanguagesTest, repeatedLanguageTests) { - FontLanguage english = createFontLanguage("en"); - FontLanguage french = createFontLanguage("fr"); - FontLanguage englishInLatn = createFontLanguage("en-Latn"); +TEST(FontLanguagesTest, repeatedLanguageTests) { + FontLanguage english("en", 2); + FontLanguage englishInLatn("en-Latn", 2); ASSERT_TRUE(english == englishInLatn); - FontLanguages langs = createFontLanguages("en,en-Latn"); + FontLanguages langs("en,en-Latn", 10); EXPECT_EQ(1u, langs.size()); EXPECT_EQ(english, langs[0]); - - // Country codes are ignored. - FontLanguages fr = createFontLanguages("fr,fr-CA,fr-FR"); - EXPECT_EQ(1u, fr.size()); - EXPECT_EQ(french, fr[0]); - - // The order should be kept. - langs = createFontLanguages("en,fr,en-Latn"); - EXPECT_EQ(2u, langs.size()); - EXPECT_EQ(english, langs[0]); - EXPECT_EQ(french, langs[1]); } -TEST_F(FontLanguagesTest, undEmojiTests) { - FontLanguage emoji = createFontLanguage("und-Qaae"); +TEST(FontLanguagesTest, undEmojiTests) { + FontLanguage emoji("und-Qaae", 8); EXPECT_TRUE(emoji.hasEmojiFlag()); - FontLanguage und = createFontLanguage("und"); + FontLanguage und("und", 3); EXPECT_FALSE(und.hasEmojiFlag()); EXPECT_FALSE(emoji == und); - FontLanguage undExample = createFontLanguage("und-example"); + FontLanguage undExample("und-example", 10); EXPECT_FALSE(undExample.hasEmojiFlag()); EXPECT_FALSE(emoji == undExample); } -TEST_F(FontLanguagesTest, registerLanguageListTest) { +TEST(FontLanguagesTest, registerLanguageListTest) { EXPECT_EQ(0UL, FontStyle::registerLanguageList("")); EXPECT_NE(0UL, FontStyle::registerLanguageList("en")); EXPECT_NE(0UL, FontStyle::registerLanguageList("jp")); @@ -309,10 +122,9 @@ TEST_F(FontLanguagesTest, registerLanguageListTest) { // U+717D U+E0103 (VS20) const char kVsTestFont[] = kTestFontDir "VarioationSelectorTest-Regular.ttf"; -class FontFamilyTest : public ICUTestBase { +class FontFamilyTest : public testing::Test { public: virtual void SetUp() override { - ICUTestBase::SetUp(); if (access(kVsTestFont, R_OK) != 0) { FAIL() << "Unable to read " << kVsTestFont << ". " << "Please prepare the test data directory. " diff --git a/tests/FontLanguageListCacheTest.cpp b/tests/FontLanguageListCacheTest.cpp index f83988c1f501a1dcd83e9abd520165d64798afb9..29757fedceb0a4d27d049d1c0297054ae33705bc 100644 --- a/tests/FontLanguageListCacheTest.cpp +++ b/tests/FontLanguageListCacheTest.cpp @@ -17,15 +17,11 @@ #include #include - #include "FontLanguageListCache.h" -#include "ICUTestBase.h" namespace android { -typedef ICUTestBase FontLanguageListCacheTest; - -TEST_F(FontLanguageListCacheTest, getId) { +TEST(FontLanguageListCacheTest, getId) { EXPECT_EQ(0UL, FontLanguageListCache::getId("")); EXPECT_NE(0UL, FontStyle::registerLanguageList("en")); EXPECT_NE(0UL, FontStyle::registerLanguageList("jp")); @@ -46,15 +42,11 @@ TEST_F(FontLanguageListCacheTest, getId) { FontLanguageListCache::getId("en,zh-Hant")); } -TEST_F(FontLanguageListCacheTest, getById) { - uint32_t enLangId = FontLanguageListCache::getId("en"); - uint32_t jpLangId = FontLanguageListCache::getId("jp"); - FontLanguage english = FontLanguageListCache::getById(enLangId)[0]; - FontLanguage japanese = FontLanguageListCache::getById(jpLangId)[0]; +TEST(FontLanguageListCacheTest, getById) { + FontLanguage english("en", 2); + FontLanguage japanese("jp", 2); - FontLanguages defLangs = FontLanguageListCache::getById(0); - EXPECT_EQ(1UL, defLangs.size()); - EXPECT_TRUE(defLangs[0].isUnsupported()); + EXPECT_EQ(0UL, FontLanguageListCache::getById(0).size()); FontLanguages langs = FontLanguageListCache::getById(FontLanguageListCache::getId("en")); ASSERT_EQ(1UL, langs.size()); diff --git a/tests/FontTestUtils.cpp b/tests/FontTestUtils.cpp index 98dab5121b0d88aa62a8b6da9260bf62e0168747..8e1d184adcc42f0457a51ac57ec2dd038e2c386a 100644 --- a/tests/FontTestUtils.cpp +++ b/tests/FontTestUtils.cpp @@ -20,8 +20,6 @@ #include #include - -#include "FontLanguage.h" #include "MinikinFontForTest.h" std::unique_ptr getFontCollection( @@ -46,10 +44,9 @@ std::unique_ptr getFontCollection( } xmlChar* lang = xmlGetProp(familyNode, (const xmlChar*)"lang"); - uint32_t langId = android::FontStyle::registerLanguageList( - std::string((const char*)lang, xmlStrlen(lang))); - android::FontFamily* family = new android::FontFamily(langId, variant); + android::FontFamily* family = new android::FontFamily( + android::FontLanguage((const char*)lang, xmlStrlen(lang)), variant); for (xmlNode* fontNode = familyNode->children; fontNode; fontNode = fontNode->next) { if (xmlStrcmp(fontNode->name, (const xmlChar*)"font") != 0) { diff --git a/tests/ICUTestBase.h b/tests/ICUTestBase.h deleted file mode 100644 index 3bcfaf36945efe6714c3229e5caa67b8ae42d1c4..0000000000000000000000000000000000000000 --- a/tests/ICUTestBase.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MINIKIN_TEST_ICU_TEST_BASE_H -#define MINIKIN_TEST_ICU_TEST_BASE_H - -#include -#include -#include - -// low level file access for mapping ICU data -#include -#include -#include - -class ICUTestBase : public testing::Test { -protected: - virtual void SetUp() override { - const char* fn = "/system/usr/icu/" U_ICUDATA_NAME ".dat"; - int fd = open(fn, O_RDONLY); - ASSERT_NE(-1, fd); - struct stat sb; - ASSERT_EQ(0, fstat(fd, &sb)); - void* data = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); - - UErrorCode errorCode = U_ZERO_ERROR; - udata_setCommonData(data, &errorCode); - ASSERT_TRUE(U_SUCCESS(errorCode)); - u_init(&errorCode); - ASSERT_TRUE(U_SUCCESS(errorCode)); - } - - virtual void TearDown() override { - u_cleanup(); - } -}; - - -#endif // MINIKIN_TEST_ICU_TEST_BASE_H