|
|
@ -2,6 +2,7 @@
|
|
|
|
Text rendering module.
|
|
|
|
Text rendering module.
|
|
|
|
]]
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local bit = require("bit")
|
|
|
|
local Font = require("ui/font")
|
|
|
|
local Font = require("ui/font")
|
|
|
|
local Cache = require("cache")
|
|
|
|
local Cache = require("cache")
|
|
|
|
local CacheItem = require("cacheitem")
|
|
|
|
local CacheItem = require("cacheitem")
|
|
|
@ -9,6 +10,10 @@ local BlitBuffer = require("ffi/blitbuffer")
|
|
|
|
local Device = require("device")
|
|
|
|
local Device = require("device")
|
|
|
|
local logger = require("logger")
|
|
|
|
local logger = require("logger")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local band = bit.band
|
|
|
|
|
|
|
|
local bor = bit.bor
|
|
|
|
|
|
|
|
local lshift = bit.lshift
|
|
|
|
|
|
|
|
|
|
|
|
if Device.should_restrict_JIT then
|
|
|
|
if Device.should_restrict_JIT then
|
|
|
|
require("jit").off(true, true)
|
|
|
|
require("jit").off(true, true)
|
|
|
|
end
|
|
|
|
end
|
|
|
@ -31,23 +36,23 @@ local function utf8Chars(input_text)
|
|
|
|
local function read_next_glyph(input, pos)
|
|
|
|
local function read_next_glyph(input, pos)
|
|
|
|
if string.len(input) < pos then return nil end
|
|
|
|
if string.len(input) < pos then return nil end
|
|
|
|
local value = string.byte(input, pos)
|
|
|
|
local value = string.byte(input, pos)
|
|
|
|
if bit.band(value, 0x80) == 0 then
|
|
|
|
if band(value, 0x80) == 0 then
|
|
|
|
-- TODO: check valid ranges
|
|
|
|
-- TODO: check valid ranges
|
|
|
|
return pos+1, value, string.sub(input, pos, pos)
|
|
|
|
return pos+1, value, string.sub(input, pos, pos)
|
|
|
|
elseif bit.band(value, 0xC0) == 0x80 -- invalid, continuation
|
|
|
|
elseif band(value, 0xC0) == 0x80 -- invalid, continuation
|
|
|
|
or bit.band(value, 0xF8) == 0xF8 -- 5-or-more byte sequence, illegal due to RFC3629
|
|
|
|
or band(value, 0xF8) == 0xF8 -- 5-or-more byte sequence, illegal due to RFC3629
|
|
|
|
then
|
|
|
|
then
|
|
|
|
return pos+1, 0xFFFD, "\xFF\xFD"
|
|
|
|
return pos+1, 0xFFFD, "\xFF\xFD"
|
|
|
|
else
|
|
|
|
else
|
|
|
|
local glyph, bytes_left
|
|
|
|
local glyph, bytes_left
|
|
|
|
if bit.band(value, 0xE0) == 0xC0 then
|
|
|
|
if band(value, 0xE0) == 0xC0 then
|
|
|
|
glyph = bit.band(value, 0x1F)
|
|
|
|
glyph = band(value, 0x1F)
|
|
|
|
bytes_left = 1
|
|
|
|
bytes_left = 1
|
|
|
|
elseif bit.band(value, 0xF0) == 0xE0 then
|
|
|
|
elseif band(value, 0xF0) == 0xE0 then
|
|
|
|
glyph = bit.band(value, 0x0F)
|
|
|
|
glyph = band(value, 0x0F)
|
|
|
|
bytes_left = 2
|
|
|
|
bytes_left = 2
|
|
|
|
elseif bit.band(value, 0xF8) == 0xF0 then
|
|
|
|
elseif band(value, 0xF8) == 0xF0 then
|
|
|
|
glyph = bit.band(value, 0x07)
|
|
|
|
glyph = band(value, 0x07)
|
|
|
|
bytes_left = 3
|
|
|
|
bytes_left = 3
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return pos+1, 0xFFFD, "\xFF\xFD"
|
|
|
|
return pos+1, 0xFFFD, "\xFF\xFD"
|
|
|
@ -57,8 +62,8 @@ local function utf8Chars(input_text)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
for i = pos+1, pos + bytes_left do
|
|
|
|
for i = pos+1, pos + bytes_left do
|
|
|
|
value = string.byte(input, i)
|
|
|
|
value = string.byte(input, i)
|
|
|
|
if bit.band(value, 0xC0) == 0x80 then
|
|
|
|
if band(value, 0xC0) == 0x80 then
|
|
|
|
glyph = bit.bor(bit.lshift(glyph, 6), bit.band(value, 0x3F))
|
|
|
|
glyph = bor(lshift(glyph, 6), band(value, 0x3F))
|
|
|
|
else
|
|
|
|
else
|
|
|
|
-- invalid UTF8 continuation - don't be greedy, just skip
|
|
|
|
-- invalid UTF8 continuation - don't be greedy, just skip
|
|
|
|
-- the initial char of the sequence.
|
|
|
|
-- the initial char of the sequence.
|
|
|
|