1198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka/* 2198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka * Copyright (C) 2015 The Android Open Source Project 3198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka * 4198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka * Licensed under the Apache License, Version 2.0 (the "License"); 5198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka * you may not use this file except in compliance with the License. 6198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka * You may obtain a copy of the License at 7198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka * 8198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka * http://www.apache.org/licenses/LICENSE-2.0 9198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka * 10198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka * Unless required by applicable law or agreed to in writing, software 11198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka * distributed under the License is distributed on an "AS IS" BASIS, 12198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka * See the License for the specific language governing permissions and 14198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka * limitations under the License. 15198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka */ 16198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 17198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka#ifndef MINIKIN_FONT_LANGUAGE_H 18198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka#define MINIKIN_FONT_LANGUAGE_H 19198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 20198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka#include <string> 21198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka#include <vector> 22198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 23198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka#include <hb.h> 24198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 25198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonakanamespace android { 26198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 27f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka// Due to the limits in font fallback score calculation, we can't use anything more than 17 28f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka// languages. 29f3afe92def0fff022889fd036d68451223aac146Seigo Nonakaconst size_t FONT_LANGUAGES_LIMIT = 17; 30f3afe92def0fff022889fd036d68451223aac146Seigo Nonakaclass FontLanguages; 31f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 32198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka// FontLanguage is a compact representation of a BCP 47 language tag. It 33198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka// does not capture all possible information, only what directly affects 34198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka// font rendering. 35198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonakastruct FontLanguage { 36198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonakapublic: 37198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka // Default constructor creates the unsupported language. 38198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka FontLanguage() : mScript(0ul), mLanguage(0ul), mSubScriptBits(0ul) {} 39198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 40198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka // Parse from string 41198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka FontLanguage(const char* buf, size_t length); 42198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 43198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka bool operator==(const FontLanguage other) const { 446f9966ea7c1910fd780cf7779cc59701c9b98a2bSeigo Nonaka return !isUnsupported() && isEqualScript(other) && mLanguage == other.mLanguage; 45198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka } 46198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 47198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka bool operator!=(const FontLanguage other) const { 48198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka return !(*this == other); 49198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka } 50198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 51198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka bool isUnsupported() const { return mLanguage == 0ul; } 52198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka bool hasEmojiFlag() const { return mSubScriptBits & kEmojiFlag; } 53198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 546f9966ea7c1910fd780cf7779cc59701c9b98a2bSeigo Nonaka bool isEqualScript(const FontLanguage& other) const; 55198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 56198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka // Returns true if this script supports the given script. For example, ja-Jpan supports Hira, 57198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka // ja-Hira doesn't support Jpan. 58198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka bool supportsHbScript(hb_script_t script) const; 59198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 60198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka std::string getString() const; 61198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 62f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka // Calculates a matching score. This score represents how well the input languages cover this 63f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka // language. The maximum score in the language list is returned. 646f9966ea7c1910fd780cf7779cc59701c9b98a2bSeigo Nonaka // 0 = no match, 1 = script match, 2 = script and primary language match. 65f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka int calcScoreFor(const FontLanguages& supported) const; 66198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 67198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka uint64_t getIdentifier() const { return (uint64_t)mScript << 32 | (uint64_t)mLanguage; } 68198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 69198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonakaprivate: 70f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka friend class FontLanguages; // for FontLanguages constructor 71f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 72198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka // ISO 15924 compliant script code. The 4 chars script code are packed into a 32 bit integer. 73198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka uint32_t mScript; 74198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 75198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka // ISO 639-1 or ISO 639-2 compliant language code. 76198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka // The two or three letter language code is packed into 32 bit integer. 77198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka // mLanguage = 0 means the FontLanguage is unsupported. 78198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka uint32_t mLanguage; 79198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 80533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka // For faster comparing, use 8 bits for specific scripts. 81533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka static const uint8_t kBopomofoFlag = 1u; 82533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka static const uint8_t kEmojiFlag = 1u << 1; 83533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka static const uint8_t kHanFlag = 1u << 2; 84533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka static const uint8_t kHangulFlag = 1u << 3; 85533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka static const uint8_t kHiraganaFlag = 1u << 4; 86533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka static const uint8_t kKatakanaFlag = 1u << 5; 87533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka static const uint8_t kSimplifiedChineseFlag = 1u << 6; 88533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka static const uint8_t kTraditionalChineseFlag = 1u << 7; 89198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka uint8_t mSubScriptBits; 90198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 91198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka static uint8_t scriptToSubScriptBits(uint32_t script); 92f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 93f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka // Returns true if the provide subscript bits has the requested subscript bits. 94f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka // Note that this function returns false if the requested subscript bits are empty. 95f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka static bool supportsScript(uint8_t providedBits, uint8_t requestedBits); 96198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka}; 97198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 98f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka// An immutable list of languages. 99f3afe92def0fff022889fd036d68451223aac146Seigo Nonakaclass FontLanguages { 100f3afe92def0fff022889fd036d68451223aac146Seigo Nonakapublic: 101f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka FontLanguages(std::vector<FontLanguage>&& languages); 102f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka FontLanguages() : mUnionOfSubScriptBits(0), mIsAllTheSameLanguage(false) {} 103f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka FontLanguages(FontLanguages&&) = default; 104f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 105f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka size_t size() const { return mLanguages.size(); } 106f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka bool empty() const { return mLanguages.empty(); } 107f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka const FontLanguage& operator[] (size_t n) const { return mLanguages[n]; } 108f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 109f3afe92def0fff022889fd036d68451223aac146Seigo Nonakaprivate: 110f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka friend struct FontLanguage; // for calcScoreFor 111f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 112f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka std::vector<FontLanguage> mLanguages; 113f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka uint8_t mUnionOfSubScriptBits; 114f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka bool mIsAllTheSameLanguage; 115f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 116f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka uint8_t getUnionOfSubScriptBits() const { return mUnionOfSubScriptBits; } 117f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka bool isAllTheSameLanguage() const { return mIsAllTheSameLanguage; } 118f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 119f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka // Do not copy and assign. 120f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka FontLanguages(const FontLanguages&) = delete; 121f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka void operator=(const FontLanguages&) = delete; 122f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka}; 123198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 124198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka} // namespace android 125198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 126198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka#endif // MINIKIN_FONT_LANGUAGE_H 127