Add set of APIs for emoji-character-properties 46/266046/8
authorShrouq Sabah <s.sabah@samsung.com>
Wed, 3 Nov 2021 07:39:47 +0000 (09:39 +0200)
committerShrouq Sabah <s.sabah@samsung.com>
Tue, 16 Nov 2021 14:27:07 +0000 (16:27 +0200)
defined-characters.h contains set of the defined unicodes
emoji-character-properties.h/cpp contains set of the for emoji-data and properties

Change-Id: I42eb6d580a8803ddb90b1b0cc4a0fa9fbe2fdc33

20 files changed:
dali/devel-api/file.list
dali/devel-api/text-abstraction/defined-characters.h [new file with mode: 0644]
dali/devel-api/text-abstraction/emoji-character-properties.cpp [new file with mode: 0644]
dali/devel-api/text-abstraction/emoji-character-properties.h [new file with mode: 0644]
dali/devel-api/text-abstraction/emoji-helper.cpp [new file with mode: 0644]
dali/devel-api/text-abstraction/emoji-helper.h [new file with mode: 0644]
dali/devel-api/text-abstraction/font-client.cpp
dali/devel-api/text-abstraction/font-client.h
dali/devel-api/text-abstraction/script.cpp
dali/devel-api/text-abstraction/script.h
dali/devel-api/text-abstraction/shaping.h
dali/internal/text/text-abstraction/font-client-impl.cpp
dali/internal/text/text-abstraction/font-client-impl.h
dali/internal/text/text-abstraction/plugin/bitmap-font-cache-item.h
dali/internal/text/text-abstraction/plugin/font-cache-item-interface.h
dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.cpp
dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.h
dali/internal/text/text-abstraction/plugin/font-face-cache-item.cpp
dali/internal/text/text-abstraction/plugin/font-face-cache-item.h
dali/internal/text/text-abstraction/shaping-impl.cpp

index c87ab49..4e16b3b 100755 (executable)
@@ -148,6 +148,8 @@ SET( devel_api_text_abstraction_src_files
    ${adaptor_devel_api_dir}/text-abstraction/text-renderer.cpp
    ${adaptor_devel_api_dir}/text-abstraction/text-renderer-layout-helper.cpp
    ${adaptor_devel_api_dir}/text-abstraction/hyphenation.cpp
+   ${adaptor_devel_api_dir}/text-abstraction/emoji-character-properties.cpp
+   ${adaptor_devel_api_dir}/text-abstraction/emoji-helper.cpp
 )
 
 
@@ -166,4 +168,7 @@ SET( text_abstraction_header_files
    ${adaptor_devel_api_dir}/text-abstraction/text-renderer.h
    ${adaptor_devel_api_dir}/text-abstraction/text-renderer-layout-helper.h
    ${adaptor_devel_api_dir}/text-abstraction/hyphenation.h
+   ${adaptor_devel_api_dir}/text-abstraction/emoji-character-properties.h
+   ${adaptor_devel_api_dir}/text-abstraction/emoji-helper.h
+   ${adaptor_devel_api_dir}/text-abstraction/defined-characters.h
 )
