LibUnicode+LibGfx: Remove superfluous emoji metadata

For SerenityOS, we parse emoji metadata from the UCD to learn emoji
groups, subgroups, names, etc. We used this information only in the
emoji picker dialog. It is entirely unused within Ladybird.

This removes our dependence on the UCD emoji file, as we no longer
need any of its information. All we need to know is the file path to
our custom emoji, which we get from Meta/emoji-file-list.txt.
This commit is contained in:
Timothy Flynn 2024-06-21 16:30:27 -04:00 committed by Andreas Kling
parent aa3a30870b
commit 069bed5d47
Notes: sideshowbarker 2024-07-18 22:57:59 +09:00
7 changed files with 70 additions and 660 deletions

View File

@ -1,275 +0,0 @@
ZWJ Sequence Emoji (limited cross-platform support)
---------
🐱‍🐶 - U+1F431 U+200D U+1F436 CATDOG FACE
Yak Emoji (limited cross-platform support)
---------
􌴀 - U+10CD00 HAIRYAK
􌴁 - U+10CD01 IMMINENTYAKSHAVE
􌴂 - U+10CD02 SHAVEDYAK
􌴃 - U+10CD03 YAKPLUS
􌴄 - U+10CD04 YAKPING
􌴅 - U+10CD05 YAKMINUS
􌴆 - U+10CD06 YAKTANGLE
􌴇 - U+10CD07 YAKBAIT
􌴈 - U+10CD08 REYAKTED
􌴉 - U+10CD09 SLEEPYAK
􌴊 - U+10CD0A YAKBRAIN
􌴋 - U+10CD0B GOLDYAK
􌴌 - U+10CD0C YAKKING
􌴍 - U+10CD0D YAKMAIL
􌴎 - U+10CD0E YAKMAGNET
􌴏 - U+10CD0F YAKFIRE
􌴐 - U+10CD10 YAKSPLODE
􌴑 - U+10CD11 YAKSHED
􌴒 - U+10CD12 YAKFUSED
􌴓 - U+10CD13 8BITYAK
􌴔 - U+10CD14 SKELEYAK
􌴕 - U+10CD15 NEOYAK
􌴖 - U+10CD16 YAKEA
􌴗 - U+10CD17 YAKID2
􌴘 - U+10CD18 YAKSLICE
􌴙 - U+10CD19 YAKSTICKER
􌴚 - U+10CD1A YAKKIE
􌴛 - U+10CD1B ANGELYAK
􌴜 - U+10CD1C YAK
􌴝 - U+10CD1D YAKGONE
􌴞 - U+10CD1E YAKMEASURE
􌴟 - U+10CD1F YAKCOWBOY
􌴠 - U+10CD20 YAKSPEED
􌴡 - U+10CD21 YAKMANDO
􌴢 - U+10CD22 NINJYAK
􌴣 - U+10CD23 YOWL
􌴤 - U+10CD24 YAKSLOW
􌴥 - U+10CD25 BUFFYAK
􌴦 - U+10CD26 YAKTRAP
􌵠 - U+10CD60 PARTYAK
􌵡 - U+10CD61 YAKKISS
􌵢 - U+10CD62 THOUSANDYAKSTARE
􌵣 - U+10CD63 YAKBLUSH
􌵤 - U+10CD64 YAKSHRUG
􌵥 - U+10CD65 YAKTHONK
􌵦 - U+10CD66 YAKSAD
􌵧 - U+10CD67 BABYAK
􌵨 - U+10CD68 YAKKETYSAX
􌵩 - U+10CD69 YAKBANE
􌵪 - U+10CD6A YAKTHINK
􌵫 - U+10CD6B HYPERYAKKIE
􌶐 - U+10CD90 YAKSTACK
􌶑 - U+10CD91 YAKCHAIN
􌶒 - U+10CD92 YAKRING
􌶓 - U+10CD93 YAKOVERFLOW
􌶰 - U+10CDB0 XMASYAK
􌶱 - U+10CDB1 YAKTOBERFEST
􌷐 - U+10CDD0 YAKSTEPS
􌷠 - U+10CDE0 YAKRAGE-FRAME-1
􌷡 - U+10CDE1 YAKRAGE-FRAME-2
􌷢 - U+10CDE2 YAKRAGE-FRAME-3
􌷣 - U+10CDE3 YAKRAGE-FRAME-4
􌷤 - U+10CDE4 YAKRAGE-FRAME-5
􌷥 - U+10CDE5 YAKRAGE-FRAME-6
ZWJ Sequence Flags (limited cross-platform support)
------------------
🏳️‍🐞 - U+1F3F3 U+200D U+1F41E SerenityOS flag
🏳️‍ - U+1F3F3 U+200D U+F8FF Klingon flag
🏳️‍🖖 - U+1F3F3 U+200D U+1F596 Vulcan flag
Emoji Tag Sequence Flags (limited cross-platform support)
------------------------
🏴󠁢󠁱󠁢󠁯󠁿 - U+1F3F4 U+E0062 U+E0071 U+E0062 U+E006F U+E007F BQ-BO Bonaire
🏴󠁢󠁱󠁳󠁡󠁿 - U+1F3F4 U+E0062 U+E0071 U+E0073 U+E0061 U+E007F BQ-SA Saba
🏴󠁢󠁱󠁳󠁥󠁿 - U+1F3F4 U+E0062 U+E0071 U+E0073 U+E0065 U+E007F BQ-SE Sint Eustatius
🏴󠁣󠁡󠁱󠁣󠁿 - U+1F3F4 U+E0063 U+E0061 U+E0071 U+E0063 U+E007F CA-QC Quebec
🏴󠁤󠁥󠁢󠁢󠁿 - U+1F3F4 U+E0064 U+E0065 U+E0062 U+E0062 U+E007F DE-BB Brandenburg
🏴󠁤󠁥󠁢󠁥󠁿 - U+1F3F4 U+E0064 U+E0065 U+E0062 U+E0065 U+E007F DE-BE Berlin
🏴󠁤󠁥󠁢󠁷󠁿 - U+1F3F4 U+E0064 U+E0065 U+E0062 U+E0077 U+E007F DE-BW Baden-Württemberg
🏴󠁤󠁥󠁢󠁹󠁿 - U+1F3F4 U+E0064 U+E0065 U+E0062 U+E0079 U+E007F DE-BY Bavaria
🏴󠁤󠁥󠁨󠁢󠁿 - U+1F3F4 U+E0064 U+E0065 U+E0068 U+E0062 U+E007F DE-HB Bremen
🏴󠁤󠁥󠁨󠁥󠁿 - U+1F3F4 U+E0064 U+E0065 U+E0068 U+E0065 U+E007F DE-HE Hesse
🏴󠁤󠁥󠁨󠁨󠁿 - U+1F3F4 U+E0064 U+E0065 U+E0068 U+E0068 U+E007F DE-HH Hamburg
🏴󠁤󠁥󠁭󠁶󠁿 - U+1F3F4 U+E0064 U+E0065 U+E006D U+E0076 U+E007F DE-MV Mecklenburg-Vorpommern
🏴󠁤󠁥󠁮󠁩󠁿 - U+1F3F4 U+E0064 U+E0065 U+E006E U+E0069 U+E007F DE-NI Lower Saxony
🏴󠁤󠁥󠁮󠁷󠁿 - U+1F3F4 U+E0064 U+E0065 U+E006E U+E0077 U+E007F DE-NW North Rhine-Westphalia
🏴󠁤󠁥󠁲󠁰󠁿 - U+1F3F4 U+E0064 U+E0065 U+E0072 U+E0070 U+E007F DE-RP Rhineland-Palatinate
🏴󠁤󠁥󠁳󠁨󠁿 - U+1F3F4 U+E0064 U+E0065 U+E0073 U+E0068 U+E007F DE-SH Schleswig-Holstein
🏴󠁤󠁥󠁳󠁬󠁿 - U+1F3F4 U+E0064 U+E0065 U+E0073 U+E006C U+E007F DE-SL Saarland
🏴󠁤󠁥󠁳󠁮󠁿 - U+1F3F4 U+E0064 U+E0065 U+E0073 U+E006E U+E007F DE-SN Saxony
🏴󠁤󠁥󠁳󠁴󠁿 - U+1F3F4 U+E0064 U+E0065 U+E0073 U+E0074 U+E007F DE-ST Saxony-Anhalt
🏴󠁤󠁥󠁴󠁨󠁿 - U+1F3F4 U+E0064 U+E0065 U+E0074 U+E0068 U+E007F DE-TH Thuringia
🏴󠁥󠁳󠁣󠁴󠁿 - U+1F3F4 U+E0065 U+E0073 U+E0063 U+E0074 U+E007F ES-CT Catalonia
🏴󠁥󠁳󠁰󠁶󠁿 - U+1F3F4 U+E0065 U+E0073 U+E0070 U+E0076 U+E007F ES-PV Basque Country
🏴󠁦󠁩󠀰󠀳󠁿 - U+1F3F4 U+E0066 U+E0069 U+E0030 U+E0033 U+E007F FI-03 South Ostrobothnia
🏴󠁦󠁩󠀰󠀴󠁿 - U+1F3F4 U+E0066 U+E0069 U+E0030 U+E0034 U+E007F FI-04 South Savonia
🏴󠁦󠁩󠀰󠀵󠁿 - U+1F3F4 U+E0066 U+E0069 U+E0030 U+E0035 U+E007F FI-05 Kainuu
🏴󠁦󠁩󠀰󠀶󠁿 - U+1F3F4 U+E0066 U+E0069 U+E0030 U+E0036 U+E007F FI-06 Kanta-Häme (Tavastia Proper)
🏴󠁦󠁩󠀰󠀷󠁿 - U+1F3F4 U+E0066 U+E0069 U+E0030 U+E0037 U+E007F FI-07 Central Ostrobothnia
🏴󠁦󠁩󠀰󠀸󠁿 - U+1F3F4 U+E0066 U+E0069 U+E0030 U+E0038 U+E007F FI-08 Central Finland
🏴󠁦󠁩󠀱󠀳󠁿 - U+1F3F4 U+E0066 U+E0069 U+E0031 U+E0033 U+E007F FI-13 North Karelia
🏴󠁦󠁩󠀱󠀵󠁿 - U+1F3F4 U+E0066 U+E0069 U+E0031 U+E0035 U+E007F FI-15 Northern Savonia
🏴󠁦󠁩󠀱󠀶󠁿 - U+1F3F4 U+E0066 U+E0069 U+E0031 U+E0036 U+E007F FI-16 Päijänne Tavastia
🏴󠁦󠁩󠀱󠀷󠁿 - U+1F3F4 U+E0066 U+E0069 U+E0031 U+E0037 U+E007F FI-17 Satakunta
🏴󠁦󠁩󠀱󠀸󠁿 - U+1F3F4 U+E0066 U+E0069 U+E0031 U+E0038 U+E007F FI-18 Uusimaa
🏴󠁦󠁲󠁡󠁲󠁡󠁿 - U+1F3F4 U+E0066 U+E0072 U+E0061 U+E0072 U+E0061 U+E007F FR-ARA Auvergne-Rhône-Alpes
🏴󠁦󠁲󠁢󠁦󠁣󠁿 - U+1F3F4 U+E0066 U+E0072 U+E0062 U+E0066 U+E0063 U+E007F FR-BFC Bourgogne-Franche-Comté
🏴󠁦󠁲󠁢󠁲󠁥󠁿 - U+1F3F4 U+E0066 U+E0072 U+E0062 U+E0072 U+E0065 U+E007F FR-BRE Bretagne
🏴󠁦󠁲󠁣󠁯󠁲󠁿 - U+1F3F4 U+E0066 U+E0072 U+E0063 U+E006F U+E0072 U+E007F FR-COR Corse
🏴󠁦󠁲󠁣󠁶󠁬󠁿 - U+1F3F4 U+E0066 U+E0072 U+E0063 U+E0076 U+E006C U+E007F FR-CVL Centre-Val de Loire
🏴󠁦󠁲󠁯󠁣󠁣󠁿 - U+1F3F4 U+E0066 U+E0072 U+E006F U+E0063 U+E0063 U+E007F FR-OCC Occitanie
🏴󠁦󠁲󠁮󠁡󠁱󠁿 - U+1F3F4 U+E0066 U+E0072 U+E006E U+E0061 U+E0071 U+E007F FR-NAQ Nouvelle-Aquitaine
🏴󠁦󠁲󠁮󠁯󠁲󠁿 - U+1F3F4 U+E0066 U+E0072 U+E006E U+E006F U+E0072 U+E007F FR-NOR Normandie
🏴󠁦󠁲󠁰󠁡󠁣󠁿 - U+1F3F4 U+E0066 U+E0072 U+E0070 U+E0061 U+E0063 U+E007F FR-PAC Provence-Alpes-Côte-dAzur
🏴󠁦󠁲󠁰󠁤󠁬󠁿 - U+1F3F4 U+E0066 U+E0072 U+E0070 U+E0064 U+E006C U+E007F FR-PDL Pays-de-la-Loire
🏴󠁩󠁥󠁬󠁿 - U+1F3F4 U+E0069 U+E0065 U+E006C U+E007F IE-L Leinster
🏴󠁩󠁥󠁭󠁿 - U+1F3F4 U+E0069 U+E0065 U+E006D U+E007F IE-M Munster
🏴󠁩󠁥󠁵󠁿 - U+1F3F4 U+E0069 U+E0065 U+E0075 U+E007F IE-U Ulster
🏴󠁫󠁲󠀱󠀱󠁿 - U+1F3F4 U+E006B U+E0072 U+E0031 U+E0031 U+E007F KR-11 Seoul
🏴󠁫󠁲󠀲󠀹󠁿 - U+1F3F4 U+E006B U+E0072 U+E0032 U+E0039 U+E007F KR-29 Gwangju City
🏴󠁫󠁲󠀳󠀰󠁿 - U+1F3F4 U+E006B U+E0072 U+E0033 U+E0030 U+E007F KR-30 Daejeon
🏴󠁫󠁲󠀴󠀱󠁿 - U+1F3F4 U+E006B U+E0072 U+E0034 U+E0031 U+E007F KR-41 Gyeonggi
🏴󠁫󠁲󠀴󠀴󠁿 - U+1F3F4 U+E006B U+E0072 U+E0034 U+E0034 U+E007F KR-44 South Chungcheong
🏴󠁫󠁲󠀴󠀶󠁿 - U+1F3F4 U+E006B U+E0072 U+E0034 U+E0036 U+E007F KR-46 South Jeolla
🏴󠁫󠁲󠀴󠀸󠁿 - U+1F3F4 U+E006B U+E0072 U+E0034 U+E0038 U+E007F KR-48 South Gyeongsang
🏴󠁫󠁲󠀴󠀹󠁿 - U+1F3F4 U+E006B U+E0072 U+E0034 U+E0039 U+E007F KR-49 Jeju
🏴󠁬󠁲󠁢󠁭󠁿 - U+1F3F4 U+E006C U+E0072 U+E0062 U+E006D U+E007F LR-BM Bomi
🏴󠁬󠁲󠁢󠁧󠁿 - U+1F3F4 U+E006C U+E0072 U+E0062 U+E0067 U+E007F LR-BG Bong
🏴󠁬󠁲󠁧󠁰󠁿 - U+1F3F4 U+E006C U+E0072 U+E0067 U+E0070 U+E007F LR-GP Gbarpolu
🏴󠁬󠁲󠁧󠁢󠁿 - U+1F3F4 U+E006C U+E0072 U+E0067 U+E0062 U+E007F LR-GB Grand Bassa
🏴󠁬󠁲󠁣󠁭󠁿 - U+1F3F4 U+E006C U+E0072 U+E0063 U+E006D U+E007F LR-CM Grand Cape Mount
🏴󠁬󠁲󠁧󠁧󠁿 - U+1F3F4 U+E006C U+E0072 U+E0067 U+E0067 U+E007F LR-GG Grand Gedeh
🏴󠁬󠁲󠁧󠁫󠁿 - U+1F3F4 U+E006C U+E0072 U+E0067 U+E006B U+E007F LR-GK Grand Kru
🏴󠁬󠁲󠁬󠁯󠁿 - U+1F3F4 U+E006C U+E0072 U+E006C U+E006F U+E007F LR-LO Lofa
🏴󠁬󠁲󠁭󠁧󠁿 - U+1F3F4 U+E006C U+E0072 U+E006D U+E0067 U+E007F LR-MG Margibi
🏴󠁬󠁲󠁭󠁯󠁿 - U+1F3F4 U+E006C U+E0072 U+E006D U+E006F U+E007F LR-MO Montserrado
🏴󠁬󠁲󠁭󠁹󠁿 - U+1F3F4 U+E006C U+E0072 U+E006D U+E0079 U+E007F LR-MY Maryland
🏴󠁬󠁲󠁮󠁩󠁿 - U+1F3F4 U+E006C U+E0072 U+E006E U+E0069 U+E007F LR-NI Nimba
🏴󠁬󠁲󠁲󠁩󠁿 - U+1F3F4 U+E006C U+E0072 U+E0072 U+E0069 U+E007F LR-RI Rivercess
🏴󠁬󠁲󠁲󠁧󠁿 - U+1F3F4 U+E006C U+E0072 U+E0072 U+E0067 U+E007F LR-RG River Gee
🏴󠁬󠁲󠁳󠁩󠁿 - U+1F3F4 U+E006C U+E0072 U+E0073 U+E0069 U+E007F LR-SI Sinoe
🏴󠁮󠁬󠁢󠁱󠀱󠁿 - U+1F3F4 U+E006E U+E006C U+E0062 U+E0071 U+E0031 U+E007F NL-BQ1 Bonaire
🏴󠁮󠁬󠁢󠁱󠀲󠁿 - U+1F3F4 U+E006E U+E006C U+E0062 U+E0071 U+E0032 U+E007F NL-BQ2 Saba
🏴󠁮󠁬󠁢󠁱󠀳󠁿 - U+1F3F4 U+E006E U+E006C U+E0062 U+E0071 U+E0033 U+E007F NL-BQ3 Sint Eustatius
🏴󠁮󠁬󠁤󠁲󠁿 - U+1F3F4 U+E006E U+E006C U+E0064 U+E0072 U+E007F NL-DR Drenthe
🏴󠁮󠁬󠁦󠁬󠁿 - U+1F3F4 U+E006E U+E006C U+E0066 U+E006C U+E007F NL-FL Flevoland
🏴󠁮󠁬󠁦󠁲󠁿 - U+1F3F4 U+E006E U+E006C U+E0066 U+E0072 U+E007F NL-FR Friesland
🏴󠁮󠁬󠁧󠁥󠁿 - U+1F3F4 U+E006E U+E006C U+E0067 U+E0065 U+E007F NL-GE Gelderland
🏴󠁮󠁬󠁧󠁲󠁿 - U+1F3F4 U+E006E U+E006C U+E0067 U+E0072 U+E007F NL-GR Groningen
🏴󠁮󠁬󠁬󠁩󠁿 - U+1F3F4 U+E006E U+E006C U+E006C U+E0069 U+E007F NL-LI Limburg
🏴󠁮󠁬󠁮󠁢󠁿 - U+1F3F4 U+E006E U+E006C U+E006E U+E0062 U+E007F NL-NB North Brabant
🏴󠁮󠁬󠁮󠁨󠁿 - U+1F3F4 U+E006E U+E006C U+E006E U+E0068 U+E007F NL-NH North Holland
🏴󠁮󠁬󠁯󠁶󠁿 - U+1F3F4 U+E006E U+E006C U+E006F U+E0076 U+E007F NL-OV Overijssel
🏴󠁮󠁬󠁵󠁴󠁿 - U+1F3F4 U+E006E U+E006C U+E0075 U+E0074 U+E007F NL-UT Utrecht
🏴󠁮󠁬󠁺󠁥󠁿 - U+1F3F4 U+E006E U+E006C U+E007A U+E0065 U+E007F NL-ZE Zeeland
🏴󠁮󠁬󠁺󠁨󠁿 - U+1F3F4 U+E006E U+E006C U+E007A U+E0068 U+E007F NL-ZH South Holland
🏴󠁮󠁯󠀰󠀱󠁿 - U+1F3F4 U+E006E U+E006F U+E0030 U+E0031 U+E007F NO-01 Østfold
🏴󠁮󠁯󠀰󠀲󠁿 - U+1F3F4 U+E006E U+E006F U+E0030 U+E0032 U+E007F NO-02 Akershus
🏴󠁮󠁯󠀰󠀳󠁿 - U+1F3F4 U+E006E U+E006F U+E0030 U+E0033 U+E007F NO-03 Oslo
🏴󠁮󠁯󠀰󠀴󠁿 - U+1F3F4 U+E006E U+E006F U+E0030 U+E0034 U+E007F NO-04 Hedmark
🏴󠁮󠁯󠀰󠀵󠁿 - U+1F3F4 U+E006E U+E006F U+E0030 U+E0035 U+E007F NO-05 Oppland
🏴󠁮󠁯󠀰󠀶󠁿 - U+1F3F4 U+E006E U+E006F U+E0030 U+E0036 U+E007F NO-06 Buskerud
🏴󠁮󠁯󠀰󠀷󠁿 - U+1F3F4 U+E006E U+E006F U+E0030 U+E0037 U+E007F NO-07 Vestfold
🏴󠁮󠁯󠀰󠀸󠁿 - U+1F3F4 U+E006E U+E006F U+E0030 U+E0038 U+E007F NO-08 Telemark
🏴󠁮󠁯󠀰󠀹󠁿 - U+1F3F4 U+E006E U+E006F U+E0030 U+E0039 U+E007F NO-09 Aust-Agder
🏴󠁮󠁯󠀱󠀰󠁿 - U+1F3F4 U+E006E U+E006F U+E0031 U+E0030 U+E007F NO-10 Vest-Agder
🏴󠁮󠁯󠀱󠀱󠁿 - U+1F3F4 U+E006E U+E006F U+E0031 U+E0031 U+E007F NO-11 Rogaland
🏴󠁮󠁯󠀱󠀲󠁿 - U+1F3F4 U+E006E U+E006F U+E0031 U+E0032 U+E007F NO-12 Hordaland
🏴󠁮󠁯󠀱󠀴󠁿 - U+1F3F4 U+E006E U+E006F U+E0031 U+E0034 U+E007F NO-14 Fjordane
🏴󠁮󠁯󠀱󠀵󠁿 - U+1F3F4 U+E006E U+E006F U+E0031 U+E0035 U+E007F NO-15 Møre og Romsdal
🏴󠁮󠁯󠀱󠀶󠁿 - U+1F3F4 U+E006E U+E006F U+E0031 U+E0036 U+E007F NO-16 Sør-Trøndelag
🏴󠁮󠁯󠀱󠀷󠁿 - U+1F3F4 U+E006E U+E006F U+E0031 U+E0037 U+E007F NO-17 Nord-Trøndelag
🏴󠁮󠁯󠀱󠀸󠁿 - U+1F3F4 U+E006E U+E006F U+E0031 U+E0038 U+E007F NO-18 Nordland
🏴󠁮󠁯󠀱󠀹󠁿 - U+1F3F4 U+E006E U+E006F U+E0031 U+E0039 U+E007F NO-19 Troms
🏴󠁮󠁯󠀲󠀰󠁿 - U+1F3F4 U+E006E U+E006F U+E0032 U+E0030 U+E007F NO-20 Finnmark
🏴󠁮󠁯󠀲󠀱󠁿 - U+1F3F4 U+E006E U+E006F U+E0032 U+E0031 U+E007F NO-21 Svalbard
🏴󠁮󠁯󠀲󠀲󠁿 - U+1F3F4 U+E006E U+E006F U+E0032 U+E0032 U+E007F NO-22 Jan Mayen
🏴󠁮󠁯󠀲󠀳󠁿 - U+1F3F4 U+E006E U+E006F U+E0032 U+E0033 U+E007F NO-23 Trøndelag
🏴󠁮󠁯󠀳󠀰󠁿 - U+1F3F4 U+E006E U+E006F U+E0033 U+E0030 U+E007F NO-30 Viken
🏴󠁮󠁯󠀳󠀴󠁿 - U+1F3F4 U+E006E U+E006F U+E0033 U+E0034 U+E007F NO-34 Innlandet
🏴󠁮󠁯󠀳󠀸󠁿 - U+1F3F4 U+E006E U+E006F U+E0033 U+E0038 U+E007F NO-38 Vestfold og Telemark
🏴󠁮󠁯󠀴󠀲󠁿 - U+1F3F4 U+E006E U+E006F U+E0034 U+E0032 U+E007F NO-42 Agder
🏴󠁮󠁯󠀴󠀶󠁿 - U+1F3F4 U+E006E U+E006F U+E0034 U+E0036 U+E007F NO-46 Vestland
🏴󠁮󠁯󠀵󠀰󠁿 - U+1F3F4 U+E006E U+E006F U+E0035 U+E0030 U+E007F NO-50 Trøndelag
🏴󠁮󠁯󠀵󠀴󠁿 - U+1F3F4 U+E006E U+E006F U+E0035 U+E0034 U+E007F NO-54 Troms og Finnmark
🏴󠁮󠁺󠁡󠁵󠁫󠁿 - U+1F3F4 U+E006E U+E007A U+E0061 U+E0075 U+E006B U+E007F NZ-AUK Auckland
🏴󠁮󠁺󠁮󠁳󠁮󠁿 - U+1F3F4 U+E006E U+E007A U+E006E U+E0073 U+E006E U+E007F NZ-NSN Nelson
🏴󠁮󠁺󠁯󠁴󠁡󠁿 - U+1F3F4 U+E006E U+E007A U+E006F U+E0074 U+E0061 U+E007F NZ-OTA Otago
🏴󠁮󠁺󠁷󠁧󠁮󠁿 - U+1F3F4 U+E006E U+E007A U+E0077 U+E0067 U+E006E U+E007F NZ-WGN Wellington
🏴󠁰󠁡󠀱󠁿 - U+1F3F4 U+E0070 U+E0061 U+E0031 U+E007F PA-1 Bocas del Toro
🏴󠁰󠁡󠀲󠁿 - U+1F3F4 U+E0070 U+E0061 U+E0032 U+E007F PA-2 Coclé
🏴󠁰󠁡󠀳󠁿 - U+1F3F4 U+E0070 U+E0061 U+E0033 U+E007F PA-3 Colón
🏴󠁰󠁡󠀴󠁿 - U+1F3F4 U+E0070 U+E0061 U+E0034 U+E007F PA-4 Chiriquí
🏴󠁰󠁡󠀵󠁿 - U+1F3F4 U+E0070 U+E0061 U+E0035 U+E007F PA-5 Darién
🏴󠁰󠁡󠀶󠁿 - U+1F3F4 U+E0070 U+E0061 U+E0036 U+E007F PA-6 Herrera
🏴󠁰󠁡󠀷󠁿 - U+1F3F4 U+E0070 U+E0061 U+E0037 U+E007F PA-7 Los Santos
🏴󠁰󠁡󠀹󠁿 - U+1F3F4 U+E0070 U+E0061 U+E0039 U+E007F PA-9 Veraguas
🏴󠁰󠁡󠀱󠀰󠁿 - U+1F3F4 U+E0070 U+E0061 U+E0031 U+E0030 U+E007F PA-10 West Panamá
🏴󠁰󠁡󠁫󠁹󠁿 - U+1F3F4 U+E0070 U+E0061 U+E006B U+E0079 U+E007F PA-KY Guna Yala
🏴󠁰󠁡󠁮󠁢󠁿 - U+1F3F4 U+E0070 U+E0061 U+E006E U+E0062 U+E007F PA-NB Ngöbe-Buglé
🏴󠁳󠁥󠁭󠁿 - U+1F3F4 U+E0073 U+E0065 U+E006D U+E007F SE-M Skåne
🏴󠁳󠁫󠁢󠁣󠁿 - U+1F3F4 U+E0073 U+E006B U+E0062 U+E0063 U+E007F SK-BC Banská Bystrica
🏴󠁳󠁫󠁢󠁬󠁿 - U+1F3F4 U+E0073 U+E006B U+E0062 U+E006C U+E007F SK-BL Bratislava
🏴󠁳󠁫󠁫󠁩󠁿 - U+1F3F4 U+E0073 U+E006B U+E006B U+E0069 U+E007F SK-KI Košice
🏴󠁳󠁫󠁮󠁩󠁿 - U+1F3F4 U+E0073 U+E006B U+E006E U+E0069 U+E007F SK-NI Nitra
🏴󠁳󠁫󠁰󠁶󠁿 - U+1F3F4 U+E0073 U+E006B U+E0070 U+E0076 U+E007F SK-PV Prešov
🏴󠁳󠁫󠁴󠁡󠁿 - U+1F3F4 U+E0073 U+E006B U+E0074 U+E0061 U+E007F SK-TA Trnava
🏴󠁳󠁫󠁴󠁣󠁿 - U+1F3F4 U+E0073 U+E006B U+E0074 U+E0063 U+E007F SK-TC Trenčín
🏴󠁳󠁫󠁺󠁩󠁿 - U+1F3F4 U+E0073 U+E006B U+E007A U+E0069 U+E007F SK-ZI Žilina
🏴󠁵󠁡󠀰󠀵󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0030 U+E0035 U+E007F UA-05 Vinnychchyna
🏴󠁵󠁡󠀰󠀷󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0030 U+E0037 U+E007F UA-07 Volyn
🏴󠁵󠁡󠀰󠀹󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0030 U+E0039 U+E007F UA-09 Luhanshchyna
🏴󠁵󠁡󠀱󠀲󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0031 U+E0032 U+E007F UA-12 Dnipropetrovshchyna
🏴󠁵󠁡󠀱󠀴󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0031 U+E0034 U+E007F UA-14 Donechchyna
🏴󠁵󠁡󠀱󠀸󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0031 U+E0038 U+E007F UA-18 Zhytomyrshchyna
🏴󠁵󠁡󠀲󠀱󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0032 U+E0031 U+E007F UA-21 Zakarpattia
🏴󠁵󠁡󠀲󠀳󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0032 U+E0033 U+E007F UA-23 Zaporizhzhya
🏴󠁵󠁡󠀲󠀶󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0032 U+E0036 U+E007F UA-26 Prykarpattia
🏴󠁵󠁡󠀳󠀰󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0033 U+E0030 U+E007F UA-30 Kiev
🏴󠁵󠁡󠀳󠀲󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0033 U+E0032 U+E007F UA-32 Kyivshchyna
🏴󠁵󠁡󠀳󠀵󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0033 U+E0035 U+E007F UA-35 Kirovohradschyna
🏴󠁵󠁡󠀴󠀰󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0034 U+E0030 U+E007F UA-40 Sevastopol
🏴󠁵󠁡󠀴󠀳󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0034 U+E0033 U+E007F UA-43 Crimea
🏴󠁵󠁡󠀴󠀶󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0034 U+E0036 U+E007F UA-46 Lvivshchyna
🏴󠁵󠁡󠀴󠀸󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0034 U+E0038 U+E007F UA-48 Mykolayivschyna
🏴󠁵󠁡󠀵󠀱󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0035 U+E0031 U+E007F UA-51 Odeshchyna
🏴󠁵󠁡󠀵󠀳󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0035 U+E0033 U+E007F UA-53 Poltavshchyna
🏴󠁵󠁡󠀵󠀶󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0035 U+E0036 U+E007F UA-56 Rivnenshchyna
🏴󠁵󠁡󠀵󠀹󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0035 U+E0039 U+E007F UA-59 Sumshchyna
🏴󠁵󠁡󠀶󠀱󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0036 U+E0031 U+E007F UA-61 Ternopilshchyna
🏴󠁵󠁡󠀶󠀳󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0036 U+E0033 U+E007F UA-63 Kharkivshchyna
🏴󠁵󠁡󠀶󠀵󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0036 U+E0035 U+E007F UA-65 Khersonshchyna
🏴󠁵󠁡󠀶󠀸󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0036 U+E0038 U+E007F UA-68 Khmelnychchyna
🏴󠁵󠁡󠀷󠀱󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0037 U+E0031 U+E007F UA-71 Cherkashchyna
🏴󠁵󠁡󠀷󠀴󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0037 U+E0034 U+E007F UA-74 Chernihivshchyna
🏴󠁵󠁡󠀷󠀷󠁿 - U+1F3F4 U+E0075 U+E0061 U+E0037 U+E0037 U+E007F UA-77 Chernivtsi Oblast
🏴󠁵󠁳󠁡󠁬󠁿 - U+1F3F4 U+E0075 U+E0073 U+E0061 U+E006C U+E007F US-AL Alabama
🏴󠁵󠁳󠁡󠁺󠁿 - U+1F3F4 U+E0075 U+E0073 U+E0061 U+E007A U+E007F US-AZ Arizona
🏴󠁵󠁳󠁴󠁸󠁿 - U+1F3F4 U+E0075 U+E0073 U+E0074 U+E0078 U+E007F US-TX Texas
🏴󠁺󠁷󠁨󠁡󠁿 - U+1F3F4 U+E007A U+E0077 U+E0068 U+E0061 U+E007F ZW-HA Harare
Emoji 15.1
----------
🔗‍💥 - U+1F517 U+200D U+1F4A5 BROKEN CHAIN
🍄‍🟫 - U+1F344 U+200D U+1F7EB MUSHROOM (NON-POISONOUS)
🙂‍↕ - U+1F642 U+200D U+2195 NODDING FACE
🙂‍↔ - U+1F642 U+200D U+2194 SHAKING FACE
🍋‍🟩 - U+1F34B U+200D U+1F7E9 LIME
🐦‍🔥 - U+1F426 U+200D U+1F525 PHOENIX
🧑‍🧒 - U+1F9D1 U+200D U+1F9D2 FAMILY: ADULT, CHILD
🧑‍🧑‍🧒 - U+1F9D1 U+200D U+1F9D1 U+200D U+1F9D2 FAMILY: ADULT, ADULT, CHILD
🧑‍🧒‍🧒 - U+1F9D1 U+200D U+1F9D2 U+200D U+1F9D2 FAMILY: ADULT, CHILD, CHILD
🧑‍🧑‍🧒‍🧒 - U+1F9D1 U+200D U+1F9D1 U+200D U+1F9D2 U+200D U+1F9D2 FAMILY: ADULT, ADULT, CHILD, CHILD
Emoji 16
----------
🫩 - U+1FAE9 FACE WITH BAGS UNDER EYES
🫟 - U+1FADF SPLATTER
🪉 - U+1FA89 HARP
🫆 - U+1FAC6 FINGERPRINT
🫜 - U+1FADC ROOT VEGETABLE
🪾 - U+1FABE LEAFLESS TREE
🪏 - U+1FA8F SHOVEL
🇨🇶 - U+1F1E8 U+1F1F6 CQ SARK

