diff options
author | Karl Berry <karl@freefriends.org> | 2022-06-23 20:54:26 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2022-06-23 20:54:26 +0000 |
commit | 98a8cf07f9f44a4cac1d296b1dd75e3878530ccc (patch) | |
tree | f31fa96c1aff46b19a2d804103db3cf07d0cecd9 /Master/texmf-dist/scripts/barracuda/lib-driver | |
parent | 5fbfc6793c15fb90af66f2bc1f3a5538daafda78 (diff) |
barracuda (23jun22)
git-svn-id: svn://tug.org/texlive/trunk@63701 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts/barracuda/lib-driver')
3 files changed, 369 insertions, 97 deletions
diff --git a/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-driver.lua b/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-driver.lua index 045a23e9d62..d2d86720aec 100644 --- a/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-driver.lua +++ b/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-driver.lua @@ -1,19 +1,16 @@ -- -- ga Intermediate Graphic Language for barcode drawing --- Copyright (C) 2020 Roberto Giacomelli +-- Copyright (C) 2019-2022 Roberto Giacomelli -- -- Basic driver interface --- drawing elementary vector shape +-- drawing elementary vector graphic -- All dimensions are in scaled point (sp) -local Driver = { - _VERSION = "Driver v0.0.9", - _NAME = "Driver", - _DESCRIPTION = "Driver for ga graphic assembler stream", -} - +local Driver = {_classname = "Driver"} Driver.__index = Driver Driver._drv_instance = {} -- driver instances repository +Driver.mm = 186467.98110236 -- conversion factor sp -> mm (millimeter) +Driver.bp = 65781.76 -- conversion factor sp -> bp (big point) -- driver_type/submodule name Driver._drv_available_drv = { -- lowercase keys please @@ -21,12 +18,13 @@ Driver._drv_available_drv = { -- lowercase keys please svg = "lib-driver.brcd-drv-svg", } +-- id_drv is specific driver identifier as a string function Driver:_get_driver(id_drv) --> object, err if type(id_drv) ~= "string" then - return nil, "[ArgErr] 'id_drv' is not a string" + return nil, "[ArgErr: id_drv] string expected" end if not self._drv_available_drv[id_drv] then - return nil, "[ArgErr] driver '"..id_drv.."' not found" + return nil, "[ArgErr: id_drv] driver '"..id_drv.."' not found" end local t_drv = self._drv_instance if t_drv[id_drv] then -- is the repo already loaded? @@ -39,47 +37,87 @@ function Driver:_get_driver(id_drv) --> object, err end end -function Driver:_new_state() --> a new state +function Driver:default_style() --> new table as default graphic init state return { - line_width = 65781.76, -- line width 1bp (in scaled point sp) - line_cap = 0, -- line cap style - line_join = 0, -- line join style - gtext = false, -- text group off - bb_on = true, -- bounding box checking activation - bb_x1 = nil, -- bounding box coordinates in sp (nil means no data) - bb_y1 = nil, - bb_x2 = nil, - bb_y2 = nil, - mm = 186467.98110236, -- conversion factor sp -> mm (millimeter) - bp = 65781.76, -- conversion factor sp -> bp (big point) + linewidth = 65781.76, -- line width 1bp (in scaled point sp) + linecap = 0, -- line cap style + linejoin = 0, -- line join style + dashpattern = nil, -- dash definition + dashphase = nil, -- dash phase definition } end -function Driver:_ga_process(drv, ga, st, bf, xt) +function Driver:_new_state() --> a new state + local st = self:default_style() + st.bb_on = true -- bounding box checking is active + st.gtext = false -- text group off + st.bb_x1 = nil -- bounding box coordinates in sp (nil means no data) + st.bb_y1 = nil + st.bb_x2 = nil + st.bb_y2 = nil + st.mm = self.mm -- conversion factor sp -> mm (millimeter) + st.bp = self.bp -- conversion factor sp -> bp (big point) + return st +end + +function Driver:_ga_init_style(drv, st, bf, xt) + local op_fn = self._opcode_v001 + -- linewidth + if not drv.append_001 then + error("[InternalErr] unimplemented opcode 1 for "..drv._drvname) + end + local w = st.linewidth + drv.append_001(st, bf, xt, w) + -- linecap + if not drv.append_002 then + error("[InternalErr] unimplemented opcode 2 for "..drv._drvname) + end + local linecap = st.linecap + drv.append_002(st, bf, xt, linecap) + -- line join style + if not drv.append_003 then + error("[InternalErr] unimplemented opcode 3 for "..drv._drvname) + end + local join = st.linejoin + drv.append_003(st, bf, xt, join) + -- dash pattern (reset) + if not drv.append_006 then + error("[InternalErr] unimplemented opcode 6 for "..drv._drvname) + end + drv.append_006(st, bf, xt) +end + +function Driver:_ga_process(drv, ga_stream, st, bf, xt) local op_fn = self._opcode_v001 local pc = 1 -- program counter - local data = ga._data - while data[pc] do -- stream processing - local opcode = data[pc] + while ga_stream[pc] do -- stream processing + local opcode = ga_stream[pc] local fn = assert(op_fn[opcode], "[InternalErr] unimpl opcode ".. opcode) - pc = fn(drv, st, pc + 1, data, bf, xt) + pc = fn(drv, st, pc + 1, ga_stream, bf, xt) end end -- save graphic data in an external file with the 'id_drv' format --- id_drv: specific driver output --- ga: ga object --- filename: file name --- ext: file extension (optional) +-- id_drv: specific driver output identifier +-- ga ::= gaCanvas class | ga stream table array +-- filename ::= string, file name +-- ext ::= string, file extension (optional, default SVG) function Driver:save(id_drv, ga, filename, ext) --> ok, err -- retrive the output library local drv, err = self:_get_driver(id_drv) if err then return false, err end + local ga_stream; if ga._classname == "gaCanvas" then + ga_stream = ga:get_stream() + else + ga_stream = ga + end -- init local state = self:_new_state() local buf, txt_buf = drv.init_buffer(state) -- a new buffer and text_buffer + -- send every defualt style parameter to the special driver + self:_ga_init_style(drv, state, buf, txt_buf) -- processing - self:_ga_process(drv, ga, state, buf, txt_buf) + self:_ga_process(drv, ga_stream, state, buf, txt_buf) -- buffer finalizing drv.close_buffer(state, buf, txt_buf) -- finalize the istruction -- file saving @@ -91,9 +129,19 @@ function Driver:save(id_drv, ga, filename, ext) --> ok, err return true, nil end --- insert a ga drawing in a TeX box +-- insert a ga drawing in a TeX hbox -- PDFnative only function +-- ga ::= gaCanvas class | ga stream table array +-- boxname ::= string function Driver:ga_to_hbox(ga, boxname) --> ok, err + if type(ga) ~= "table" then + return false, "[ArgErr: ga] table expected" + end + local ga_stream; if ga._classname == "gaCanvas" then + ga_stream = ga:get_stream() + else + ga_stream = ga + end -- retrive the output library local id_drv = "native" local drv, err = self:_get_driver(id_drv) @@ -101,13 +149,14 @@ function Driver:ga_to_hbox(ga, boxname) --> ok, err -- init process local state = self:_new_state() local buf, txt_buf = drv.init_buffer(state) -- a new buffer and text_buffer + -- send every defualt style parameter to the special driver + self:_ga_init_style(drv, state, buf, txt_buf) -- processing - self:_ga_process(drv, ga, state, buf, txt_buf) + self:_ga_process(drv, ga_stream, state, buf, txt_buf) -- finalizing drv.close_buffer(state, buf, txt_buf) -- finalize the istruction sequence -- build hbox - local ok, err = drv.hboxcreate(boxname, state, buf, txt_buf) - return ok, err + return drv.hboxcreate(boxname, state, buf, txt_buf) end @@ -124,38 +173,62 @@ end Driver._opcode_v001 = { [1] = function (drv, st, pc, ga, bf, xt) -- 1 <W: dim>; set line width local w = ga[pc] - st.line_width = w - if not drv.append_001 then - error("[InternalErr] unimplemented opcode 1 for "..drv._NAME) - end + st.linewidth = w drv.append_001(st, bf, xt, w) return pc + 1 end, [2] = function (drv, st, pc, ga, bf, xt) -- 2 <e: u8>; set line cap style local style = ga[pc] - st.line_cap = style + st.linecap = style if not drv.append_002 then - error("[InternalErr] unimplemented opcode 2 for "..drv._NAME) + error("[InternalErr] unimplemented opcode 2 for "..drv._drvname) end drv.append_002(st, bf, xt, style) return pc + 1 end, [3] = function (drv, st, pc, ga, bf, xt) -- 3 <e: u8>; set line join style local join = ga[pc] - if not drv.append_003 then - error("[InternalErr] unimplemented opcode 3 for "..drv._NAME) - end + st.linejoin = join drv.append_003(st, bf, xt, join) return pc + 1 end, - [30] = function (drv, st, pc, ga, bf, xt) -- start_bbox_group - assert(st.bb_on) - st.bb_on = false + -- 5 <dash_pattern>, Dash pattern line style + -- phase <len> n <qty> [bi <len>]+ + [5] = function (drv, st, pc, ga, bf, xt) + if not drv.append_005 then + error("[InternalErr] unimplemented opcode 5 for "..drv._drvname) + end + local phase = ga[pc]; pc = pc + 1 + local n = ga[pc]; pc = pc + 1 + assert(n > 0, "[Err] dash pattern needs one length or more ("..n..")") + st.dashphase = phase + local dash = {} + for i = pc, pc + n - 1 do + local v = ga[i] + dash[#dash + 1] = v + end + st.dashpattern = dash + drv.append_005(st, bf, xt, phase, dash) + return pc + n + end, + [6] = function (drv, st, pc, ga, bf, xt) -- 6 <reset_pattern> + if not drv.append_006 then + error("[InternalErr] unimplemented opcode 6 for "..drv._drvname) + end + st.dashpattern = nil -- reset dash pattern array and phase + st.dashphase = nil + drv.append_006(st, bf, xt) return pc end, - [31] = function (drv, st, pc, ga, bf, xt) -- end_bbox_group - assert(st.bb_on == false) + [29] = function (drv, st, pc, ga, bf, xt) -- enable_bbox st.bb_on = true + return pc + end, + [30] = function (drv, st, pc, ga, bf, xt) -- disable_bbox + st.bb_on = false + return pc + end, + [31] = function (drv, st, pc, ga, bf, xt) -- set_bbox local x1 = ga[pc]; pc = pc + 1 local y1 = ga[pc]; pc = pc + 1 local x2 = ga[pc]; pc = pc + 1 @@ -180,7 +253,7 @@ Driver._opcode_v001 = { local x2 = ga[pc]; pc = pc + 1 local y = ga[pc]; pc = pc + 1 if st.bb_on then -- eventually update bbox - local hw = st.line_width/2 + local hw = st.linewidth/2 local by1 = y - hw local by2 = y + hw if st.bb_x1 == nil then @@ -196,7 +269,7 @@ Driver._opcode_v001 = { end end if not drv.append_033 then - error("[InternalErr] unimplemented opcode 33 for "..drv._NAME) + error("[InternalErr] unimplemented opcode 33 for "..drv._drvname) end drv.append_033(st, bf, xt, x1, x2, y) return pc @@ -206,8 +279,8 @@ Driver._opcode_v001 = { local y1 = ga[pc]; pc = pc + 1 local y2 = ga[pc]; pc = pc + 1 local x = ga[pc]; pc = pc + 1 - if st.bb_on then -- eventually update the figure bounding box - local hw = st.line_width/2 + if st.bb_on then -- eventually update the figure's bounding box + local hw = st.linewidth/2 local bx1 = x - hw local bx2 = x + hw if st.bb_x1 == nil then @@ -223,7 +296,7 @@ Driver._opcode_v001 = { end end if not drv.append_034 then - error("[InternalErr] unimplemented opcode 34 for "..drv._NAME) + error("[InternalErr] unimplemented opcode 34 for "..drv._drvname) end drv.append_034(st, bf, xt, y1, y2, x) return pc @@ -277,16 +350,64 @@ Driver._opcode_v001 = { end return pc_next end, + -- draw a polyline + -- 38 <n> <x1: DIM> <y1: DIM> ... <xn: DIM> <yn: DIM> + -- basic support for bounding box calculation + [38] = function(drv, st, pc, ga, bf, xt) -- polyline + local n = ga[pc]; pc = pc + 1; assert(n > 1) + local x1 = ga[pc]; pc = pc + 1 + local y1 = ga[pc]; pc = pc + 1 + if drv.append_038_start then + drv.append_038_start(st, bf, xt, n, x1, y1) + end + local pc_next = pc + 2*(n - 1) + local bx1, bx2, by1, by2 = x1, x1, y1, y1 -- simplified bb vertex + for i = pc, pc_next - 1, 2 do -- reading coordinates <x> <y> + local x = assert(ga[i], "[InternalErr] ga prematurely reached the end") + local y = assert(ga[i+1], "[InternalErr] ga prematurely reached the end") + drv.append_038_point(st, bf, xt, x, y) + -- check the bounding box only if the corresponding flag is true + if st.bb_on then + if x > bx2 then + bx2 = x + elseif x < bx1 then + bx1 = x + end + if y > by2 then + by2 = y + elseif y < by1 then + by1 = y + end + end + end + if drv.append_038_stop then + drv.append_038_stop(st, bf, xt) + end + if st.bb_on then -- eventually update bbox + if st.bb_x1 == nil then + st.bb_x1 = bx1 + st.bb_x2 = bx2 + st.bb_y1 = by1 + st.bb_y2 = by2 + else + if bx1 < st.bb_x1 then st.bb_x1 = bx1 end + if bx2 > st.bb_x2 then st.bb_x2 = bx2 end + if by1 < st.bb_y1 then st.bb_y1 = by1 end + if by2 > st.bb_y2 then st.bb_y2 = by2 end + end + end + return pc_next + end, -- draw a rectangle -- 48 <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM> [48] = function(drv, st, pc, ga, bf, xt) - local x1 = ga[pc]; pc = pc + 1 - local y1 = ga[pc]; pc = pc + 1 - local x2 = ga[pc]; pc = pc + 1 - local y2 = ga[pc]; pc = pc + 1 + local x1 = ga[pc]; pc = pc + 1 + local y1 = ga[pc]; pc = pc + 1 + local x2 = ga[pc]; pc = pc + 1 + local y2 = ga[pc]; pc = pc + 1 -- check the bounding box only if the flag is true if st.bb_on then - local hw = st.line_width/2 + local hw = st.linewidth/2 local bx1, bx2 = x1 - hw, x2 + hw local by1, by2 = y1 - hw, y2 + hw if st.bb_x1 == nil then @@ -302,7 +423,7 @@ Driver._opcode_v001 = { end end if not drv.append_048 then - error("[InternalErr] unimplemented opcode 48 for "..drv._NAME) + error("[InternalErr] unimplemented opcode 48 for "..drv._drvname) end drv.append_048(st, bf, xt, x1, y1, x2, y2) return pc diff --git a/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-pdfliteral.lua b/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-pdfliteral.lua index b36021f9b62..a5cfccf4cb8 100644 --- a/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-pdfliteral.lua +++ b/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-pdfliteral.lua @@ -1,22 +1,17 @@ -- -- ga graphic assembler or -- Intermediate Graphic Language for barcode drawing --- Copyright (C) 2020 Roberto Giacomelli +-- Copyright (C) 2019-2022 Roberto Giacomelli -- -- All dimensions are in scaled point (sp) -- ga LuaTeX Driver (native implementation node+pdfliteral) --- class for drawing elementary geometric elements -local PDFnative = { - _VERSION = "PDFnative v0.0.4", - _NAME = "PDFnative", - _DESCRIPTION = "A LuaTeX native pdfliteral driver for ga graphic stream", -} - local tex = assert(tex, "This require a Lua powered TeX engine") local node = assert(node, "This require a Lua powered TeX engine") local font = assert(font, "This require a Lua powered TeX engine") +-- class for drawing elementary geometric elements +local PDFnative = {_drvname = "PDFnative"} PDFnative.ext = "txt" -- file extension PDFnative.buf_sep = "\n" -- separation string for buffer concat @@ -24,6 +19,7 @@ function PDFnative.init_buffer(st) --> buffer, text buffer st.head = nil -- addition for text processing (to remember purpose) st.last = nil st.hbox = nil + st.dash_array = nil st.cw = nil st.x_hbox = nil st.char_counter = nil @@ -126,12 +122,27 @@ function PDFnative.append_003(st, bf, xt, j) bf[#bf + 1] = string.format("%d j", j) end +-- 5 dash_pattern +function PDFnative.append_005(st, bf, xt, phase, dash_array) + local bp = st.bp -- conversion factor bp -> sp + local t = {} + for _, d in ipairs(dash_array) do + t[#t + 1] = string.format("%0.6f", d/bp) + end + bf[#bf + 1] = string.format("[%s] %0.6f d",table.concat(t, " "), phase/bp) +end + +-- 6 reset_pattern +function PDFnative.append_006(st, bf, xt) + bf[#bf + 1] = string.format("[] 0 d") +end + -- draw an horizontal line -- 33 <x1: DIM> <x2: DIM> <y: DIM> function PDFnative.append_033(st, bf, xt, x1, x2, y) local bp = st.bp -- conversion factor bp -> sp - bf[#bf + 1] = string.format("% 0.6f %0.6f m", x1/bp, y/bp) - bf[#bf + 1] = string.format("% 0.6f %0.6f l", x2/bp, y/bp) + bf[#bf + 1] = string.format("%0.6f %0.6f m", x1/bp, y/bp) + bf[#bf + 1] = string.format("%0.6f %0.6f l", x2/bp, y/bp) bf[#bf + 1] = "S" -- stroke end @@ -140,8 +151,8 @@ end -- 34 <y1: DIM> <y2: DIM> <x: DIM> function PDFnative.append_034(st, bf, xt, y1, y2, x) local bp = st.bp -- conversion factor bp -> sp - bf[#bf + 1] = string.format("% 0.6f %0.6f m", x/bp, y1/bp) - bf[#bf + 1] = string.format("% 0.6f %0.6f l", x/bp, y2/bp) + bf[#bf + 1] = string.format("%0.6f %0.6f m", x/bp, y1/bp) + bf[#bf + 1] = string.format("%0.6f %0.6f l", x/bp, y2/bp) bf[#bf + 1] = "S" -- stroke end @@ -161,6 +172,21 @@ function PDFnative.append_036_stop(st, bf, xt, nbar, y1, y2) bf[#bf + 1] = "S" -- stroke end +-- Polyline +-- draw a polyline +-- 38 <n> <x1: DIM> <y1: DIM> ... <xn: DIM> <yn: DIM> +function PDFnative.append_038_start(st, bf, xt, n, x1, y1) + local bp = st.bp -- conversion factor bp -> sp + bf[#bf + 1] = string.format("%0.6f %0.6f m", x1/bp, y1/bp) +end +function PDFnative.append_038_point(st, bf, xt, x, y) + local bp = st.bp -- conversion factor bp -> sp + bf[#bf + 1] = string.format("%0.6f %0.6f l", x/bp, y/bp) +end +function PDFnative.append_038_stop(st, bf, xt) + bf[#bf + 1] = "S" -- stroke +end + -- draw a rectangle -- 48 <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM> function PDFnative.append_048(st, bf, xt, x1, y1, x2, y2) diff --git a/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-svg.lua b/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-svg.lua index ce1f5bffbc2..df5ae0e366f 100644 --- a/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-svg.lua +++ b/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-svg.lua @@ -1,18 +1,13 @@ -- -- ga Intermediate Graphic Language for barcode drawing --- SVG library --- Copyright (C) 2020 Roberto Giacomelli +-- SVG driver for the ga graphic stream +-- Copyright (C) 2019-2022 Roberto Giacomelli -- -- All dimension in the ga stream are scaled point (sp) -- 1 pt = 65536 sp -- class for drawing elementary geometric elements -local SVG = { - _VERSION = "SVGdriver v0.0.1", - _NAME = "SVGdriver", - _DESCRIPTION = "A SVG driver for the ga graphic stream", -} - +local SVG = {_drvname = "SVG"} SVG.ext = "svg" -- file extension SVG.buf_sep = nil -- separation string for buffer concat @@ -30,10 +25,10 @@ function SVG.init_buffer(st) --> buffer, text buffer } -- additions for SVG driver to 'state' st.ident_lvl = 1 -- identation level - st.char_buf = nil + st.char_buf = nil -- character buffer local mm = st.mm st.h_char = 2.1 * mm -- char height (mm) - st.w_char = st.h_char / 1.303 -- avg char width (mm) + st.w_char = st.h_char / 1.303 -- average char width (mm) st.d_char = st.h_char / 3.7 -- char deep (mm) return bf, {} end @@ -42,7 +37,7 @@ function SVG.close_buffer(st, bf, xt) bf[#bf + 1] = '</svg>\n' -- close svg xml element bf[#bf + 1] = '\n' -- a last empty line local mm = st.mm - local x1, y1, x2, y2 = st.bb_x1, st.bb_y1, st.bb_x2, st.bb_y2 + local x1, y1, x2, y2 = st.bb_x1 or 0, st.bb_y1 or 0, st.bb_x2 or 0, st.bb_y2 or 0 local w = (x2 - x1)/mm local h = (y2 - y1)/mm local fmt_wh = bf[7] @@ -55,25 +50,55 @@ end -- SVG encoding functions -- 1 <W: dim>; set line width -function SVG.append_001(st, bf, xt, w) - -- nothing to do +function SVG.append_001(st, bf, xt, w) -- nothing to do +end + +-- 2 <enum: u8>; set line cap style +function SVG.append_002(st, bf, xt, cap) -- nothing to do +end + +-- 3 <enum: u8>; set line join style +function SVG.append_003(st, bf, xt, j) -- nothing to do +end + +-- 5 <dash_pattern> +function SVG.append_005(st, bf, xt) -- nothing to do +end + +-- 6 <reset_pattern> +function SVG.append_006(st, bf, xt) -- nothing to do end --- draw an horizontal line +-- draw an horizontal line <hline> opcode -- 33 <x1: DIM> <x2: DIM> <y: DIM> function SVG.append_033(st, bf, xt, x1, x2, y) local lvl = st.ident_lvl local ident = string.rep(" ", lvl) -- a couple of spaces as indentation local mm = st.mm -- conversion ratio sp -> bp bf[#bf + 1] = string.format( -- <path> element - '%s<path d="M%0.6f %0.6fH%0.6f"\n', - ident, x1/mm, -y/mm, x2/mm + '%s<path d="M%0.6f %0.6fH %0.6f"\n', ident, x1/mm, -y/mm, x2/mm ) - local lw = st.line_width + local lw = st.linewidth bf[#bf + 1] = string.format( - '%s style="stroke:#000000;stroke-width:%0.6f"\n', - ident, lw/mm + '%s stroke="black" stroke-width="%0.6f"\n', ident, lw/mm ) + local dash = st.dashpattern + if dash then + local t = {} + for _, d in ipairs(dash) do + t[#t + 1] = string.format("%0.6f", d/mm) + end + bf[#bf + 1] = string.format( + '%s stroke-dasharray="%s"\n', ident, table.concat(t, " ") + ) + local phase = st.dashphase + assert(phase >= 0) + if phase > 0 then + bf[#bf + 1] = string.format( + '%s stroke-dashoffset="%0.6f"\n', ident, phase/mm + ) + end + end bf[#bf + 1] = ident..'/>\n' end @@ -83,14 +108,29 @@ function SVG.append_034(st, bf, xt, y1, y2, x) local ident = string.rep(" ", lvl) -- a couple of spaces as indentation local mm = st.mm -- conversion ratio sp -> mm bf[#bf + 1] = string.format( -- <path> element - '%s<path d="M%0.6f %0.6fV%0.6f"\n', - ident, x/mm, -y2/mm, -y1/mm + '%s<path d="M%0.6f %0.6f V%0.6f"\n', ident, x/mm, -y2/mm, -y1/mm ) - local lw = st.line_width + local lw = st.linewidth bf[#bf + 1] = string.format( - '%s style="stroke:#000000;stroke-width:%0.6f"\n', - ident, lw/mm + '%s stroke="black" stroke-width="%0.6f"\n', ident, lw/mm ) + local dash = st.dashpattern + if dash then + local t = {} + for _, d in ipairs(dash) do + t[#t + 1] = string.format("%0.6f", d/mm) + end + bf[#bf + 1] = string.format( + '%s stroke-dasharray="%s"\n', ident, table.concat(t, " ") + ) + local phase = st.dashphase + assert(phase >= 0) + if phase > 0 then + bf[#bf + 1] = string.format( + '%s stroke-dashoffset="%0.6f"\n', ident, phase/mm + ) + end + end bf[#bf + 1] = ident..'/>\n' end @@ -118,6 +158,91 @@ function SVG.append_036_stop(st, bf, xt, nbar, y1, y2) bf[#bf + 1] = ident..'</g>\n' -- end group end +-- Polyline +-- draw a polyline +-- 38 <n> <x1: DIM> <y1: DIM> ... <xn: DIM> <yn: DIM> +function SVG.append_038_start(st, bf, xt, n, x1, y1) + local lvl = st.ident_lvl + local ident = string.rep(" ", lvl) + local mm = st.mm -- conversion factor mm -> sp + local style = string.format( + '%s<g stroke="black" stroke-width="%0.6f" fill="none"', + ident, st.linewidth/mm + ) + local dash = st.dashpattern + if dash then + local t = {} + for _, d in ipairs(dash) do + t[#t + 1] = string.format("%0.6f", d/mm) + end + style = string.format( + '%s stroke-dasharray="%s"', style, table.concat(t, " ") + ) + local phase = st.dashphase + assert(phase >= 0) + if phase > 0 then + style = string.format( + '%s stroke-dashoffset="%0.6f"', style, phase/mm + ) + end + end + bf[#bf + 1] = style..'>\n' + ident = ident .. " " + bf[#bf + 1] = string.format('%s<polyline points="%0.6f,%0.6f', + ident, x1/mm, -y1/mm + ) + st.ident_lvl = lvl + 1 +end +function SVG.append_038_point(st, bf, xt, x, y) + local lvl = st.ident_lvl + local ident = string.rep(" ", lvl) + local mm = st.mm -- conversion factor mm -> sp + bf[#bf + 1] = string.format('\n%s%0.6f,%0.6f', ident, x/mm, -y/mm) +end +function SVG.append_038_stop(st, bf, xt) + bf[#bf + 1] = '"/>\n' -- closing tag + local lvl = st.ident_lvl - 1 + local ident = string.rep(" ", lvl) + st.ident_lvl = lvl + bf[#bf + 1] = ident..'</g>\n' -- close the group +end + +-- draw a rectangle +-- 48 <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM> +function SVG.append_048(st, bf, xt, x1, y1, x2, y2) + local w = x2 - x1 -- rectangle width + assert(w > 0) + local h = y2 - y1 -- rectangle height + assert(h > 0) + local mm = st.mm -- conversion factor mm -> sp + local lvl = st.ident_lvl + local ident = string.rep(" ", lvl) + local fmt = '%s<rect x="%0.6f" y="%0.6f" width="%0.6f" height="%0.6f"' + bf[#bf + 1] = string.format(fmt, ident, x1/mm, -y2/mm, w/mm, h/mm) + local lw = st.linewidth + bf[#bf + 1] = string.format( + '%s fill="none" stroke="black" stroke-width="%0.6f"\n', ident, lw/mm + ) + local dash = st.dashpattern + if dash then + local t = {} + for _, d in ipairs(dash) do + t[#t + 1] = string.format("%0.6f", d/mm) + end + bf[#bf + 1] = string.format( + '%s stroke-dasharray="%s"\n', ident, table.concat(t, " ") + ) + local phase = st.dashphase + assert(phase >= 0) + if phase > 0 then + bf[#bf + 1] = string.format( + '%s stroke-dashoffset="%0.6f"\n', ident, phase/mm + ) + end + end + bf[#bf + 1] = ident..'/>\n' +end + -- Text -- 130 <text> Text with several glyphs -- 130 <ax: FLOAT> <ay: FLOAT> <xpos: DIM> <ypos: DIM> <c: CHARS> |