mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-02-09 07:30:04 +00:00
Use blit to draw boxes, add colors.toBlit (#570)
This commit is contained in:
parent
666e83cf4f
commit
741adfa7bb
@ -332,3 +332,21 @@ function rgb8(r, g, b)
|
||||
return packRGB(r, g, b)
|
||||
end
|
||||
end
|
||||
|
||||
-- Colour to hex lookup table for toBlit
|
||||
local color_hex_lookup = {}
|
||||
for i = 0, 15 do
|
||||
color_hex_lookup[2 ^ i] = string.format("%x", i)
|
||||
end
|
||||
|
||||
--- Converts the given color to a paint/blit hex character (0-9a-f).
|
||||
--
|
||||
-- This is equivalent to converting floor(log_2(color)) to hexadecimal.
|
||||
--
|
||||
-- @tparam number color The color to convert.
|
||||
-- @treturn string The blit hex code of the color.
|
||||
function toBlit(color)
|
||||
expect(1, color, "number")
|
||||
return color_hex_lookup[color] or
|
||||
string.format("%x", math.floor(math.log(color) / math.log(2)))
|
||||
end
|
||||
|
@ -23,6 +23,25 @@ local function parseLine(tImageArg, sLine)
|
||||
table.insert(tImageArg, tLine)
|
||||
end
|
||||
|
||||
-- Sorts pairs of startX/startY/endX/endY such that the start is always the min
|
||||
local function sortCoords(startX, startY, endX, endY)
|
||||
local minX, maxX, minY, maxY
|
||||
|
||||
if startX <= endX then
|
||||
minX, maxX = startX, endX
|
||||
else
|
||||
minX, maxX = endX, startX
|
||||
end
|
||||
|
||||
if startY <= endY then
|
||||
minY, maxY = startY, endY
|
||||
else
|
||||
minY, maxY = endY, startY
|
||||
end
|
||||
|
||||
return minX, maxX, minY, maxY
|
||||
end
|
||||
|
||||
--- Parses an image from a multi-line string
|
||||
--
|
||||
-- @tparam string image The string containing the raw-image data.
|
||||
@ -71,9 +90,6 @@ function drawPixel(xPos, yPos, colour)
|
||||
expect(2, yPos, "number")
|
||||
expect(3, colour, "number", "nil")
|
||||
|
||||
if type(xPos) ~= "number" then error("bad argument #1 (expected number, got " .. type(xPos) .. ")", 2) end
|
||||
if type(yPos) ~= "number" then error("bad argument #2 (expected number, got " .. type(yPos) .. ")", 2) end
|
||||
if colour ~= nil and type(colour) ~= "number" then error("bad argument #3 (expected number, got " .. type(colour) .. ")", 2) end
|
||||
if colour then
|
||||
term.setBackgroundColor(colour)
|
||||
end
|
||||
@ -111,17 +127,7 @@ function drawLine(startX, startY, endX, endY, colour)
|
||||
return
|
||||
end
|
||||
|
||||
local minX = math.min(startX, endX)
|
||||
local maxX, minY, maxY
|
||||
if minX == startX then
|
||||
minY = startY
|
||||
maxX = endX
|
||||
maxY = endY
|
||||
else
|
||||
minY = endY
|
||||
maxX = startX
|
||||
maxY = startY
|
||||
end
|
||||
local minX, maxX, minY, maxY = sortCoords(startX, startY, endX, endY)
|
||||
|
||||
-- TODO: clip to screen rectangle?
|
||||
|
||||
@ -177,37 +183,33 @@ function drawBox(startX, startY, endX, endY, nColour)
|
||||
endY = math.floor(endY)
|
||||
|
||||
if nColour then
|
||||
term.setBackgroundColor(nColour)
|
||||
term.setBackgroundColor(nColour) -- Maintain legacy behaviour
|
||||
else
|
||||
nColour = term.getBackgroundColour()
|
||||
end
|
||||
local colourHex = colours.toBlit(nColour)
|
||||
|
||||
if startX == endX and startY == endY then
|
||||
drawPixelInternal(startX, startY)
|
||||
return
|
||||
end
|
||||
|
||||
local minX = math.min(startX, endX)
|
||||
local maxX, minY, maxY
|
||||
if minX == startX then
|
||||
minY = startY
|
||||
maxX = endX
|
||||
maxY = endY
|
||||
else
|
||||
minY = endY
|
||||
maxX = startX
|
||||
maxY = startY
|
||||
end
|
||||
local minX, maxX, minY, maxY = sortCoords(startX, startY, endX, endY)
|
||||
local width = maxX - minX + 1
|
||||
|
||||
for x = minX, maxX do
|
||||
drawPixelInternal(x, minY)
|
||||
drawPixelInternal(x, maxY)
|
||||
end
|
||||
|
||||
if maxY - minY >= 2 then
|
||||
for y = minY + 1, maxY - 1 do
|
||||
drawPixelInternal(minX, y)
|
||||
drawPixelInternal(maxX, y)
|
||||
for y = minY, maxY do
|
||||
if y == minY or y == maxY then
|
||||
term.setCursorPos(minX, y)
|
||||
term.blit((" "):rep(width), colourHex:rep(width), colourHex:rep(width))
|
||||
else
|
||||
term.setCursorPos(minX, y)
|
||||
term.blit(" ", colourHex, colourHex)
|
||||
term.setCursorPos(maxX, y)
|
||||
term.blit(" ", colourHex, colourHex)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Draws a filled box on the current term from the specified start position to
|
||||
-- the specified end position.
|
||||
--
|
||||
@ -233,29 +235,23 @@ function drawFilledBox(startX, startY, endX, endY, nColour)
|
||||
endY = math.floor(endY)
|
||||
|
||||
if nColour then
|
||||
term.setBackgroundColor(nColour)
|
||||
term.setBackgroundColor(nColour) -- Maintain legacy behaviour
|
||||
else
|
||||
nColour = term.getBackgroundColour()
|
||||
end
|
||||
local colourHex = colours.toBlit(nColour)
|
||||
|
||||
if startX == endX and startY == endY then
|
||||
drawPixelInternal(startX, startY)
|
||||
return
|
||||
end
|
||||
|
||||
local minX = math.min(startX, endX)
|
||||
local maxX, minY, maxY
|
||||
if minX == startX then
|
||||
minY = startY
|
||||
maxX = endX
|
||||
maxY = endY
|
||||
else
|
||||
minY = endY
|
||||
maxX = startX
|
||||
maxY = startY
|
||||
end
|
||||
local minX, maxX, minY, maxY = sortCoords(startX, startY, endX, endY)
|
||||
local width = maxX - minX + 1
|
||||
|
||||
for x = minX, maxX do
|
||||
for y = minY, maxY do
|
||||
drawPixelInternal(x, y)
|
||||
end
|
||||
for y = minY, maxY do
|
||||
term.setCursorPos(minX, y)
|
||||
term.blit((" "):rep(width), colourHex:rep(width), colourHex:rep(width))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -73,4 +73,20 @@ describe("The colors library", function()
|
||||
expect(colors.rgb8(0.3, 0.5, 0.6)):equals(0x4c7f99)
|
||||
expect({ colors.rgb8(0x4c7f99) }):same { 0x4c / 0xFF, 0x7f / 0xFF, 0.6 }
|
||||
end)
|
||||
|
||||
describe("colors.toBlit", function()
|
||||
it("validates arguments", function()
|
||||
expect.error(colors.toBlit, nil):eq("bad argument #1 (expected number, got nil)")
|
||||
end)
|
||||
|
||||
it("converts all colors", function()
|
||||
for i = 0, 15 do
|
||||
expect(colors.toBlit(2 ^ i)):eq(string.format("%x", i))
|
||||
end
|
||||
end)
|
||||
|
||||
it("floors colors", function()
|
||||
expect(colors.toBlit(16385)):eq("e")
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
@ -1,4 +1,19 @@
|
||||
local with_window = require "test_helpers".with_window
|
||||
|
||||
describe("The paintutils library", function()
|
||||
-- Verifies that a window's lines are equal to the given table of blit
|
||||
-- strings ({{"text", "fg", "bg"}, {"text", "fg", "bg"}...})
|
||||
local function window_eq(w, state)
|
||||
-- Verification of the size isn't really important in the tests, but
|
||||
-- better safe than sorry.
|
||||
local _, height = w.getSize()
|
||||
expect(#state):eq(height)
|
||||
|
||||
for line = 1, height do
|
||||
expect({ w.getLine(line) }):same(state[line])
|
||||
end
|
||||
end
|
||||
|
||||
describe("paintutils.parseImage", function()
|
||||
it("validates arguments", function()
|
||||
paintutils.parseImage("")
|
||||
@ -28,6 +43,30 @@ describe("The paintutils library", function()
|
||||
expect.error(paintutils.drawLine, 1, 1, 1, nil):eq("bad argument #4 (expected number, got nil)")
|
||||
expect.error(paintutils.drawLine, 1, 1, 1, 1, false):eq("bad argument #5 (expected number, got boolean)")
|
||||
end)
|
||||
|
||||
it("draws a line going across with custom colour", function()
|
||||
local w = with_window(3, 2, function()
|
||||
paintutils.drawLine(1, 1, 3, 1, colours.red)
|
||||
end)
|
||||
|
||||
window_eq(w, {
|
||||
{ " ", "000", "eee" },
|
||||
{ " ", "000", "fff" },
|
||||
})
|
||||
end)
|
||||
|
||||
it("draws a line going diagonally with term colour", function()
|
||||
local w = with_window(3, 3, function()
|
||||
term.setBackgroundColour(colours.red)
|
||||
paintutils.drawLine(1, 1, 3, 3)
|
||||
end)
|
||||
|
||||
window_eq(w, {
|
||||
{ " ", "000", "eff" },
|
||||
{ " ", "000", "fef" },
|
||||
{ " ", "000", "ffe" },
|
||||
})
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("paintutils.drawBox", function()
|
||||
@ -38,6 +77,45 @@ describe("The paintutils library", function()
|
||||
expect.error(paintutils.drawBox, 1, 1, 1, nil):eq("bad argument #4 (expected number, got nil)")
|
||||
expect.error(paintutils.drawBox, 1, 1, 1, 1, false):eq("bad argument #5 (expected number, got boolean)")
|
||||
end)
|
||||
|
||||
it("draws a box with term colour", function()
|
||||
local w = with_window(3, 3, function()
|
||||
term.setBackgroundColour(colours.red)
|
||||
paintutils.drawBox(1, 1, 3, 3)
|
||||
end)
|
||||
|
||||
window_eq(w, {
|
||||
{ " ", "eee", "eee" },
|
||||
{ " ", "e0e", "efe" },
|
||||
{ " ", "eee", "eee" },
|
||||
})
|
||||
end)
|
||||
|
||||
it("draws a box with custom colour", function()
|
||||
local w = with_window(3, 3, function()
|
||||
paintutils.drawBox(1, 1, 3, 3, colours.red)
|
||||
end)
|
||||
|
||||
window_eq(w, {
|
||||
{ " ", "eee", "eee" },
|
||||
{ " ", "e0e", "efe" },
|
||||
{ " ", "eee", "eee" },
|
||||
})
|
||||
end)
|
||||
|
||||
it("draws a box without overwriting existing content", function()
|
||||
local w = with_window(3, 3, function()
|
||||
term.setCursorPos(2, 2)
|
||||
term.write("a")
|
||||
paintutils.drawBox(1, 1, 3, 3, colours.red)
|
||||
end)
|
||||
|
||||
window_eq(w, {
|
||||
{ " ", "eee", "eee" },
|
||||
{ " a ", "e0e", "efe" },
|
||||
{ " ", "eee", "eee" },
|
||||
})
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("paintutils.drawFilledBox", function()
|
||||
@ -48,6 +126,31 @@ describe("The paintutils library", function()
|
||||
expect.error(paintutils.drawFilledBox, 1, 1, 1, nil):eq("bad argument #4 (expected number, got nil)")
|
||||
expect.error(paintutils.drawFilledBox, 1, 1, 1, 1, false):eq("bad argument #5 (expected number, got boolean)")
|
||||
end)
|
||||
|
||||
it("draws a filled box with term colour", function()
|
||||
local w = with_window(3, 3, function()
|
||||
term.setBackgroundColour(colours.red)
|
||||
paintutils.drawFilledBox(1, 1, 3, 3)
|
||||
end)
|
||||
|
||||
window_eq(w, {
|
||||
{ " ", "eee", "eee" },
|
||||
{ " ", "eee", "eee" },
|
||||
{ " ", "eee", "eee" },
|
||||
})
|
||||
end)
|
||||
|
||||
it("draws a filled box with custom colour", function()
|
||||
local w = with_window(3, 3, function()
|
||||
paintutils.drawFilledBox(1, 1, 3, 3, colours.red)
|
||||
end)
|
||||
|
||||
window_eq(w, {
|
||||
{ " ", "eee", "eee" },
|
||||
{ " ", "eee", "eee" },
|
||||
{ " ", "eee", "eee" },
|
||||
})
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("paintutils.drawImage", function()
|
||||
|
Loading…
x
Reference in New Issue
Block a user