diff options
Diffstat (limited to 'Master/texmf-dist/scripts/barracuda/lib-geo/brcd-libgeo.lua')
-rw-r--r-- | Master/texmf-dist/scripts/barracuda/lib-geo/brcd-libgeo.lua | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/Master/texmf-dist/scripts/barracuda/lib-geo/brcd-libgeo.lua b/Master/texmf-dist/scripts/barracuda/lib-geo/brcd-libgeo.lua new file mode 100644 index 00000000000..fd53ca65095 --- /dev/null +++ b/Master/texmf-dist/scripts/barracuda/lib-geo/brcd-libgeo.lua @@ -0,0 +1,289 @@ + +-- libgeo simple Geometric Library +-- Copyright (C) 2018 Roberto Giacomelli + +-- All dimension must be in scaled point (sp) + +local libgeo = { + _VERSION = "libgeo v0.0.3", + _NAME = "libgeo", + _DESCRIPTION = "simple geometric library", +} + +-- VBar class +-- a pure geometric entity of several infinite vertical lines +libgeo.Vbar = {} +local Vbar = libgeo.Vbar +Vbar.__index = Vbar + +-- Vbar costructors + +-- VBar costructor from an array [xcenter1, width1, xcenter2, width2, ...] +function Vbar:from_array(yl_arr) --> <vbar object> + assert(type(yl_arr) == "table", "'yline_array' is a mandatory arg") + -- stream scanning + local i = 1 + local xlim = 0.0 + while yl_arr[i] do + local x = yl_arr[i]; i = i + 1 + local w = yl_arr[i]; i = i + 1 + assert(type(x) == "number", "[InternalErr] not a number") + assert(type(w) == "number", "[InternalErr] not a number") + xlim = x + w/2 + end + assert(i % 2 == 0, "[InternalErr] the index is not even") + assert(i > 0, "[InternalErr] empty array") + local o = { + _yline = yl_arr, -- [<xcenter>, <width>, ...] flat array + _x_lim = xlim, -- right external bounding box coordinates + } + setmetatable(o, self) + return o +end + +-- costructor useful for Code128 encoder +-- from an integer: 21231 -> binary 11 0 11 000 1 -> symbol 110110001 +-- is_bar :: boolean :: bar or space as first element, default true +function Vbar:from_int(ngen, mod, is_bar) --> <vbar object> + assert(type(ngen) == "number", "Invalid argument for n") + assert(type(mod) == "number", "Invalid argument for module width") + if is_bar == nil then is_bar = true else + assert(type(is_bar) == "boolean", "Invalid argument for is_bar") + end + -- scan ngen for digits + local digits = {} + while ngen > 0 do + local d = ngen % 10 + digits[#digits + 1] = d + ngen = (ngen - d)/10 + end + local x0 = 0.0 -- axis reference + local yl = {} + for k = #digits, 1, -1 do + local d = digits[k] + local w = d*mod -- bar width + if is_bar then -- bar + yl[#yl + 1] = x0 + w/2 + yl[#yl + 1] = w + end + x0 = x0 + w + is_bar = not is_bar + end + local o = { + _yline = yl, -- [<xcenter>, <width>, ...] flat array + _x_lim = x0, -- right external coordinate + } + setmetatable(o, self) + return o +end + +-- from an integer to read from right to left +-- 13212 ->rev 21231 ->binary 11 0 11 000 1 -> symbol 110110001 +-- is_bar :: boolean :: bar or space for first, default true +function Vbar:from_int_revstep(ngen, mod, is_bar) --> <vbar object> + assert(type(ngen) == "number", "Invalid argument for n") + assert(type(mod) == "number", "Invalid argument for module width") + if is_bar == nil then is_bar = true else + assert(type(is_bar) == "boolean", "Invalid argument for is_bar") + end + -- + local x0 = 0.0 -- axis reference + local i = 0 + local yl = {} + while ngen > 0 do + local d = ngen % 10 -- first digit + local w = d*mod -- bar width + if is_bar then -- bar + i = i + 1; yl[i] = x0 + w/2 + i = i + 1; yl[i] = w + end + x0 = x0 + w + is_bar = not is_bar + ngen = (ngen - d)/10 + end + assert(not is_bar, "[InternalErr] the last element in not a bar") + local o = { + _yline = yl, -- [<xcenter>, <width>, ...] flat array + _x_lim = x0, -- right external coordinate + } + setmetatable(o, self) + return o +end + +-- costructor useful for Code39 encoder +-- i.e. 11212 -> rev -> 2 1 2 1 1 -> decodes to -> B w B w b +-- build a yline array from the integer definition. Digit decoding rule: +-- mod: b or w => 1 -- narrow bar/space +-- MOD: B or W => 2 -- wide bar/space +-- is_bar: the first element is a bar not a space, default to true +function Vbar:from_int_revpair(ngen, mod, MOD, is_bar) --> <vbar object> + assert(type(ngen) == "number", "Invalid argument for n") + assert(type(mod) == "number", "Invalid argument for narrow module width") + assert(type(MOD) == "number", "Invalid argument for wide module width") + assert(mod < MOD, "Not ordered narrow/Wide values") + if is_bar == nil then + is_bar = true + else + assert(type(is_bar) == "boolean", "Invalid argument for 'is_bar'") + end + local yl = {} + local x0 = 0.0 + local k = 0 + while ngen > 0 do + local d = ngen % 10 -- digit + ngen = (ngen - d)/10 + local w; if d == 1 then + w = mod + elseif d == 2 then + w = MOD + end; assert(w, "[InternalErr] Allowed digits are only 1 or 2") + if is_bar then -- bars + k = k + 1; yl[k] = x0 + w/2 -- xcenter + k = k + 1; yl[k] = w -- width + end + is_bar = not is_bar + x0 = x0 + w + end + assert(not is_bar, "[InternalErr] the last element is not a bar") + local o = { + _yline = yl, -- [<xcenter>, <width>, ...] flat array + _x_lim = x0, -- external x coordinate + } + setmetatable(o, self) + return o +end + +-- return a Vbar inteleaving to sequence narrow/Wide +-- tbar, tspace = {boolean sequence}, true -> narrow, false -> Wide +function Vbar:from_two_tab(tbar, tspace, mod, MOD) --> <vbar object> + assert(type(tbar) == "table", "tbar must be a table") + assert(type(tspace) == "table", "tspace must be a table") + assert(#tbar == #tspace, "tbar and tspace must be longer the same") + assert(type(mod) == "number", "Invalid argument for narrow module width") + assert(type(MOD) == "number", "Invalid argument for wide module width") + assert(mod < MOD, "Not ordered narrow/Wide values") + local x0 = 0.0 -- x-coordinate + local yl = {} + for i = 1, #tbar do + local is_narrow = tbar[i] + assert(type(is_narrow) == "boolean", "[InternalErr] found a not boolean value") + if is_narrow then + yl[#yl + 1] = x0 + mod/2 -- bar x-coordinate + yl[#yl + 1] = mod -- bar width + x0 = x0 + mod + else + yl[#yl + 1] = x0 + MOD/2 -- bar x-coordinate + yl[#yl + 1] = MOD -- bar width + x0 = x0 + MOD + end + local is_narrow_space = tspace[i] + assert(type(is_narrow_space) == "boolean", "[InternalErr] found a not boolean value") + if is_narrow_space then + x0 = x0 + mod + else + x0 = x0 + MOD + end + end + local o = { + _yline = yl, -- [<xcenter>, <width>, ...] flat array + _x_lim = x0, -- external x coordinate + } + setmetatable(o, self) + return o +end + +-- Text class + +libgeo.Text = {} +local Text = libgeo.Text +Text.__index = Text + +-- costructors +-- internally it keeps text as a sequence of codepoint +function Text:from_string(s) --> object + assert(type(s) == "string", "[ArgErr] 's' not a valid string") + assert(#s > 0, "[Err] 's' empty string not allowed") + + local cp = {} -- codepoint array + for b in string.gmatch(s, ".") do + cp[#cp + 1] = string.byte(b) + end + local o = { + codepoint = cp, + } + setmetatable(o, self) + return o +end + +-- arr, array of single digit number +-- i start index +-- j stop index +function Text:from_digit_array(arr, i, j) --> object + assert(type(arr) == "table", "[ArgErr] 'arr' not a table") + assert(#arr > 0, "[ArgErr] 'arr' is an empty array") + local cp = {} -- codepoint array + if i ~= nil then + assert(type(i) == "number", "[ArgErr] 'i' is not a number") + else + i = 1 + end + if j ~= nil then + assert(type(j) == "number", "[ArgErr] 'j' is not a number") + assert(i <= j, "[ArgErr] not suitable pair of array index") + else + j = #arr + end + for k = i, j do + local d = arr[k] + assert(type(d) == "number", "[ArgErr] array contains a not number element") + assert(d == math.floor(d), "[ArgErr] array contains a not integer number") + assert(d >= 0 or d < 10, "[ArgErr] array contains a not single digit number") + cp[#cp + 1] = d + 48 + end + local o = { + codepoint = cp, + } + setmetatable(o, self) + return o +end + + +-- from an array of chars +function Text:from_chars(chars) --> object + assert(type(chars) == "table", "[ArgErr] 'chars' must be a table") + local arr = {} + for _, c in ipairs(chars) do + arr[#arr + 1] = string.byte(c) + end + local o = { + codepoint = arr, + } + setmetatable(o, self) + return o +end + +-- provide an integer to build a Text object +function Text:from_int(n) --> object + assert(type(n) == "number", "[ArgErr] 'n' must be a number") + assert( n > 0, "[Err] 'n' must be positive") + assert( n == math.floor(n), "[Err] 'n' must be an integer") + local cp = {} + while n > 0 do + local d = n % 10 + cp[#cp + 1] = d + 48 + n = (n - d)/10 + end + local digits = #cp + for i = 1, digits/2 do -- reverse the array + local d = cp[digits - i + 1] + cp[digits - i + 1] = cp[i] + cp[i] = d + end + local o = { + codepoint = cp, + } + setmetatable(o, self) + return o +end + +return libgeo |