FontLanguage.h revision 198b46f1fea3f47ef8eb6317799c0d77aaec52f6
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef MINIKIN_FONT_LANGUAGE_H
18#define MINIKIN_FONT_LANGUAGE_H
19
20#include <string>
21#include <vector>
22
23#include <hb.h>
24
25namespace android {
26
27// FontLanguage is a compact representation of a BCP 47 language tag. It
28// does not capture all possible information, only what directly affects
29// font rendering.
30struct FontLanguage {
31public:
32    // Default constructor creates the unsupported language.
33    FontLanguage() : mScript(0ul), mLanguage(0ul), mSubScriptBits(0ul) {}
34
35    // Parse from string
36    FontLanguage(const char* buf, size_t length);
37
38    bool operator==(const FontLanguage other) const {
39        return !isUnsupported() && isEqualScript(other) && isEqualLanguage(other);
40    }
41
42    bool operator!=(const FontLanguage other) const {
43        return !(*this == other);
44    }
45
46    bool isUnsupported() const { return mLanguage == 0ul; }
47    bool hasEmojiFlag() const { return mSubScriptBits & kEmojiFlag; }
48
49    bool isEqualLanguage(const FontLanguage other) const { return mLanguage == other.mLanguage; }
50    bool isEqualScript(const FontLanguage other) const;
51
52    // Returns true if this script supports the given script. For example, ja-Jpan supports Hira,
53    // ja-Hira doesn't support Jpan.
54    bool supportsHbScript(hb_script_t script) const;
55
56    std::string getString() const;
57
58    // 0 = no match, 1 = language matches
59    int match(const FontLanguage other) const;
60
61    uint64_t getIdentifier() const { return (uint64_t)mScript << 32 | (uint64_t)mLanguage; }
62
63private:
64    // ISO 15924 compliant script code. The 4 chars script code are packed into a 32 bit integer.
65    uint32_t mScript;
66
67    // ISO 639-1 or ISO 639-2 compliant language code.
68    // The two or three letter language code is packed into 32 bit integer.
69    // mLanguage = 0 means the FontLanguage is unsupported.
70    uint32_t mLanguage;
71
72    // For faster comparing, use 7 bits for specific scripts.
73    static const uint8_t kEmojiFlag = 1u;
74    static const uint8_t kHanFlag = 1u << 1;
75    static const uint8_t kHangulFlag = 1u << 2;
76    static const uint8_t kHiraganaFlag = 1u << 3;
77    static const uint8_t kKatakanaFlag = 1u << 4;
78    static const uint8_t kSimplifiedChineseFlag = 1u << 5;
79    static const uint8_t kTraditionalChineseFlag = 1u << 6;
80    uint8_t mSubScriptBits;
81
82    static uint8_t scriptToSubScriptBits(uint32_t script);
83};
84
85typedef std::vector<FontLanguage> FontLanguages;
86
87}  // namespace android
88
89#endif  // MINIKIN_FONT_LANGUAGE_H
90