diff --git a/dali/devel-api/text-abstraction/defined-characters.h b/dali/devel-api/text-abstraction/defined-characters.h
new file mode 100644 (file)
index 0000000..09ede7e
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef DALI_TOOLKIT_TEXT_ABSTRACTION_DEFINED_CHARACTERS_H
+#define DALI_TOOLKIT_TEXT_ABSTRACTION_DEFINED_CHARACTERS_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+constexpr unsigned int CHAR_COMBINING_ENCLOSING_KEYCAP = 0x20E3; ///< Combining Enclosing Keycap. https://unicode-table.com/en/1F1E6/
+
+//Emoji Components (Hair style)
+constexpr unsigned int CHAR_EMOJI_COMPONENT_BALD       = 0x1F9B2; ///< Emoji CompOnent Bald. https://unicode-table.com/en/1F9B2/
+constexpr unsigned int CHAR_EMOJI_COMPONENT_RED_HAIR   = 0x1F9B0; ///< Emoji CompOnent Red Hair. https://unicode-table.com/en/1F9B0/
+constexpr unsigned int CHAR_EMOJI_COMPONENT_CURLY_HAIR = 0x1F9B1; ///< Emoji CompOnent Curly Hair. https://unicode-table.com/en/1F9B1/
+constexpr unsigned int CHAR_EMOJI_COMPONENT_WHITE_HAIR = 0x1F9B3; ///< Emoji CompOnent White Hair. https://unicode-table.com/en/1F9B3/
+
+//Regional Indicators
+constexpr unsigned int CHAR_REGIONAL_INDICATOR_SYMBOL_LETTER_A = 0x1F1E6; ///< Regional Indicator Symbol Letter A. https://unicode-table.com/en/1F1E6/
+constexpr unsigned int CHAR_REGIONAL_INDICATOR_SYMBOL_LETTER_Z = 0x1F1FF; ///< Regional Indicator Symbol Letter Z. https://unicode-table.com/en/1F1FF/
+
+//Variation Selectors
+constexpr unsigned int CHAR_VARIATION_SELECTOR_15 = 0xFE0E; ///< Variation Selector-15. https://unicode-table.com/en/FE0E/
+constexpr unsigned int CHAR_VARIATION_SELECTOR_16 = 0xFE0F; ///< Variation Selector-16. https://unicode-table.com/en/FE0F/
+
+//Emoji Tags
+constexpr unsigned int CHAR_CANCEL_TAG = 0xE007F; ///< Stateful tag terminator: Cancel Tag. https://unicode-table.com/en/E007F/
+constexpr unsigned int CHAR_TAG_SPACE  = 0xE0020; ///< Tag components: Tag Space. The first tag in tag_spec https://unicode-table.com/en/E0020/
+constexpr unsigned int CHAR_TAG_TILDE  = 0xE007E; ///< Tag components: Tag Tilde. The last tag in tag_spec https://unicode-table.com/en/E007E/
+
+//Emoji Modifiers (Skin tone)
+constexpr unsigned int CHAR_EMOJI_MODIFIER_FITZPATRICK_TYPE_1_2 = 0x1F3FB; ///< Emoji Modifier Fitzpatrick Type-1-2 (Light Skin Tone). https://unicode-table.com/en/1F3FB/
+constexpr unsigned int CHAR_EMOJI_MODIFIER_FITZPATRICK_TYPE_3   = 0x1F3FC; ///< Emoji Modifier Fitzpatrick Type-3 (Medium-Light Skin Tone). https://unicode-table.com/en/1F3FC/
+constexpr unsigned int CHAR_EMOJI_MODIFIER_FITZPATRICK_TYPE_4   = 0x1F3FD; ///< Emoji Modifier Fitzpatrick Type-4 (Medium Skin Tone). https://unicode-table.com/en/1F3FD/
+constexpr unsigned int CHAR_EMOJI_MODIFIER_FITZPATRICK_TYPE_5   = 0x1F3FE; ///< Emoji Modifier Fitzpatrick Type-5 (Medium-Dark Skin Tone). https://unicode-table.com/en/1F3FE/
+constexpr unsigned int CHAR_EMOJI_MODIFIER_FITZPATRICK_TYPE_6   = 0x1F3FF; ///< Emoji Modifier Fitzpatrick Type-6 (Dark Skin Tone). https://unicode-table.com/en/1F3FF/
+
+//Miscellaneous Symbols and Arrows. Range: 2B00—2BFF
+constexpr unsigned int CHAR_NORTH_EAST_WHITE_ARROW     = 0x2B00; ///< North East White Arrow. https://unicode-table.com/en/2B00/
+constexpr unsigned int CHAR_HELLSCHREIBER_PAUSE_SYMBOL = 0x2BFF; ///< Hellschreiber Pause Symbol . https://unicode-table.com/en/2BFF/
+
+//Dingbats. Range: 2700—27BF
+constexpr unsigned int CHAR_BLACK_SAFETY_SCISSORS   = 0x2700; ///< Black Safety Scissors. https://unicode-table.com/en/2700/
+constexpr unsigned int CHAR_DOUBLE_CURLY_LOOP_EMOJI = 0x27BF; ///< Double Curly Loop Emoji . https://unicode-table.com/en/27BF/
+
+//Basic Latin. Range: 0000—007F
+constexpr unsigned int CHAR_NUMBER_SIGN   = 0x0023; ///< # Number Sign . https://unicode-table.com/en/0023/
+constexpr unsigned int CHAR_ASTERISK      = 0x002A; ///< * Asterisk. https://unicode-table.com/en/002A/
+constexpr unsigned int CHAR_ASCII_DIGIT_0 = 0x0030; ///< 0 Digit Zero. https://unicode-table.com/en/0030/
+constexpr unsigned int CHAR_ASCII_DIGIT_9 = 0x0039; ///< 9 Digit Nine. https://unicode-table.com/en/0039/
+
+// General unicodes
+constexpr unsigned int CHAR_ZWS = 0x200B; ///< Zero width space.
+
+} // namespace TextAbstraction
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_ABSTRACTION_DEFINED_CHARACTERS_H
\ No newline at end of file
diff --git a/dali/devel-api/text-abstraction/emoji-character-properties.cpp b/dali/devel-api/text-abstraction/emoji-character-properties.cpp
new file mode 100644 (file)
index 0000000..c6c8f99
--- /dev/null
@@ -0,0 +1,469 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+// FILE HEADER
+#include <dali/devel-api/text-abstraction/emoji-character-properties.h>
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+namespace
+{
+//Emoji Variation Sequences for UTS #51: https://www.unicode.org/Public/14.0.0/ucd/emoji/emoji-variation-sequences.txt
+//emoji-variation-sequences-14.0.0.txt
+std::set<unsigned int> SET_CHAR_EMOJI_VARIATION_SEQUENCES = {
+  0x002A,  //  #(1.1)ASTERISK
+  0x0030,  //  #(1.1)DIGITZERO
+  0x0031,  //  #(1.1)DIGITONE
+  0x0032,  //  #(1.1)DIGITTWO
+  0x0033,  //  #(1.1)DIGITTHREE
+  0x0034,  //  #(1.1)DIGITFOUR
+  0x0035,  //  #(1.1)DIGITFIVE
+  0x0036,  //  #(1.1)DIGITSIX
+  0x0037,  //  #(1.1)DIGITSEVEN
+  0x0038,  //  #(1.1)DIGITEIGHT
+  0x0039,  //  #(1.1)DIGITNINE
+  0x00A9,  //  #(1.1)COPYRIGHTSIGN
+  0x00AE,  //  #(1.1)REGISTEREDSIGN
+  0x203C,  //  #(1.1)DOUBLEEXCLAMATIONMARK
+  0x2049,  //  #(3.0)EXCLAMATIONQUESTIONMARK
+  0x2122,  //  #(1.1)TRADEMARKSIGN
+  0x2139,  //  #(3.0)INFORMATIONSOURCE
+  0x2194,  //  #(1.1)LEFTRIGHTARROW
+  0x2195,  //  #(1.1)UPDOWNARROW
+  0x2196,  //  #(1.1)NORTHWESTARROW
+  0x2197,  //  #(1.1)NORTHEASTARROW
+  0x2198,  //  #(1.1)SOUTHEASTARROW
+  0x2199,  //  #(1.1)SOUTHWESTARROW
+  0x21A9,  //  #(1.1)LEFTWARDSARROWWITHHOOK
+  0x21AA,  //  #(1.1)RIGHTWARDSARROWWITHHOOK
+  0x231A,  //  #(1.1)WATCH
+  0x231B,  //  #(1.1)HOURGLASS
+  0x2328,  //  #(1.1)KEYBOARD
+  0x23CF,  //  #(4.0)EJECTSYMBOL
+  0x23E9,  //  #(6.0)BLACKRIGHT-POINTINGDOUBLETRIANGLE
+  0x23EA,  //  #(6.0)BLACKLEFT-POINTINGDOUBLETRIANGLE
+  0x23ED,  //  #(6.0)BLACKRIGHT-POINTINGDOUBLETRIANGLEWITHVERTICALBAR
+  0x23EE,  //  #(6.0)BLACKLEFT-POINTINGDOUBLETRIANGLEWITHVERTICALBAR
+  0x23EF,  //  #(6.0)BLACKRIGHT-POINTINGTRIANGLEWITHDOUBLEVERTICALBAR
+  0x23F1,  //  #(6.0)STOPWATCH
+  0x23F2,  //  #(6.0)TIMERCLOCK
+  0x23F3,  //  #(6.0)HOURGLASSWITHFLOWINGSAND
+  0x23F8,  //  #(7.0)DOUBLEVERTICALBAR
+  0x23F9,  //  #(7.0)BLACKSQUAREFORSTOP
+  0x23FA,  //  #(7.0)BLACKCIRCLEFORRECORD
+  0x24C2,  //  #(1.1)CIRCLEDLATINCAPITALLETTERM
+  0x25AA,  //  #(1.1)BLACKSMALLSQUARE
+  0x25AB,  //  #(1.1)WHITESMALLSQUARE
+  0x25B6,  //  #(1.1)BLACKRIGHT-POINTINGTRIANGLE
+  0x25C0,  //  #(1.1)BLACKLEFT-POINTINGTRIANGLE
+  0x25FB,  //  #(3.2)WHITEMEDIUMSQUARE
+  0x25FC,  //  #(3.2)BLACKMEDIUMSQUARE
+  0x25FD,  //  #(3.2)WHITEMEDIUMSMALLSQUARE
+  0x25FE,  //  #(3.2)BLACKMEDIUMSMALLSQUARE
+  0x2600,  //  #(1.1)BLACKSUNWITHRAYS
+  0x2601,  //  #(1.1)CLOUD
+  0x2602,  //  #(1.1)UMBRELLA
+  0x2603,  //  #(1.1)SNOWMAN
+  0x2604,  //  #(1.1)COMET
+  0x260E,  //  #(1.1)BLACKTELEPHONE
+  0x2611,  //  #(1.1)BALLOTBOXWITHCHECK
+  0x2614,  //  #(4.0)UMBRELLAWITHRAINDROPS
+  0x2615,  //  #(4.0)HOTBEVERAGE
+  0x2618,  //  #(4.1)SHAMROCK
+  0x261D,  //  #(1.1)WHITEUPPOINTINGINDEX
+  0x2620,  //  #(1.1)SKULLANDCROSSBONES
+  0x2622,  //  #(1.1)RADIOACTIVESIGN
+  0x2623,  //  #(1.1)BIOHAZARDSIGN
+  0x2626,  //  #(1.1)ORTHODOXCROSS
+  0x262A,  //  #(1.1)STARANDCRESCENT
+  0x262E,  //  #(1.1)PEACESYMBOL
+  0x262F,  //  #(1.1)YINYANG
+  0x2638,  //  #(1.1)WHEELOFDHARMA
+  0x2639,  //  #(1.1)WHITEFROWNINGFACE
+  0x263A,  //  #(1.1)WHITESMILINGFACE
+  0x2640,  //  #(1.1)FEMALESIGN
+  0x2642,  //  #(1.1)MALESIGN
+  0x2648,  //  #(1.1)ARIES
+  0x2649,  //  #(1.1)TAURUS
+  0x264A,  //  #(1.1)GEMINI
+  0x264B,  //  #(1.1)CANCER
+  0x264C,  //  #(1.1)LEO
+  0x264D,  //  #(1.1)VIRGO
+  0x264E,  //  #(1.1)LIBRA
+  0x264F,  //  #(1.1)SCORPIUS
+  0x2650,  //  #(1.1)SAGITTARIUS
+  0x2651,  //  #(1.1)CAPRICORN
+  0x2652,  //  #(1.1)AQUARIUS
+  0x2653,  //  #(1.1)PISCES
+  0x265F,  //  #(1.1)BLACKCHESSPAWN
+  0x2660,  //  #(1.1)BLACKSPADESUIT
+  0x2663,  //  #(1.1)BLACKCLUBSUIT
+  0x2665,  //  #(1.1)BLACKHEARTSUIT
+  0x2666,  //  #(1.1)BLACKDIAMONDSUIT
+  0x2668,  //  #(1.1)HOTSPRINGS
+  0x267B,  //  #(3.2)BLACKUNIVERSALRECYCLINGSYMBOL
+  0x267E,  //  #(4.1)PERMANENTPAPERSIGN
+  0x267F,  //  #(4.1)WHEELCHAIRSYMBOL
+  0x2692,  //  #(4.1)HAMMERANDPICK
+  0x2693,  //  #(4.1)ANCHOR
+  0x2694,  //  #(4.1)CROSSEDSWORDS
+  0x2695,  //  #(4.1)STAFFOFAESCULAPIUS
+  0x2696,  //  #(4.1)SCALES
+  0x2697,  //  #(4.1)ALEMBIC
+  0x2699,  //  #(4.1)GEAR
+  0x269B,  //  #(4.1)ATOMSYMBOL
+  0x269C,  //  #(4.1)FLEUR-DE-LIS
+  0x26A0,  //  #(4.0)WARNINGSIGN
+  0x26A1,  //  #(4.0)HIGHVOLTAGESIGN
+  0x26A7,  //  #(4.1)MALEWITHSTROKEANDMALEANDFEMALESIGN
+  0x26AA,  //  #(4.1)MEDIUMWHITECIRCLE
+  0x26AB,  //  #(4.1)MEDIUMBLACKCIRCLE
+  0x26B0,  //  #(4.1)COFFIN
+  0x26B1,  //  #(4.1)FUNERALURN
+  0x26BD,  //  #(5.2)SOCCERBALL
+  0x26BE,  //  #(5.2)BASEBALL
+  0x26C4,  //  #(5.2)SNOWMANWITHOUTSNOW
+  0x26C5,  //  #(5.2)SUNBEHINDCLOUD
+  0x26C8,  //  #(5.2)THUNDERCLOUDANDRAIN
+  0x26CF,  //  #(5.2)PICK
+  0x26D1,  //  #(5.2)HELMETWITHWHITECROSS
+  0x26D3,  //  #(5.2)CHAINS
+  0x26D4,  //  #(5.2)NOENTRY
+  0x26E9,  //  #(5.2)SHINTOSHRINE
+  0x26EA,  //  #(5.2)CHURCH
+  0x26F0,  //  #(5.2)MOUNTAIN
+  0x26F1,  //  #(5.2)UMBRELLAONGROUND
+  0x26F2,  //  #(5.2)FOUNTAIN
+  0x26F3,  //  #(5.2)FLAGINHOLE
+  0x26F4,  //  #(5.2)FERRY
+  0x26F5,  //  #(5.2)SAILBOAT
+  0x26F7,  //  #(5.2)SKIER
+  0x26F8,  //  #(5.2)ICESKATE
+  0x26F9,  //  #(5.2)PERSONWITHBALL
+  0x26FA,  //  #(5.2)TENT
+  0x26FD,  //  #(5.2)FUELPUMP
+  0x2702,  //  #(1.1)BLACKSCISSORS
+  0x2708,  //  #(1.1)AIRPLANE
+  0x2709,  //  #(1.1)ENVELOPE
+  0x270C,  //  #(1.1)VICTORYHAND
+  0x270D,  //  #(1.1)WRITINGHAND
+  0x270F,  //  #(1.1)PENCIL
+  0x2712,  //  #(1.1)BLACKNIB
+  0x2714,  //  #(1.1)HEAVYCHECKMARK
+  0x2716,  //  #(1.1)HEAVYMULTIPLICATIONX
+  0x271D,  //  #(1.1)LATINCROSS
+  0x2721,  //  #(1.1)STAROFDAVID
+  0x2733,  //  #(1.1)EIGHTSPOKEDASTERISK
+  0x2734,  //  #(1.1)EIGHTPOINTEDBLACKSTAR
+  0x2744,  //  #(1.1)SNOWFLAKE
+  0x2747,  //  #(1.1)SPARKLE
+  0x2753,  //  #(6.0)BLACKQUESTIONMARKORNAMENT
+  0x2757,  //  #(5.2)HEAVYEXCLAMATIONMARKSYMBOL
+  0x2763,  //  #(1.1)HEAVYHEARTEXCLAMATIONMARKORNAMENT
+  0x2764,  //  #(1.1)HEAVYBLACKHEART
+  0x27A1,  //  #(1.1)BLACKRIGHTWARDSARROW
+  0x2934,  //  #(3.2)ARROWPOINTINGRIGHTWARDSTHENCURVINGUPWARDS
+  0x2935,  //  #(3.2)ARROWPOINTINGRIGHTWARDSTHENCURVINGDOWNWARDS
+  0x2B05,  //  #(4.0)LEFTWARDSBLACKARROW
+  0x2B06,  //  #(4.0)UPWARDSBLACKARROW
+  0x2B07,  //  #(4.0)DOWNWARDSBLACKARROW
+  0x2B1B,  //  #(5.1)BLACKLARGESQUARE
+  0x2B1C,  //  #(5.1)WHITELARGESQUARE
+  0x2B50,  //  #(5.1)WHITEMEDIUMSTAR
+  0x2B55,  //  #(5.2)HEAVYLARGECIRCLE
+  0x3030,  //  #(1.1)WAVYDASH
+  0x303D,  //  #(3.2)PARTALTERNATIONMARK
+  0x3297,  //  #(1.1)CIRCLEDIDEOGRAPHCONGRATULATION
+  0x3299,  //  #(1.1)CIRCLEDIDEOGRAPHSECRET
+  0x1F004, //  #(5.1)MAHJONGTILEREDDRAGON
+  0x1F170, //  #(6.0)NEGATIVESQUAREDLATINCAPITALLETTERA
+  0x1F171, //  #(6.0)NEGATIVESQUAREDLATINCAPITALLETTERB
+  0x1F17E, //  #(6.0)NEGATIVESQUAREDLATINCAPITALLETTERO
+  0x1F17F, //  #(5.2)NEGATIVESQUAREDLATINCAPITALLETTERP
+  0x1F202, //  #(6.0)SQUAREDKATAKANASA
+  0x1F21A, //  #(5.2)SQUAREDCJKUNIFIEDIDEOGRAPH-7121
+  0x1F22F, //  #(5.2)SQUAREDCJKUNIFIEDIDEOGRAPH-6307
+  0x1F237, //  #(6.0)SQUAREDCJKUNIFIEDIDEOGRAPH-6708
+  0x1F30D, //  #(6.0)EARTHGLOBEEUROPE-AFRICA
+  0x1F30E, //  #(6.0)EARTHGLOBEAMERICAS
+  0x1F30F, //  #(6.0)EARTHGLOBEASIA-AUSTRALIA
+  0x1F315, //  #(6.0)FULLMOONSYMBOL
+  0x1F31C, //  #(6.0)LASTQUARTERMOONWITHFACE
+  0x1F321, //  #(7.0)THERMOMETER
+  0x1F324, //  #(7.0)WHITESUNWITHSMALLCLOUD
+  0x1F325, //  #(7.0)WHITESUNBEHINDCLOUD
+  0x1F326, //  #(7.0)WHITESUNBEHINDCLOUDWITHRAIN
+  0x1F327, //  #(7.0)CLOUDWITHRAIN
+  0x1F328, //  #(7.0)CLOUDWITHSNOW
+  0x1F329, //  #(7.0)CLOUDWITHLIGHTNING
+  0x1F32A, //  #(7.0)CLOUDWITHTORNADO
+  0x1F32B, //  #(7.0)FOG
+  0x1F32C, //  #(7.0)WINDBLOWINGFACE
+  0x1F336, //  #(7.0)HOTPEPPER
+  0x1F378, //  #(6.0)COCKTAILGLASS
+  0x1F37D, //  #(7.0)FORKANDKNIFEWITHPLATE
+  0x1F393, //  #(6.0)GRADUATIONCAP
+  0x1F396, //  #(7.0)MILITARYMEDAL
+  0x1F397, //  #(7.0)REMINDERRIBBON
+  0x1F399, //  #(7.0)STUDIOMICROPHONE
+  0x1F39A, //  #(7.0)LEVELSLIDER
+  0x1F39B, //  #(7.0)CONTROLKNOBS
+  0x1F39E, //  #(7.0)FILMFRAMES
+  0x1F39F, //  #(7.0)ADMISSIONTICKETS
+  0x1F3A7, //  #(6.0)HEADPHONE
+  0x1F3AC, //  #(6.0)CLAPPERBOARD
+  0x1F3AD, //  #(6.0)PERFORMINGARTS
+  0x1F3AE, //  #(6.0)VIDEOGAME
+  0x1F3C2, //  #(6.0)SNOWBOARDER
+  0x1F3C4, //  #(6.0)SURFER
+  0x1F3C6, //  #(6.0)TROPHY
+  0x1F3CA, //  #(6.0)SWIMMER
+  0x1F3CB, //  #(7.0)WEIGHTLIFTER
+  0x1F3CC, //  #(7.0)GOLFER
+  0x1F3CD, //  #(7.0)RACINGMOTORCYCLE
+  0x1F3CE, //  #(7.0)RACINGCAR
+  0x1F3D4, //  #(7.0)SNOWCAPPEDMOUNTAIN
+  0x1F3D5, //  #(7.0)CAMPING
+  0x1F3D6, //  #(7.0)BEACHWITHUMBRELLA
+  0x1F3D7, //  #(7.0)BUILDINGCONSTRUCTION
+  0x1F3D8, //  #(7.0)HOUSEBUILDINGS
+  0x1F3D9, //  #(7.0)CITYSCAPE
+  0x1F3DA, //  #(7.0)DERELICTHOUSEBUILDING
+  0x1F3DB, //  #(7.0)CLASSICALBUILDING
+  0x1F3DC, //  #(7.0)DESERT
+  0x1F3DD, //  #(7.0)DESERTISLAND
+  0x1F3DE, //  #(7.0)NATIONALPARK
+  0x1F3DF, //  #(7.0)STADIUM
+  0x1F3E0, //  #(6.0)HOUSEBUILDING
+  0x1F3ED, //  #(6.0)FACTORY
+  0x1F3F3, //  #(7.0)WAVINGWHITEFLAG
+  0x1F3F5, //  #(7.0)ROSETTE
+  0x1F3F7, //  #(7.0)LABEL
+  0x1F408, //  #(6.0)CAT
+  0x1F415, //  #(6.0)DOG
+  0x1F41F, //  #(6.0)FISH
+  0x1F426, //  #(6.0)BIRD
+  0x1F43F, //  #(7.0)CHIPMUNK
+  0x1F441, //  #(7.0)EYE
+  0x1F442, //  #(6.0)EAR
+  0x1F446, //  #(6.0)WHITEUPPOINTINGBACKHANDINDEX
+  0x1F447, //  #(6.0)WHITEDOWNPOINTINGBACKHANDINDEX
+  0x1F448, //  #(6.0)WHITELEFTPOINTINGBACKHANDINDEX
+  0x1F449, //  #(6.0)WHITERIGHTPOINTINGBACKHANDINDEX
+  0x1F44D, //  #(6.0)THUMBSUPSIGN
+  0x1F44E, //  #(6.0)THUMBSDOWNSIGN
+  0x1F453, //  #(6.0)EYEGLASSES
+  0x1F46A, //  #(6.0)FAMILY
+  0x1F47D, //  #(6.0)EXTRATERRESTRIALALIEN
+  0x1F4A3, //  #(6.0)BOMB
+  0x1F4B0, //  #(6.0)MONEYBAG
+  0x1F4B3, //  #(6.0)CREDITCARD
+  0x1F4BB, //  #(6.0)PERSONALCOMPUTER
+  0x1F4BF, //  #(6.0)OPTICALDISC
+  0x1F4CB, //  #(6.0)CLIPBOARD
+  0x1F4DA, //  #(6.0)BOOKS
+  0x1F4DF, //  #(6.0)PAGER
+  0x1F4E4, //  #(6.0)OUTBOXTRAY
+  0x1F4E5, //  #(6.0)INBOXTRAY
+  0x1F4E6, //  #(6.0)PACKAGE
+  0x1F4EA, //  #(6.0)CLOSEDMAILBOXWITHLOWEREDFLAG
+  0x1F4EB, //  #(6.0)CLOSEDMAILBOXWITHRAISEDFLAG
+  0x1F4EC, //  #(6.0)OPENMAILBOXWITHRAISEDFLAG
+  0x1F4ED, //  #(6.0)OPENMAILBOXWITHLOWEREDFLAG
+  0x1F4F7, //  #(6.0)CAMERA
+  0x1F4F9, //  #(6.0)VIDEOCAMERA
+  0x1F4FA, //  #(6.0)TELEVISION
+  0x1F4FB, //  #(6.0)RADIO
+  0x1F4FD, //  #(7.0)FILMPROJECTOR
+  0x1F508, //  #(6.0)SPEAKER
+  0x1F50D, //  #(6.0)LEFT-POINTINGMAGNIFYINGGLASS
+  0x1F512, //  #(6.0)LOCK
+  0x1F513, //  #(6.0)OPENLOCK
+  0x1F549, //  #(7.0)OMSYMBOL
+  0x1F54A, //  #(7.0)DOVEOFPEACE
+  0x1F550, //  #(6.0)CLOCKFACEONEOCLOCK
+  0x1F551, //  #(6.0)CLOCKFACETWOOCLOCK
+  0x1F552, //  #(6.0)CLOCKFACETHREEOCLOCK
+  0x1F553, //  #(6.0)CLOCKFACEFOUROCLOCK
+  0x1F554, //  #(6.0)CLOCKFACEFIVEOCLOCK
+  0x1F555, //  #(6.0)CLOCKFACESIXOCLOCK
+  0x1F556, //  #(6.0)CLOCKFACESEVENOCLOCK
+  0x1F557, //  #(6.0)CLOCKFACEEIGHTOCLOCK
+  0x1F558, //  #(6.0)CLOCKFACENINEOCLOCK
+  0x1F559, //  #(6.0)CLOCKFACETENOCLOCK
+  0x1F55A, //  #(6.0)CLOCKFACEELEVENOCLOCK
+  0x1F55B, //  #(6.0)CLOCKFACETWELVEOCLOCK
+  0x1F55C, //  #(6.0)CLOCKFACEONE-THIRTY
+  0x1F55D, //  #(6.0)CLOCKFACETWO-THIRTY
+  0x1F55E, //  #(6.0)CLOCKFACETHREE-THIRTY
+  0x1F55F, //  #(6.0)CLOCKFACEFOUR-THIRTY
+  0x1F560, //  #(6.0)CLOCKFACEFIVE-THIRTY
+  0x1F561, //  #(6.0)CLOCKFACESIX-THIRTY
+  0x1F562, //  #(6.0)CLOCKFACESEVEN-THIRTY
+  0x1F563, //  #(6.0)CLOCKFACEEIGHT-THIRTY
+  0x1F564, //  #(6.0)CLOCKFACENINE-THIRTY
+  0x1F565, //  #(6.0)CLOCKFACETEN-THIRTY
+  0x1F566, //  #(6.0)CLOCKFACEELEVEN-THIRTY
+  0x1F567, //  #(6.0)CLOCKFACETWELVE-THIRTY
+  0x1F56F, //  #(7.0)CANDLE
+  0x1F570, //  #(7.0)MANTELPIECECLOCK
+  0x1F573, //  #(7.0)HOLE
+  0x1F574, //  #(7.0)MANINBUSINESSSUITLEVITATING
+  0x1F575, //  #(7.0)SLEUTHORSPY
+  0x1F576, //  #(7.0)DARKSUNGLASSES
+  0x1F577, //  #(7.0)SPIDER
+  0x1F578, //  #(7.0)SPIDERWEB
+  0x1F579, //  #(7.0)JOYSTICK
+  0x1F587, //  #(7.0)LINKEDPAPERCLIPS
+  0x1F58A, //  #(7.0)LOWERLEFTBALLPOINTPEN
+  0x1F58B, //  #(7.0)LOWERLEFTFOUNTAINPEN
+  0x1F58C, //  #(7.0)LOWERLEFTPAINTBRUSH
+  0x1F58D, //  #(7.0)LOWERLEFTCRAYON
+  0x1F590, //  #(7.0)RAISEDHANDWITHFINGERSSPLAYED
+  0x1F5A5, //  #(7.0)DESKTOPCOMPUTER
+  0x1F5A8, //  #(7.0)PRINTER
+  0x1F5B1, //  #(7.0)THREEBUTTONMOUSE
+  0x1F5B2, //  #(7.0)TRACKBALL
+  0x1F5BC, //  #(7.0)FRAMEWITHPICTURE
+  0x1F5C2, //  #(7.0)CARDINDEXDIVIDERS
+  0x1F5C3, //  #(7.0)CARDFILEBOX
+  0x1F5C4, //  #(7.0)FILECABINET
+  0x1F5D1, //  #(7.0)WASTEBASKET
+  0x1F5D2, //  #(7.0)SPIRALNOTEPAD
+  0x1F5D3, //  #(7.0)SPIRALCALENDARPAD
+  0x1F5DC, //  #(7.0)COMPRESSION
+  0x1F5DD, //  #(7.0)OLDKEY
+  0x1F5DE, //  #(7.0)ROLLED-UPNEWSPAPER
+  0x1F5E1, //  #(7.0)DAGGERKNIFE
+  0x1F5E3, //  #(7.0)SPEAKINGHEADINSILHOUETTE
+  0x1F5E8, //  #(7.0)LEFTSPEECHBUBBLE
+  0x1F5EF, //  #(7.0)RIGHTANGERBUBBLE
+  0x1F5F3, //  #(7.0)BALLOTBOXWITHBALLOT
+  0x1F5FA, //  #(7.0)WORLDMAP
+  0x1F610, //  #(6.0)NEUTRALFACE
+  0x1F687, //  #(6.0)METRO
+  0x1F68D, //  #(6.0)ONCOMINGBUS
+  0x1F691, //  #(6.0)AMBULANCE
+  0x1F694, //  #(6.0)ONCOMINGPOLICECAR
+  0x1F698, //  #(6.0)ONCOMINGAUTOMOBILE
+  0x1F6AD, //  #(6.0)NOSMOKINGSYMBOL
+  0x1F6B2, //  #(6.0)BICYCLE
+  0x1F6B9, //  #(6.0)MENSSYMBOL
+  0x1F6BA, //  #(6.0)WOMENSSYMBOL
+  0x1F6BC, //  #(6.0)BABYSYMBOL
+  0x1F6CB, //  #(7.0)COUCHANDLAMP
+  0x1F6CD, //  #(7.0)SHOPPINGBAGS
+  0x1F6CE, //  #(7.0)BELLHOPBELL
+  0x1F6CF, //  #(7.0)BED
+  0x1F6E0, //  #(7.0)HAMMERANDWRENCH
+  0x1F6E1, //  #(7.0)SHIELD
+  0x1F6E2, //  #(7.0)OILDRUM
+  0x1F6E3, //  #(7.0)MOTORWAY
+  0x1F6E4, //  #(7.0)RAILWAYTRACK
+  0x1F6E5, //  #(7.0)MOTORBOAT
+  0x1F6E9, //  #(7.0)SMALLAIRPLANE
+  0x1F6F0, //  #(7.0)SATELLITE
+  0x1F6F3, //  #(7.0)PASSENGERSHIP
+};
+
+} // namespace
+//TODO: find/create library or API to check emoji properties. OR parse file https://www.unicode.org/Public/14.0.0/ucd/emoji/emoji-data.txt then call the below APIs
+
+DALI_ADAPTOR_API bool IsEmojiComponent(Character character)
+{
+  return (TextAbstraction::CHAR_EMOJI_COMPONENT_BALD == character ||
+          TextAbstraction::CHAR_EMOJI_COMPONENT_RED_HAIR == character ||
+          TextAbstraction::CHAR_EMOJI_COMPONENT_CURLY_HAIR == character ||
+          TextAbstraction::CHAR_EMOJI_COMPONENT_WHITE_HAIR == character);
+}
+
+DALI_ADAPTOR_API bool IsEmojiModifier(Character character)
+{
+  return (TextAbstraction::CHAR_EMOJI_MODIFIER_FITZPATRICK_TYPE_1_2 <= character &&
+          TextAbstraction::CHAR_EMOJI_MODIFIER_FITZPATRICK_TYPE_6 >= character);
+}
+
+DALI_ADAPTOR_API bool IsCombiningEnclosingKeycap(Character character)
+{
+  return (TextAbstraction::CHAR_COMBINING_ENCLOSING_KEYCAP == character);
+}
+
+DALI_ADAPTOR_API bool IsRegionalIndicator(Character character)
+{
+  return (TextAbstraction::CHAR_REGIONAL_INDICATOR_SYMBOL_LETTER_A <= character &&
+          TextAbstraction::CHAR_REGIONAL_INDICATOR_SYMBOL_LETTER_Z >= character);
+}
+
+DALI_ADAPTOR_API bool IsTextPresentationSelector(Character character)
+{
+  return (TextAbstraction::CHAR_VARIATION_SELECTOR_15 == character);
+}
+
+DALI_ADAPTOR_API bool IsEmojiPresentationSelector(Character character)
+{
+  return (TextAbstraction::CHAR_VARIATION_SELECTOR_16 == character);
+}
+
+DALI_ADAPTOR_API bool IsTagSpec(Character character)
+{
+  return (TextAbstraction::CHAR_TAG_SPACE <= character &&
+          TextAbstraction::CHAR_TAG_TILDE >= character);
+}
+
+DALI_ADAPTOR_API bool IsTagEnd(Character character)
+{
+  return (TextAbstraction::CHAR_CANCEL_TAG == character);
+}
+
+DALI_ADAPTOR_API bool IsEmojiItem(Character character)
+{
+  return (IsEmojiComponent(character) ||
+          IsEmojiModifier(character) ||
+          IsTextPresentationSelector(character) ||
+          IsEmojiPresentationSelector(character) ||
+          IsTagSpec(character) ||
+          IsTagEnd(character));
+}
+
+DALI_ADAPTOR_API bool IsMiscellaneousSymbolsAndArrowsEmoji(Character character)
+{
+  return (CHAR_NORTH_EAST_WHITE_ARROW <= character &&
+          CHAR_HELLSCHREIBER_PAUSE_SYMBOL >= character);
+}
+
+DALI_ADAPTOR_API bool IsDingbatsEmoji(Character character)
+{
+  return (CHAR_BLACK_SAFETY_SCISSORS <= character &&
+          CHAR_DOUBLE_CURLY_LOOP_EMOJI >= character);
+}
+
+DALI_ADAPTOR_API bool IsASCIIDigits(Character character)
+{
+  return (CHAR_ASCII_DIGIT_0 <= character &&
+          CHAR_ASCII_DIGIT_9 >= character);
+}
+
+DALI_ADAPTOR_API bool IsEmojiVariationSequences(Character character)
+{
+  return SET_CHAR_EMOJI_VARIATION_SEQUENCES.find(character) != SET_CHAR_EMOJI_VARIATION_SEQUENCES.end();
+}
+
+} // namespace TextAbstraction
+
+} // namespace Dali
diff --git a/dali/devel-api/text-abstraction/emoji-character-properties.h b/dali/devel-api/text-abstraction/emoji-character-properties.h
new file mode 100644 (file)
index 0000000..13287e3
--- /dev/null
@@ -0,0 +1,190 @@
+#ifndef DALI_TOOLKIT_TEXT_ABSTRACTION_EMOJI_CHARACTER_PROPERTIES_H
+#define DALI_TOOLKIT_TEXT_ABSTRACTION_EMOJI_CHARACTER_PROPERTIES_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <set>
+// INTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/defined-characters.h>
+#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
+#include <dali/public-api/dali-adaptor-common.h>
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+/**
+ * @brief Whether the character is emoji-component | emoji-modifier | COMBINING-ENCLOSING-KEYCAP | regional-indicator | TextPresentationSelector | EmojiPresentationSelector | TagSpec | TagEnd.
+ *
+ * @param[in] character The character
+ *
+ * @return @e true if the character  is emoji-component | emoji-modifier | COMBINING-ENCLOSING-KEYCAP | regional-indicator | TextPresentationSelector | EmojiPresentationSelector | TagSpec | TagEnd.
+ */
+DALI_ADAPTOR_API bool IsEmojiItem(Character character);
+
+/**
+ * @brief Whether the character is emoji component.
+ * Emoji Properties and Data Files: https://www.unicode.org/reports/tr51/#Emoji_Properties_and_Data_Files
+ *
+ * @note True for characters used in emoji sequences that normally do not appear on emoji keyboards as separate choices, such as keycap base characters or Regional_Indicator characters.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is emoji component.
+ */
+DALI_ADAPTOR_API bool IsEmojiComponent(Character character);
+
+/**
+ * @brief Whether the character is emoji modifier.
+ * Emoji Properties and Data Files: https://www.unicode.org/reports/tr51/#Emoji_Properties_and_Data_Files
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is emoji modifier.
+ */
+DALI_ADAPTOR_API bool IsEmojiModifier(Character character);
+
+/**
+ * @brief Whether the character is COMBINING ENCLOSING KEYCAP.
+ * Combining Enclosing Keycap: https://emojipedia.org/combining-enclosing-keycap/
+ *
+ * @note The Codepoint of COMBINING ENCLOSING KEYCAP is {U+20E3}
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is COMBINING ENCLOSING KEYCAP.
+ */
+DALI_ADAPTOR_API bool IsCombiningEnclosingKeycap(Character character);
+
+/**
+ * @brief Whether the character is Regional Indicator.
+ * Regional Indicator Symbol Letter A: https://emojipedia.org/regional-indicator-symbol-letter-a/
+ * Regional Indicator Symbol Letter Z: https://emojipedia.org/regional-indicator-symbol-letter-z/
+ *
+ * @note The Codepoints of Regional Indicator Symbol Letters [A-Z] are [U+1F1E6 - U+1F1FF]
+ *
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is Regional Indicator.
+ */
+DALI_ADAPTOR_API bool IsRegionalIndicator(Character character);
+
+/**
+ * @brief Whether the character is text presentation selector (VARIATION SELECTOR-15).
+ * Text Presentation Selector: https://www.unicode.org/reports/tr51/#def_text_presentation_selector
+ *
+ * @note The character U+FE0E VARIATION SELECTOR-15 (VS15), used to request a text presentation for an emoji character. Also known as text variation selector.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is text presentation selector (VARIATION SELECTOR-15).
+ */
+DALI_ADAPTOR_API bool IsTextPresentationSelector(Character character);
+
+/**
+ * @brief Whether the character is emoji variation selector (VARIATION SELECTOR-16).
+ * Emoji Presentation Selector: https://www.unicode.org/reports/tr51/#def_emoji_presentation_selector
+ *
+ * @note The character U+FE0F VARIATION SELECTOR-16 (VS16), used to request an emoji presentation for an emoji character. Also known as emoji variation selector.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is emoji presentation selector (VARIATION SELECTOR-16).
+ */
+DALI_ADAPTOR_API bool IsEmojiPresentationSelector(Character character);
+
+/**
+ * @brief Whether the character is tag spec.
+ * Emoji Tag Sequence (ETS): https://www.unicode.org/reports/tr51/#def_emoji_tag_sequence
+ *
+ * @note The tag_spec consists of all characters from U+E0020 TAG SPACE to U+E007E TAG TILDE.
+ * Each tag_spec defines a particular visual variant to be applied to the tag_base character(s).
+ * Though tag_spec includes the values U+E0041 TAG LATIN CAPITAL LETTER A .. U+E005A TAG LATIN CAPITAL LETTER Z,
+ * they are not used currently and are reserved for future extensions.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is tag spec.
+ */
+DALI_ADAPTOR_API bool IsTagSpec(Character character);
+
+/**
+ * @brief Whether the character is tag end.
+ * Emoji Tag Sequence (ETS): https://www.unicode.org/reports/tr51/#def_emoji_tag_sequence
+ *
+ * @note The tag_end consists of the character U+E007F CANCEL TAG, and must be used to terminate the tag sequence.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is tag end.
+ */
+DALI_ADAPTOR_API bool IsTagEnd(Character character);
+
+/**
+ * @brief Whether the character is Miscellaneous Symbols and Arrows emoji.
+ * Miscellaneous Symbols and Arrows emoji: https://unicode-table.com/en/blocks/miscellaneous-symbols-and-arrows/
+ *
+ * @note The Range is 2B00—2BFF and the quantity of characters is 256.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is Miscellaneous Symbols and Arrows emoji.
+ */
+DALI_ADAPTOR_API bool IsMiscellaneousSymbolsAndArrowsEmoji(Character character);
+
+/**
+ * @brief Whether the character is Dingbats emoji.
+ * Dingbats emoji: https://unicode-table.com/en/blocks/dingbats/
+ *
+ * @note The Range is 2700—27BF and the quantity of characters is 192.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is Dingbats emoji.
+ */
+DALI_ADAPTOR_API bool IsDingbatsEmoji(Character character);
+
+/**
+ * @brief Whether the character is ASCII digits.
+ * ASCII digits: https://unicode-table.com/en/blocks/basic-latin/
+ *
+ * @note The Range is 0030—0039 and the quantity of characters is 10.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is ASCII digits.
+ */
+DALI_ADAPTOR_API bool IsASCIIDigits(Character character);
+
+/**
+ * @brief Whether the character is emoji-variation-sequences.
+ * Emoji Variation Sequences for UTS #51: https://www.unicode.org/Public/14.0.0/ucd/emoji/emoji-variation-sequences.txt
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is emoji-variation-sequences.
+ */
+DALI_ADAPTOR_API bool IsEmojiVariationSequences(Character character);
+
+} // namespace TextAbstraction
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_ABSTRACTION_EMOJI_CHARACTER_PROPERTIES_H
\ No newline at end of file
diff --git a/dali/devel-api/text-abstraction/emoji-helper.cpp b/dali/devel-api/text-abstraction/emoji-helper.cpp
new file mode 100644 (file)
index 0000000..a86572f
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+// FILE HEADER
+#include <dali/devel-api/text-abstraction/emoji-helper.h>
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+DALI_ADAPTOR_API bool IsSymbolScript(const TextAbstraction::Script& script)
+{
+  return (TextAbstraction::SYMBOLS1 == script ||
+          TextAbstraction::SYMBOLS2 == script ||
+          TextAbstraction::SYMBOLS3 == script ||
+          TextAbstraction::SYMBOLS4 == script ||
+          TextAbstraction::SYMBOLS5 == script);
+}
+
+DALI_ADAPTOR_API bool IsEmojiScript(const TextAbstraction::Script& script)
+{
+  return (TextAbstraction::EMOJI == script);
+}
+
+DALI_ADAPTOR_API bool IsEmojiTextScript(const TextAbstraction::Script& script)
+{
+  return (TextAbstraction::EMOJI_TEXT == script);
+}
+
+DALI_ADAPTOR_API bool IsEmojiColorScript(const TextAbstraction::Script& script)
+{
+  return (TextAbstraction::EMOJI_COLOR == script);
+}
+
+DALI_ADAPTOR_API bool IsOneOfEmojiScripts(const TextAbstraction::Script& script)
+{
+  return (IsEmojiScript(script) || IsEmojiColorScript(script) || IsEmojiTextScript(script));
+}
+
+DALI_ADAPTOR_API bool IsSymbolOrEmojiScript(const TextAbstraction::Script& script)
+{
+  return (IsEmojiScript(script) || IsSymbolScript(script));
+}
+
+DALI_ADAPTOR_API bool IsSymbolOrEmojiOrTextScript(const TextAbstraction::Script& script)
+{
+  return (IsSymbolScript(script) || IsOneOfEmojiScripts(script));
+}
+
+DALI_ADAPTOR_API Character GetUnicodeForInvisibleGlyph()
+{
+  return TextAbstraction::CHAR_ZWS;
+}
+
+} // namespace TextAbstraction
+
+} // namespace Dali
\ No newline at end of file
diff --git a/dali/devel-api/text-abstraction/emoji-helper.h b/dali/devel-api/text-abstraction/emoji-helper.h
new file mode 100644 (file)
index 0000000..26e2e0b
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef DALI_TOOLKIT_TEXT_ABSTRACTION_EMOJI_HELPER_H
+#define DALI_TOOLKIT_TEXT_ABSTRACTION_EMOJI_HELPER_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/script.h>
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+/**
+ * @brief Whether the script is symbol.
+ *
+ * @note Check whether the script is in [SYMBOLS1, SYMBOLS2, SYMBOLS3, SYMBOLS4, SYMBOLS5]
+ *
+ * @param[in] script The script.
+ *
+ * @return @e true if the script is symbol.
+ */
+DALI_ADAPTOR_API bool IsSymbolScript(const TextAbstraction::Script& script);
+
+/**
+ * @brief Whether the script is EMOJI.
+ *
+ * @param[in] script The script.
+ *
+ * @return @e true if the script is EMOJI.
+ */
+DALI_ADAPTOR_API bool IsEmojiScript(const TextAbstraction::Script& script);
+
+/**
+ * @brief Whether the script is EMOJI_TEXT.
+ *
+ * @param[in] script The script.
+ *
+ * @return @e true if the script is EMOJI_TEXT.
+ */
+DALI_ADAPTOR_API bool IsEmojiTextScript(const TextAbstraction::Script& script);
+
+/**
+ * @brief Whether the script is EMOJI_COLOR.
+ *
+ * @param[in] script The script.
+ *
+ * @return @e true if the script is EMOJI_COLOR.
+ */
+DALI_ADAPTOR_API bool IsEmojiColorScript(const TextAbstraction::Script& script);
+
+/**
+ * @brief Whether the script is symbol or emoji.
+ *
+ * @note At least one of IsSymbol and IsEmoji is true.
+ *
+ * @param[in] script The script.
+ *
+ * @return @e true if the script is symbol or emoji.
+ */
+DALI_ADAPTOR_API bool IsSymbolOrEmojiScript(const TextAbstraction::Script& script);
+
+/**
+ * @brief Whether the script is SYMBOL | EMOJI | TEXT.
+ *
+ * @note At least one of IsSymbol and IsEmoji and IsText is true.
+ *
+ * @param[in] script The script.
+ *
+ * @return @e true if the script is SYMBOL | EMOJI | EMOJI_COLOR| EMOJI_TEXT.
+ */
+DALI_ADAPTOR_API bool IsSymbolOrEmojiOrTextScript(const TextAbstraction::Script& script);
+
+/**
+ * @brief Whether the script is EMOJI | EMOJI_COLOR| EMOJI_TEXT.
+ *
+ * @param[in] script The script.
+ *
+ * @return @e true if the script is EMOJI | EMOJI_COLOR| EMOJI_TEXT.
+ */
+DALI_ADAPTOR_API bool IsOneOfEmojiScripts(const TextAbstraction::Script& script);
+
+/**
+ * @brief Retrieve the unicode for invisible glyphs
+ *
+ * @note Used CHAR_ZWS it is the unicode for Zero Width Space character
+ *
+ * @return Retrieve the unicode for Zero Width Space character
+ */
+DALI_ADAPTOR_API Character GetUnicodeForInvisibleGlyph();
+
+} // namespace TextAbstraction
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_ABSTRACTION_EMOJI_HELPER_H
\ No newline at end of file
index b19fa22..7cea697 100644 (file)
@@ -215,6 +215,11 @@ GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode)
   return GetImplementation(*this).GetGlyphIndex(fontId, charcode);
 }
 
+GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode, Character variantSelector)
+{
+  return GetImplementation(*this).GetGlyphIndex(fontId, charcode, variantSelector);
+}
+
 bool FontClient::GetGlyphMetrics(GlyphInfo* array, uint32_t size, GlyphType type, bool horizontal)
 {
   return GetImplementation(*this).GetGlyphMetrics(array, size, type, horizontal);
index b1d6317..992f8aa 100644 (file)
@@ -385,6 +385,17 @@ public:
   GlyphIndex GetGlyphIndex(FontId fontId, Character charcode);
 
   /**
+   * @brief Return the glyph index of a given character code as modified by the variation selector.
+   *
+   * @param[in] fontId The identifier of the font for the required glyph.
+   * @param[in] charcode The UTF-32 character code.
+   * @param[in] variantSelector The UTF-32 character code point of the variation selector.
+   *
+   * @return The glyph index, or zero if the character code is undefined.
+   */
+  GlyphIndex GetGlyphIndex(FontId fontId, Character charcode, Character variantSelector);
+
+  /**
    * @brief Retrieve the metrics for a series of glyphs.
    *
    * @param[in,out] array An array of glyph-info structures with initialized FontId & GlyphIndex values.
index 62dfaa9..1a5b742 100644 (file)
@@ -24,6 +24,7 @@ namespace TextAbstraction
 {
 namespace
 {
+//TODO: Move the below defined characters to "defined-characters.h"
 constexpr unsigned int WHITE_SPACE_THRESHOLD = 0x21;   ///< All characters below 0x21 are considered white spaces.
 constexpr unsigned int CHAR_LF               = 0x000A; ///< NL Line feed, new line.
 constexpr unsigned int CHAR_VT               = 0x000B; ///< Vertical tab.
@@ -33,7 +34,6 @@ constexpr unsigned int CHAR_NEL              = 0x0085; ///< Next line.
 constexpr unsigned int CHAR_LS               = 0x2028; ///< Line separator.
 constexpr unsigned int CHAR_PS               = 0x2029; ///< Paragraph separator
 
-constexpr unsigned int CHAR_ZWS  = 0x200B; ///< Zero width space.
 constexpr unsigned int CHAR_ZWNJ = 0x200C; ///< Zero width non joiner.
 constexpr unsigned int CHAR_ZWJ  = 0x200D; ///< Zero width joiner.
 constexpr unsigned int CHAR_LTRM = 0x200E; ///< Left to Right Mark.
@@ -941,7 +941,11 @@ Script GetCharacterScript(Character character)
 {
   Script script = UNKNOWN;
 
-  if(IsCommonScript(character))
+  if(IsEmojiItem(character))
+  {
+    script = EMOJI;
+  }
+  else if(IsCommonScript(character))
   {
     script = COMMON;
   }
@@ -1035,6 +1039,11 @@ bool HasLigatureMustBreak(Script script)
           (ARABIC == script));
 }
 
+Length GetNumberOfScripts()
+{
+  return EMOJI_COLOR + 1;
+}
+
 } // namespace TextAbstraction
 
 } // namespace Dali
index d63e267..ab22ac7 100644 (file)
  */
 
 // INTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/emoji-character-properties.h>
 #include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
 #include <dali/public-api/dali-adaptor-common.h>
+#include <sys/types.h>
 
 namespace Dali
 {
@@ -100,7 +102,11 @@ enum Script
   SYMBOLS4, ///< Some symbols.
   SYMBOLS5, ///< Some symbols.
 
-  UNKNOWN ///< The script is unknown.
+  UNKNOWN,    ///< The script is unknown.
+  EMOJI_TEXT, ///< The Emoji request a text presentation for an emoji character.
+  EMOJI_COLOR ///< The Emoji request a color-emoji presentation for an emoji character.
+
+  //Note: update ScriptName and GetNumberOfScripts when adding new script
 };
 
 const char* const ScriptName[] =
@@ -173,7 +179,9 @@ const char* const ScriptName[] =
     "SYMBOLS4", ///< Some symbols.
     "SYMBOLS5", ///< Some symbols.
 
-    "UNKNOWN" ///< The script is unknown.
+    "UNKNOWN",    ///< The script is unknown.
+    "EMOJI_TEXT", ///< The Emoji request a text presentation for an emoji character.
+    "EMOJI_COLOR" ///< The Emoji request a color-emoji presentation for an emoji character.
 };
 
 /**
@@ -286,6 +294,14 @@ DALI_ADAPTOR_API bool IsCommonScript(Character character);
  * @return @e true if the script has ligatures that must be 'broken'.
  */
 DALI_ADAPTOR_API bool HasLigatureMustBreak(Script script);
