diff options
author | William Wilgus <me.theuser@yahoo.com> | 2019-08-26 22:17:33 -0500 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2019-08-26 22:17:33 -0500 |
commit | b99d4d7fa900a4f6cebd5b87420e2831fdb5a4f3 (patch) | |
tree | 39b20e0710f33e76897224865497b42781696aa8 /apps/plugins/lua/include_lua | |
parent | 9f551b09f68a8cf5d319ab2a2cf97cef15a53074 (diff) | |
download | rockbox-b99d4d7fa900a4f6cebd5b87420e2831fdb5a4f3.tar.gz rockbox-b99d4d7fa900a4f6cebd5b87420e2831fdb5a4f3.zip |
lua optimize poly_draw add draw_number, poly_points modules
Change-Id: Id36e765f18234f5a4f3092d090c0adffa3da1612
Diffstat (limited to 'apps/plugins/lua/include_lua')
-rw-r--r-- | apps/plugins/lua/include_lua/draw_num.lua | 115 | ||||
-rw-r--r-- | apps/plugins/lua/include_lua/draw_poly.lua | 107 | ||||
-rw-r--r-- | apps/plugins/lua/include_lua/poly_points.lua | 118 |
3 files changed, 297 insertions, 43 deletions
diff --git a/apps/plugins/lua/include_lua/draw_num.lua b/apps/plugins/lua/include_lua/draw_num.lua new file mode 100644 index 0000000000..0f42c1f9f5 --- /dev/null +++ b/apps/plugins/lua/include_lua/draw_num.lua | |||
@@ -0,0 +1,115 @@ | |||
1 | --[[ Lua draw number function | ||
2 | /*************************************************************************** | ||
3 | * __________ __ ___. | ||
4 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
5 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
6 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
7 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
8 | * \/ \/ \/ \/ \/ | ||
9 | * $Id$ | ||
10 | * | ||
11 | * Copyright (C) 2019 William Wilgus | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | ]] | ||
23 | |||
24 | --[[ Exposed Functions | ||
25 | _draw_nums.print; binary (base = 2) , octal (base = 8), hexadecimal (base = 16) | ||
26 | _draw_nums.nums; table of number characters | ||
27 | ]] | ||
28 | |||
29 | if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end | ||
30 | |||
31 | local _draw_nums = {} do | ||
32 | local _poly = require "draw_poly" | ||
33 | |||
34 | -- every 2 elements is an x, y coord pair | ||
35 | -- n[?] = {x,y,x,y,x,y} | ||
36 | local nums = { | ||
37 | ["b"] = {0,1,0,7,0,5,1,4,1,4,2,4,3,5,3,6,2,7,1,7,0,6,0,5}, | ||
38 | ["o"] = {1,4,0,5,0,6,1,7,2,7,3,6,3,5,2,4,1,4}, | ||
39 | ["x"] = {0,3,4,7,2,5,4,3,0,7}, | ||
40 | [-1] = {1,4, 3,4}, | ||
41 | [0] = {1,2,1,6,2,7,3,7,4,6,4,2,3,1,2,1,1,2}, | ||
42 | [1] = {3,1,3,7}, | ||
43 | [2] = {1,1,3,1,4,2,4,3,3,4,1,5,1,7,4,7}, | ||
44 | [3] = {1,1,3,1,4,2,4,3,3,4,2,4,3,4,4,5,4,6,3,7,1,7}, | ||
45 | [4] = {1,1,1,3,2,4,4,4,4,1,4,7}, | ||
46 | [5] = {1,1,4,1,1,1,1,4,3,4,4,5,4,7,1,7}, | ||
47 | [6] = {1,2,1,4,1,6,2,7,3,7,4,6,4,4,1,4,1,2,2,1,4,1}, | ||
48 | [7] = {1,1,4,1,4,2,1,7}, | ||
49 | [8] = {1,2,1,6,2,7,3,7,4,6,4,4,1,4,4,4,4,2,3,1,2,1,1,2}, | ||
50 | [9] = {4,6,4,4,4,2,3,1,2,1,1,2,1,4,4,4,4,6,3,7,1,7}, | ||
51 | [10] = {1,7,1,4,4,4,4,7,4,2,3,1,2,1,1,2,1,4}, | ||
52 | [11] = {1,1,1,7,3,7,4,6,4,5,3,4,1,4,3,4,4,3,4,2,3,1,1,1}, | ||
53 | [12] = {4,2,3,1,2,1,1,2,1,6,2,7,3,7,4,6}, | ||
54 | [13] = {1,1,1,7,3,7,4,6,4,2,3,1,1,1}, | ||
55 | [14] = {4,1,1,1,1,4,3,4,1,4,1,7,4,7}, | ||
56 | [15] = {4,1,1,1,1,4,3,4,1,4,1,7}, | ||
57 | } | ||
58 | _draw_nums.nums = nums | ||
59 | |||
60 | |||
61 | _draw_nums.print = function(img, num, x, y, chrw, color, base, prefix, bClip, scale_x, scale_y, t_nums) | ||
62 | scale_x = scale_x or 1 | ||
63 | scale_y = scale_y or 1 | ||
64 | chrw = chrw * scale_x | ||
65 | prefix = (prefix == nil or prefix == true) and true or false | ||
66 | t_nums = t_nums or nums | ||
67 | local max_x, max_y, digits = 0, 0, {} | ||
68 | |||
69 | if num <= 0 then | ||
70 | if num < 0 then | ||
71 | digits[-3] = -1 | ||
72 | num = -num | ||
73 | else | ||
74 | digits[0] = 0 | ||
75 | end | ||
76 | end | ||
77 | |||
78 | if not prefix and (base == 2 or base == 8 or base == 16) then | ||
79 | -- no prefix | ||
80 | elseif base == 2 then | ||
81 | digits[-1] = "b" | ||
82 | elseif base == 8 then | ||
83 | digits[-1] = "o" | ||
84 | elseif base == 10 then | ||
85 | -- no prefix | ||
86 | elseif base == 16 then | ||
87 | digits[-2] = 0 | ||
88 | digits[-1] = "x" | ||
89 | elseif base == nil then -- default | ||
90 | base = 10 | ||
91 | else | ||
92 | error("unknown number base: " .. base) | ||
93 | return nil | ||
94 | end | ||
95 | |||
96 | while num > 0 do -- get each digit (LeastSignificant) | ||
97 | digits[#digits + 1] = num % base; | ||
98 | num=num/base; | ||
99 | end | ||
100 | |||
101 | digits[#digits + 1] = digits[0] -- zero | ||
102 | digits[#digits + 1] = digits[-1] -- base prefix | ||
103 | digits[#digits + 1] = digits[-2] -- base prefix (hex) | ||
104 | digits[#digits + 1] = digits[-3] -- neg sign | ||
105 | |||
106 | for i = #digits, 1, -1 do | ||
107 | max_x, max_y = _poly.polyline(img, x, y, t_nums[digits[i]], | ||
108 | color, false, bClip, scale_x, scale_y) | ||
109 | x = x + chrw | ||
110 | end | ||
111 | |||
112 | return x, y + max_y, chrw | ||
113 | end | ||
114 | end | ||
115 | return _draw_nums | ||
diff --git a/apps/plugins/lua/include_lua/draw_poly.lua b/apps/plugins/lua/include_lua/draw_poly.lua index dc2783898a..23e02d0955 100644 --- a/apps/plugins/lua/include_lua/draw_poly.lua +++ b/apps/plugins/lua/include_lua/draw_poly.lua | |||
@@ -25,7 +25,11 @@ | |||
25 | _poly.polygon | 25 | _poly.polygon |
26 | _poly.polyline | 26 | _poly.polyline |
27 | ]] | 27 | ]] |
28 | 28 | --[[ | |
29 | every 2 elements in t_pts is an x, y coord pair | ||
30 | p[?] = {x,y,x,y,x,y} | ||
31 | lines get drawn between the coords | ||
32 | ]] | ||
29 | if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end | 33 | if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end |
30 | 34 | ||
31 | local _poly = {} do | 35 | local _poly = {} do |
@@ -39,66 +43,83 @@ local _poly = {} do | |||
39 | local _copy = rocklib_image.copy | 43 | local _copy = rocklib_image.copy |
40 | local _line = rocklib_image.line | 44 | local _line = rocklib_image.line |
41 | local _newimg = rb.new_image | 45 | local _newimg = rb.new_image |
42 | local flood_fill = require("draw_floodfill") | 46 | local flood_fill |
43 | 47 | ||
44 | -- draws a non-filled figure based on points in t-points | 48 | -- draws a non-filled figure based on points in t-points |
45 | local function polyline(img, x, y, t_points, color, bClosed, bClip) | 49 | local function polyline(img, x, y, t_pts, color, bClosed, bClip, scale_x, scale_y) |
46 | if #t_points < 2 then error("not enough points", 3) end | 50 | scale_x = scale_x or 1 |
51 | scale_y = scale_y or 1 | ||
47 | 52 | ||
48 | local pt_first_last | 53 | local pt_first_last, pt1, pt2 |
54 | local max_x, max_y = 0, 0 | ||
55 | local len = #t_pts | ||
56 | if len < 4 then error("not enough points", 3) end | ||
49 | 57 | ||
50 | if bClosed then | 58 | if bClosed then |
51 | pt_first_last = t_points[1] | 59 | pt_first_last = {t_pts[1] * scale_x, t_pts[2] * scale_y} |
52 | else | 60 | else |
53 | pt_first_last = t_points[#t_points] | 61 | pt_first_last = {t_pts[len - 1] * scale_x, t_pts[len] * scale_y} |
54 | end | 62 | end |
55 | 63 | ||
56 | for i = 1, #t_points, 1 do | 64 | pt2 = {t_pts[1] * scale_x, t_pts[2] * scale_y} |
57 | local pt1 = t_points[i] | 65 | for i = 3, len + 2, 2 do |
58 | 66 | pt1 = pt2 | |
59 | local pt2 = t_points[i + 1] or pt_first_last-- first and last point | 67 | if t_pts[i + 1] == nil then |
68 | pt2 = pt_first_last | ||
69 | else | ||
70 | pt2 = {t_pts[i] * scale_x, t_pts[i + 1] * scale_y} | ||
71 | end-- first and last point | ||
60 | 72 | ||
61 | _line(img, pt1[1] + x, pt1[2] + y, pt2[1] + x, pt2[2] + y, color, bClip) | 73 | _line(img, pt1[1] + x, pt1[2] + y, pt2[1] + x, pt2[2] + y, color, bClip) |
74 | if pt1[1] > max_x then max_x = pt1[1] end | ||
75 | if pt1[2] > max_y then max_y = pt1[2] end | ||
62 | end | 76 | end |
63 | 77 | if pt2[1] > max_x then max_x = pt2[1] end | |
78 | if pt2[2] > max_y then max_y = pt2[2] end | ||
79 | return max_x + x, max_y + y | ||
64 | end | 80 | end |
65 | 81 | ||
66 | -- draws a closed figure based on points in t_points | 82 | -- draws a closed figure based on points in t_pts |
67 | _poly.polygon = function(img, x, y, t_points, color, fillcolor, bClip) | 83 | _poly.polygon = function(img, x, y, t_pts, color, fillcolor, bClip, scale_x, scale_y) |
68 | if #t_points < 2 then error("not enough points", 3) end | 84 | scale_x = scale_x or 1 |
85 | scale_y = scale_y or 1 | ||
86 | if #t_pts < 2 then error("not enough points", 3) end | ||
69 | 87 | ||
70 | if fillcolor then | 88 | if fillcolor then |
71 | local x_min, x_max = 0, 0 | 89 | flood_fill = flood_fill or require("draw_floodfill") |
72 | local y_min, y_max = 0, 0 | 90 | local x_min, x_max = 0, 0 |
73 | local w, h = 0, 0 | 91 | local y_min, y_max = 0, 0 |
74 | -- find boundries of polygon | 92 | local w, h = 0, 0 |
75 | for i = 1, #t_points, 1 do | 93 | local pt1, pt2 |
76 | local pt = t_points[i] | 94 | -- find boundries of polygon |
77 | if pt[1] < x_min then x_min = pt[1] end | 95 | for i = 1, #t_pts, 2 do |
78 | if pt[1] > x_max then x_max = pt[1] end | 96 | if t_pts[i] < x_min then x_min = t_pts[i] end |
79 | if pt[2] < y_min then y_min = pt[2] end | 97 | if t_pts[i] > x_max then x_max = t_pts[i] end |
80 | if pt[2] > y_max then y_max = pt[2] end | 98 | |
81 | end | 99 | if t_pts[i+1] < y_min then y_min = t_pts[i+1] end |
82 | w = _abs(x_max) + _abs(x_min) | 100 | if t_pts[i+1] > y_max then y_max = t_pts[i+1] end |
83 | h = _abs(y_max) + _abs(y_min) | 101 | end |
84 | x_min = x_min - 2 -- leave a border to use flood_fill | 102 | x_max = x_max * scale_x |
85 | y_min = y_min - 2 | 103 | x_min = x_min * scale_x |
86 | 104 | y_max = y_max * scale_y | |
87 | local fill_img = _newimg(w + 3, h + 3) | 105 | y_min = y_min * scale_y |
88 | _clear(fill_img, 0x1) | 106 | w = _abs(x_max) + _abs(x_min) |
89 | 107 | h = _abs(y_max) + _abs(y_min) | |
90 | for i = 1, #t_points, 1 do | 108 | x_min = -(x_min - 2) -- leave a border to use flood_fill |
91 | local pt1 = t_points[i] | 109 | y_min = -(y_min - 2) |
92 | local pt2 = t_points[i + 1] or t_points[1]-- first and last point | 110 | |
93 | _line(fill_img, pt1[1] - x_min, pt1[2] - y_min, | 111 | local fill_img = _newimg(w + 3, h + 3) |
94 | pt2[1]- x_min, pt2[2] - y_min, 0) | 112 | _clear(fill_img, 0x1) |
95 | 113 | ||
96 | end | 114 | polyline(fill_img, x_min, y_min, t_pts, |
115 | 0x0, true, bClip, scale_x, scale_y) | ||
116 | -- flood the outside of the figure with 0 the inside will be fillcolor | ||
97 | flood_fill(fill_img, fill_img:width(), fill_img:height() , 0x1, 0x0) | 117 | flood_fill(fill_img, fill_img:width(), fill_img:height() , 0x1, 0x0) |
98 | _copy(img, fill_img, x - 1, y - 1, _NIL, _NIL, _NIL, _NIL, bClip, BSAND, fillcolor) | 118 | _copy(img, fill_img, x - 1, y - 1, |
119 | _NIL, _NIL, _NIL, _NIL, bClip, BSAND, fillcolor) | ||
99 | end | 120 | end |
100 | 121 | ||
101 | polyline(img, x, y, t_points, color, true, bClip) | 122 | polyline(img, x, y, t_pts, color, true, bClip, scale_x, scale_y) |
102 | end | 123 | end |
103 | 124 | ||
104 | -- expose internal functions to the outside through _poly table | 125 | -- expose internal functions to the outside through _poly table |
diff --git a/apps/plugins/lua/include_lua/poly_points.lua b/apps/plugins/lua/include_lua/poly_points.lua new file mode 100644 index 0000000000..d313710e5c --- /dev/null +++ b/apps/plugins/lua/include_lua/poly_points.lua | |||
@@ -0,0 +1,118 @@ | |||
1 | --PolyPoints.lua | ||
2 | --[[ | ||
3 | /*************************************************************************** | ||
4 | * __________ __ ___. | ||
5 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
6 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
7 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
8 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
9 | * \/ \/ \/ \/ \/ | ||
10 | * $Id$ | ||
11 | * | ||
12 | * Copyright (C) 2017 William Wilgus | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version 2 | ||
17 | * of the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
20 | * KIND, either express or implied. | ||
21 | * | ||
22 | ****************************************************************************/ | ||
23 | ]] | ||
24 | |||
25 | -------------------------------------------------------------------------------- | ||
26 | |||
27 | -------------------------------------------------------------------------------- | ||
28 | -- decodes ascii string back to t_pts | ||
29 | function points_from_ascii(encstr, scale) | ||
30 | scale = scale or 1 | ||
31 | local t_pts = {} | ||
32 | encstr = encstr or "00000008" | ||
33 | local chroffset = tonumber(string.sub(encstr, 1, 3)) or 0 | ||
34 | local chrlen = tonumber(string.sub(encstr, 4, 8)) or 0 | ||
35 | |||
36 | if string.len(encstr) ~= chrlen then | ||
37 | error("Invalid Points String" .. string.len(encstr), 2) | ||
38 | end | ||
39 | |||
40 | for i = 9, string.len(encstr) - 1, 2 do | ||
41 | local x = string.byte(encstr, i, i) - chroffset | ||
42 | local y = string.byte(encstr, i + 1, i + 1) - chroffset | ||
43 | t_pts[#t_pts + 1] = x * scale | ||
44 | t_pts[#t_pts + 1] = y * scale | ||
45 | end | ||
46 | return t_pts | ||
47 | end | ||
48 | -------------------------------------------------------------------------------- | ||
49 | -- encodes t_pts as a ascii string non print chars are excluded so | ||
50 | -- size is limited to approx ~ 90x90 | ||
51 | function points_to_ascii(t_pts) | ||
52 | if not t_pts then return "" end | ||
53 | local chroffset = 33 | ||
54 | local maxoffset = 126 - 33 | ||
55 | local t_enc = {[1] = string.format("%03d%05d", chroffset, #t_pts + 8)} | ||
56 | local max_n, min_n = 0, 0 | ||
57 | for i = 1, #t_pts, 2 do | ||
58 | if t_pts[i] > max_n then max_n = t_pts[i] end | ||
59 | if t_pts[i] < min_n then min_n = t_pts[i] end | ||
60 | if t_pts[i+1] > max_n then max_n = t_pts[i+1] end | ||
61 | if t_pts[i+1] < min_n then min_n = t_pts[i+1] end | ||
62 | if max_n > maxoffset or min_n < 0 then break; end | ||
63 | t_enc[#t_enc + 1] = string.char(t_pts[i] + chroffset) | ||
64 | t_enc[#t_enc + 1] = string.char(t_pts[i+1] + chroffset) | ||
65 | end | ||
66 | if min_n >= 0 and (max_n - min_n) <= maxoffset then | ||
67 | return table.concat(t_enc) | ||
68 | else | ||
69 | return "00000008" | ||
70 | end | ||
71 | end | ||
72 | -------------------------------------------------------------------------------- | ||
73 | -- scales t_pts by percentage (x/y) | ||
74 | function points_scale_pct(t_pts, x_pct, y_pct) | ||
75 | for i = 1, #t_pts, 2 do | ||
76 | local t_pt = {t_pts[i], t_pts[i + 1]} | ||
77 | t_pt = t_pt or {0, 0} | ||
78 | t_pts[i] = (t_pt[1] * x_pct) / 100 | ||
79 | t_pts[i+1] = (t_pt[2] * y_pct) / 100 | ||
80 | end | ||
81 | return t_pts | ||
82 | end | ||
83 | -------------------------------------------------------------------------------- | ||
84 | -- scales t_pts by (x/y) | ||
85 | function points_scale(t_pts, width, height) | ||
86 | local max_x, max_y = 0, 0 | ||
87 | for i = 1, #t_pts, 2 do | ||
88 | if t_pts[i] > max_x then max_x = t_pts[i] end | ||
89 | if t_pts[i+1] > max_y then max_y = t_pts[i+1] end | ||
90 | end | ||
91 | |||
92 | local x_pct = (width * 100) / max_x | ||
93 | local y_pct = (height * 100) / max_y | ||
94 | |||
95 | return points_scale_pct(t_pts, x_pct, y_pct) | ||
96 | end | ||
97 | -------------------------------------------------------------------------------- | ||
98 | --[[ | ||
99 | function scaleup(t_pts, scale_x, scale_y) | ||
100 | local t_coord | ||
101 | for key,value in pairs(t_pts) do | ||
102 | t_coord = t_pts[key] | ||
103 | t_coord[1] = t_coord[1] * scale_x | ||
104 | t_coord[2] = t_coord[2] * scale_y | ||
105 | t_pts[key] = t_coord | ||
106 | end | ||
107 | end | ||
108 | |||
109 | function scaledn(t_pts, scale_x, scale_y) | ||
110 | local t_coord | ||
111 | for key,value in pairs(t_pts) do | ||
112 | t_coord = t_pts[key] | ||
113 | t_coord[1] = t_coord[1] / scale_x | ||
114 | t_coord[2] = t_coord[2] / scale_y | ||
115 | t_pts[key] = t_coord | ||
116 | end | ||
117 | end | ||
118 | ]] | ||