Slide 1

Slide 1 text

גࣜձࣾϊϋφɹ෢ࢢ༥ل "OESPJEΤϯδχΞ͕཈͓͑ͯ͘΂͖ 6OJDPEF&NPKJͷ஌ࣝ

Slide 2

Slide 2 text

͜ͷൃදͷΰʔϧ ͳΜͱͳ͔͘͠஌Βͳ͔ͬͨ6OJDPEF&NPKJͷ஌͕ࣝ ੔ཧ͞ΕΔ "OESPJEΞϓϦͰҙਤͤͣֆจࣈ่͕Εͳ͍Α͏ਖ਼͠ ͍࣮૷͕Ͱ͖ΔΑ͏ʹͳΔ

Slide 3

Slide 3 text

:VLJ5BLFJDIJ גࣜձࣾϊϋφ$50 !UBDLF@KQ ޷͖ͳֆจࣈ☺

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

6OJDPEF&NPKJ3FMFBTFE ৽ͨʹͷֆจࣈ͕௥ Ճ͞Ε·ͨ͠ IUUQCMPHVOJDPEFPSHVOJDPEFFNPKJpOBMGPSIUNM

Slide 6

Slide 6 text

ͳͥֆจࣈ͸่ΕΔͷ͔ ࠷৽ن֨΁ͷ௥ैઓུ ಠࣗͷֆจࣈϑΥϯτͷར༻

Slide 7

Slide 7 text

ͳͥֆจࣈ͸่ΕΔͷ͔

Slide 8

Slide 8 text

"OESPJE J04 ಉ͡จࣈྻͳͷʹ

Slide 9

Slide 9 text

