Fixed some Lua 5.0/5.1 compatibility problems in includes

Originally committed to SVN as r1161.
This commit is contained in:
Niels Martin Hansen 2007-05-03 18:22:11 +00:00
parent 480e7706a1
commit 73288ed43f
4 changed files with 566 additions and 508 deletions

View file

@ -0,0 +1,310 @@
--[[
Copyright (c) 2007, Niels Martin Hansen, Rodrigo Braz Monteiro
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Aegisub Group nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
]]
include("utils.lua")
include("unicode.lua")
-- Make sure karaskel table exists
if not karaskel then
karaskel = {}
end
-- Collect styles and metadata from the subs
function karaskel.collect_head(subs, generate_furigana)
local meta = { res_x = 0, res_y = 0 }
local styles = { n = 0 }
if not karaskel.furigana_scale then
karaskel.furigana_scale = 0.5
end
local i = 1
while i < #subs do
local l = subs[i]
if l.class == "style" then
-- Store styles into the style table
styles.n = styles.n + 1
styles[styles.n] = l
styles[l.name] = l
l.margin_v = l.margin_t
-- And also generate furigana styles if wanted
if generate_furigana and not l.name:match("furigana") then
local fs = table.copy(l)
fs.fontsize = l.fontsize * karaskel.furigana_scale
fs.outline = l.outline * karaskel.furigana_scale
fs.shadow = l.shadow * karaskel.furigana_scale
fs.name = l.name .. "-furigana"
styles.n = styles.n + 1
styles[styles.n] = fs
styles[fs.name] = fs
end
elseif l.class == "info" then
-- Also look for script resolution
local k = l.key:lower()
if k == "playresx" then
meta.res_x = math.floor(l.value)
elseif k == "playresy" then
meta.res_y = math.floor(l.value)
end
end
end
-- Fix missing resolution data
if meta.res_x == 0 and meta_res_y == 0 then
meta.res_x = 384
meta.res_y = 288
elseif meta.res_x == 0 then
-- This is braindead, but it's how TextSub does things...
if meta.res_y == 1024 then
meta.res_x = 1280
else
meta.res_x = meta.res_y / 3 * 4
end
elseif meta.res_y == 0 then
-- As if 1280x960 didn't exist
if meta.res_x == 1280 then
meta.res_y = 1024
else
meta.res_y = meta.res_x * 3 / 4
end
end
return meta, styles
end
-- Pre-process line, determining stripped text, karaoke data and splitting off furigana data
-- Modifies the object passed for line
function karaskel.preproc_line_text(meta, styles, line)
-- Assume line is class=dialogue
local kara = aegisub.parse_karaoke_data(line)
line.kara = { n = 0 }
line.furi = { n = 0 }
line.text_stripped = ""
line.duration = line.end_time - line.start_time
local worksyl = { }
local cur_inline_fx = ""
for i = 0, #kara do
local syl = kara[i]
-- Detect any inline-fx tags
local inline_fx = syl.text:match("%{.*\\%-(.-)[}\\]")
if inline_fx then
cur_inline_fx = inline_fx
end
end
end
-- Pre-calculate positioning information for the given line, also layouting furigana text if needed
-- Modifies the object passed for line
function karaskel.preproc_line_pos(meta, styles, line)
end
-- Precalc some info on a line
-- Modifies the line parameter
function karaskel.preproc_line(subs, meta, styles, line)
-- Assume line is class=dialogue
local kara = aegisub.parse_karaoke_data(line)
line.kara = { n = 0 }
line.furi = { n = 0 }
if styles[line.style] then
line.styleref = styles[line.style]
else
aegisub.debug.out(2, "WARNING: Style not found: " .. line.style .. "\n")
line.styleref = styles[1]
end
line.text_stripped = ""
line.duration = line.end_time - line.start_time
local curx = 0
local worksyl = { }
for i = 0, #kara do
local syl = kara[i]
-- Spaces at the start and end of the syllable are best ignored
local prespace, syltext, postspace = syl.text_stripped:match("^([ \t]*)(.-)([ \t]*)$")
local prefix = syltext:sub(1,unicode.charwidth(syltext,1))
if prefix ~= "#" and prefix ~= "" and i > 0 then
line.kara[line.kara.n] = worksyl
line.kara.n = line.kara.n + 1
worksyl = { }
end
-- Check if there is a chance of furigana
-- FIXME: multi-highlights aren't being generated, are they? At least not with syllables with a lone # in
if syltext:find("|") or syltext:find("") then
syltext = syltext:gsub("", "|")
local maintext, furitext = syl:match("^(.-)|(.-)$")
syltext = maintext
local furi = { }
furi.syl = worksyl
local prefix = furitext:sub(1,unicode.charwidth(furitext,1))
if prefix == "!" or prefix == "" then
furi.isbreak = true
furi.spillback = false
elseif prefix == "<" or prefix == "" then
furi.isbreak = true
furi.spillback = true
else
furi.isbreak = false
furi.spillback = false
end
if furi.isbreak then
furitext = furitext:sub(unicode.charwidth(furitext,1)+1)
end
furi.start_time = syl.start_time
furi.end_time = syl.end_time
furi.duration = syl.duration
furi.text = furitext
line.furi.n = line.furi.n + 1
line.furi[line.furi.n] = furi
end
-- If this is the start of a highlight group, do regular processing
if prefix ~= "#" and prefix ~= "" then
-- Update stripped line-text
line.text_stripped = line.text_stripped .. syl.text_stripped
-- Copy data from syl to worksyl
worksyl.text = syl.text
worksyl.duration = syl.duration
worksyl.kdur = syl.duration / 10
worksyl.start_time = syl.start_time
worksyl.end_time = syl.end_time
worksyl.tag = syl.tag
worksyl.line = line
worksyl.style = line.styleref
-- And add new data to worksyl
worksyl.i = line.kara.n
worksyl.text_stripped = syltext
worksyl.width = aegisub.text_extents(line.styleref, syltext)
curx = curx + aegisub.text_extents(line.styleref, prespace)
worksyl.left = curx
worksyl.center = curx + worksyl.width/2
worksyl.right = curx + worksyl.width
curx = curx + worksyl.width + aegisub.text_extents(line.styleref, postspace)
-- TODO: inlinefx here
end
-- And in either case, add highlight data
local hl = {
start_time = worksyl.start_time,
end_time = worksyl.end_time,
duration = worksyl.duration
}
worksyl.highlights = { n = 1, [1] = hl }
end
-- Add last syllable
line.kara[line.kara.n] = worksyl
-- Full line sizes
line.width, line.height, line.descent, line.extlead = aegisub.text_extents(line.styleref, line.text_stripped)
-- Effective margins
line.margin_v = line.margin_t
line.eff_margin_l = ((line.margin_l > 0) and line.margin_l) or line.styleref.margin_l
line.eff_margin_r = ((line.margin_r > 0) and line.margin_r) or line.styleref.margin_r
line.eff_margin_t = ((line.margin_t > 0) and line.margin_t) or line.styleref.margin_t
line.eff_margin_b = ((line.margin_b > 0) and line.margin_b) or line.styleref.margin_b
line.eff_margin_v = ((line.margin_v > 0) and line.margin_v) or line.styleref.margin_v
-- And positioning
if line.styleref.align == 1 or line.styleref.align == 4 or line.styleref.align == 7 then
-- Left aligned
line.left = line.eff_margin_l
line.center = line.left + line.width / 2
line.right = line.left + line.width
line.x = line.left
line.halign = "left"
elseif line.styleref.align == 2 or line.styleref.align == 5 or line.styleref.align == 8 then
-- Centered
line.left = (meta.res_x - line.eff_margin_l - line.eff_margin_r - line.width) / 2 + line.eff_margin_l
line.center = line.left + line.width / 2
line.right = line.left + line.width
line.x = line.center
line.halign = "center"
elseif line.styleref.align == 3 or line.styleref.align == 6 or line.styleref.align == 9 then
-- Right aligned
line.left = meta.res_x - line.eff_margin_r - line.width
line.center = line.left + line.width / 2
line.right = line.left + line.width
line.x = line.right
line.halign = "right"
end
line.hcenter = line.center
if line.styleref.align >=1 and line.styleref.align <= 3 then
-- Bottom aligned
line.bottom = meta.res_y - line.eff_margin_b
line.middle = line.bottom - line.height / 2
line.top = line.bottom - line.height
line.y = line.bottom
line.valign = "bottom"
elseif line.styleref.align >= 4 and line.styleref.align <= 6 then
-- Mid aligned
line.top = (meta.res_y - line.eff_margin_t - line.eff_margin_b) / 2 + line.eff_margin_t
line.middle = line.top + line.height / 2
line.bottom = line.top + line.height
line.y = line.middle
line.valign = "middle"
elseif line.styleref.align >= 7 and line.styleref.align <= 9 then
-- Top aligned
line.top = line.eff_margin_t
line.middle = line.top + line.height / 2
line.bottom = line.top + line.height
line.y = line.top
line.valign = "top"
end
line.vcenter = line.middle
-- Generate furigana style
local furistyle = table.copy(line.styleref)
furistyle.fontsize = furistyle.fontsize / 2
furistyle.outline = furistyle.outline / 2
-- Layout furigana
for i = 1, line.furi.n do
end
end