+
+/**
+ * @brief Get the number of elements in enum Script
+ *
+ * @return returns the number of Scripts
+ */
+DALI_ADAPTOR_API Length GetNumberOfScripts();
+
 } // namespace TextAbstraction
 
 } // namespace Dali
index 39eb0ca..8dd7053 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 // INTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/emoji-helper.h>
 #include <dali/devel-api/text-abstraction/script.h>
 #include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
 
index 70678ca..2b5c40a 100644 (file)
@@ -284,6 +284,13 @@ GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode)
   return mPlugin->GetGlyphIndex(fontId, charcode);
 }
 
+GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode, Character variantSelector)
+{
+  CreatePlugin();
+
+  return mPlugin->GetGlyphIndex(fontId, charcode, variantSelector);
+}
+
 bool FontClient::GetGlyphMetrics(GlyphInfo* array, uint32_t size, GlyphType type, bool horizontal)
 {
   CreatePlugin();
index 80abee5..ffa070a 100644 (file)
@@ -184,6 +184,11 @@ public:
   GlyphIndex GetGlyphIndex(FontId fontId, Character charcode);
 
   /**
+   * @copydoc Dali::TextAbstraction::FontClient::GetGlyphIndex()
+   */
+  GlyphIndex GetGlyphIndex(FontId fontId, Character charcode, Character variantSelector);
+
+  /**
    * @copydoc Dali::TextAbstraction::FontClient::GetGlyphMetrics()
    */
   bool GetGlyphMetrics(GlyphInfo* array, uint32_t size, GlyphType type, bool horizontal);
index d8f083c..501f56e 100644 (file)
@@ -86,6 +86,14 @@ struct BitmapFontCacheItem : public FontCacheItemInterface
   }
 
   /**
+   * @copydoc FontCacheItemInterface::GetGlyphIndex()
+   */
+  GlyphIndex GetGlyphIndex(Character character, Character variantSelector) const override
+  {
+    return 0u;
+  }
+
+  /**
    * @copydoc FontCacheItemInterface::GetTypeface()
    */
   FT_Face GetTypeface() const override