6OJDPEF&NPKJͷ஀ੜ ΩϟϦΞֆจࣈ4+*4ͷ֎ࣈྖҬʹఆٛ (NBJMͷ೔ຊਐग़΍4PGU#BOL͔ΒͷJ1IPOF(ൢചΛ͖͔͚ͬʹ 6OJDPEFʹऩ࿥ ͢Ͱʹऩ࿥͞Ε͍ͯͨه߸ͱॏෳ͢Δֆจࣈ͸·ͱΊΒΕͨ

Slide 10

Slide 10 text

6OJDPEFʹ͓͚Δֆจࣈͷߟ͑ํ 6OJDPEFʹऩ࿥͞Εͨจࣈͷ͏ͪҰ෦͕ ࣋ͭಛผͳੑ࣭ ֆจࣈͱͯ͠දࣔ͞Ε͏Δจࣈ͸ Emojiଐੑ͕YesͱͳΔ ❤ 6  ' 4+*4 6  ❤ Emoji=Yes 6OJDPEF 6OJDPEF

Slide 11

Slide 11 text

&NPKJଐੑͷఆٛ https://unicode.org/Public/emoji/12.0/emoji-data.txt Emojiଐੑ͕YesͰ͋Δ จࣈͷίʔυϙΠϯτΛྻ ڍ͢Δ͜ͱͰఆٛ͞Ε͍ͯ Δ (emoji-data.txt)

Slide 12

Slide 12 text

*$6ʹΑΔ&NPKJଐੑͷ൑ఆ import android.icu.lang.UCharacter import android.icu.lang.UProperty val whiteSmilingFace = Character.codePointAt("☺", 0) // (int)0x0000263a UCharacter.hasBinaryProperty(whiteSmilingFace, UProperty.EMOJI) // true val smilingFaceWithHalo = Character.codePointAt("", 0) // (int)0x0001f607 UCharacter.hasBinaryProperty(smilingFaceWithHalo, UProperty.EMOJI) // true val hiraganaLetterA = Character.codePointAt("͋", 0) // (int)0x00003042 UCharacter.hasBinaryProperty(hiraganaLetterA, UProperty.EMOJI) // false

Slide 13

Slide 13 text

WT ❤

Slide 14

Slide 14 text

&NPKJ1SFTFOUBUJPOଐੑ ❤ 5FYU1SFTFOUBUJPO നࠇ &NPKJ1SFTFOUBUJPO ֆจࣈ Emoji=Yes Emoji_Presentation=No 6  6 # Emoji=Yes Emoji_Presentation=Yes σϑΥϧτͷ1SFTFOUBUJPOΛࢦఆ ಉ༷ʹemoji-data.txtʹจࣈΛྻڍ͢Δ͜ͱͰఆٛ

Slide 15

Slide 15 text

&NPKJ1SFTFOUBUJPOͱҟମࣈηϨΫλ ❤ ⭐ 6  6 # 6 '&' 6 '&& 74 ʴ ʴ 74 &NPKJ1SFTFOUBUJPO 7BSJBUJPO4FMFDUPS 5FYU1SFTFOUBUJPO ˞IUUQTVOJDPEFPSH1VCMJDFNPKJFNPKJWBSJBUJPOTFRVFODFTUYUͰఆٛ͞Εͨ΋ͷ͔͠74͕෇͚ΒΕͳ͍

Slide 16

Slide 16 text

"OESPJE04ͷϑΥϯτͱ1SFTFOUBUJPO /PUP4BOT4ZNCPMT UFYUQSFTFOUBUJPO /PUP$PMPS&NPKJ FNPKJQSFTFOUBUJPO ࣍ϕδΤۂઢ HMZGςʔϒϧ 1/(ը૾ $#%5ςʔϒϧ

Slide 17

Slide 17 text

⭐ "OESPJE04ͰͷϑΥϯτͷ༏ઌ౓ /PUP4BOT4ZNCPMT3FHVMBS4VCTFUUFEUUG /PUP$PMPS&NPKJUUG /PUP4BOT4ZNCPMT3FHVMBS4VCTFUUFEUUG 6 ' /system/etc/fonts.xml ˞ ༏ઌ౓ 6 # 6 ' ˞74 74Λ͚ͭΔͱ༏ઌ౓͕มΘΔ   6 &% IJHI MPX σϑΥϧτ͕5FYU1SFTFOUBUJPOͷจࣈ σϑΥϧτ͕&NPKJ1SFTFOUBUJPOͷจࣈ σϑΥϧτ͕&NPKJ1SFTFOUBUJPO͕ͩޙΖʹ74Λ෇͚ΕΔจࣈ ˞IUUQTBOESPJEHPPHMFTPVSDFDPNQMBUGPSNGSBNFXPSLTCBTF BOESPJEDUT@SEBUBGPOUTGPOUTYNM

Slide 18

Slide 18 text

"OESPJEͰͷ6541SFTFOUBUJPOରԠঢ়گͷ࣮ࡍ w 74Λ͚ͭͯ΋5FYU1SFTFOUBUJPOʹͳΒͳ͍จࣈ͕͋Δ w /PUP4BOT4ZNCPMTϑΥϯτʹάϦϑ͕ͳ͍ͨΊ w σϑΥϧτ͕Emoji_Presentation=Noʹ΋ؔΘΒͣ5FYU 1SFTFOUBUJPOʹͳΒͳ͍จࣈ͕͋Δ w Emoji_Presentation=No͕ͩҙਤతʹσϑΥϧτΛ&NPKJ 1SFTFOUBUJPOʹઃఆ͍ͯ͠ΔͨΊ

Slide 19

Slide 19 text

IUUQTBOESPJEHPPHMFTPVSDFDPNQMBUGPSNFYUFSOBMOPUPGPOUT FEBFDFCDCED

Slide 20

Slide 20 text

6OJDPEFͷܗࣜతͳਖ਼͠͞ͱɺ ଟ͘Λֆจࣈʹ͢Δ"QQMF੡඼ Ͱͷ࣮ࡍͷ࢖ΘΕํͱͷؒͰͷ ଥڠҊͩͬͨΜͩɻ ҙ༁ IUUQTUXJUUFSDPNSBQIMJOVTTUBUVT

Slide 21

Slide 21 text

"OESPJE J04 σϑΥϧτ1SFTFOUBUJPOͷҧ͍

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

"OESPJE "OESPJE

Slide 24

Slide 24 text

&NPKJ4FRVFODF ෳ਺ͷจࣈ͕̍ͭͷֆจࣈΛߏ੒ FNPKJNPEJpFSTFRVFODF ˞Emoji_Modifier_BaseଐੑɺEmoji_Modifierଐੑ͸emoji-data.txtͰఆٛ Emoji_Modifier_Base Emoji_Modifier ʴ FNPKJDIBSBDUFS FNPKJQSFTFOUBUJPOTFRVFODF ❤ 6  6 '&' 74 ʴ 6 ' Emoji=Yes Emoji=Yes

Slide 25

Slide 25 text

ʴ 6  6 & FNPKJLFZDBQTFRVFODF  ⃣  6 '&' 74 ʴ FNPKJ[XKTFRVFODF ;8+ 6 % ;8+ ;8+ 6 % 6 % ʴ ʴ ʴ ʴ ʴ ʴ   $0.#*/*/(&/$-04*/(,&:$"1 ˞IUUQTVOJDPEFPSH1VCMJDFNPKJFNPKJ[XKTFRVFODFTUYUͰఆٛ͞Εͨ3(*4FRVFODFͷΈ

Slide 26

Slide 26 text

FNPKJqBHTFRVFODF ʴ FNPKJUBHTFRVFODF ( 6 & # & 6 & 6 && ʴ ʴ ʴ ʴ ʴ ʴ 6 '' / ( ✦ 6 & 6 & 6 &' 5BH$IBSBDUFST 3FHJPOBM*OEJDBUPS Y ˞IUUQTVOJDPEFPSH1VCMJDFNPKJFNPKJTFRVFODFTUYUͰఆٛ͞Εͨ3(*4FRVFODFͷΈ

Slide 27

Slide 27 text

"OESPJEͰͷ&NPKJ4FRVFODFͷඳը (46#ςʔϒϧʹ &NPKJ4FRVFODF͔ ΒάϦϑ΁ͷରԠ෇ ͚͕ఆٛ͞Ε͓ͯΓɺ )BSG#V[[͕ͦΕΛར ༻ͯ͠άϦϑΛஔ׵ HMZQI HMZQI HMZQI HMZQI (MZQI*% $#%5 V'"" (46#ςʔϒϧ 0QFO5ZQF  

Slide 28

Slide 28 text

ϑΥϯτʹ࠷৽ͷֆจࣈ͕ఆٛ͞Ε͍ͯͳ͍

Slide 29

Slide 29 text

(46#ʹ࠷৽ͷ4FRVFODF͕ఆٛ͞Ε͍ͯͳ͍

Slide 30

Slide 30 text

࠷৽ن֨΁ͷ௥ैઓུ

Slide 31

Slide 31 text

&NPKJ$PNQBUΛ࢖͓͏

Slide 32

Slide 32 text

&NPKJ$PNQBUͷ࢓૊Έ  04ͷֆจࣈඳըͷڍಈΛ্ॻ͖͢Δ 5FYU7JFX $BOWBT &NPKJ5FYU7JFX $BOWBT 4QBOOBCMF4USJOH &NPKJ4QBO

Slide 33

Slide 33 text

&NPKJ$PNQBUͷ࢓૊Έ  SpannableString Ϋϥε ಛघͳ૷০͕ࢪ͞Εͨ 4QBOOFE จࣈྻΛද͢ ReplacementSpan Ϋϥε ಛఆͷจࣈͷඳը෦෼Λஔ͖׵ ͑ΔͨΊͷSpan (PPE GGGGE 4QBOOBCMF4USJOH &NPKJ4QBO ˢ&NPKJ4QBO͕ඳը 04͕ඳըˢ $BOWBT

Slide 34

Slide 34 text

&NPKJ$PNQBUͷϑΥϯτϑΝΠϧ w ઐ༻ͷ/PUP$PMPS&NPKJ$PNQBUUUGΛར༻ w metaςʔϒϧʹ&NPKJ4FRVFODFͱରԠ ͢ΔάϦϑͳͲͷ৘ใ͕ຒΊࠐ·Ε͍ͯΔ w ϑΥϯτΛࠩ͠ସ͑Δ͜ͱͰ࠷৽ͷ&NPKJʹ ରԠ͢Δ͜ͱ͕Ͱ͖Δ ˠ%PXOMPBEBCMF'POUTͰৗʹ࠷৽ʹ table MetadataItem { id : int;= emojiStyle : bool; sdkAdded : short; compatAdded : short; width : short; height : short; codepoints : [int]; } FlatBuffer

Slide 35

Slide 35 text

&NPKJ$PNQBUͷઃఆ implementation "com.android.support:support-emoji-appcompat:27.1.1" implementation "com.android.support:support-emoji-bundled:27.1.1" class MyApplication : Application() { override fun onCreate() { super.onCreate() val config = BundledEmojiCompatConfig(this) config.setReplaceAll(true) EmojiCompat.init(config) } }

Slide 36

Slide 36 text

σϑΥϧτͷ1SFTFOUBUJPOΛมߋ͢Δ // શ෦Emoji Presentationʹ͢Δ config.setUseEmojiAsDefaultStyle(true) // iOSͷσϑΥϧτڍಈʹ߹ΘͤΔ val list = "☺☹✈♠♥♟↗↘↙↖↔㽉㽊⚕♾‼⁉⾺©®™".toCharArray().map { it.toInt() } + listOf(0x1f170, 0x1f171, 0x1f17e, 0x1f17f) // ⷁⷂ⷏ⷐ config.setUseEmojiAsDefaultStyle(true, list) // ແࢦఆ → Android OSͷσϑΥϧτPresentationʹै͏

Slide 37

Slide 37 text

6OJDPEF&NPKJͷจࣈྻॲཧ ͷ࣮૷ઓུ

Slide 38

Slide 38 text

6OJDPEF&NPKJΛؚΉจࣈྻͷॲཧ "OESPJE಺ଂͷ*$6͸࠷৽ͷֆจࣈʹରԠ͍ͯ͠ͳ͍ IUUQTBOESPJEHPPHMFTPVSDFDPNQMBUGPSNGSBNFXPSLTNJOJLJO BOESPJEDUT@SMJCTNJOJLJO&NPKJDQQ bool isNewEmoji(uint32_t c) { // Emoji characters new in Unicode emoji 11 // From https://www.unicode.org/Public/emoji/11.0/emoji-data.txt // TODO: Remove once emoji-data.text 11 is in ICU or update to 11. if (c < 0x1F6F9 || c > 0x1F9FF) { // Optimization for characters outside the new emoji range. return false; } return c == 0x265F || c == 0x267E || c == 0x1F6F9 || (0x1F94D <= c && c <= 0x1F94F) || (0x1F96C <= c && c <= 0x1F970) || (0x1F973 <= c && c <= 0x1F976) || c == 0x1F97A || (0x1F97C <= c && c <= 0x1F97F) || (0x1F998 <= c && c <= 0x1F9A2) || (0x1F9B0 <= c && c <= 0x1F9B9) || (0x1F9C1 <= c && c <= 0x1F9C2) || (0x1F9E7 <= c && c <= 0x1F9FF); } bool isEmoji(uint32_t c) { return isNewEmoji(c) || u_hasBinaryProperty(c, UCHAR_EMOJI); } ˣ*$6ͷ"1* minikin/Emoji.cpp

Slide 39

Slide 39 text

6OJDPEF&NPKJΛؚΉจࣈྻͷॲཧ val string = this.toString() var displayLength = 0 var i = 0 while (i < text.length) { val span = spans.firstOrNull { i == text.getSpanStart(it) } if (span == null) { //charCountͷ෼͚ͩΛ1จࣈͱΈͳ͢ val codePoint = string.codePointAt(i) val count = Character.charCount(codePoint) i += count } else { //EmojiSpanͷ͔͔͍ͬͯΔindex·ͰΛ1จࣈͱΈͳ͢ i = text.getSpanEnd(span) } displayLength++ } return displayLength IUUQTRJJUBDPNIJSPZVLJTFUPJUFNTDCCGBFGB

Slide 40

Slide 40 text

ಠࣗͷֆจࣈϑΥϯτͷར༻

Slide 41

Slide 41 text

ˡ5XFNPKJ

Slide 42

Slide 42 text

ΧελϜֆจࣈϑΥϯτ B αʔυύʔςΟͷֆจࣈϑΥϯτϕϯμ͔Βೖख w FNPKJPOFͳͲ C /PUP$PMPS&NPKJΛੜ੒͢ΔεΫϦϓτΛར༻ͯ͠࡞੒ w IUUQTHJUIVCDPNHPPHMFJOOPUPFNPKJ ˞ ˞ϊϋφͰ͸IUUQTHJUIVCDPNOPIBOBOPUPFNPKJUSFFUXFNPKJWQJTUPMVQEBUFͰੜ੒ ࡞੒ͨ͠ϑΥϯτΛGPOUSFTPVSDFʹ͍ΕͯsetTypeface() w ਺ࣈͳͲ͕ਖ਼͘͠දࣔ͞Εͳ͘ͳΔ͜ͱ͕͋Δ

Slide 43

Slide 43 text

/PUP4BOT4ZNCPMT3FHVMBS4VCTFUUFEUUG /PUP$PMPS&NPKJUUG /PUP4BOT4ZNCPMT3FHVMBS4VCTFUUFEUUG 6 ' 6 # 6 ' 6  FNPKJPOF@BOESPJEUUG ༏ઌ౓ IJHI MPX ʢsetTypface()Ͱࢦఆʣ ⭐ 3PCPUP3FHVMBSUUG 7 σϑΥϧτϑΥϯτΛ্ॻ͖ͯ͠͠·͏

Slide 44

Slide 44 text

&NPKJ$PNQBUXJUIΧελϜֆจࣈ "041಺ͷcreatefont.pyͰֆจࣈϑΥϯτΛ&NPKJ$PNQBU޲͚ ʹม׵ ͪΐͬͱͨ͠IBDL͸ඞཁ  "TTFUT಺ͷಠࣗϑΥϯτΛ&NPKJ$PNQBUʹಡΈࠐ·ͤΔ IUUQTHJTUHJUIVCDPNZVLJUBLFJDIJEFEFGFDEECEECGFG IUUQTBOESPJEHPPHMFTPVSDFDPNQMBUGPSNFYUFSOBMOPUPGPOUT BOESPJEDUT@SFNPKJDPNQBUDSFBUFGPOUQZ #VOEMFE&NPKJ$PNQBU$POpHΛࢀߟʹಠ࣮ࣗ૷

Slide 45

Slide 45 text

཈͓͍͑ͯͯ΄͍͠ϙΠϯτ

Slide 46

Slide 46 text

"OESPJE04 &NPKJ$PNQBU࣮૷ *$6 ಠࣗίʔυ ઐ༻ϑΥϯτʹຒΊࠐ· ΕͨϝλσʔλΛར༻ 04ϓϦΠϯετʔϧ ઐ༻ϑΥϯτΛ "TTFUPS(.4ܦ༝Ͱऔಘ จࣈྻॲཧ ϑΥϯτ

Slide 47

Slide 47 text

6OJDPEF&NPKJͷඳը΍จࣈྻॲཧ͸04Ͱ͸ͳ͘ &NPKJ$PNQBUʹґଘ͢ΔΑ͏ʹ࣮૷͢Δͷ͕Φεεϝ

Slide 48

Slide 48 text

No content