210 lines
6.6 KiB
Lua
210 lines
6.6 KiB
Lua
--这是一个简单的打印字符的程序,他使用下方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
|
||
|