index 805719b..09addd2 100644 (file)
@@ -82,6 +82,15 @@ struct FontCacheItemInterface
   virtual GlyphIndex GetGlyphIndex(Character character) const = 0;
 
   /**
+   * Get the index into this font's glyph table of the character
+   *
+   * @param[in] character to look up
+   * @param[in] variantSelector the variation selector modify character code
+   * @return the glyph index of this character
+   */
+  virtual GlyphIndex GetGlyphIndex(Character character, Character variantSelector) const = 0;
+
+  /**
    * Get the freetype typeface for this font.
    */
   virtual FT_Face GetTypeface() const = 0;
index e438a53..40d3f32 100644 (file)
@@ -1000,6 +1000,19 @@ GlyphIndex FontClient::Plugin::GetGlyphIndex(FontId    fontId,
   return 0u;
 }
 
+GlyphIndex FontClient::Plugin::GetGlyphIndex(FontId    fontId,
+                                             Character charcode,
+                                             Character variantSelector)
+{
+  const FontCacheItemInterface* fontCacheItem = GetCachedFontItem(fontId);
+  if(fontCacheItem != nullptr)
+  {
+    return fontCacheItem->GetGlyphIndex(charcode, variantSelector);
+  }
+
+  return 0u;
+}
+
 bool FontClient::Plugin::GetGlyphMetrics(GlyphInfo* array,
                                          uint32_t   size,
                                          GlyphType  type,
index 6274cdf..e6eb986 100644 (file)
@@ -286,6 +286,11 @@ struct FontClient::Plugin
   GlyphIndex GetGlyphIndex(FontId fontId, Character charcode);
 
   /**
+   * @copydoc Dali::TextAbstraction::FontClient::GetGlyphIndex()
+   */
+  GlyphIndex GetGlyphIndex(FontId fontId, Character charcode, Character variantSelector);
+
+  /**
    * @copydoc Dali::TextAbstraction::FontClient::GetGlyphMetrics()
    */
   bool GetGlyphMetrics(GlyphInfo* array, uint32_t size, GlyphType type, bool horizontal);
index 5608b03..894500e 100644 (file)
@@ -404,4 +404,9 @@ GlyphIndex FontFaceCacheItem::GetGlyphIndex(Character character) const
   return FT_Get_Char_Index(mFreeTypeFace, character);
 }
 
