summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/minikin/FontCollection.cpp10
-rw-r--r--libs/minikin/GraphemeBreak.cpp43
-rw-r--r--libs/minikin/MinikinInternal.cpp42
-rw-r--r--libs/minikin/MinikinInternal.h6
4 files changed, 55 insertions, 46 deletions
diff --git a/libs/minikin/FontCollection.cpp b/libs/minikin/FontCollection.cpp
index dd905a3..4541af8 100644
--- a/libs/minikin/FontCollection.cpp
+++ b/libs/minikin/FontCollection.cpp
@@ -379,11 +379,13 @@ void FontCollection::itemize(const uint16_t *string, size_t string_size, FontSty
langListId, variant);
if (utf16Pos == 0 || family != lastFamily) {
size_t start = utf16Pos;
- // Workaround for Emoji keycap until we implement per-cluster font
- // selection: if keycap is found in a different font that also
- // supports previous char, attach previous char to the new run.
+ // Workaround for Emoji keycap and emoji modifier until we implement per-cluster
+ // font selection: if a keycap or an emoji modifier is found in a different font
+ // that also supports previous char, attach previous char to the new run.
// Bug 7557244.
- if (ch == KEYCAP && utf16Pos != 0 && family && family->getCoverage()->get(prevCh)) {
+ if (utf16Pos != 0 &&
+ (ch == KEYCAP || (isEmojiModifier(ch) && isEmojiBase(prevCh))) &&
+ family && family->getCoverage()->get(prevCh)) {
const size_t prevChLength = U16_LENGTH(prevCh);
run->end -= prevChLength;
if (run->start == run->end) {
diff --git a/libs/minikin/GraphemeBreak.cpp b/libs/minikin/GraphemeBreak.cpp
index 4141091..ef323d5 100644
--- a/libs/minikin/GraphemeBreak.cpp
+++ b/libs/minikin/GraphemeBreak.cpp
@@ -19,6 +19,7 @@
#include <unicode/utf16.h>
#include <minikin/GraphemeBreak.h>
+#include "MinikinInternal.h"
namespace android {
@@ -77,48 +78,6 @@ bool isZwjEmoji(uint32_t c) {
|| c == 0x1F5E8); // LEFT SPEECH BUBBLE
}
-// Based on Modifiers from http://www.unicode.org/L2/L2016/16011-data-file.txt
-bool isEmojiModifier(uint32_t c) {
- return (0x1F3FB <= c && c <= 0x1F3FF);
-}
-
-// Based on Emoji_Modifier_Base from
-// http://www.unicode.org/Public/emoji/3.0/emoji-data.txt
-bool isEmojiBase(uint32_t c) {
- if (0x261D <= c && c <= 0x270D) {
- return (c == 0x261D || c == 0x26F9 || (0x270A <= c && c <= 0x270D));
- } else if (0x1F385 <= c && c <= 0x1F93E) {
- return (c == 0x1F385
- || (0x1F3C3 <= c || c <= 0x1F3C4)
- || (0x1F3CA <= c || c <= 0x1F3CB)
- || (0x1F442 <= c || c <= 0x1F443)
- || (0x1F446 <= c || c <= 0x1F450)
- || (0x1F466 <= c || c <= 0x1F469)
- || c == 0x1F46E
- || (0x1F470 <= c || c <= 0x1F478)
- || c == 0x1F47C
- || (0x1F481 <= c || c <= 0x1F483)
- || (0x1F485 <= c || c <= 0x1F487)
- || c == 0x1F4AA
- || c == 0x1F575
- || c == 0x1F57A
- || c == 0x1F590
- || (0x1F595 <= c || c <= 0x1F596)
- || (0x1F645 <= c || c <= 0x1F647)
- || (0x1F64B <= c || c <= 0x1F64F)
- || c == 0x1F6A3
- || (0x1F6B4 <= c || c <= 0x1F6B6)
- || c == 0x1F6C0
- || (0x1F918 <= c || c <= 0x1F91E)
- || c == 0x1F926
- || c == 0x1F930
- || (0x1F933 <= c || c <= 0x1F939)
- || (0x1F93B <= c || c <= 0x1F93E));
- } else {
- return false;
- }
-}
-
bool GraphemeBreak::isGraphemeBreak(const uint16_t* buf, size_t start, size_t count,
size_t offset) {
// This implementation closely follows Unicode Standard Annex #29 on
diff --git a/libs/minikin/MinikinInternal.cpp b/libs/minikin/MinikinInternal.cpp
index c2aa01a..7fa7ce9 100644
--- a/libs/minikin/MinikinInternal.cpp
+++ b/libs/minikin/MinikinInternal.cpp
@@ -30,4 +30,46 @@ void assertMinikinLocked() {
#endif
}
+// Based on Modifiers from http://www.unicode.org/L2/L2016/16011-data-file.txt
+bool isEmojiModifier(uint32_t c) {
+ return (0x1F3FB <= c && c <= 0x1F3FF);
+}
+
+// Based on Emoji_Modifier_Base from
+// http://www.unicode.org/Public/emoji/3.0/emoji-data.txt
+bool isEmojiBase(uint32_t c) {
+ if (0x261D <= c && c <= 0x270D) {
+ return (c == 0x261D || c == 0x26F9 || (0x270A <= c && c <= 0x270D));
+ } else if (0x1F385 <= c && c <= 0x1F93E) {
+ return (c == 0x1F385
+ || (0x1F3C3 <= c || c <= 0x1F3C4)
+ || (0x1F3CA <= c || c <= 0x1F3CB)
+ || (0x1F442 <= c || c <= 0x1F443)
+ || (0x1F446 <= c || c <= 0x1F450)
+ || (0x1F466 <= c || c <= 0x1F469)
+ || c == 0x1F46E
+ || (0x1F470 <= c || c <= 0x1F478)
+ || c == 0x1F47C
+ || (0x1F481 <= c || c <= 0x1F483)
+ || (0x1F485 <= c || c <= 0x1F487)
+ || c == 0x1F4AA
+ || c == 0x1F575
+ || c == 0x1F57A
+ || c == 0x1F590
+ || (0x1F595 <= c || c <= 0x1F596)
+ || (0x1F645 <= c || c <= 0x1F647)
+ || (0x1F64B <= c || c <= 0x1F64F)
+ || c == 0x1F6A3
+ || (0x1F6B4 <= c || c <= 0x1F6B6)
+ || c == 0x1F6C0
+ || (0x1F918 <= c || c <= 0x1F91E)
+ || c == 0x1F926
+ || c == 0x1F930
+ || (0x1F933 <= c || c <= 0x1F939)
+ || (0x1F93B <= c || c <= 0x1F93E));
+ } else {
+ return false;
+ }
+}
+
}
diff --git a/libs/minikin/MinikinInternal.h b/libs/minikin/MinikinInternal.h
index 34a95bb..3d68691 100644
--- a/libs/minikin/MinikinInternal.h
+++ b/libs/minikin/MinikinInternal.h
@@ -32,6 +32,12 @@ extern Mutex gMinikinLock;
// Aborts if gMinikinLock is not acquired. Do nothing on the release build.
void assertMinikinLocked();
+// Returns true if c is emoji modifier base.
+bool isEmojiBase(uint32_t c);
+
+// Returns true if c is emoji modifier.
+bool isEmojiModifier(uint32_t c);
+
}
#endif // MINIKIN_INTERNAL_H