The (simple) experiment below (updated for Codea version 1.5.1) takes into account the past discussions here
and here.
It illustrates the current (odd) behaviour of the text() function when rendering Unicode emoji at different fontSize(), when the font() is not font("AppleColorEmoji").
--
-- Emoji
--
supportedOrientations(LANDSCAPE_ANY)
function setup()
parameter.integer("size", 1, 64, 20)
-- This could be entered directly from an iPad emoji keyboard
-- but that can not be copy-pasted into the Codea forum
monkeyFace = unicode2UTF8(0x01F435)
dogFace = unicode2UTF8(0x01F436)
pigFace = unicode2UTF8(0x01F437)
frogFace = unicode2UTF8(0x01F438)
str = "emoji: "..monkeyFace..dogFace..pigFace..frogFace
fill(255)
textMode(CORNER)
print("Experiments with emoji.")
print(str)
w = 50
h = {
HEIGHT/2 + 180,
HEIGHT/2 + 100,
HEIGHT/2,
HEIGHT/2 - 80
}
end
function draw()
background(0)
fontSize(20)
font("Inconsolata")
text("With font(\"HelveticaNeue\")", w, h[1])
text("With font (\"AppleColorEmoji\")", w, h[3])
fontSize(size)
font("HelveticaNeue")
text(str, w, h[2]) -- Emoji stop scaling if size > ~20
font("AppleColorEmoji")
text(str, w, h[4]) -- Emoji are scaled as expected
end
-- Unicode code point to UTF-8 format string of bytes
--
-- Bit Last point Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
-- 7 U+007F 0xxxxxxx
-- 11 U+07FF 110xxxxx 10xxxxxx
-- 16 U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
-- 21 U+1FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-- 26 U+3FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
-- 31 U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
--
-- However, largest integer in Codea's Lua is 0x7FFFFF (23 bit)
-- With acknowledgement also to Andrew Stacey's UTF-8 library
function unicode2UTF8(u)
u = math.max(0, math.floor(u)) -- A positive integer
local UTF8
if u < 0x80 then -- less than 8 bits
UTF8 = string.char(u)
elseif u < 0x800 then -- less than 12 bits
local b2 = u % 0x40 + 0x80
local b1 = math.floor(u/0x40) + 0xC0
UTF8 = string.char(b1, b2)
elseif u < 0x10000 then -- less than 16 bits
local b3 = u % 0x40 + 0x80
local b2 = math.floor(u/0x40) % 0x40 + 0x80
local b1 = math.floor(u/0x1000) + 0xE0
UTF8 = string.char(b1, b2, b3)
elseif u < 0x200000 then -- less than 22 bits
local b4 = u % 0x40 + 0x80
local b3 = math.floor(u/0x40) % 0x40 + 0x80
local b2 = math.floor(u/0x1000) % 0x40 + 0x80
local b1 = math.floor(u/0x40000) + 0xF0
UTF8 = string.char(b1, b2, b3, b4)
elseif u < 0x800000 then -- less than 24 bits
local b5 = u % 0x40 + 0x80
local b4 = math.floor(u/0x40) % 0x40 + 0x80
local b3 = math.floor(u/0x1000) % 0x40 + 0x80
local b2 = math.floor(u/0x40000) % 0x40 + 0x80
local b1 = math.floor(u/0x1000000) + 0xF8
UTF8 = string.char(b1, b2, b3, b4, b5)
else
print("Error: Code point too large for Codea's Lua.")
end
return UTF8
end
```
The code below (updated for Codea version 1.5.1) provides a viewer for the various emoji.
--
-- Emoji Viewer
--
supportedOrientations(LANDSCAPE_ANY)
function setup()
parameter.integer("Page", 1, 5)
fill(255)
textMode(CENTER)
isZoomed = false
pickedCharUnicode = nil
pickedChar = nil
page = Page
print("Use the slider to choose a page of emoji.")
print("Tap emoji to zoom in")
print("Tap again to zoom out.")
print()
print("A white box means no emoji defined for that code.")
end
function draw()
background(0)
if Page ~= page then
page = Page
isZoomed = false
end
if isZoomed then
font("AppleColorEmoji")
fontSize(512)
text(pickedChar, WIDTH/2, HEIGHT/2)
fontSize(64)
text(pickedChar, WIDTH/2, 150)
font("Inconsolata")
fontSize(64)
local title = string.format("U+%4X", pickedCharUnicode)..
" (= "..pickedCharUnicode..")"
text(title, WIDTH/2, 50)
else
font("AppleColorEmoji")
fontSize(40)
local base = base(Page)
for j = 0, 15 do
for i = 0, 15 do
local u = base + i * 0x10 + j
local char = unicode2UTF8(u)
local x = WIDTH/16 * (i + 1/2)
local y = HEIGHT/16 * (15 - j + 1/2)
text(char, x, y)
end
end
end
end
function base(page)
if page < 4 then
return 0x1F300 + (page - 1) * 0x100
elseif page < 5 then
return 0x1F600
end
return 0x2600
end
function touched(touch)
if touch.state == BEGAN then
if isZoomed then
isZoomed = false
else
isZoomed = true
local base = base(Page)
local i = math.floor(touch.x/WIDTH * 16)
local j = 15 - math.floor(touch.y/HEIGHT * 16)
pickedCharUnicode = base + i * 0x10 + j
pickedChar = unicode2UTF8(pickedCharUnicode)
end
end
end
-- Unicode code point to UTF-8 format string of bytes
--
-- Bit Last point Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
-- 7 U+007F 0xxxxxxx
-- 11 U+07FF 110xxxxx 10xxxxxx
-- 16 U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
-- 21 U+1FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-- 26 U+3FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
-- 31 U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
--
-- However, largest integer in Codea's Lua is 0x7FFFFF (23 bit)
-- With acknowledgement also to Andrew Stacey's UTF-8 library
function unicode2UTF8(u)
u = math.max(0, math.floor(u)) -- A positive integer
local UTF8
if u < 0x80 then -- less than 8 bits
UTF8 = string.char(u)
elseif u < 0x800 then -- less than 12 bits
local b2 = u % 0x40 + 0x80
local b1 = math.floor(u/0x40) + 0xC0
UTF8 = string.char(b1, b2)
elseif u < 0x10000 then -- less than 16 bits
local b3 = u % 0x40 + 0x80
local b2 = math.floor(u/0x40) % 0x40 + 0x80
local b1 = math.floor(u/0x1000) + 0xE0
UTF8 = string.char(b1, b2, b3)
elseif u < 0x200000 then -- less than 22 bits
local b4 = u % 0x40 + 0x80
local b3 = math.floor(u/0x40) % 0x40 + 0x80
local b2 = math.floor(u/0x1000) % 0x40 + 0x80
local b1 = math.floor(u/0x40000) + 0xF0
UTF8 = string.char(b1, b2, b3, b4)
elseif u < 0x800000 then -- less than 24 bits
local b5 = u % 0x40 + 0x80
local b4 = math.floor(u/0x40) % 0x40 + 0x80
local b3 = math.floor(u/0x1000) % 0x40 + 0x80
local b2 = math.floor(u/0x40000) % 0x40 + 0x80
local b1 = math.floor(u/0x1000000) + 0xF8
UTF8 = string.char(b1, b2, b3, b4, b5)
else
print("Error: Code point too large for Codea's Lua.")
end
return UTF8
end
```