View file

@ -27,292 +27,10 @@
POSSIBILITY OF SUCH DAMAGE.
]]
-- Aegisub Automation 4 Lua karaoke skeleton
-- Compatibility hatch
-- Include the right file, depending on Automation version
-- The Auto4 version has to be in a separate include to avoid parser problems with Lua 5.0
if aegisub.lua_automation_version < 4 then
include("karaskel.auto3")
return
end
include("utils.lua")
include("unicode.lua")
-- Make sure karaskel table exists
if not karaskel then
karaskel = {}
end
-- Collect styles and metadata from the subs
function karaskel.collect_head(subs, generate_furigana)
local meta = { res_x = 0, res_y = 0 }
local styles = { n = 0 }
if not karaskel.furigana_scale then
karaskel.furigana_scale = 0.5
end
local i = 1
while i < #subs do
local l = subs[i]
if l.class == "style" then
-- Store styles into the style table
styles.n = styles.n + 1
styles[styles.n] = l
styles[l.name] = l
l.margin_v = l.margin_t
-- And also generate furigana styles if wanted
if generate_furigana and not l.name:match("furigana") then
local fs = table.copy(l)
fs.fontsize = l.fontsize * karaskel.furigana_scale
fs.outline = l.outline * karaskel.furigana_scale
fs.shadow = l.shadow * karaskel.furigana_scale
fs.name = l.name .. "-furigana"
styles.n = styles.n + 1
styles[styles.n] = fs
styles[fs.name] = fs
end
elseif l.class == "info" then
-- Also look for script resolution
local k = l.key:lower()
if k == "playresx" then
meta.res_x = math.floor(l.value)
elseif k == "playresy" then
meta.res_y = math.floor(l.value)
end
end
end
-- Fix missing resolution data
if meta.res_x == 0 and meta_res_y == 0 then
meta.res_x = 384
meta.res_y = 288
elseif meta.res_x == 0 then
-- This is braindead, but it's how TextSub does things...
if meta.res_y == 1024 then
meta.res_x = 1280
include "karaskel.auto3"
else
meta.res_x = meta.res_y / 3 * 4
end
elseif meta.res_y == 0 then
-- As if 1280x960 didn't exist
if meta.res_x == 1280 then
meta.res_y = 1024
else
meta.res_y = meta.res_x * 3 / 4
end
end
return meta, styles
end
-- Pre-process line, determining stripped text, karaoke data and splitting off furigana data
-- Modifies the object passed for line
function karaskel.preproc_line_text(meta, styles, line)
-- Assume line is class=dialogue
local kara = aegisub.parse_karaoke_data(line)
line.kara = { n = 0 }
line.furi = { n = 0 }
line.text_stripped = ""
line.duration = line.end_time - line.start_time
local worksyl = { }
local cur_inline_fx = ""
for i = 0, #kara do
local syl = kara[i]
-- Detect any inline-fx tags
local inline_fx = syl.text:match("%{.*\\%-(.-)[}\\]")
if inline_fx then
cur_inline_fx = inline_fx
end
end
end
-- Pre-calculate positioning information for the given line, also layouting furigana text if needed
-- Modifies the object passed for line
function karaskel.preproc_line_pos(meta, styles, line)
end
-- Precalc some info on a line
-- Modifies the line parameter
function karaskel.preproc_line(subs, meta, styles, line)
-- Assume line is class=dialogue
local kara = aegisub.parse_karaoke_data(line)
line.kara = { n = 0 }
line.furi = { n = 0 }
if styles[line.style] then
line.styleref = styles[line.style]
else
aegisub.debug.out(2, "WARNING: Style not found: " .. line.style .. "\n")
line.styleref = styles[1]
end
line.text_stripped = ""
line.duration = line.end_time - line.start_time
local curx = 0
local worksyl = { }
for i = 0, #kara do
local syl = kara[i]
-- Spaces at the start and end of the syllable are best ignored
local prespace, syltext, postspace = syl.text_stripped:match("^([ \t]*)(.-)([ \t]*)$")
local prefix = syltext:sub(1,unicode.charwidth(syltext,1))
if prefix ~= "#" and prefix ~= "" and i > 0 then
line.kara[line.kara.n] = worksyl
line.kara.n = line.kara.n + 1
worksyl = { }
end
-- Check if there is a chance of furigana
-- FIXME: multi-highlights aren't being generated, are they? At least not with syllables with a lone # in
if syltext:find("|") or syltext:find("") then
syltext = syltext:gsub("", "|")
local maintext, furitext = syl:match("^(.-)|(.-)$")
syltext = maintext
local furi = { }
furi.syl = worksyl
local prefix = furitext:sub(1,unicode.charwidth(furitext,1))
if prefix == "!" or prefix == "" then
furi.isbreak = true
furi.spillback = false
elseif prefix == "<" or prefix == "" then
furi.isbreak = true
furi.spillback = true
else
furi.isbreak = false
furi.spillback = false
end
if furi.isbreak then
furitext = furitext:sub(unicode.charwidth(furitext,1)+1)
end
furi.start_time = syl.start_time
furi.end_time = syl.end_time
furi.duration = syl.duration
furi.text = furitext
line.furi.n = line.furi.n + 1
line.furi[line.furi.n] = furi
end
-- If this is the start of a highlight group, do regular processing
if prefix ~= "#" and prefix ~= "" then
-- Update stripped line-text
line.text_stripped = line.text_stripped .. syl.text_stripped
-- Copy data from syl to worksyl
worksyl.text = syl.text
worksyl.duration = syl.duration
worksyl.kdur = syl.duration / 10
worksyl.start_time = syl.start_time
worksyl.end_time = syl.end_time
worksyl.tag = syl.tag
worksyl.line = line
worksyl.style = line.styleref
-- And add new data to worksyl
worksyl.i = line.kara.n
worksyl.text_stripped = syltext
worksyl.width = aegisub.text_extents(line.styleref, syltext)
curx = curx + aegisub.text_extents(line.styleref, prespace)
worksyl.left = curx
worksyl.center = curx + worksyl.width/2
worksyl.right = curx + worksyl.width
curx = curx + worksyl.width + aegisub.text_extents(line.styleref, postspace)
-- TODO: inlinefx here
end
-- And in either case, add highlight data
local hl = {
start_time = worksyl.start_time,
end_time = worksyl.end_time,
duration = worksyl.duration
}
worksyl.highlights = { n = 1, [1] = hl }
end
-- Add last syllable
line.kara[line.kara.n] = worksyl
-- Full line sizes
line.width, line.height, line.descent, line.extlead = aegisub.text_extents(line.styleref, line.text_stripped)
-- Effective margins
line.margin_v = line.margin_t
line.eff_margin_l = ((line.margin_l > 0) and line.margin_l) or line.styleref.margin_l
line.eff_margin_r = ((line.margin_r > 0) and line.margin_r) or line.styleref.margin_r
line.eff_margin_t = ((line.margin_t > 0) and line.margin_t) or line.styleref.margin_t
line.eff_margin_b = ((line.margin_b > 0) and line.margin_b) or line.styleref.margin_b
line.eff_margin_v = ((line.margin_v > 0) and line.margin_v) or line.styleref.margin_v
-- And positioning
if line.styleref.align == 1 or line.styleref.align == 4 or line.styleref.align == 7 then
-- Left aligned
line.left = line.eff_margin_l
line.center = line.left + line.width / 2
line.right = line.left + line.width
line.x = line.left
line.halign = "left"
elseif line.styleref.align == 2 or line.styleref.align == 5 or line.styleref.align == 8 then
-- Centered
line.left = (meta.res_x - line.eff_margin_l - line.eff_margin_r - line.width) / 2 + line.eff_margin_l
line.center = line.left + line.width / 2
line.right = line.left + line.width
line.x = line.center
line.halign = "center"
elseif line.styleref.align == 3 or line.styleref.align == 6 or line.styleref.align == 9 then
-- Right aligned
line.left = meta.res_x - line.eff_margin_r - line.width
line.center = line.left + line.width / 2
line.right = line.left + line.width
line.x = line.right
line.halign = "right"
end
line.hcenter = line.center
if line.styleref.align >=1 and line.styleref.align <= 3 then
-- Bottom aligned
line.bottom = meta.res_y - line.eff_margin_b
line.middle = line.bottom - line.height / 2
line.top = line.bottom - line.height
line.y = line.bottom
line.valign = "bottom"
elseif line.styleref.align >= 4 and line.styleref.align <= 6 then
-- Mid aligned
line.top = (meta.res_y - line.eff_margin_t - line.eff_margin_b) / 2 + line.eff_margin_t
line.middle = line.top + line.height / 2
line.bottom = line.top + line.height
line.y = line.middle
line.valign = "middle"
elseif line.styleref.align >= 7 and line.styleref.align <= 9 then
-- Top aligned
line.top = line.eff_margin_t
line.middle = line.top + line.height / 2
line.bottom = line.top + line.height
line.y = line.top
line.valign = "top"
end
line.vcenter = line.middle
-- Generate furigana style
local furistyle = table.copy(line.styleref)
furistyle.fontsize = furistyle.fontsize / 2
furistyle.outline = furistyle.outline / 2
-- Layout furigana
for i = 1, line.furi.n do
end
include "karaskel-auto4.lua"
end

