rockbox/apps/plugins/lua/include_lua/lcd.lua

155 lines
4.3 KiB
Lua
Raw Normal View History

Rocklua -- Extend / Fix rliImage Some devices(1-bit / 2-bit displays) have packed bit formats that need to be unpacked in order to work on them at a pixel level. This caused a few issues on 1 & 2-bit devices: Greatly Oversized data arrays for bitmaps Improper handling of native image data Framebuffer data was near unusable without jumping through hoops Conversion between native addressing and per pixel addressing incurs extra overhead but it is much faster to do it on the 'C' side rather than in lua. Not to mention the advantage of a unified interface for the end programer ------------------------------------------------------------------- Adds a sane way to access each pixel of image data Adds: -------------------------------------------------------------------- img:clear([color],[x1],[y1],[x2],[y2]) (set whole image or a portion to a particular value) -------------------------------------------------------------------- img:invert([x1],[y1],[x2],[y2]) (inverts whole image or a portion) -------------------------------------------------------------------- img:marshal([x1],[y1],[x2],[y2],[funct]) (calls funct for each point defined by rect of x1,y1 x2,y2 returns value and allows setting value of each point return nil to terminate early) -------------------------------------------------------------------- img:points([x1],[y1],[x2],[y2],[dx],[dy]) (returns iterator function that steps delta-x and delta-y pixels each call returns value of pixel each call but doesn't allow setting to a new value compare to lua pairs method) -------------------------------------------------------------------- img:copy(src,[x1],[y1],[x2],[y2],[w],[h],[clip][operation][clr/funct]) (copies all or part of an image -- straight copy or special ops optionally calls funct for each point defined by rect of x1, y1, w, h and x2, y2, w, h for dest and src images returns value of dst and src and allows setting value of each point return nil to terminate early) -------------------------------------------------------------------- img:line(x1, y1, x2, y2, color) -------------------------------------------------------------------- img:ellipse(x1, y1, x2, y2, color, [fillcolor] -------------------------------------------------------------------- Fixed handling of 2-bit vertical integrated screens Added direct element access for saving / restoring native image etc. Added more data to tostring() handler and a way to access individual items Added equals method to see if two variables reference the same image address (doesn't check if two separate images contain the same 'picture') Optimized get and set routines Fixed out of bound x coord access shifting to next line Added lua include files to expose new functionality Finished image saving routine Static allocation of set_viewport struct faster + saves ram over dynamic Cleaned up code Fixed pixel get/set for 1/2 bit devices Fixed handling for 24-bit devices (32?) ------------------------------------------------------------------------- Example lua script to follow on forums ------------------------------------------------------------------------- Change-Id: I8a9ff0ff72aacf4b1662767ccb2b312fc355239c
2018-07-23 00:50:22 +00:00
--[[ Lua LCD Wrapper functions
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2017 William Wilgus
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
]]
--[[ Exposed Functions
_lcd.clear
_lcd.duplicate
_lcd.image
_lcd.set_viewport
_lcd.splashf
_lcd.text_extent
_lcd.update
_lcd.update_rect
-- Exposed Constants
_lcd.CX
_lcd.CY
_lcd.DEPTH
_lcd.W
_lcd.H
_lcd
_LCD
]]
if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end
_LCD = rb.lcd_framebuffer()
local _lcd = {} do
--internal constants
local _NIL = nil -- _NIL placeholder
local LCD_W, LCD_H = rb.LCD_WIDTH, rb.LCD_HEIGHT
-- clamps value to >= min and <= max
local function clamp(val, min, max)
-- Warning doesn't check if min < max
if val < min then
return min
elseif val < max then
return val
end
return max
end
-- return a copy of lcd screen
local function duplicate(t, screen_img)
screen_img = screen_img or rb.new_image()
screen_img:copy(rb.lcd_framebuffer())
return screen_img
end
-- updates screen in specified rectangle
local function update_rect(t, x, y, w, h)
rb.lcd_update_rect(x - 1, y - 1,
clamp(x + w, 1, LCD_W) - 1,
clamp(y + h, 1, LCD_H) - 1)
end
-- clears lcd, optional.. ([color, x1, y1, x2, y2, clip])
local function clear(t, clr, ...)
if clr == _NIL and ... == _NIL then
rb.lcd_clear_display()
else
rb.lcd_scroll_stop() --rb really doesn't like bg change while scroll
_LCD:clear(clr, ...)
end
end
-- loads an image to the screen
local function image(t, src, x, y)
if not src then --make sure an image was passed, otherwise bail
rb.splash(rb.HZ, "No Image!")
return _NIL
end
_LCD:copy(src,x,y,1,1)
end
-- Formattable version of splash
local function splashf(t, timeout, ...)
rb.splash(timeout, string.format(...))
end
-- Gets size of text
local function text_extent(t, msg, font)
font = font or rb.FONT_UI
return rb.font_getstringsize(msg, font)
end
-- Sets viewport size
local function set_viewport(t, vp)
if not vp then rb.set_viewport() return end
if rb.LCD_DEPTH == 2 then -- invert 2-bit screens
--vp.drawmode = bit.bxor(vp.drawmode, 4)
vp.fg_pattern = 3 - vp.fg_pattern
vp.bg_pattern = 3 - vp.bg_pattern
end
rb.set_viewport(vp)
end
-- allows the use of _lcd() as a identifier for the screen
local function index(k, v)
return function(x, ...)
_LCD[v](_LCD, ...)
end
end
-- allows the use of _lcd() as a identifier for the screen
local function call()
return rb.lcd_framebuffer()
end
--expose functions to the outside through _lcd table
_lcd.text_extent = text_extent
_lcd.set_viewport = set_viewport
_lcd.duplicate = duplicate
_lcd.update = rb.lcd_update
_lcd.update_rect = update_rect
_lcd.clear = clear
_lcd.splashf = splashf
_lcd.image = image
_lcd.DEPTH = rb.LCD_DEPTH
_lcd.W = rb.LCD_WIDTH
_lcd.H = rb.LCD_HEIGHT
_lcd.CX = (rb.LCD_WIDTH / 2)
_lcd.CY = (rb.LCD_HEIGHT / 2)
_lcd = setmetatable(_lcd,{__index = index, __call = call})
end -- _lcd functions
return _lcd