View File

@ -14,9 +14,7 @@ string(REGEX REPLACE "([0-9]+\\.[0-9]+)\\.[0-9]+" "\\1" EMOJI_VERSION "${UCD_VER
set(EMOJI_TEST_URL "https://www.unicode.org/Public/emoji/${EMOJI_VERSION}/emoji-test.txt")
set(EMOJI_TEST_PATH "${UCD_PATH}/emoji-test.txt")
set(EMOJI_RES_PATH "${SerenityOS_SOURCE_DIR}/Base/res/emoji")
set(EMOJI_SERENITY_PATH "${SerenityOS_SOURCE_DIR}/Base/home/anon/Documents/emoji-serenity.txt")
set(EMOJI_FILE_LIST_PATH "${SerenityOS_SOURCE_DIR}/Meta/emoji-file-list.txt")
set(EMOJI_INSTALL_PATH "${CMAKE_BINARY_DIR}/Root/home/anon/Documents/emoji.txt")
if (ENABLE_UNICODE_DATABASE_DOWNLOAD)
remove_path_if_version_changed("${UCD_VERSION}" "${UCD_VERSION_FILE}" "${UCD_PATH}")
@ -32,23 +30,19 @@ if (ENABLE_UNICODE_DATABASE_DOWNLOAD)
set(EMOJI_DATA_HEADER EmojiData.h)
set(EMOJI_DATA_IMPLEMENTATION EmojiData.cpp)
if (SERENITYOS)
set(EMOJI_INSTALL_ARG -i "${EMOJI_INSTALL_PATH}")
endif()
invoke_generator(
"EmojiData"
Lagom::GenerateEmojiData
"${UCD_VERSION_FILE}"
"${EMOJI_DATA_HEADER}"
"${EMOJI_DATA_IMPLEMENTATION}"
arguments "${EMOJI_INSTALL_ARG}" -e "${EMOJI_TEST_PATH}" -s "${EMOJI_SERENITY_PATH}" -f "${EMOJI_FILE_LIST_PATH}" -r "${EMOJI_RES_PATH}"
arguments "${EMOJI_INSTALL_ARG}" -f "${EMOJI_FILE_LIST_PATH}" -r "${EMOJI_RES_PATH}"
# This will make this command only run when the modified time of the directory changes,
# which only happens if files within it are added or deleted, but not when a file is modified.
# This is fine for this use-case, because the contents of a file changing should not affect
# the generated emoji.txt file.
dependencies "${EMOJI_RES_PATH}" "${EMOJI_SERENITY_PATH}" "${EMOJI_FILE_LIST_PATH}"
dependencies "${EMOJI_RES_PATH}" "${EMOJI_FILE_LIST_PATH}"
)
set(UNICODE_DATA_SOURCES

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
* Copyright (c) 2022-2024, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -17,161 +17,20 @@
#include <LibUnicode/Emoji.h>
struct Emoji {
size_t name { 0 };
Optional<size_t> image_path;
Unicode::EmojiGroup group;
ByteString subgroup;
u32 display_order { 0 };
size_t image_path { 0 };
Vector<u32> code_points;
ByteString encoded_code_points;
ByteString status;
size_t code_point_array_index { 0 };
};
struct EmojiData {
UniqueStringStorage unique_strings;
Vector<Emoji> emojis;
Vector<String> emoji_file_list;
Vector<ByteString> emoji_file_list;
};
static void set_image_path_for_emoji(StringView emoji_resource_path, EmojiData& emoji_data, Emoji& emoji)
{
StringBuilder builder;
for (auto code_point : emoji.code_points) {
if (code_point == 0xfe0f)
continue;
if (!builder.is_empty())
builder.append('_');
builder.appendff("U+{:X}", code_point);
}
auto file = ByteString::formatted("{}.png", builder.to_byte_string());
auto path = ByteString::formatted("{}/{}", emoji_resource_path, file);
if (!FileSystem::exists(path))
return;
emoji.image_path = emoji_data.unique_strings.ensure(move(file));
}
static ErrorOr<void> parse_emoji_test_data(Core::InputBufferedFile& file, EmojiData& emoji_data)
{
static constexpr auto group_header = "# group: "sv;
static constexpr auto subgroup_header = "# subgroup: "sv;
Array<u8, 1024> buffer;
Unicode::EmojiGroup group;
ByteString subgroup;
u32 display_order { 0 };
while (TRY(file.can_read_line())) {
auto line = TRY(file.read_line(buffer));
if (line.is_empty())
continue;
if (line.starts_with('#')) {
if (line.starts_with(group_header)) {
auto name = line.substring_view(group_header.length());
group = Unicode::emoji_group_from_string(name);
} else if (line.starts_with(subgroup_header)) {
subgroup = line.substring_view(subgroup_header.length());
}
continue;
}
auto status_index = line.find(';');
VERIFY(status_index.has_value());
auto emoji_and_name_index = line.find('#', *status_index);
VERIFY(emoji_and_name_index.has_value());
Emoji emoji {};
emoji.group = group;
emoji.subgroup = subgroup;
emoji.display_order = display_order++;
auto code_points = line.substring_view(0, *status_index).split_view(' ');
TRY(emoji.code_points.try_ensure_capacity(code_points.size()));
for (auto code_point : code_points) {
auto value = AK::StringUtils::convert_to_uint_from_hex<u32>(code_point);
VERIFY(value.has_value());
emoji.code_points.unchecked_append(*value);
}
auto emoji_and_name = line.substring_view(*emoji_and_name_index + 1);
auto emoji_and_name_spaces = emoji_and_name.find_all(" "sv);
VERIFY(emoji_and_name_spaces.size() > 2);
auto name = emoji_and_name.substring_view(emoji_and_name_spaces[2]).trim_whitespace();
emoji.name = emoji_data.unique_strings.ensure(name.to_titlecase_string());
emoji.encoded_code_points = emoji_and_name.substring_view(0, emoji_and_name_spaces[1]).trim_whitespace();
emoji.status = line.substring_view(*status_index + 1, *emoji_and_name_index - *status_index - 1).trim_whitespace();
TRY(emoji_data.emojis.try_append(move(emoji)));
}
return {};
}
static ErrorOr<void> parse_emoji_serenity_data(Core::InputBufferedFile& file, EmojiData& emoji_data)
{
static constexpr auto code_point_header = "U+"sv;
Array<u8, 1024> buffer;
auto display_order = static_cast<u32>(emoji_data.emojis.size()) + 1u;
while (TRY(file.can_read_line())) {
auto line = TRY(file.read_line(buffer));
if (line.is_empty())
continue;
auto index = line.find(code_point_header);
if (!index.has_value())
continue;
line = line.substring_view(*index);
StringBuilder builder;
Emoji emoji {};
emoji.group = Unicode::EmojiGroup::SerenityOS;
emoji.display_order = display_order++;
TRY(line.for_each_split_view(' ', SplitBehavior::Nothing, [&](auto segment) -> ErrorOr<void> {
if (segment.starts_with(code_point_header)) {
segment = segment.substring_view(code_point_header.length());
auto code_point = AK::StringUtils::convert_to_uint_from_hex<u32>(segment);
VERIFY(code_point.has_value());
TRY(emoji.code_points.try_append(*code_point));
} else {
if (!builder.is_empty())
TRY(builder.try_append(' '));
TRY(builder.try_append(segment));
}
return {};
}));
auto name = builder.to_byte_string();
if (!any_of(name, is_ascii_lower_alpha))
name = name.to_titlecase();
emoji.name = emoji_data.unique_strings.ensure(move(name));
TRY(emoji_data.emojis.try_append(move(emoji)));
}
return {};
}
static ErrorOr<void> parse_emoji_file_list(Core::InputBufferedFile& file, EmojiData& emoji_data)
{
HashTable<String> seen_emojis;
HashTable<ByteString> seen_emojis;
Array<u8, 1024> buffer;
while (TRY(file.can_read_line())) {
@ -184,8 +43,28 @@ static ErrorOr<void> parse_emoji_file_list(Core::InputBufferedFile& file, EmojiD
return Error::from_errno(EEXIST);
}
emoji_data.emoji_file_list.append(TRY(String::from_utf8(line)));
seen_emojis.set(emoji_data.emoji_file_list.last());
ByteString emoji_file { line.trim_whitespace() };
emoji_data.emoji_file_list.append(emoji_file);
seen_emojis.set(emoji_file);
Emoji emoji;
emoji.image_path = emoji_data.unique_strings.ensure(emoji_file);
auto emoji_basename = LexicalPath::basename(emoji_file, LexicalPath::StripExtension::Yes);
emoji_basename.view().for_each_split_view('_', SplitBehavior::Nothing, [&](StringView code_point) {
static constexpr auto code_point_header = "U+"sv;
VERIFY(code_point.starts_with(code_point_header));
code_point = code_point.substring_view(code_point_header.length());
auto code_point_value = AK::StringUtils::convert_to_uint_from_hex<u32>(code_point);
VERIFY(code_point_value.has_value());
emoji.code_points.append(*code_point_value);
});
emoji_data.emojis.append(move(emoji));
}
return {};
@ -220,7 +99,7 @@ static ErrorOr<void> validate_emoji(StringView emoji_resource_path, EmojiData& e
return Error::from_errno(ENOENT);
}
if (!emoji_data.emoji_file_list.contains_slow(lexical_path.string().view())) {
if (!emoji_data.emoji_file_list.contains_slow(lexical_path.string())) {
warnln("\x1b[1;31mError!\x1b[0m Emoji entry for \x1b[35m{}\x1b[0m not found. Please check emoji-file-list.txt.", lexical_path);
return Error::from_errno(ENOENT);
}
@ -263,9 +142,8 @@ namespace Unicode {
emoji_data.unique_strings.generate(generator);
size_t total_code_point_count { 0 };
for (auto const& emoji : emoji_data.emojis) {
for (auto const& emoji : emoji_data.emojis)
total_code_point_count += emoji.code_points.size();
}
generator.set("total_code_point_count", ByteString::number(total_code_point_count));
generator.append(R"~~~(
@ -280,32 +158,16 @@ static constexpr Array<u32, @total_code_point_count@> s_emoji_code_points { {)~~
}
}
generator.append(" } };"sv);
generator.append(" } };\n"sv);
generator.append(R"~~~(
struct EmojiData {
Emoji to_unicode_emoji() const
{
Emoji emoji {};
emoji.name = decode_string(name);
if (image_path != 0)
emoji.image_path = decode_string(image_path);
emoji.group = static_cast<EmojiGroup>(group);
emoji.display_order = display_order;
emoji.code_points = code_points();
return emoji;
}
constexpr ReadonlySpan<u32> code_points() const
{
return ReadonlySpan<u32>(s_emoji_code_points.data() + code_point_start, code_point_count);
}
@string_index_type@ name { 0 };
@string_index_type@ image_path { 0 };
u8 group { 0 };
u32 display_order { 0 };
size_t code_point_start { 0 };
size_t code_point_count { 0 };
};
@ -316,15 +178,12 @@ struct EmojiData {
static constexpr Array<EmojiData, @emojis_size@> s_emojis { {)~~~");
for (auto const& emoji : emoji_data.emojis) {
generator.set("name"sv, ByteString::number(emoji.name));
generator.set("image_path"sv, ByteString::number(emoji.image_path.value_or(0)));
generator.set("group"sv, ByteString::number(to_underlying(emoji.group)));
generator.set("display_order"sv, ByteString::number(emoji.display_order));
generator.set("image_path"sv, ByteString::number(emoji.image_path));
generator.set("code_point_start"sv, ByteString::number(emoji.code_point_array_index));
generator.set("code_point_count"sv, ByteString::number(emoji.code_points.size()));
generator.append(R"~~~(
{ @name@, @image_path@, @group@, @display_order@, @code_point_start@, @code_point_count@ },)~~~");
{ @image_path@, @code_point_start@, @code_point_count@ },)~~~");
}
generator.append(R"~~~(
@ -347,10 +206,10 @@ struct EmojiCodePointComparator {
}
};
Optional<Emoji> find_emoji_for_code_points(ReadonlySpan<u32> code_points)
Optional<StringView> emoji_image_for_code_points(ReadonlySpan<u32> code_points)
{
if (auto const* emoji = binary_search(s_emojis, code_points, nullptr, EmojiCodePointComparator {}))
return emoji->to_unicode_emoji();
return decode_string(emoji->image_path);
return {};
}
@ -361,127 +220,55 @@ Optional<Emoji> find_emoji_for_code_points(ReadonlySpan<u32> code_points)
return {};
}
static ErrorOr<void> generate_emoji_installation(Core::InputBufferedFile& file, EmojiData const& emoji_data)
{
StringBuilder builder;
SourceGenerator generator { builder };
auto current_group = Unicode::EmojiGroup::Unknown;
StringView current_subgroup;
for (auto const& emoji : emoji_data.emojis) {
if (!emoji.image_path.has_value())
continue;
if (emoji.group == Unicode::EmojiGroup::SerenityOS)
continue; // SerenityOS emojis are in emoji-serenity.txt
if (current_group != emoji.group) {
if (!builder.is_empty())
generator.append("\n"sv);
generator.set("group"sv, Unicode::emoji_group_to_string(emoji.group));
generator.append("# group: @group@\n");
current_group = emoji.group;
}
if (current_subgroup != emoji.subgroup) {
generator.set("subgroup"sv, emoji.subgroup);
generator.append("\n# subgroup: @subgroup@\n");
current_subgroup = emoji.subgroup;
}
generator.set("emoji"sv, emoji.encoded_code_points);
generator.set("name"sv, emoji_data.unique_strings.get(emoji.name));
generator.set("status"sv, emoji.status);
generator.append("@emoji@"sv);
generator.append(" - "sv);
generator.append(ByteString::join(" "sv, emoji.code_points, "U+{:X}"sv));
generator.append(" @name@ (@status@)\n"sv);
}
TRY(file.write_until_depleted(generator.as_string_view().bytes()));
return {};
}
ErrorOr<int> serenity_main(Main::Arguments arguments)
{
StringView generated_header_path;
StringView generated_implementation_path;
StringView generated_installation_path;
StringView emoji_test_path;
StringView emoji_serenity_path;
StringView emoji_file_list_path;
StringView emoji_resource_path;
Core::ArgsParser args_parser;
args_parser.add_option(generated_header_path, "Path to the Unicode Data header file to generate", "generated-header-path", 'h', "generated-header-path");
args_parser.add_option(generated_implementation_path, "Path to the Unicode Data implementation file to generate", "generated-implementation-path", 'c', "generated-implementation-path");
args_parser.add_option(generated_installation_path, "Path to the emoji.txt file to generate", "generated-installation-path", 'i', "generated-installation-path");
args_parser.add_option(emoji_test_path, "Path to emoji-test.txt file", "emoji-test-path", 'e', "emoji-test-path");
args_parser.add_option(emoji_serenity_path, "Path to emoji-serenity.txt file", "emoji-serenity-path", 's', "emoji-serenity-path");
args_parser.add_option(emoji_file_list_path, "Path to the emoji-file-list.txt file", "emoji-file-list-path", 'f', "emoji-file-list-path");
args_parser.add_option(emoji_resource_path, "Path to the /res/emoji directory", "emoji-resource-path", 'r', "emoji-resource-path");
args_parser.parse(arguments);
VERIFY(!emoji_resource_path.is_empty() && FileSystem::exists(emoji_resource_path));
auto emoji_test_file = TRY(open_file(emoji_test_path, Core::File::OpenMode::Read));
VERIFY(!emoji_file_list_path.is_empty() && FileSystem::exists(emoji_file_list_path));
EmojiData emoji_data {};
TRY(parse_emoji_test_data(*emoji_test_file, emoji_data));
if (!emoji_serenity_path.is_empty() && !emoji_file_list_path.is_empty()) {
auto emoji_serenity_file = TRY(open_file(emoji_serenity_path, Core::File::OpenMode::Read));
TRY(parse_emoji_serenity_data(*emoji_serenity_file, emoji_data));
auto emoji_file_list_file = TRY(open_file(emoji_file_list_path, Core::File::OpenMode::Read));
TRY(parse_emoji_file_list(*emoji_file_list_file, emoji_data));
auto emoji_file_list_file = TRY(open_file(emoji_file_list_path, Core::File::OpenMode::Read));
TRY(parse_emoji_file_list(*emoji_file_list_file, emoji_data));
TRY(validate_emoji(emoji_resource_path, emoji_data));
TRY(validate_emoji(emoji_resource_path, emoji_data));
}
auto generated_header_file = TRY(open_file(generated_header_path, Core::File::OpenMode::Write));
TRY(generate_emoji_data_header(*generated_header_file, emoji_data));
for (auto& emoji : emoji_data.emojis)
set_image_path_for_emoji(emoji_resource_path, emoji_data, emoji);
quick_sort(emoji_data.emojis, [](auto const& lhs, auto const& rhs) {
if (lhs.code_points.size() != rhs.code_points.size())
return lhs.code_points.size() < rhs.code_points.size();
if (!generated_installation_path.is_empty()) {
TRY(Core::Directory::create(LexicalPath { generated_installation_path }.parent(), Core::Directory::CreateDirectories::Yes));
auto generated_installation_file = TRY(open_file(generated_installation_path, Core::File::OpenMode::Write));
TRY(generate_emoji_installation(*generated_installation_file, emoji_data));
}
if (!generated_header_path.is_empty()) {
auto generated_header_file = TRY(open_file(generated_header_path, Core::File::OpenMode::Write));
TRY(generate_emoji_data_header(*generated_header_file, emoji_data));
}
if (!generated_implementation_path.is_empty()) {
quick_sort(emoji_data.emojis, [](auto const& lhs, auto const& rhs) {
if (lhs.code_points.size() != rhs.code_points.size())
return lhs.code_points.size() < rhs.code_points.size();
for (size_t i = 0; i < lhs.code_points.size(); ++i) {
if (lhs.code_points[i] < rhs.code_points[i])
return true;
if (lhs.code_points[i] > rhs.code_points[i])
return false;
}
return false;
});
size_t code_point_array_index { 0 };
for (auto& emoji : emoji_data.emojis) {
emoji.code_point_array_index = code_point_array_index;
code_point_array_index += emoji.code_points.size();
for (size_t i = 0; i < lhs.code_points.size(); ++i) {
if (lhs.code_points[i] < rhs.code_points[i])
return true;
if (lhs.code_points[i] > rhs.code_points[i])
return false;
}
auto generated_implementation_file = TRY(open_file(generated_implementation_path, Core::File::OpenMode::Write));
TRY(generate_emoji_data_implementation(*generated_implementation_file, emoji_data));
return false;
});
size_t code_point_array_index { 0 };
for (auto& emoji : emoji_data.emojis) {
emoji.code_point_array_index = code_point_array_index;
code_point_array_index += emoji.code_points.size();
}
auto generated_implementation_file = TRY(open_file(generated_implementation_path, Core::File::OpenMode::Write));
TRY(generate_emoji_data_implementation(*generated_implementation_file, emoji_data));
return 0;
}

View File

@ -43,25 +43,24 @@ Bitmap const* Emoji::emoji_for_code_point(u32 code_point)
Bitmap const* Emoji::emoji_for_code_points(ReadonlySpan<u32> const& code_points)
{
auto emoji = Unicode::find_emoji_for_code_points(code_points);
if (!emoji.has_value() || !emoji->image_path.has_value())
auto emoji_file = Unicode::emoji_image_for_code_points(code_points);
if (!emoji_file.has_value())
return nullptr;
auto emoji_file = emoji->image_path.value();
if (auto it = s_emojis.find(emoji_file); it != s_emojis.end())
if (auto it = s_emojis.find(*emoji_file); it != s_emojis.end())
return it->value.ptr();
auto emoji_path = LexicalPath::join(emoji_lookup_path(), emoji_file);
auto emoji_path = LexicalPath::join(emoji_lookup_path(), *emoji_file);
auto bitmap_or_error = Bitmap::load_from_file(emoji_path.string());
if (bitmap_or_error.is_error()) {
dbgln_if(EMOJI_DEBUG, "Generated emoji data has file {}, but could not load image: {}", emoji_file, bitmap_or_error.error());
s_emojis.set(emoji_file, nullptr);
dbgln_if(EMOJI_DEBUG, "Generated emoji data has file {}, but could not load image: {}", *emoji_file, bitmap_or_error.error());
s_emojis.set(*emoji_file, nullptr);
return nullptr;
}
auto bitmap = bitmap_or_error.release_value();
s_emojis.set(emoji_file, bitmap);
s_emojis.set(*emoji_file, bitmap);
return bitmap.ptr();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, Tim Flynn <trflynn89@serenityos.org>
* Copyright (c) 2022-2024, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -12,7 +12,7 @@
namespace Unicode {
Optional<Emoji> __attribute__((weak)) find_emoji_for_code_points(ReadonlySpan<u32>) { return {}; }
Optional<StringView> __attribute__((weak)) emoji_image_for_code_points(ReadonlySpan<u32>) { return {}; }
// https://unicode.org/reports/tr51/#def_emoji_core_sequence
static bool could_be_start_of_emoji_core_sequence(u32 code_point, Optional<u32> const& next_code_point, SequenceType type)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, Tim Flynn <trflynn89@serenityos.org>
* Copyright (c) 2022-2024, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -13,39 +13,7 @@
namespace Unicode {
enum class EmojiGroup : u8 {
Unknown,
SmileysAndEmotion,
PeopleAndBody,
Component,
AnimalsAndNature,
FoodAndDrink,
TravelAndPlaces,
Activities,
Objects,
Symbols,
Flags,
// Non-standard emoji added for SerenityOS:
SerenityOS,
};
struct Emoji {
StringView name;
Optional<StringView> image_path;
EmojiGroup group { EmojiGroup::Unknown };
u32 display_order { 0 };
ReadonlySpan<u32> code_points;
};
Optional<Emoji> find_emoji_for_code_points(ReadonlySpan<u32> code_points);
template<size_t Size>
Optional<Emoji> find_emoji_for_code_points(u32 const (&code_points)[Size])
{
return find_emoji_for_code_points(ReadonlySpan<u32> { code_points });
}
Optional<StringView> emoji_image_for_code_points(ReadonlySpan<u32> code_points);
enum class SequenceType {
Any,
@ -55,66 +23,4 @@ enum class SequenceType {
bool could_be_start_of_emoji_sequence(Utf8CodePointIterator const&, SequenceType = SequenceType::Any);
bool could_be_start_of_emoji_sequence(Utf32CodePointIterator const&, SequenceType = SequenceType::Any);
constexpr StringView emoji_group_to_string(EmojiGroup group)
{
switch (group) {
case EmojiGroup::Unknown:
return "Unknown"sv;
case EmojiGroup::SmileysAndEmotion:
return "Smileys & Emotion"sv;
case EmojiGroup::PeopleAndBody:
return "People & Body"sv;
case EmojiGroup::Component:
return "Component"sv;
case EmojiGroup::AnimalsAndNature:
return "Animals & Nature"sv;
case EmojiGroup::FoodAndDrink:
return "Food & Drink"sv;
case EmojiGroup::TravelAndPlaces:
return "Travel & Places"sv;
case EmojiGroup::Activities:
return "Activities"sv;
case EmojiGroup::Objects:
return "Objects"sv;
case EmojiGroup::Symbols:
return "Symbols"sv;
case EmojiGroup::Flags:
return "Flags"sv;
case EmojiGroup::SerenityOS:
return "SerenityOS"sv;
}
VERIFY_NOT_REACHED();
}
constexpr EmojiGroup emoji_group_from_string(StringView group)
{
if (group == "Unknown"sv)
return EmojiGroup::Unknown;
if (group == "Smileys & Emotion"sv)
return EmojiGroup::SmileysAndEmotion;
if (group == "People & Body"sv)
return EmojiGroup::PeopleAndBody;
if (group == "Component"sv)
return EmojiGroup::Component;
if (group == "Animals & Nature"sv)
return EmojiGroup::AnimalsAndNature;
if (group == "Food & Drink"sv)
return EmojiGroup::FoodAndDrink;
if (group == "Travel & Places"sv)
return EmojiGroup::TravelAndPlaces;
if (group == "Activities"sv)
return EmojiGroup::Activities;
if (group == "Objects"sv)
return EmojiGroup::Objects;
if (group == "Symbols"sv)
return EmojiGroup::Symbols;
if (group == "Flags"sv)
return EmojiGroup::Flags;
if (group == "SerenityOS"sv)
return EmojiGroup::SerenityOS;
VERIFY_NOT_REACHED();
}
}

View File

@ -12,7 +12,6 @@
namespace Unicode {
enum class BidiClass;
enum class EmojiGroup : u8;
struct CurrencyCode;
struct Emoji;