View file

@ -0,0 +1,247 @@
--[[
Copyright (c) 2005-2006, Niels Martin Hansen, Rodrigo Braz Monteiro
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Aegisub Group nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
]]
-- Make a shallow copy of a table
function table.copy(oldtab)
local newtab = {}
for key, val in pairs(oldtab) do
newtab[key] = val
end
return newtab
end
-- Compability
copy_line = table.copy
-- Make a deep copy of a table
-- This will do infinite recursion if there's any circular references. (Eg. if you try to copy _G)
function table.copy_deep(srctab)
-- Table to hold subtables already copied, to avoid circular references causing infinite recursion
local circular = {}
local function do_copy(oldtab)
local newtab = {}
for key, val in pairs(newtab) do
if type(val) == "table" then
if not circular[val] then
circular[val] = do_copy(val)
end
newtab[key] = circular[val]
else
newtab[key] = val
end
end
end
return do_copy(srctab)
end
-- Generates ASS hexadecimal string from R,G,B integer components, in &HBBGGRR& format
function ass_color(r,g,b)
return string.format("&H%02X%02X%02X&",b,g,r)
end
-- Format an alpha-string for \Xa style overrides
function ass_alpha(a)
return string.format("&H%02X&", a)
end
-- Format an ABGR string for use in style definitions (these don't end with & either)
function ass_style_color(r,g,b,a)
return string.format("&H%02X%02X%02X%02X",a,b,g,r)
end
-- Extract colour components of an ASS colour
function extract_color(s)
local a, b, g, r
-- Try a style first
a, b, g, r = s:match("&H(%x%x)(%x%x)(%x%x)(%x%x)")
if a then
return tonumber(r, 16), tonumber(g, 16), tonumber(b, 16), tonumber(a, 16)
end
-- Then a colour override
b, g, r = s:match("&H(%x%x)(%x%x)(%x%x)&")
if b then
return tonumber(r, 16), tonumber(g, 16), tonumber(b, 16), 0
end
-- Then an alpha override
a = s:match("&H(%x%x)&")
if a then
return 0, 0, 0, tonumber(a, 16)
end
-- Ok how about HTML format then?
r, g, b, a = s:match("#(%x%x)(%x%x)?(%x%x)?(%x%x)?")
if r then
return tonumber(r or 0, 16), tonumber(g or 0, 16), tonumber(b or 0, 16), tonumber(a or 0, 16)
end
-- Failed...
return nil
end
-- Create an alpha override code from a style definition colour code
function alpha_from_style(scolor)
local r, g, b, a = extract_color(scolor)
return ass_alpha(a)
end
-- Create an colour override code from a style definition colour code
function color_from_style(scolor)
local r, g, b = extract_color(scolor)
return ass_color(r, g, b)
end
-- Converts HSV (Hue, Saturation, Value) to RGB
function HSV_to_RGB(H,S,V)
local r,g,b = 0,0,0
-- Saturation is zero, make grey
if S == 0 then
r = V*255
if r < 0 then
r = 0
end
if r > 255 then
r = 255
end
g = r
b = r
-- Else, calculate color
else
-- Calculate subvalues
H = H % 360 -- Put H in range [0,360)
local Hi = math.floor(H/60)
local f = H/60.0 - Hi
local p = V*(1-S)
local q = V*(1-f*S)
local t = V*(1-(1-f)*S)
-- Do math based on hue index
if Hi == 0 then
r = V*255.0
g = t*255.0
b = p*255.0
elseif Hi == 1 then
r = q*255.0
g = V*255.0
b = p*255.0
elseif Hi == 2 then
r = p*255.0
g = V*255.0
b = t*255.0
elseif Hi == 3 then
r = p*255.0
g = q*255.0
b = V*255.0
elseif Hi == 4 then
r = t*255.0
g = p*255.0
b = V*255.0
elseif Hi == 5 then
r = V*255.0
g = p*255.0
b = q*255.0
else
aegisub.debug.out(2, "RGB_to_HSV: Hi got an unexpected value: %d\n\n", Hi)
end
end
r = math.floor(r)
g = math.floor(g)
b = math.floor(b)
return r,g,b
end
-- Removes spaces at the start and end of string
function string.trim(s)
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
end
-- Get the "head" and "tail" of a string, treating it as a sequence of words separated by one or more space-characters
function string.headtail(s)
local a, b, head, tail = string.find(s, "(.-)%s+(.*)")
if a then
return head, tail
else
return s, ""
end
end
-- Iterator function for headtail
function string.words(s)
local t = s
local function wordloop()
if t == "" then
return nil
end
local head, tail = string.headtail(t)
t = tail
return head
end
return wordloop, nil, nil
end
-- Clamp a number value to a range
function clamp(val, min, max)
if val < min then
return min
elseif val > max then
return max
else
return val
end
end
-- Interpolate between two numbers
function interpolate(pct, min, max)
if pct <= 0 then
return min
elseif pct >= 1 then
return max
else
return pct * (max - min) + min
end
end
-- Interpolate between two colour values, given in either style definition or style override format
-- Return in style override format
function interpolate_color(pct, first, last)
local r1, g1, b1 = extract_color(first)
local r2, g2, b2 = extract_color(first)
local r, g, b = interpolate(pct, r1, r2), interpolate(pct, g1, g2), interpolate(pct, b1, b2)
return ass_color(r, g, b)
end
-- Interpolate between two alpha values, given either in style override or as part as a style definition colour
-- Return in style override format
function interpolate_alpha(pct, first, last)
local r1, g1, b1, a1 = extract_color(first)
local r2, g2, b2, a2 = extract_color(first)
return ass_alpha(interpolate(pct, a1, a2))
end

View file

@ -27,227 +27,10 @@
POSSIBILITY OF SUCH DAMAGE.
]]
-- Compatibility hatch
-- Include the right file, depending on Automation version
-- The Auto4 version has to be in a separate include to avoid parser problems with Lua 5.0
if aegisub.lua_automation_version < 4 then
include "utils.auto3"
return
end
-- Make a shallow copy of a table
function table.copy(oldtab)
local newtab = {}
for key, val in pairs(oldtab) do
newtab[key] = val
end
return newtab
end
-- Compability
copy_line = table.copy
-- Make a deep copy of a table
-- This will do infinite recursion if there's any circular references. (Eg. if you try to copy _G)
function table.copy_deep(srctab)
-- Table to hold subtables already copied, to avoid circular references causing infinite recursion
local circular = {}
local function do_copy(oldtab)
local newtab = {}
for key, val in pairs(newtab) do
if type(val) == "table" then
if not circular[val] then
circular[val] = do_copy(val)
end
newtab[key] = circular[val]
else
newtab[key] = val
end
end
end
return do_copy(srctab)
end
-- Generates ASS hexadecimal string from R,G,B integer components, in &HBBGGRR& format
function ass_color(r,g,b)
return string.format("&H%02X%02X%02X&",b,g,r)
end
-- Format an alpha-string for \Xa style overrides
function ass_alpha(a)
return string.format("&H%02X&", a)
end
-- Format an ABGR string for use in style definitions (these don't end with & either)
function ass_style_color(r,g,b,a)
return string.format("&H%02X%02X%02X%02X",a,b,g,r)
end
-- Extract colour components of an ASS colour
function extract_color(s)
local a, b, g, r
-- Try a style first
a, b, g, r = s:match("&H(%x%x)(%x%x)(%x%x)(%x%x)")
if a then
return tonumber(r, 16), tonumber(g, 16), tonumber(b, 16), tonumber(a, 16)
end
-- Then a colour override
b, g, r = s:match("&H(%x%x)(%x%x)(%x%x)&")
if b then
return tonumber(r, 16), tonumber(g, 16), tonumber(b, 16), 0
end
-- Then an alpha override
a = s:match("&H(%x%x)&")
if a then
return 0, 0, 0, tonumber(a, 16)
end
-- Ok how about HTML format then?
r, g, b, a = s:match("#(%x%x)(%x%x)?(%x%x)?(%x%x)?")
if r then
return tonumber(r or 0, 16), tonumber(g or 0, 16), tonumber(b or 0, 16), tonumber(a or 0, 16)
end
-- Failed...
return nil
end
-- Create an alpha override code from a style definition colour code
function alpha_from_style(scolor)
local r, g, b, a = extract_color(scolor)
return ass_alpha(a)
end
-- Create an colour override code from a style definition colour code
function color_from_style(scolor)
local r, g, b = extract_color(scolor)
return ass_color(r, g, b)
end
-- Converts HSV (Hue, Saturation, Value) to RGB
function HSV_to_RGB(H,S,V)
local r,g,b = 0,0,0
-- Saturation is zero, make grey
if S == 0 then
r = V*255
if r < 0 then
r = 0
end
if r > 255 then
r = 255
end
g = r
b = r
-- Else, calculate color
else
-- Calculate subvalues
H = H % 360 -- Put H in range [0,360)
local Hi = math.floor(H/60)
local f = H/60.0 - Hi
local p = V*(1-S)
local q = V*(1-f*S)
local t = V*(1-(1-f)*S)
-- Do math based on hue index
if Hi == 0 then
r = V*255.0
g = t*255.0
b = p*255.0
elseif Hi == 1 then
r = q*255.0
g = V*255.0
b = p*255.0
elseif Hi == 2 then
r = p*255.0
g = V*255.0
b = t*255.0
elseif Hi == 3 then
r = p*255.0
g = q*255.0
b = V*255.0
elseif Hi == 4 then
r = t*255.0
g = p*255.0
b = V*255.0
elseif Hi == 5 then
r = V*255.0
g = p*255.0
b = q*255.0
else
aegisub.debug.out(2, "RGB_to_HSV: Hi got an unexpected value: %d\n\n", Hi)
end
end
r = math.floor(r)
g = math.floor(g)
b = math.floor(b)
return r,g,b
end
-- Removes spaces at the start and end of string
function string.trim(s)
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
end
-- Get the "head" and "tail" of a string, treating it as a sequence of words separated by one or more space-characters
function string.headtail(s)
local a, b, head, tail = string.find(s, "(.-)%s+(.*)")
if a then
return head, tail
else
return s, ""
end
end
-- Iterator function for headtail
function string.words(s)
local t = s
local function wordloop()
if t == "" then
return nil
end
local head, tail = string.headtail(t)
t = tail
return head
end
return wordloop, nil, nil
end
-- Clamp a number value to a range
function clamp(val, min, max)
if val < min then
return min
elseif val > max then
return max
else
return val
end
end
-- Interpolate between two numbers
function interpolate(pct, min, max)
if pct <= 0 then
return min
elseif pct >= 1 then
return max
else
return pct * (max - min) + min
end
end
-- Interpolate between two colour values, given in either style definition or style override format
-- Return in style override format
function interpolate_color(pct, first, last)
local r1, g1, b1 = extract_color(first)
local r2, g2, b2 = extract_color(first)
local r, g, b = interpolate(pct, r1, r2), interpolate(pct, g1, g2), interpolate(pct, b1, b2)
return ass_color(r, g, b)
end
-- Interpolate between two alpha values, given either in style override or as part as a style definition colour
-- Return in style override format
function interpolate_alpha(pct, first, last)
local r1, g1, b1, a1 = extract_color(first)
local r2, g2, b2, a2 = extract_color(first)
return ass_alpha(interpolate(pct, a1, a2))
include "utils-auto4.lua"
end