+GlyphIndex FontFaceCacheItem::GetGlyphIndex(Character character, Character variantSelector) const
+{
+  return FT_Face_GetCharVariantIndex(mFreeTypeFace, character, variantSelector);
+}
+
 } // namespace Dali::TextAbstraction::Internal
index 4a13d32..cf75b27 100644 (file)
@@ -96,6 +96,11 @@ struct FontFaceCacheItem : public FontCacheItemInterface
   GlyphIndex GetGlyphIndex(Character character) const override;
 
   /**
+   * @copydoc FontCacheItemInterface::GetGlyphIndex()
+   */
+  GlyphIndex GetGlyphIndex(Character character, Character variantSelector) const override;
+
+  /**
    * @copydoc FontCacheItemInterface::GetTypeface()
    */
   FT_Face GetTypeface() const override
index 31a2efa..89d6498 100644 (file)
@@ -106,13 +106,15 @@ const hb_script_t SCRIPT_TO_HARFBUZZ[] =
     HB_SCRIPT_TAGALOG,
     HB_SCRIPT_MEETEI_MAYEK,
 
-    HB_SCRIPT_UNKNOWN, // EMOJI
-    HB_SCRIPT_UNKNOWN, // SYMBOLS1
-    HB_SCRIPT_UNKNOWN, // SYMBOLS2
-    HB_SCRIPT_UNKNOWN, // SYMBOLS3
-    HB_SCRIPT_UNKNOWN, // SYMBOLS4
-    HB_SCRIPT_UNKNOWN, // SYMBOLS5
-    HB_SCRIPT_UNKNOWN};
+    HB_SCRIPT_UNKNOWN,  // EMOJI
+    HB_SCRIPT_UNKNOWN,  // SYMBOLS1
+    HB_SCRIPT_UNKNOWN,  // SYMBOLS2
+    HB_SCRIPT_UNKNOWN,  // SYMBOLS3
+    HB_SCRIPT_UNKNOWN,  // SYMBOLS4
+    HB_SCRIPT_UNKNOWN,  // SYMBOLS5
+    HB_SCRIPT_UNKNOWN,  // UNKNOWN
+    HB_SCRIPT_UNKNOWN,  // EMOJI_TEXT
+    HB_SCRIPT_UNKNOWN}; // EMOJI_COLOR
 
 struct Shaping::Plugin
 {
@@ -198,6 +200,15 @@ struct Shaping::Plugin
         /* Layout the text */
         hb_buffer_add_utf32(harfBuzzBuffer, text, numberOfCharacters, 0u, numberOfCharacters);
 
+        //The invisible unicodes like U+FE0F and U+FE0E should be replaced by zero width glyph
+        //i.e: This text "&#x262a;&#xfe0f;&#xfe0f;&#xfe0f;&#x262a;&#xfe0f;" should be rendered as two adjacent glyphs.
+        if(TextAbstraction::IsOneOfEmojiScripts(script))
+        {
+          //TODO: check if this should be applied to all scripts
+          //Applied this only on EMOJI scripts to avoid compatibility issues with other scripts
+          hb_buffer_set_invisible_glyph(harfBuzzBuffer, TextAbstraction::GetUnicodeForInvisibleGlyph());
+        }
+
         hb_shape(harfBuzzFont, harfBuzzBuffer, NULL, 0u);
 
         /* Get glyph data */