Files
ComputerCraft-Utf8/utf8ptrint.lua
2025-11-12 12:06:16 +08:00

210 lines
6.6 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--这是一个简单的打印字符的程序他使用下方url的字体进行显示
--因为字体文件超过cc存储大小所以使用网络加载字体
--通过printUtf8("字符",文字颜色,背景颜色)来达到类似 print的效果
--示例printUtf8("你好世界! Hello Word!",colors.white,colors.lightGray)
-- 从网络加载字库
local function loadRemoteFont(url)
local response = http.get(url)
if not response then
error("无法连接到字体服务器")
end
if response.getResponseCode() ~= 200 then
error("字体服务器返回错误: " .. response.getResponseCode())
end
local content = response.readAll()
response.close()
-- 使用沙箱环境安全加载字体
local sandbox = {}
local chunk, err = load(content, "=remoteFont", "t", sandbox)
if not chunk then
error("加载字体失败: " .. err)
end
local success, result = pcall(chunk)
if not success then
error("执行字体脚本失败: " .. result)
end
return sandbox.font or sandbox[1] or result
end
-- 字体URL
local fontUrl = "https://git.liulikeji.cn/xingluo/ComputerCraft-Utf8/raw/branch/main/fonts/fusion-pixel-8px-proportional-zh_hans.lua"
local font = loadRemoteFont(fontUrl)
-- 显示单个字符的函数
local function displayChar(charMap, x, y, textColor, backgroundColor)
-- 保存原始终端颜色设置
local origTextColor = term.getTextColor()
local origBackgroundColor = term.getBackgroundColor()
-- 设置新颜色
term.setTextColor(textColor)
term.setBackgroundColor(backgroundColor)
-- 遍历字符位图的每一行
for row = 1, #charMap do
term.setCursorPos(x, y + row - 1)
local line = charMap[row]
-- 遍历行中的每个像素
for col = 1, #line do
local byte = string.byte(line, col)
-- 处理像素颜色
if byte < 128 then
-- 背景色像素:反转颜色设置
term.setTextColor(backgroundColor)
term.setBackgroundColor(textColor)
term.write(string.char(byte + 128)) -- 转换为可打印字符
else
-- 前景色像素:正常颜色设置
term.setTextColor(textColor)
term.setBackgroundColor(backgroundColor)
term.write(string.char(byte))
end
end
end
-- 恢复原始颜色设置
term.setTextColor(origTextColor)
term.setBackgroundColor(origBackgroundColor)
end
-- 显示UTF-8字符串的函数
local function displayUtf8String(str, font, x, y, textColor, backgroundColor)
-- UTF-8解码器简化版
local function utf8codes(str)
local i = 1
return function()
if i > #str then return end
local b1 = string.byte(str, i)
i = i + 1
-- 单字节字符 (ASCII)
if b1 < 0x80 then
return b1
-- 双字节字符
elseif b1 >= 0xC0 and b1 < 0xE0 then
local b2 = string.byte(str, i) or 0
i = i + 1
return (b1 - 0xC0) * 64 + (b2 - 0x80)
-- 三字节字符(中文)
elseif b1 >= 0xE0 and b1 < 0xF0 then
local b2 = string.byte(str, i) or 0
i = i + 1
local b3 = string.byte(str, i) or 0
i = i + 1
return (b1 - 0xE0) * 4096 + (b2 - 0x80) * 64 + (b3 - 0x80)
else
-- 不支持的编码,返回空格
return 32
end
end
end
local cursorX = x
-- 遍历字符串中的所有字符
for code in utf8codes(str) do
-- 获取字符位图
local charMap = font[code]
if not charMap then
-- 如果字库中没有该字符,使用空格代替
charMap = font[32] or {{"\x80"}} -- 空格字符
end
-- 显示字符
displayChar(charMap, cursorX, y, textColor, backgroundColor)
-- 移动到下一个字符位置
cursorX = cursorX + #charMap[1]
end
end
local cursorX, cursorY = 1, 1
local fontHeight = #font[32] -- 获取字体高度(使用空格字符)
-- 自定义打印函数(带自动换行和滚动)
local function printUtf8(str, textColor, backgroundColor)
local width, screenHeight = term.getSize() -- 获取终端尺寸
-- UTF-8解码器
local function utf8codes(str)
local i = 1
return function()
if i > #str then return end
local b1 = string.byte(str, i)
i = i + 1
if b1 < 0x80 then
return b1
elseif b1 >= 0xC0 and b1 < 0xE0 then
local b2 = string.byte(str, i) or 0
i = i + 1
return (b1 - 0xC0) * 64 + (b2 - 0x80)
elseif b1 >= 0xE0 and b1 < 0xF0 then
local b2 = string.byte(str, i) or 0
i = i + 1
local b3 = string.byte(str, i) or 0
i = i + 1
return (b1 - 0xE0) * 4096 + (b2 - 0x80) * 64 + (b3 - 0x80)
else
return 32 -- 不支持的字符显示为空格
end
end
end
-- 处理字符串中的每个字符
for code in utf8codes(str) do
-- 处理换行符
if code == 10 then -- \n 的 ASCII
cursorX = 1
cursorY = cursorY + fontHeight
else
local charMap = font[code] or font[32]
local charWidth = #charMap[1]
-- 检查是否需要换行
if cursorX + charWidth - 1 > width then
cursorX = 1
cursorY = cursorY + fontHeight
end
-- 检查是否需要滚动屏幕
if cursorY + fontHeight - 1 > screenHeight then
term.scroll(fontHeight)
cursorY = cursorY - fontHeight
end
-- 显示字符
displayChar(charMap, cursorX, cursorY, textColor, backgroundColor)
cursorX = cursorX + charWidth
end
end
-- 自动换行(处理完字符串后)
cursorX = 1
-- 光标应该位于下一行的顶部,而不是底部
cursorY = cursorY + fontHeight
-- 检查滚动(换行后)
if cursorY > screenHeight then
term.scroll(fontHeight)
cursorY = screenHeight - fontHeight + 1
end
end
return printUtf8