Locale.cpp revision e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1
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#define LOG_TAG "Minikin" 18198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 19198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka#include "FontLanguage.h" 20198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 21e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui#include <algorithm> 22198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka#include <hb.h> 23e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui#include <string.h> 24198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka#include <unicode/uloc.h> 25198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 2614e2d136aaef271ba131f917cf5f27baa31ae5adSeigo Nonakanamespace minikin { 27198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 28198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka#define SCRIPT_TAG(c1, c2, c3, c4) \ 29198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka (((uint32_t)(c1)) << 24 | ((uint32_t)(c2)) << 16 | ((uint32_t)(c3)) << 8 | \ 30198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka ((uint32_t)(c4))) 31198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 32e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui// Check if a language code supports emoji according to its subtag 33e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yiruistatic bool isEmojiSubtag(const char* buf, size_t bufLen, const char* subtag, size_t subtagLen) { 34e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui if (bufLen < subtagLen) { 35e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui return false; 36e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui } 37e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui if (strncmp(buf, subtag, subtagLen) != 0) { 38e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui return false; // no match between two strings 39e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui } 40e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui return (bufLen == subtagLen || buf[subtagLen] == '\0' || 41e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui buf[subtagLen] == '-' || buf[subtagLen] == '_'); 42e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui} 43e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui 44198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka// Parse BCP 47 language identifier into internal structure 45198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo NonakaFontLanguage::FontLanguage(const char* buf, size_t length) : FontLanguage() { 46198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka size_t i; 47198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka for (i = 0; i < length; i++) { 48198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka char c = buf[i]; 49198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka if (c == '-' || c == '_') break; 50198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka } 51198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka if (i == 2 || i == 3) { // only accept two or three letter language code. 52198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka mLanguage = buf[0] | (buf[1] << 8) | ((i == 3) ? (buf[2] << 16) : 0); 53198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka } else { 54198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka // We don't understand anything other than two-letter or three-letter 55198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka // language codes, so we skip parsing the rest of the string. 56198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka mLanguage = 0ul; 57198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka return; 58198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka } 59198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 60198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka size_t next; 61198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka for (i++; i < length; i = next + 1) { 62198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka for (next = i; next < length; next++) { 63198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka char c = buf[next]; 64198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka if (c == '-' || c == '_') break; 65198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka } 66198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka if (next - i == 4 && 'A' <= buf[i] && buf[i] <= 'Z') { 67198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka mScript = SCRIPT_TAG(buf[i], buf[i + 1], buf[i + 2], buf[i + 3]); 68198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka } 69198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka } 70198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka mSubScriptBits = scriptToSubScriptBits(mScript); 71e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui 72e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui if (mScript == SCRIPT_TAG('Z', 's', 'y', 'e')) { 73e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui mEmojiStyle = EMSTYLE_EMOJI; 74e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui } else if (mScript == SCRIPT_TAG('Z', 's', 'y', 'm')) { 75e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui mEmojiStyle = EMSTYLE_TEXT; 76e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui } 77e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui // 10 is the length of "-u-em-text", which is the shortest emoji subtag, 78e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui // unnecessary comparison can be avoided if total length is smaller than 10. 79e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui const size_t kMinSubtagLength = 10; 80e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui if (length < kMinSubtagLength) { 81e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui return; 82e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui } 83e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui 84e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui static const char kPrefix[] = "-u-em-"; 85e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui const char *pos = std::search(buf, buf + length, kPrefix, kPrefix + strlen(kPrefix)); 86e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui if (pos == buf + length) { 87e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui return; 88e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui } 89e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui pos += strlen(kPrefix); 90e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui const size_t remainingLength = length - (pos - buf); 91e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui if (isEmojiSubtag(pos, remainingLength, "emoji", 5)){ 92e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui mEmojiStyle = EMSTYLE_EMOJI; 93e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui } else if (isEmojiSubtag(pos, remainingLength, "text", 4)){ 94e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui mEmojiStyle = EMSTYLE_TEXT; 95e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui } else if (isEmojiSubtag(pos, remainingLength, "default", 7)){ 96e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui mEmojiStyle = EMSTYLE_DEFAULT; 97e1d7f6168a0a485ecac75cfc9ae3bdc5143d0fb1yirui } 98198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka} 99198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 100198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka//static 101198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonakauint8_t FontLanguage::scriptToSubScriptBits(uint32_t script) { 102198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka uint8_t subScriptBits = 0u; 103198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka switch (script) { 104533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka case SCRIPT_TAG('B', 'o', 'p', 'o'): 105533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka subScriptBits = kBopomofoFlag; 106533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka break; 107198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka case SCRIPT_TAG('H', 'a', 'n', 'g'): 108198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka subScriptBits = kHangulFlag; 109198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka break; 110533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka case SCRIPT_TAG('H', 'a', 'n', 'b'): 111533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka // Bopomofo is almost exclusively used in Taiwan. 112533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka subScriptBits = kHanFlag | kBopomofoFlag; 113533a01ea8438bb102b0dbc71f6c4ef356b260ed5Seigo Nonaka break; 114198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka case SCRIPT_TAG('H', 'a', 'n', 'i'): 115198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka subScriptBits = kHanFlag; 116198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka break; 117198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka case SCRIPT_TAG('H', 'a', 'n', 's'): 118198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka subScriptBits = kHanFlag | kSimplifiedChineseFlag; 119198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka break; 120198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka case SCRIPT_TAG('H', 'a', 'n', 't'): 121198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka subScriptBits = kHanFlag | kTraditionalChineseFlag; 122198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka break; 123198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka case SCRIPT_TAG('H', 'i', 'r', 'a'): 124198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka subScriptBits = kHiraganaFlag; 125198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka break; 126198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka case SCRIPT_TAG('H', 'r', 'k', 't'): 127198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka subScriptBits = kKatakanaFlag | kHiraganaFlag; 128198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka break; 129198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka case SCRIPT_TAG('J', 'p', 'a', 'n'): 130198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka subScriptBits = kHanFlag | kKatakanaFlag | kHiraganaFlag; 131198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka break; 132198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka case SCRIPT_TAG('K', 'a', 'n', 'a'): 133198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka subScriptBits = kKatakanaFlag; 134198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka break; 135198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka case SCRIPT_TAG('K', 'o', 'r', 'e'): 136198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka subScriptBits = kHanFlag | kHangulFlag; 137198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka break; 138198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka } 139198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka return subScriptBits; 140198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka} 141198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 142198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonakastd::string FontLanguage::getString() const { 143198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka if (mLanguage == 0ul) { 144198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka return "und"; 145198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka } 146198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka char buf[16]; 147198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka size_t i = 0; 148198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka buf[i++] = mLanguage & 0xFF ; 149198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka buf[i++] = (mLanguage >> 8) & 0xFF; 150198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka char third_letter = (mLanguage >> 16) & 0xFF; 151198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka if (third_letter != 0) buf[i++] = third_letter; 152198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka if (mScript != 0) { 153198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka buf[i++] = '-'; 154198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka buf[i++] = (mScript >> 24) & 0xFFu; 155198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka buf[i++] = (mScript >> 16) & 0xFFu; 156198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka buf[i++] = (mScript >> 8) & 0xFFu; 157198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka buf[i++] = mScript & 0xFFu; 158198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka } 159198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka return std::string(buf, i); 160198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka} 161198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 1626f9966ea7c1910fd780cf7779cc59701c9b98a2bSeigo Nonakabool FontLanguage::isEqualScript(const FontLanguage& other) const { 163198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka return other.mScript == mScript; 164198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka} 165198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 166f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka// static 167f3afe92def0fff022889fd036d68451223aac146Seigo Nonakabool FontLanguage::supportsScript(uint8_t providedBits, uint8_t requestedBits) { 168f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka return requestedBits != 0 && (providedBits & requestedBits) == requestedBits; 1696f9966ea7c1910fd780cf7779cc59701c9b98a2bSeigo Nonaka} 1706f9966ea7c1910fd780cf7779cc59701c9b98a2bSeigo Nonaka 171198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonakabool FontLanguage::supportsHbScript(hb_script_t script) const { 172198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka static_assert(SCRIPT_TAG('J', 'p', 'a', 'n') == HB_TAG('J', 'p', 'a', 'n'), 173198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka "The Minikin script and HarfBuzz hb_script_t have different encodings."); 174198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka if (script == mScript) return true; 175f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka return supportsScript(mSubScriptBits, scriptToSubScriptBits(script)); 176198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka} 177198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 178f3afe92def0fff022889fd036d68451223aac146Seigo Nonakaint FontLanguage::calcScoreFor(const FontLanguages& supported) const { 179f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka int score = 0; 180f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka for (size_t i = 0; i < supported.size(); ++i) { 181f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka if (isEqualScript(supported[i]) || 182f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka supportsScript(supported[i].mSubScriptBits, mSubScriptBits)) { 183f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka if (mLanguage == supported[i].mLanguage) { 184f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka return 2; 185f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka } else { 186f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka score = 1; 187f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka } 188f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka } 189f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka } 190f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 191f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka if (score == 1) { 192f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka return score; 193f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka } 194f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 195f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka if (supportsScript(supported.getUnionOfSubScriptBits(), mSubScriptBits)) { 196f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka // Gives score of 2 only if the language matches all of the font languages except for the 197f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka // exact match case handled above. 198f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka return (mLanguage == supported[0].mLanguage && supported.isAllTheSameLanguage()) ? 2 : 1; 199f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka } 200f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 201f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka return 0; 202f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka} 203f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 204f3afe92def0fff022889fd036d68451223aac146Seigo NonakaFontLanguages::FontLanguages(std::vector<FontLanguage>&& languages) 205f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka : mLanguages(std::move(languages)) { 206f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka if (mLanguages.empty()) { 207f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka return; 208f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka } 209f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 210f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka const FontLanguage& lang = mLanguages[0]; 211f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka 212f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka mIsAllTheSameLanguage = true; 213f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka mUnionOfSubScriptBits = lang.mSubScriptBits; 214f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka for (size_t i = 1; i < mLanguages.size(); ++i) { 215f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka mUnionOfSubScriptBits |= mLanguages[i].mSubScriptBits; 216f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka if (mIsAllTheSameLanguage && lang.mLanguage != mLanguages[i].mLanguage) { 217f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka mIsAllTheSameLanguage = false; 218f3afe92def0fff022889fd036d68451223aac146Seigo Nonaka } 2196f9966ea7c1910fd780cf7779cc59701c9b98a2bSeigo Nonaka } 220198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka} 221198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka 222198b46f1fea3f47ef8eb6317799c0d77aaec52f6Seigo Nonaka#undef SCRIPT_TAG 22314e2d136aaef271ba131f917cf5f27baa31ae5adSeigo Nonaka} // namespace minikin 224