texlive[63701] Master/texmf-dist: barracuda (23jun22)

commits+karl at tug.org commits+karl at tug.org
Thu Jun 23 22:54:26 CEST 2022


Revision: 63701
          http://tug.org/svn/texlive?view=revision&revision=63701
Author:   karl
Date:     2022-06-23 22:54:26 +0200 (Thu, 23 Jun 2022)
Log Message:
-----------
barracuda (23jun22)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/luatex/barracuda/PLANNER.txt
    trunk/Master/texmf-dist/doc/luatex/barracuda/README.md
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-barracuda-package/01-barracuda-latex-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-barracuda-package/01-barracuda-latex-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-barracuda-package/02-ord_iter-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/002-code128-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/002-code128-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/02-05-pdfliteral.txt
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/002-code39-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/002-code39-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/003-code39-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/003-code39-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/004-code39-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/004-code39-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/006-code39-test.lua
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/001-13-ean-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/001-13-ean-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/002-ean-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/003-ean-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/005-isbn-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/006-issn-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/006-issn-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/8006194056290.svg
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/ars.svg
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/001-ga-pdfliteral-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/001-ga-pdfliteral-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-svg/002-ga-svg-test.lua
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/001-i2of5-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/001-i2of5-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/002-ITF14-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/002-ITF14-test.tex
    trunk/Master/texmf-dist/scripts/barracuda/barracuda.lua
    trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-barcode.lua
    trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-code128.lua
    trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-code39.lua
    trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-ean.lua
    trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-i2of5.lua
    trunk/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-driver.lua
    trunk/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-pdfliteral.lua
    trunk/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-svg.lua
    trunk/Master/texmf-dist/scripts/barracuda/lib-geo/brcd-gacanvas.lua
    trunk/Master/texmf-dist/scripts/barracuda/lib-geo/brcd-libgeo.lua
    trunk/Master/texmf-dist/tex/luatex/barracuda/barracuda.sty

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/ga-graphic-asm/
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/ga-graphic-asm/barracuda-ga-asm.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/ga-graphic-asm/barracuda-ga-asm.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual-tool.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/image/
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/image/8006194056290.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/001-code128-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/001-code39-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/007-code39-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/007-code39-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/004-ean-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/002-polyline.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/002-polyline.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/polygon.svg
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/02-itf14.svg
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/001-libgeo-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/001-libgeo-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/003-ga-svg-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/003-ga-svg-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/test.svg
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/001-upca-test.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/001-upca-test.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/002-upca.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/002-upca.tex
    trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-upc.lua

Removed Paths:
-------------
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda-ga-asm.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda-ga-asm.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda-manual-tool.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda.pdf
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda.tex
    trunk/Master/texmf-dist/doc/luatex/barracuda/doc/image/
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/001-code128-test.lua
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/001-code39-test.lua
    trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/004-ean-test.lua

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/PLANNER.txt
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/PLANNER.txt	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/PLANNER.txt	2022-06-23 20:54:26 UTC (rev 63701)
@@ -5,7 +5,7 @@
 -----------
 
 + Every new version will be uploaded to CTAN network
-+ For each single task there will be a correspomding commit
++ For each single task there will be a single commit
 
 Hypothetical development task list:
 -----------------------------------
@@ -18,52 +18,101 @@
 20__-__-__: [dev] proportional options
 20__-__-__: [dev] a number parameter can be a string? unit measure...
 20__-__-__: [prj] a command line program to print barcodes
-20__-__-__: [dev] guard text in EAN simbology
-20__-__-__: [dev] UPC support
 20__-__-__: [dev] make optional file name in all the Driver methods
 20__-__-__: [prj] test l3build for testing and CTAN files packaging
 20__-__-__: [dev] load barcode parameters from an external file
 20__-__-__: [dev] new Parameter Class
+202_-__-__: [dev][barcode] new `alias` feature
+202_-__-__: [dev][barcode] new `preset` feature
+202_-__-__: [project][build] make a Lua script to easily create the CTAN upload
+          : compressed files
+202_-__-__: [dev] statistical data on how many barcode symbols was printed
+202_-__-__: [upc] UPC-E barcode symbology
 
-Scheduled task list for Data Matrix 2D simbology implementation:
+Scheduled task list for Data Matrix 2D symbology implementation:
 ----------------------------------------------------------------
 
-2020-__-__: [dmx] data matrix first run
-2020-__-__: [dmx] ecc200 error correction code
-2020-__-__: [svg] opcode for grids
-2020-__-__: [pdf] opcode for grids
-2020-__-__: [gas] ga-asm grid opcode
-2020-__-__: [geo] grid vector object
-2020-__-__: [dev] init source file encoder for Data Matrix
-2020-__-__: [dev] parameter preset
+202_-__-__: [dmx] data matrix first run
+202_-__-__: [dmx] ecc200 error correction code
+202_-__-__: [svg] opcode for grids
+202_-__-__: [pdf] opcode for grids
+202_-__-__: [ga] ga new grid opcode
+202_-__-__: [geo] grid vector object
+202_-__-__: [dev] init source file encoder for Data Matrix
 
-Dev Planner:
-============
+Ongoing Scheduler:
+==================
 -------------------------------------------------------------------------------
-2020-__-__: [milestone] version <v0.0.11> completed task/commit list
-2020-__-__: [doc] barcode symbologies reference
-2020-__-__: [doc] put ga-asm-spec together with the manual
-2020-__-__: [dev][barcode] new `alias` feature
-2020-__-__: [dev][barcode] new `preset` feature
-2020-__-__: [dev][i2of5] human readeable text for i2of5
-2020-__-__: [dev][libgeo] new `Vbar_group` class
-2020-__-__: [test] update test files with recent changes
-2020-__-__: [dev][libgeo][breaking change] return `ok, err` instead of `err`
+202_-__-__: [milestone] version 0.1
+202_-__-__: [test] update test files with recent changes
+202_-__-__: [dev][ean] fix the `ean:checksum()` to include ISBN and ISSN variant
+202_-__-__: [dev] control the method call on the right class
+202_-__-__: [code128] add human readeable text
+202_-__-__: [breaking change] refactor Text libgeo object
+202_-__-__: [project] adhere to semver specification
+202_-__-__: [doc] API reference
+202_-__-__: [doc] barcode symbologies reference: code39
+
+-------------------------------------------------------------------------------
+2022-06-22: [code128] fix a bug in the encoder (complete rewriting)
+-------------------------------------------------------------------------------
+2020-05-03: [barcode] debug_bbox option
+2020-05-03: [libgeo] optional tx, ty moving point for encode_<object>
+2020-04-06: [driver] new methods for gaCanvas class and default style graphic
+2020-03-20: [upc] new UPC-A barcode symbology
+2020-03-13: [barcode] new method get_code() and get_hri()
+2020-03-11: [breaking change][barcode] new `draw()` method
+2020-03-07: [ga] new <dash-pattern> and <reset-pattern> opcodes
+2020-03-06: [doc] new section explains `Vbar`
+2020-03-02: [doc] add a chess example for `ga` stream
+
+[merge]<--------+
+                |
+    2020-03-02: [doc] put ga-asm-spec together with the manual
+                |
+[doc-basic-ref]-+
+
+2020-02-27:*[dev][i2of5] human readeable text for i2of5 and ITF14
+
+[merge]<--------+
+                |
+    2020-02-26: [ean] guard text in EAN symbology
+    2020-02-25: [libgeo][gaCanvas] Polyline object test file
+    2020-02-25: [libgeo][gaCanvas] new Polyline object
+                |
+[Polyline]------+
+
+2020-02-22: [dev] new methods _process_char() and _process_digit()
+2020-02-09: [dev] new constructor `Barcode:new()`
+
+[merge]<--------+
+                |
+    2020-02-17: [libgeo] delete `Vbar_archive` in favour of `Archive`
+    2020-02-16: [libgeo] arithmetic of new object `Queue`
+    2020-02-12: [libgeo] new class `Archive`
+    2020-02-12: [dev][libgeo] add method `Vbar_archive:add_space()`
+    2020-02-12: [dev][libgeo] refactor `Vbar_archive:push_queue()` method
+    2020-02-12: [dev][ean] refactor ean to use `Vbar_archive`
+    2020-02-11: [dev][i2to5] refactor i2of5 to use `Vbar_archive`
+    2020-02-10: [dev][code128] refactor code128 to use `Vbar_archive`
+    2020-02-09: [dev][libgeo] refactor code39 to use `Vbar_archive`
+    2020-02-06: [dev][libgeo] new `Vbar_archive` class in libgeo
+                |
+[vbar_archive]--+
+
+2020-02-05: [dev][libgeo][breaking change] return `ok, err` instead of `err`
             for canvas methods
-2020-__-__: [dev] new constructor `Barcode:new()`
-2020-__-__: [project][build] make a Lua script to easily create the CTAN upload
-          : compressed files
-2020-__-__: [dev][ean] fix the `ean:checksum()` to include ISBN and ISSN variant
-2020-__-__: [dev][i2of5] `encoder:_init_parse_state()` adoption for ITF14
+2020-02-04: [dev][ean] new function `encoder:_init_parse_state()`, and EAN
+          : family adoption;
+          : [dev][i2of5] `encoder:_init_parse_state()` adoption for ITF14
           : variant
-2020-__-__: [dev][ean] new function `encoder:_init_parse_state()`, and EAN
-          : family adoption
-2020-__-__: update version number in preparetion of the next version.
+          : [project] update version number in preparation of the next version
 -------------------------------------------------------------------------------
+
 -------------------------------------------------------------------------------
-2020-02-04: [milestone] version <v0.0.10> completed task/commit list
+2020-02-04: [milestone] version <v0.0.10> completed task/commit list:
 -------------------------------------------------------------------------------
-2020-02-04:*[dev][ean] ISSN support
+2020-02-04: [dev][ean] ISSN support
 2020-02-03: [dev][ean] move out of `_config()` `finalize()` method as in i2of5
 2020-02-02: [dev][i2of5] new ITF14 variant, plan for the next version
 2020-02-01: [dev] new semantic for barcode parameter: alternative family
@@ -83,9 +132,8 @@
           : [api][breaking change] new encoder naming convention
           : reuse or create a new encoder object in barracuda:hbox() and
           : barracuda:save() methods
+-------------------------------------------------------------------------------
 
-(*) this commit
-
 Task history and previous version:
 ==================================
 

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/README.md	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/README.md	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,35 +1,34 @@
 # `barracuda` project
 
-This a pure Lua library is for drawing barcode symbols. The project components
-are able to typeset barcode from within a LuaTeX document. Therefore is also
-possible to use `barracuda` with a Lua standalone interpreter to draw barcodes
-with different graphic format such as `SVG` (see an example below). This package
-does not have dependences.
+This is a pure Lua library for drawing barcode symbols. `barracuda` components'
+are able to typeset barcode from within a LuaTeX document in order to produce a
+PDF file, or is also possible to use a Lua standalone interpreter to draw
+barcodes in different graphic format such as `SVG` (see an example below).
 
 ![a Code39 symbol in SVG format](/test/test-ga-svg/test-code39.svg)
 
-Internal modules are structured to ensure good performance and to give a
-complete user control over barcode symbol parameters :thumbsup: .
+The internal modules are structured to ensure good performance beside of a
+complete user control over barcode symbol parameters :thumbsup:
 
 Although development is in beta stage, `barracuda` has a good level of
-stability.
+stability. The package does not have any dependences.
 
 ## Current version
 
-Version: v0.0.10
-Date: 2020-02-04
+Version: 0.0.12 - Date: 2022-06-23
 
 ## Barcode symbologies list
 
-So far, the barcode symbologies included in the package are:
+So far, the barcode symbologies supported by the package are:
 
 - Code 39
 - Code 128
-- Interleaved 2 of 5
+- Interleaved 2 of 5 (ITF14, i2of5 general)
 - EAN family (ISBN, ISSN, EAN8, EAN13, and the add-ons EAN5 and EAN2)
+- UPC-A
 
-Other 1D encoding symbology will be added to the project, then it will be the
-turn of 2D barcode types like Datamatrix, QRCode or PDF417.
+Other 1D encoding symbology will be eventually added to the project, then it
+will be the turn of 2D barcode types like Datamatrix, QRCode or PDF417.
 
 ## A very simple LaTeX example
 
@@ -36,7 +35,7 @@
 The LaTeX package `barracuda.sty` under the cover uses Lua code so you need to
 compile your source files with LuaTeX or LuajitTeX with the LaTeX format.
 
-For instance, here is a minimal working example for LuaLaTeX:
+For instance, the follow is a minimal working example for LuaLaTeX:
 
 ```latex
 % !TeX program = LuaLaTeX
@@ -71,7 +70,7 @@
 TeX Live distribution or Lua interpreter executable are available for a very
 large number of Operating Systems so it is also for `barracuda`.
 
-Step by step istruction can be found in the INSTALL.txt file.
+Step by step instruction can be found in the INSTALL.txt file.
 
 ## Contribute
 
@@ -91,4 +90,4 @@
 Please, for more legal details refer to LICENSE.txt file or visit the web page
 <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
 
-Copyright (C) 2020 Roberto Giacomelli
+Copyright (C) 2019-2022 Roberto Giacomelli

Deleted: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda-ga-asm.pdf
===================================================================
(Binary files differ)

Deleted: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda-ga-asm.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda-ga-asm.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda-ga-asm.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,148 +0,0 @@
-% !TeX program = LuaLaTeX
-% Copyright (C) 2020 Roberto Giacomelli
-
-\documentclass{article}
-
-\usepackage{fontspec}
-\setmainfont{Libertinus Serif}
-
-\usepackage[margin=18mm]{geometry}
-\usepackage{array}
-\usepackage{booktabs}
-
-\newcolumntype{C}{>{\ttfamily}c}
-\newcolumntype{L}{>{\ttfamily}l}
-
-\begin{document}
-Goal: describe geometrical object like lines and rectangles
-mainly for a barcode drawing library.
-
-
-
-\section{\texttt{ga} instruction set}
-
-A graphic data specification format called '\texttt{ga}' \emph{graphic alchemy},
-or if you want \emph{generic graphic assembler}.
-
-\begin{verbatim}
-ga<DIM, UINT> := generic graphic assembler
-    <DIM>  := numeric type parameter for dimension, for example f64 or i32
-    <UINT> := numeric type parameter for quantity, an unsigned integer, i.e. u8
-
-ga<DIM, UINT> := +Elem<DIM, UINT>
-
-Elem<DIM, UINT> := Code<u8> + Args<DIM, UINT>
-
-Code<u8> := State<u8> | Object<u8> | Fn<u8>
-    State<u8>  :=   1 ->  31 -- graphic properties
-    Object<u8> :=  32 -> 239 -- graphic objects
-    Fn<u8>     := 240 -> 255 -- functions
-
-Args<DIM, UINT> : <x: DIM> | <e: u8> | <n: UINT> | <c: CHARS>
-   <x: DIM>    := a dimension value of type DIM
-   <e: u8>     := an enumeration value of type u8 (unsigned byte)
-   <n: UINT>   := an unsigned integer for multiplicity
-   <c: CHARS>  := chars sequence ended with 0
-\end{verbatim}
-
-
-
-\section{Properties}
-
-Colors, linecap style etc\dots
-
-\noindent\begin{tabular}{CLlL}
-\toprule
-OpCode & Mnemonic key & Graphic property & Operands\\
-\midrule
- 1 & pen\_thick & Line thick          &  <w: DIM>\\
- 2 & line\_cap\_style & Line cap style &  <e: u8>\\
- 3 & line\_join\_style & Line join style &  <e: u8>\\
- 8 & color & ... \\
-\midrule
-30 & start\_bbox\_group & Stop to check the bounding box & -\\
-31 & end\_bbox\_group   & Set a bounding box and restart to check &  <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM>\\
-\bottomrule
-\end{tabular}
-
-
-
-\section{Objects}
-
-\subsection{Lines}
-
-A segment that starts from point P1 (x1, y1) and ends to P2 (x2, y2).
-
-\noindent\begin{tabular}{CLlL}
-\toprule
-OpCode & Mnemonic key & Graphic object & Operands\\
-\midrule
-32 & line  & Line            & <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM>\\
-33 & hline & Horizontal line & <x1: DIM> <x2: DIM> <y: DIM>\\
-34 & vline & Vertical line   & <y1: DIM> <y2: DIM> <x: DIM>\\
-\midrule
-36 & vbar & Vertical bars     & <y1: DIM> <y2: DIM> <b: UINT> <x1: DIM> <t1: DIM> ...\\
-37 & hbar & Horizontal bars   & <x1: DIM> <x2: DIM> <b: UINT> <y1: DIM> <t1: DIM> ...\\
-\midrule
-38 & polyline & Open polyline  & <n: UINT> <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM> ...\\
-39 & c\_polyline & Closed polyline   & <n: UINT> <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM> ...\\
-\bottomrule
-\end{tabular}
-
-
-\subsection{Rectangles}
-
-\noindent\begin{tabular}{CLlL}
-\toprule
-OpCode & Mnemonic key & Graphic object & Operands\\
-\midrule
- 48 & rect & Rectangle & <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM>\\
- 49 & f\_rect & Filled rectangle & <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM>\\
- 50 & rect\_size & Rectangle & <x1: DIM> <y1: DIM> <w: DIM> <h: DIM>\\
- 51 & f\_rect\_size & Filled rectangle & <x1: DIM> <y1: DIM> <w: DIM> <h: DIM>\\
-
-\bottomrule
-\end{tabular}
-
-
-\subsection{Text}
-
-\noindent\begin{tabular}{CLl}
-\toprule
-OpCode & Mnemonic key & Graphic object/Operands\\
-\midrule
- 130 & text         & A text with several glyphs\\
-     & & \ttfamily <ax: FLOAT> <ay: FLOAT> <xpos: DIM> <ypos: DIM> <c: CHARS>\\
-\midrule
- 131 & text\_xspaced & A text with glyphs equally spaced on its vertical axis\\
-     & & \ttfamily <x1: DIM> <xgap: DIM> <ay: FLOAT> <ypos: DIM> <c: CHARS>\\
-\midrule
- 132 & text\_xwidth & Glyphs equally spaced on vertical axis between two x coordinates\\
-      & & \ttfamily <ay: FLOAT> <x1: DIM> <x2: DIM> <y: DIM> <c: CHARS>\\
-\midrule
-     & under design assessment\\
- 140 & \_text\_group & Texts on the same baseline \\
-     & & \ttfamily <ay: DIM> <y: DIM> <n: UINT> <<xi: DIM> <ai: FLOAT> <ci: CHARS>> \\
-\bottomrule
-\end{tabular}
-
-
-\subsection{Function}
-
-
-\noindent\begin{tabular}{CLlL}
-\toprule
-OpCode & Mnemonic key & Function & Operands\\
-\midrule
- 240 & move & Translate objects &  <n: UINT> <dx: DIM> <dy: UINT>\\
- 241 & copy & Copy object &  <n: UINT> <c: UINT> <dx1: DIM> <dy1: UINT> ...\\
- 242 & and\_copy & Place and copy objects &  <n: UINT> <c: UINT> <dx1: DIM> <dy1: UINT> ...\\
- 243 & grid & Copy next \(n\) objects on a grid &  <n: UINT> <col: UINT> <row: UINT> <dx: DIM> <dy: DIM>\\
- 244 & sl\_grid\\
- 250 & mirror\\
- 255 & comment & A string comment &  <s: STRING>\\
-\bottomrule
-\end{tabular}
-
-
-\end{document}

Deleted: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda-manual-tool.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda-manual-tool.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda-manual-tool.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,39 +0,0 @@
-% an auxiliary package for the manual
-\directlua{
-    barracuda = require "barracuda"
-    local v = barracuda._VERSION
-    local p = v:find(" ")
-    brcd_data = {
-        version = v:sub(p+1),
-        date = barracuda._DATE
-    }
-}
-
-\newcommand{\code}[1]{\texttt{#1}}
-\newcommand{\brcd}{\code{barracuda}}
-
-\newbox\barracudabox
-\newcommand\barracuda[3][_brcd_empty_=true]{\directlua{
-    local enc_name = [[#2]]
-    local data = [[#3]]
-    local opt = {#1};
-    if opt._brcd_empty_ == true then
-        barracuda:hbox(enc_name, data, "barracudabox")
-    else
-        barracuda:hbox(enc_name, data, "barracudabox", opt)
-    end
-}%
-\leavevmode\box\barracudabox
-}
-
-\newcommand{\brcdkey}[1]{\directlua{
-    local key = [===[#1]===]
-    if brcd_data[key] then
-        tex.sprint(brcd_data[key])
-    else
-        error("Key '"..key.."' not found")
-    end
-}}
-
-
-

Deleted: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda.pdf
===================================================================
(Binary files differ)

Deleted: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/doc/barracuda.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,413 +0,0 @@
-% !TeX program = LuaLaTeX
-% Copyright (C) 2020 Roberto Giacomelli
-% Barracuda manual, main TeX source file
-
-\documentclass[11pt,a4paper]{article}
-\usepackage{fontspec}
-\usepackage{geometry}
-\usepackage{fancyvrb}
-\usepackage{graphicx}
-\usepackage{hyperref}
-
-% special macro for manual typesetting
-\input{barracuda-manual-tool}
-
-\hypersetup{
-hidelinks,
-linktoc = all,
-pdfinfo={
-    Title={the Barracuda manual},
-    Subject={Barcode printing package},
-    Author={Roberto Giacomelli},
-    Keywords={Barcode EAN Code128 Lua}
-}}
-
-\setmainfont{Libertinus Serif}
-\setmonofont[Scale=0.82]{Fira Mono}
-\fvset{
-    fontsize=\small,
-    frame=single,
-    labelposition=topline,
-    framesep=5pt
-}
-\geometry{
-    left=32mm,
-    right=40mm,
-    top=22mm,
-    bottom=28mm
-}
-
-\author{Roberto Giacomelli\\\small email: \url{giaconet.mailbox at gmail.com}}
-\title{the \code{barracuda} manual\\[1ex]
-\small \url{https://github.com/robitex/barracuda}}
-\date{\small Date \brcdkey{date} --- Version \brcdkey{version} --- Beta stage}
-
-\begin{document}
-\maketitle
-
-\abstract{%
-Welcome to the \brcd{} software project devoted to barcode printing.
-
-This manual shows you how to print barcodes in your \TeX{} documents and how to
-export such graphic content to an external file, using \brcd{}.
-
-\brcd{} is written in Lua programming language and is free software released
-under the GPL 2 License.%
-}
-
-\tableofcontents
-\newpage
-
-
-\section{Getting started}
-\label{secStart}
-
-\subsection{Introduction}
-\label{secIntro}
-
-Barcode symbols are usually a sequence of vertical lines representing encoded
-data that can be retrived with special laser scanner or more simpler with a
-smartphone running dedicated apps. Almost every store item has a label with a
-printed barcode for automatic identification purpose.
-
-So far, \brcd{} supported symbologies are as the following:
-\begin{itemize}
-	\item Code 39,
-	\item Code 128,
-	\item EAN family (ISBN, ISSN, EAN 8, EAN 13, and the add-ons EAN 2 and EAN 5),
-	\item ITF 2of5, interleaved Two of Five.
-\end{itemize}
-
-The package provides different output graphic format. At the moment they are:
-\begin{itemize}
-	\item PDF Portable Document Format (a modern \TeX{} engine is required),
-	\item SVG Scalable Vector Graphic.
-\end{itemize}
-
-The name \brcd{} is an assonance to the name Barcode. I started the project back
-in 2016 for getting barcode in my \TeX{} generated PDF documents, studying the
-Lua\TeX{} technology such as direct \emph{pdfliteral node} creation.
-
-At the moment \brcd{} is in \emph{beta} stage. In this phase the Lua API can
-change respect to the result of development research.
-
-
-\subsection{Manual Content}
-
-The manual is divided into five part. In part~\ref{secIntro} introduces the
-package and gives to the user a proof of concept to how to use it. The next
-parts present detailed information about option parameter of each barcode
-symbology and methods description to change the \emph{module} width of a EAN-13
-barcode. It's also detailed how the Lua code works internally and how to
-implement a barcode symbology not already included in the package.
-
-The plan of the manual is (but some sections are not completed yet):
-\begin{description}
-\item[Part 1:] Getting started
-\begin{itemize}
-	\item general introduction \( \to \) \pageref{secIntro}
-	\item print your first barcode \( \to \) \pageref{secEnter}
-	\item installing \brcd{} on your system \( \to \) \pageref{secInstall}
-\end{itemize}
-
-\item[Part 2:] \LaTeX{} packages
-\begin{itemize}
-	\item \brcd{} \LaTeX{} package \( \to \) \pageref{secLaTeXPkg}
-\end{itemize}
-
-\item[Part 3:] Barcode Reference and Parameters
-\begin{itemize}
-	\item encoder identification rule \( \to \) \pageref{secEncName}
-	\item barcode symbologies reference \( \to \) \pageref{secBcRef}
-\end{itemize}
-
-\item[Part 4:] Advanced Work with \brcd{}
-\begin{itemize}
-	\item Lua framework description \( \to \) \pageref{secFramework}
-	\item API reference \( \to \) \pageref{secAPI}
-	\item \code{ga} specification \( \to \) \pageref{secGA}
-\end{itemize}
-
-\item[Part 5:] Real examples
-\begin{itemize}
-	\item working example and use cases \( \to \) \pageref{secExample}
-\end{itemize}
-\end{description}
-
-
-\subsection{Required knowledge and useful resources}
-
-\brcd{} is a Lua package that can be executed by any Lua interpreter. To use it,
-it's necessary a minimal knowledge of Lua programming language and a certain
-ability with the terminal of your computer system in order to run command line
-task or make software installation.
-
-It's also possible to run \brcd{} directly within a \TeX{} source file, and
-compile it with a suitable typesetting engine like Lua\TeX{}. In this case a
-minimal \TeX{} system knowledge is required. As an example of this workflow you
-simply can look to this manual because itself is typesetted with LuaLa\TeX{},
-running \brcd{} to include barcodes as a vector graphic object.
-
-A third way is to use the \LaTeX{} package \code{barracuda.sty} with its high
-level macros. A minimal knowledge of the \LaTeX{} format is obviously required.
-
-Here is a collection of useful learning resources:
-\begin{description}
-\item[Lua:] to learn Lua the main reference is the book called PIL, Programming
-in Lua from one of the language's Author Roberto Ierusalimschy.
-\item[\LaTeX:] \dots
-\item[Lua\TeX:] \dots
-\end{description}
-
-
-\subsection{Running Barracuda}
-\label{secEnter}
-
-The starting point to work with \brcd{} is always a plain text file with some
-code processed by a command line program with a Lua interpreter.
-
-The paradigm of \brcd{} is the Object Oriented Programming. Generally speaking
-every object must be created with a function called \emph{costructor} and every
-action must be run calling a \emph{method} of it.
-
-In this section you'll take a taste of \brcd{} coding in three different
-execution context: a Lua script, a Lua\TeX{} document and a \LaTeX{} source file
-using the macro package \code{barracuda.sty} providing an high level interface
-to Lua code.
-
-High level package like \code{barracuda.sty} make to write Lua code unnecessary.
-It will be always possible return to Lua code in order to resolve complex
-barcode requirements.
-
-
-\subsubsection{A Lua script}
-
-As a practical example to produce an EAN~13 barcode, open a text editor of your
-choice on an empty file and save it as \code{first-run.lua} with the content of
-the following two lines of code:
-\medskip
-\begin{Verbatim}[label=\footnotesize\code{first-run.lua}]
-local barracuda = require "barracuda"
-barracuda:save("ean-13", "8006194056290", "my_barcode", "svg")
-\end{Verbatim}
-
-What you have done is to write a \emph{script}. If you have installed a Lua
-interpreter along with \brcd{}, open a terminal and run it with the command:
-\begin{Verbatim}
-$ lua first-run.lua
-\end{Verbatim}
-
-You will see in the same directory of your script, appearing a new file called
-\code{my\_barcode.svg} with the drawing:
-\begin{center}
-\includegraphics{image/8006194056290}
-\end{center}
-
-Coming back to the script first of all, it's necessary to load the library
-\brcd{} with the standard Lua function \code{require()} that returns an
-object---more precisely a reference to a table where are stored all the
-package machinery.
-
-With the second line of code, an EAN~13 barcode is saved as
-\code{my\_barcode.svg} using the method \code{save()} of the \brcd{} object. The
-\code{save()} method takes in order the barcode symbology identifier called
-\emph{treename}, an argument as a string or as a whole number that represents
-data to be encoded, the output file name and the optional output format. With a
-fifth optional argument we can pass options to the barcode encoder as a Lua
-table.
-
-Each encoder has an own identifier called treename explained at
-section~\ref{secEncName}. In short, in \brcd{} we can build more encoders of the
-same symbology with different parameters.
-
-
-\subsubsection{A Lua\TeX{} source file}
-
-\brcd{} can also runs with Lua\TeX{} and any others Lua powered \TeX{}
-engines. The source file is a bit difference respect to the previuos script: the
-Lua code lives inside the argument of a \verb=\directlua= primitive, moreover we
-must use an horizontal box register as output destination.
-\begin{Verbatim}
-% !TeX program = LuaTeX
-\newbox\mybox
-\directlua{
-	local require "barracuda"
-	barracuda:hbox("ean-13", "8006194056290", "mybox")
-}\leavevmode\box\mybox
-\bye
-\end{Verbatim}
-
-The method \code{hbox()} works only with Lua\TeX{}. It takes three\footnote{A
-fourth argment is optional as a table with user defined barcode parameters.}
-arguments: encoder \emph{treename}, encoding data as a string, the \TeX{}
-horizontal box name.
-
-
-\subsubsection{A Lua\LaTeX{} source file}
-
-\LaTeX{} working minimal example would be:
-\begin{Verbatim}
-% !TeX program = LuaLaTeX
-\documentclass{article}
-\usepackage{barracuda}
-\begin{document}
-\barracuda{ean-13}{8006194056290}
-\end{document}
-\end{Verbatim}
-
-
-\subsection{A more deep look}
-
-\brcd{} is designed to be modular and flexible. For example it is possible to
-draw different barcodes on the same canvas or tune barcode parameters. 
-
-The main workflow to draw a barcode object reveals more details on internal
-structure. In fact, to draw an EAN~13 barcode we must do at least the following
-steps:
-\begin{enumerate}
-\item load the library,
-\item get a reference to the \code{Barcode} abstract class,
-\item build an \code{ean} encoder of the variant \code{13},
-\item build an EAN~13 symbol passing data to a costructor,
-\item get a reference to a new canvas object,
-\item draw barcode on the canvas object,
-\item get a reference of the driver object,
-\item print the graphic material saving an external \code{svg} file.
-\end{enumerate}
-
-Following that step by step procedure the corresponding code is translated in
-the next listing:
-\begin{Verbatim}
--- lua script
-local barracuda = require "barracuda" -- step 1
-local barcode = barracuda:barcode() -- step 2
-
-local ean13, err_enc = barcode:new_encoder("ean-13") -- step 3
-assert(ean13, err_enc)
-
-local symb, err_symb = ean13:from_string("8006194056290") -- step 4
-assert(symb, err_symb)
-
-local canvas = barracuda:new_canvas() -- step 5
-symb:append_ga(canvas) -- step 6
-
-local driver = barracuda:get_driver() -- step 7
-local ok, err_out = driver:save("svg", canvas, "my_barcode") -- step 8
-assert(ok, err_out)
-\end{Verbatim}
-
-Late the manual will give objects and methods references at
-section~\ref{secAPI}.
-
-
-\subsection{Installing}
-\label{secInstall}
-
-\subsubsection{Installing for Lua}
-
-Manually copy \code{src} folder content to a suitable directory of your system
-that is reachable to the system Lua interpreter.
-
-\subsubsection{Installing for TeX Live}
-
-If you have TeX Live installed from CTAN or from DVD TeX Collection, before any
-modification to your system check if the package is already installed looking
-for \emph{installed} key in the output of the command:
-\begin{Verbatim}
-$ tlmgr show barracuda
-\end{Verbatim}
-
-If `barracuda` is not present, run the command:
-\begin{Verbatim}
-$ tlmgr install barracuda
-\end{Verbatim}
-
-If you have installed TeX Live via Linux OS repository try your distribution's
-package management system running a software update.
-
-It's also possible to install the package manually:
-\begin{enumerate}
-\item Grab the sources from CTAN or \url{https://github.com/robitex/barracuda}.
-\item Unzip it at the root of one or your TDS trees (local or personal).
-\item You may need to update some filename database after this, see your \TeX{}
-distribution's manual for details.
-\end{enumerate}
-
-
-\section{Barracuda \LaTeX{} Package}
-\label{secLaTeXPkg}
-
-The \LaTeX{} package delivered with \brcd{} is still under an early stage of
-development. The only macro available is \verb=\barracuda{encoder}{data}=.
-A simple example is the following source file for Lua\LaTeX{}:
-\begin{Verbatim}
-% !TeX program = LuaLaTeX
-\documentclass{article}
-\usepackage{barracuda}
-\begin{document}
-\leavevmode
-\barracuda{code39}{123ABC}\\
-\barracuda{code128}{123ABC}
-\end{document}
-\end{Verbatim}
-
-Every macro \verb=\barracuda= typesets a barcode symbol with the encoder defined
-in the first argument, encoding data defined by the second.
-
-
-\section{Barcode parameters}
-\label{secBarcodeReference}
-
-\subsection{Encoder treename}
-\label{secEncName}
-
-TODO
-
-\subsection{Barcode Reference}
-\label{secBcRef}
-
-TODO
-
-\section{Developer zone}
-
-\subsection{The Barracuda Framework}
-\label{secFramework}
-
-The \brcd{} package framework consists in indipendent modules: a barcode class
-hierarchy encoding a text into a barcode symbology; a geometrical library called
-\code{libgeo} representing several graphic objects; an encoding library for the
-\code{ga} format (graphic assembler) and several driver to \emph{print} a ga
-stream into a file or a \TeX{} hbox register.
-
-To implement a barcode encoder you have to write a component called
-\emph{encoder} defining every parameters and implementing the encoder builder,
-while a driver must understand ga opcode stream and print the corresponding
-graphic object.
-
-Every barcode encoder come with a set of parameters, some of them can be
-reserved and can't be edit after the encoder was build. So, you can create many
-instances of the same encoder for a single barcode type, with its own parameter
-set.
-
-The basic idea is getting faster encoders, for which the user may set up
-paramenters at any level: barcode abstract class, encoder globally, down to a
-single symbol object.
-
-The Barcode class is completely indipendent from the ouput driver and viceversa.
-
-\subsection{Lua API reference}
-\label{secAPI}
-
-TODO
-
-\subsection{\code{ga} specification}
-\label{secGA}
-
-TODO
-
-\section{Example and use cases}
-\label{secExample}
-
-TODO
-
-\end{document}

Added: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/ga-graphic-asm/barracuda-ga-asm.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/ga-graphic-asm/barracuda-ga-asm.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/doc/ga-graphic-asm/barracuda-ga-asm.pdf	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/doc/ga-graphic-asm/barracuda-ga-asm.pdf	2022-06-23 20:54:26 UTC (rev 63701)

Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/ga-graphic-asm/barracuda-ga-asm.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/ga-graphic-asm/barracuda-ga-asm.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/doc/ga-graphic-asm/barracuda-ga-asm.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/doc/ga-graphic-asm/barracuda-ga-asm.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,148 @@
+% !TeX program = LuaLaTeX
+% Copyright (C) 2019-2022 Roberto Giacomelli
+
+\documentclass{article}
+
+\usepackage{fontspec}
+\setmainfont{Libertinus Serif}
+
+\usepackage[margin=18mm]{geometry}
+\usepackage{array}
+\usepackage{booktabs}
+
+\newcolumntype{C}{>{\ttfamily}c}
+\newcolumntype{L}{>{\ttfamily}l}
+
+\begin{document}
+Goal: describe geometrical object like lines and rectangles
+mainly for a barcode drawing library.
+
+
+
+\section{\texttt{ga} instruction set}
+
+A graphic data specification format called '\texttt{ga}' \emph{graphic alchemy},
+or if you want \emph{generic graphic assembler}.
+
+\begin{verbatim}
+ga<DIM, UINT> := generic graphic assembler
+    <DIM>  := numeric type parameter for dimension, for example f64 or i32
+    <UINT> := numeric type parameter for quantity, an unsigned integer, i.e. u8
+
+ga<DIM, UINT> := +Elem<DIM, UINT>
+
+Elem<DIM, UINT> := Code<u8> + Args<DIM, UINT>
+
+Code<u8> := State<u8> | Object<u8> | Fn<u8>
+    State<u8>  :=   1 ->  31 -- graphic properties
+    Object<u8> :=  32 -> 239 -- graphic objects
+    Fn<u8>     := 240 -> 255 -- functions
+
+Args<DIM, UINT> : <x: DIM> | <e: u8> | <n: UINT> | <c: CHARS>
+   <x: DIM>    := a dimension value of type DIM
+   <e: u8>     := an enumeration value of type u8 (unsigned byte)
+   <n: UINT>   := an unsigned integer for multiplicity
+   <c: CHARS>  := chars sequence ended with 0
+\end{verbatim}
+
+
+
+\section{Properties}
+
+Colors, linecap style etc\dots
+
+\noindent\begin{tabular}{CLlL}
+\toprule
+OpCode & Mnemonic key & Graphic property & Operands\\
+\midrule
+ 1 & pen\_thick & Line thick          &  <w: DIM>\\
+ 2 & line\_cap\_style & Line cap style &  <e: u8>\\
+ 3 & line\_join\_style & Line join style &  <e: u8>\\
+ 8 & color & ... \\
+\midrule
+29 & enable\_bbox & start to update the bounding box & -\\
+30 & disable\_bbox & Stop to check the bounding box & -\\
+31 & set\_bbox & Set a bounding box &  <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM>\\
+\bottomrule
+\end{tabular}
+
+
+
+\section{Objects}
+
+\subsection{Lines}
+
+A segment that starts from point P1 (x1, y1) and ends to P2 (x2, y2).
+
+\noindent\begin{tabular}{CLlL}
+\toprule
+OpCode & Mnemonic key & Graphic object & Operands\\
+\midrule
+32 & line  & Line            & <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM>\\
+33 & hline & Horizontal line & <x1: DIM> <x2: DIM> <y: DIM>\\
+34 & vline & Vertical line   & <y1: DIM> <y2: DIM> <x: DIM>\\
+\midrule
+36 & vbar & Vertical bars     & <y1: DIM> <y2: DIM> <b: UINT> <x1: DIM> <t1: DIM> ...\\
+37 & hbar & Horizontal bars   & <x1: DIM> <x2: DIM> <b: UINT> <y1: DIM> <t1: DIM> ...\\
+\midrule
+38 & polyline & Open polyline  & <n: UINT> <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM> ...\\
+39 & c\_polyline & Closed polyline   & <n: UINT> <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM> ...\\
+\bottomrule
+\end{tabular}
+
+
+\subsection{Rectangles}
+
+\noindent\begin{tabular}{CLlL}
+\toprule
+OpCode & Mnemonic key & Graphic object & Operands\\
+\midrule
+ 48 & rect & Rectangle & <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM>\\
+ 49 & f\_rect & Filled rectangle & <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM>\\
+ 50 & rect\_size & Rectangle & <x1: DIM> <y1: DIM> <w: DIM> <h: DIM>\\
+ 51 & f\_rect\_size & Filled rectangle & <x1: DIM> <y1: DIM> <w: DIM> <h: DIM>\\
+\bottomrule
+\end{tabular}
+
+
+\subsection{Text}
+
+\noindent\begin{tabular}{CLl}
+\toprule
+OpCode & Mnemonic key & Graphic object/Operands\\
+\midrule
+ 130 & text         & A text with several glyphs\\
+     & & \ttfamily <ax: FLOAT> <ay: FLOAT> <xpos: DIM> <ypos: DIM> <c: CHARS>\\
+\midrule
+ 131 & text\_xspaced & A text with glyphs equally spaced on its vertical axis\\
+     & & \ttfamily <x1: DIM> <xgap: DIM> <ay: FLOAT> <ypos: DIM> <c: CHARS>\\
+\midrule
+ 132 & text\_xwidth & Glyphs equally spaced on vertical axis between two x coordinates\\
+      & & \ttfamily <ay: FLOAT> <x1: DIM> <x2: DIM> <y: DIM> <c: CHARS>\\
+\midrule
+     & under design assessment\\
+ 140 & \_text\_group & Texts on the same baseline \\
+     & & \ttfamily <ay: DIM> <y: DIM> <n: UINT> <<xi: DIM> <ai: FLOAT> <ci: CHARS>> \\
+\bottomrule
+\end{tabular}
+
+
+\subsection{Function}
+
+
+\noindent\begin{tabular}{CLlL}
+\toprule
+OpCode & Mnemonic key & Function & Operands\\
+\midrule
+ 240 & move & Translate objects &  <n: UINT> <dx: DIM> <dy: UINT>\\
+ 241 & copy & Copy object &  <n: UINT> <c: UINT> <dx1: DIM> <dy1: UINT> ...\\
+ 242 & and\_copy & Place and copy objects &  <n: UINT> <c: UINT> <dx1: DIM> <dy1: UINT> ...\\
+ 243 & grid & Copy next \(n\) objects on a grid &  <n: UINT> <col: UINT> <row: UINT> <dx: DIM> <dy: DIM>\\
+ 244 & sl\_grid\\
+ 250 & mirror\\
+ 255 & comment & A string comment &  <s: STRING>\\
+\bottomrule
+\end{tabular}
+
+
+\end{document}


Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/ga-graphic-asm/barracuda-ga-asm.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual-tool.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual-tool.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual-tool.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,49 @@
+% an auxiliary package for the manual
+\directlua{
+    barracuda = require "barracuda"
+    local v = barracuda._VERSION
+    local p = v:find(" ")
+    brcd_data = {
+        version = v:sub(p+1),
+        date = barracuda._DATE
+    }
+}
+
+\newcommand{\code}[1]{\texttt{#1}}
+\newcommand{\brcd}{\code{barracuda}}
+
+\newbox\barracudabox
+\newcommand\barracuda[3][_brcd_empty_=true]{\directlua{
+    local enc_name = [[#2]]
+    local data = [[#3]]
+    local opt = {#1};
+    if opt._brcd_empty_ == true then
+        barracuda:hbox(enc_name, data, "barracudabox")
+    else
+        barracuda:hbox(enc_name, data, "barracudabox", opt)
+    end
+}%
+\leavevmode\box\barracudabox
+}
+
+\newcommand{\brcdkey}[1]{\directlua{
+    local key = [===[#1]===]
+    if brcd_data[key] then
+        tex.sprint(brcd_data[key])
+    else
+        error("Key '"..key.."' not found")
+    end
+}}
+
+\newcommand{\brcdparametertab}[1]{\directlua{
+    local enc_id = [=[#1]=]
+    local t = {}
+    tex.print()
+
+    local barcode = barracuda:barcode()
+    local info = barcode:info()
+    local param = info.param
+    
+}}
+
+\endinput


Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual-tool.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual.pdf	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual.pdf	2022-06-23 20:54:26 UTC (rev 63701)

Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,1312 @@
+% !TeX program = LuaLaTeX
+% Copyright (C) 2019-2022 Roberto Giacomelli
+% Barracuda manual, main TeX source file
+
+\documentclass[11pt,a4paper]{article}
+\usepackage{fontspec}
+\usepackage{geometry}
+\usepackage{fancyvrb}
+\usepackage{graphicx}
+\usepackage{booktabs}
+\usepackage{array}
+\usepackage{tikz}
+\usepackage{tcolorbox}
+\usepackage{hyperref}
+
+\newcolumntype{C}{>{\ttfamily}c}
+\newcolumntype{L}{>{\ttfamily}l}
+
+\usetikzlibrary{arrows.meta}
+
+% special macro for manual typesetting
+\input{barracuda-manual-tool}
+
+\tcbuselibrary{skins}
+\tcbset{
+    sharpish corners,
+    drop shadow=gray!75,
+    halign lower=center,
+    left=5pt,
+    boxrule=1.2pt,
+    titlerule=0.8pt,
+    colback=green!10!white,
+    colbacktitle=green!10!white,
+    coltitle=black,
+    bicolor,colbacklower=white,
+    righthand width=80pt
+}
+
+\hypersetup{
+hidelinks,
+linktoc = all,
+pdfinfo={
+    Title={The Barracuda manual},
+    Subject={Barcode printing package},
+    Author={Roberto Giacomelli},
+    Keywords={Barcode EAN UPC Code128 ITF14 Lua}
+}}
+\definecolor{CodeBlue}{rgb}{0.05,0.05,0.80}
+\setmainfont{Libertinus Serif}
+\setmonofont[Scale=0.82]{Fira Mono}
+\fvset{
+    fontsize=\small,
+    labelposition=topline,
+    formatcom=\color{black},
+}
+\geometry{
+    left=38mm,
+    right=28mm,
+    top=22mm,
+    bottom=28mm
+}
+
+\author{Roberto Giacomelli\\\small email: \url{giaconet.mailbox at gmail.com}}
+\title{the \code{barracuda} manual\\[1ex]
+\small \url{https://github.com/robitex/barracuda}}
+\date{\small Date \brcdkey{date} --- Version \brcdkey{version} --- Beta stage}
+
+\newbox\mybox
+
+\begin{document}
+\maketitle
+
+\abstract{%
+Welcome to the \brcd{} software project devoted to barcode printing.
+
+This manual shows you how to print barcodes in your \TeX{} documents and how to
+export such graphic content to an external file.
+
+\brcd{} is written in Lua and is free software released under the GPL 2 License.
+}
+
+\tableofcontents
+\newpage
+
+
+\section{Getting started}
+\label{secStart}
+
+\subsection{Introduction}
+\label{secIntro}
+
+Barcode symbols are usually a sequence of vertical lines representing encoded
+data that can be retrived with special laser scanner or more simpler with a
+smartphone running dedicated apps. Almost every store item has a label with a
+printed barcode for automatic identification purpose.
+
+So far, \brcd{} supported symbologies are as the following:
+\begin{itemize}
+\item Code 39,
+\item Code 128,
+\item EAN family (ISBN, ISSN, EAN 8, EAN 13, and the add-ons EAN 2 and EAN 5),
+\item ITF 2of5, interleaved Two of Five (ITF14, i2of5 in general),
+\item UPC-A.
+\end{itemize}
+
+The package provides different output graphic format. At the moment they are:
+\begin{itemize}
+\item PDF Portable Document Format (a modern \TeX{} engine is required),
+\item SVG Scalable Vector Graphic.
+\end{itemize}
+
+The name \brcd{} is an assonance to the name Barcode. I started the project back
+in 2016 for getting barcode in my \TeX{} generated PDF documents, studying the
+Lua\TeX{} technology such as direct \emph{pdfliteral} node creation.
+
+At the moment \brcd{} is in \emph{beta} stage. In this phase the Lua API may
+change respect to the result of development activity.
+
+
+\subsection{Manual Content}
+
+The manual is divided into five part. In part~\ref{secIntro} introduces the
+package and gives to the user a proof of concept to how to use it. The next
+parts present detailed information about option parameter of each barcode
+symbology and methods description to change the \emph{module} width of a EAN-13
+barcode. It's also detailed how the Lua code works internally and how to
+implement a barcode symbology not already included in the package.
+
+The manual plan is:
+\begin{description}
+\item[Part 1:] Getting started
+\begin{itemize}
+	\item general introduction \( \to \) \pageref{secIntro}
+	\item print your first barcode \( \to \) \pageref{secEnter}
+	\item installing \brcd{} on your system \( \to \) \pageref{secInstall}
+\end{itemize}
+
+\item[Part 2:] \LaTeX{} packages
+\begin{itemize}
+	\item \brcd{} \LaTeX{} package \( \to \) \pageref{secLaTeXPkg}
+\end{itemize}
+
+\item[Part 3:] Barcode Reference
+\begin{itemize}
+	\item barcode symbologies reference \( \to \) \pageref{secBcRef}
+\end{itemize}
+
+\item[Part 4:] Developer zone
+\begin{itemize}
+	\item the Lua framework \( \to \) \pageref{secFramework}
+    \item encoder identification rule \( \to \) \pageref{secEncName}
+	\item API reference \( \to \) \pageref{secAPI}
+	\item \code{ga} specification \( \to \) \pageref{secGA}
+\end{itemize}
+
+\item[Part 5:] Real examples
+\begin{itemize}
+	\item working example and use cases \( \to \) \pageref{secExample}
+\end{itemize}
+\end{description}
+
+
+\subsection{Required knowledge and useful resources}
+
+\brcd{} is a Lua package that can be executed by any Lua interpreter. To use it,
+it's necessary a minimal knowledge of Lua programming language and a certain
+ability with the terminal of your computer system in order to run command line
+task or make software installation.
+
+It's also possible to run \brcd{} directly within a \TeX{} source file, and
+compile it with a suitable typesetting engine like Lua\TeX{}. In this case a
+minimal \TeX{} system knowledge is required. As an example of this workflow you
+simply can look to this manual because itself is typesetted with LuaLa\TeX{},
+running \brcd{} to include barcodes as a vector graphic object.
+
+A third way is to use the \LaTeX{} package \code{barracuda.sty} with its high
+level macros. A minimal knowledge of the \LaTeX{} format is obviously required.
+
+Here is a collection of useful learning resources:
+\begin{description}
+\item[Lua:] to learn Lua the main reference is the book called PIL that stands
+for Programming in Lua from one of the language's Author Roberto Ierusalimschy.
+\item[Lua\TeX:] the typesetting engine manual can be opened running the
+\code{texdoc} utility in a terminal window of your system, typing the command:
+\begin{Verbatim}
+$ texdoc luatex
+\end{Verbatim}
+\end{description}
+
+
+\subsection{Running Barracuda}
+\label{secEnter}
+
+The starting point to work with \brcd{} is always a plain text file with some
+code processed by a command line program with a Lua interpreter.
+
+In this section you'll take a taste of \brcd{} coding in three different
+execution context: a Lua script, a Lua\TeX{} document and a \LaTeX{} source file
+using the macro package \code{barracuda.sty} providing an high level interface
+to the Lua library.
+
+High level package like \code{barracuda.sty} make to write Lua code unnecessary.
+It will be always possible to return to Lua code in order to resolve complex
+barcode requirements.
+
+
+\subsubsection{A Lua script}
+
+The paradigm of \brcd{} is the Object Oriented Programming. Generally speaking
+every library object must be created with a function called \emph{constructor}
+and every action on it must be run calling an object \emph{method}.
+
+In Lua a constructor or even a method call syntax it's a little bit different
+from the usual form because we have to use the \emph{colon notation}:
+\begin{BVerbatim}
+object:method(args)
+\end{BVerbatim}
+
+As a practical example, to produce an EAN~13 barcode, open a text editor of your
+choice on an empty file and save it as \code{first-run.lua} with the content of
+the following two lines of code:
+\begin{tcolorbox}[
+    title={\code{first-run.lua}}
+]
+\begin{BVerbatim}
+local barracuda = require "barracuda"
+barracuda:save("ean-13", "8006194056290", "my_barcode", "svg")
+\end{BVerbatim}
+\end{tcolorbox}
+
+What you have done is to write a \emph{script}. If you have installed a Lua
+interpreter along with \brcd{}, open a terminal and run it with the command:
+\begin{BVerbatim}
+$ lua first-run.lua
+\end{BVerbatim}
+
+Into the same directory of your script you will see a new file called
+\code{my\_barcode.svg} with the drawing:
+\begin{center}
+\includegraphics{image/8006194056290}
+\end{center}
+
+Coming back to the script, the first statement loads the library \brcd{} with
+the standard Lua function \code{require()} that returns an object---more
+precisely a reference to a table where are stored all the package machinery.
+
+With the second line of code, an EAN~13 barcode is saved as
+\code{my\_barcode.svg} using the method \code{save()} of the \brcd{} object. The
+\code{save()} method takes four mandatory argumetns: the barcode symbology
+identifier called \emph{treename}, an argument as a string or as a whole number
+that represents data to be encoded, the output file name and the optional output
+format. With a fifth optional argument we can pass options to the barcode
+encoder as a Lua table in the \code{option=value} format.
+
+In more detail, thanks to treename identifier explained at
+section~\ref{secEncName} is possible to build more encoders of the same
+symbology each with a different set of parameters.
+
+It's also possible to run a Lua script with \code{texlua}, the Lua interpreter
+improved with certain Lua\TeX{} libraries delivered by any modern \TeX{}
+distribution. \code{texlua} saves you to install Lua if you are a \TeX{} user.
+
+The command to run \code{first-run.lua} is the same as before, just a
+substitution of the name \code{lua} with \code{texlua}, but an adjustment is
+required if we want to run the script with \TeX{} delivered \brcd{} library
+leaving untouched the system outside \code{texmf}.
+
+An alternative path searching procedure consists to find the main file of
+\brcd{} with an internal Lua\TeX{} library called \code{kpse}:
+\begin{Verbatim}
+-- texlua script
+kpse.set_program_name("luatex")
+local path_to_brcd = kpse.find_file("barracuda", "lua")
+local barracuda = dofile(path_to_brcd)
+barracuda:save("ean-13", "8006194056290", "my_barcode", "svg")
+\end{Verbatim}
+
+
+\subsubsection{A Lua\TeX{} source file}
+
+\brcd{} can also runs with Lua\TeX{} and any others Lua powered \TeX{}
+engines. The source file is a bit difference respect to the previous script: the
+Lua code lives inside the argument of a \verb=\directlua= primitive, moreover we
+must use an horizontal box register as the output destination.
+\begin{tcolorbox}[
+    title={\code{first-run.tex}: Lua\TeX{} version}
+]
+\begin{BVerbatim}
+% !TeX program = LuaTeX
+\newbox\mybox
+\directlua{
+    local require "barracuda"
+    barracuda:hbox("ean-13", "8006194056290", "mybox")
+}\leavevmode\box\mybox
+\bye
+\end{BVerbatim}
+\end{tcolorbox}
+The method \code{hbox()} works only with Lua\TeX{}. It takes three\footnote{A
+fourth argment is optional as a table with user defined barcode parameters.}
+arguments: encoder \emph{treename}, encoding data as a string, the \TeX{}
+horizontal box name.
+
+
+\subsubsection{A Lua\LaTeX{} source file}
+
+A \LaTeX{} working minimal example would be:
+\begin{tcolorbox}[
+    sidebyside,
+    title={\code{first-run.tex}: Lua\LaTeX{} version},
+    righthand width=120pt
+]
+\begin{BVerbatim}
+% !TeX program = LuaLaTeX
+\documentclass{article}
+\usepackage{barracuda}
+\begin{document}
+\barracuda{ean-13}{8006194056290}
+\end{document}
+\end{BVerbatim}
+\tcblower\ttfamily
+\hfill\barracuda{ean-13}{8006194056290}\hfill\hbox{}
+\end{tcolorbox}
+
+
+\subsection{A more deep look}
+
+\brcd{} is designed to be modular and flexible. For example it is possible to
+draw different barcodes on the same canvas or tuning barcode parameters. 
+
+The low level workflow to draw a barcode object reveals more details on the
+internal architecture. In fact, we must do at least the following steps divided
+into three phases:
+\begin{description}
+\item[a.1] load the library,
+\item[a.2] get a reference to the \code{Barcode} abstract class,
+\item[a.3] build an encoder,
+\item[a.4] build a symbol passing data to an encoder's constructor,
+\item[b.1] get a reference to a new canvas object,
+\item[b.2] draw barcode on the canvas object,
+\item[c.1] load the driver,
+\item[c.2] print the figure as an external \code{svg} file.
+\end{description}
+
+In the phase \textbf{a} a barcode symbols is created, then in phase \textbf{b} a
+canvas object is filled with the graphic elements of the symbol, and finally in
+the phase \textbf{c} the canvas is sent to the driver output channel.
+
+Following the procedure step by step, the resulting code is as the following
+listing, where the encoder is EAN variant 13:
+\begin{tcolorbox}
+\begin{BVerbatim}
+-- a lua script
+local barracuda = require "barracuda" -- step a.1
+local barcode = barracuda:barcode()   -- step a.2
+local ean13, err_enc = barcode:new_encoder("ean-13")      -- step a.3
+assert(ean13, err_enc)
+local symb, err_symb = ean13:from_string("8006194056290") -- step a.4
+assert(symb, err_symb)
+
+local canvas = barracuda:new_canvas() -- step b.1
+symb:draw(canvas) -- step b.2
+
+local drv = barracuda:get_driver() -- step c.1
+local ok, err_out = drv:save("svg", canvas, "my_barcode") -- step c.2
+assert(ok, err_out)
+\end{BVerbatim}
+\end{tcolorbox}
+
+Anyway, more abstract methods allow the user to write a more compact code. For
+instance, phase \textbf{b} can be fuse with \textbf{c}, thanks to a
+a reference to the driver object included in the \code{canvas} object:
+\begin{Verbatim}
+-- phase b + c
+local canvas = barracuda:new_canvas() -- step bc.1
+symb:draw(canvas) -- step bc.2
+local ok, err_out = canvas:save("svg", "my_barcode") -- step bc.3
+assert(ok, err_out)
+\end{Verbatim}
+
+As we have been seen before an high level method provides a way to unify all the
+phases:
+\begin{Verbatim}
+-- unique phase version
+local require "barracuda"
+barracuda:save("ean-13", "8006194056290", "my_barcode", "svg")
+\end{Verbatim}
+
+Low level code offers more control while high level programming is quite
+compact. Late in the manual you will find the objects and methods reference at
+section~\ref{secAPI}.
+
+
+\subsection{Installing \brcd}
+\label{secInstall}
+
+\subsubsection{Installing for Lua}
+
+Manually copy \code{src} folder content to a suitable directory of your system
+that is reachable to the system Lua interpreter.
+
+
+\subsubsection{Installing for TeX Live}
+
+If you have TeX Live installed from CTAN or from DVD TeX Collection, before any
+modification to your system check if the package is already installed looking
+for \emph{installed} key in the output of the command:
+\begin{Verbatim}
+$ tlmgr show barracuda
+\end{Verbatim}
+
+If \brcd{} is reported as not installed, run the command:
+\begin{Verbatim}
+$ tlmgr install barracuda
+\end{Verbatim}
+
+If you have installed TeX Live via your Linux repository, try your
+distribution's package manager an update or check for optional packages not yet
+installed.
+
+It's also possible to install \brcd{} manually with these steps:
+\begin{enumerate}
+\item Grab the sources from CTAN or from the official repository
+\url{https://github.com/robitex/barracuda}.
+\item Unzip it at the root of one of your TDS trees (local or personal).
+\item You may need to update some filename database after this, see your \TeX{}
+distribution's manual for details.
+\end{enumerate}
+
+
+\section{Barracuda \LaTeX{} Package}
+\label{secLaTeXPkg}
+
+The \LaTeX{} package delivered with \brcd{} is still under an early stage of
+development. The only macro available is
+\verb=\barracuda[option]{encoder}{data}=. A simple example is the following
+source file for Lua\LaTeX{}:
+\begin{tcolorbox}[sidebyside]
+\begin{BVerbatim}
+% !TeX program = LuaLaTeX
+\documentclass{article}
+\usepackage{barracuda}
+\begin{document}
+\leavevmode
+\barracuda{code128}{123ABC}\\[2ex]
+\barracuda[text_star=true]{code39}{123ABC}
+\end{document}
+\end{BVerbatim}
+\tcblower
+\leavevmode
+\barracuda{code128}{123ABC}\\[2ex]
+\barracuda[text_star=true]{code39}{123ABC}
+\end{tcolorbox}
+
+Every macro \brcd{} typesets a barcode symbol with the encoder defined in the
+first argument, encoding data defined by the second.
+
+
+\section{Barcode Reference}
+\label{secBcRef}
+
+\begin{figure}
+\centering
+\begin{tikzpicture}
+\ttfamily
+\draw (-20mm, -20mm) rectangle (20mm, 20mm);
+\end{tikzpicture}
+\caption{Barcode class hierarchy.}
+\label{figBarcodeHierarchy}
+\end{figure}
+
+\subsection{Common, Global and Local Barcode Options}
+
+Every barcode encoder inherits from \code{Barcode} abstract class methods and
+options. If we change its option values, the changes will be global for all the
+encoders except if the encoder has not an own local option overwritten before.
+
+The same schema applying also for encoder and the barcode symbols build apart
+from it. Every symbol inherits methods and options from its encoder.
+
+Such three levels option system is designed to allow the user to set up option
+not only in a certain point in the tree object, but also any time in the code.
+When changes are accepted by an object they become valid for that time on.
+
+The architecture of barcode classes is shown in more details in
+figure~\ref{figBarcodeHierarchy}. At the top of the hierarchy there is the
+\code{Barcode} class. It's an abstract class in the sense that no symbols can be
+printed by that class.
+
+At an intermediate level we found a \code{Builder} with an instance of one of
+its \code{Encoder} class. When we call method \code{new\_encoder()} provided by
+\code{Barcode} class, what really happen is the loading of the \code{Builder} if
+not just loaded before, that is the actual library of the specific simbology,
+and a linked \code{Encoder} object incorporates its own options.
+
+At the last level are placed the symbol instances derived both from the
+\code{Builder} and \code{Encoder}, the first provides methods while the second
+provides option values. Only these objects are printable in a barcode graphic.
+
+Common options of \code{Barcode} are the following:
+\begin{center}
+\begin{tabular}{@{}ccp{75mm}@{}}
+\toprule
+Option Id & Type/default    & Description\\
+\midrule
+\code{ax} & numeric/0 & Relative x-coordinate for insertion point of the barcode symbol\\
+\midrule
+\code{ay} & numeric/0 & Relative y-coordinate for insertion point of the barcode symbol\\
+\midrule
+\code{debug\_bbox} & enum/\code{none} & Draw symbol bounding box with a thin dashed line\\
+ & \code{none}   & \small do nothing\\
+ & \code{symb}   & \small draw the bbox of the symbol\\
+ & \code{qz}     & \small draw the bbox at quietzone border\\
+ & \code{qzsymb} & \small draw symbol and quietzone bboxes\\
+\bottomrule
+\end{tabular}
+\end{center}
+
+
+For each barcode symbologies the next section reports parameters and optional
+methods of it.
+
+\subsection{Code39}
+\label{secCode39}
+
+\code{Code39} is one of the oldest symbologies ever invented. It doesn't include
+any checksum digit and the only encodable characters are digits, uppercase
+letters and a few symbol like \code{+} or \code{\$}.
+
+
+
+
+
+\subsection{Code128}
+\label{secCode128}
+
+
+
+% devzone color setup
+\tcbset{
+    colback=blue!10!white,
+    colbacktitle=blue!10!white,
+}
+
+\section{Developer zone}
+
+\subsection{The Barracuda Framework}
+\label{secFramework}
+
+The \brcd{} package framework consists in independent modules: a barcode class
+hierarchy encoding a text into a barcode symbology; a geometrical library called
+\code{libgeo} modeling several graphic objects; an encoding library for the
+\code{ga} format (graphic assembler) and several driver to \emph{print} a
+\code{ga} stream into a file or in a \TeX{} \code{hbox} register.
+
+To implement a barcode encoder you have to write a component called
+\emph{encoder} defining every parameters and implementing the encoder builder,
+while a driver must understand ga opcode stream and print the corresponding
+graphic object.
+
+Every barcode encoder come with a set of parameters, some of them can be
+reserved and can't be edit after the encoder was build. So, you can create many
+instances of the same encoder for a single barcode type, with its own parameter
+set.
+
+The basic idea is getting faster encoders, for which the user may set up
+parameters at any level: barcode abstract class, encoder globally, down to a
+single symbol object.
+
+The Barcode class is completely independent from the output driver and vice
+versa.
+
+
+\subsection{Error Management}
+
+Functions in Lua may return more than one parameters. \brcd{} methods takes
+advantage by this feature for the error management. In fact, \brcd{} as a
+library, remind the responsibility to the caller in order to choose what to do
+in case an error is reported.
+
+When a method may fail depending on the correctness of the input, it returns two
+parameters alternatively valid: the first is the expected result while the
+second is the error description.
+
+This behavior perfectly match the arguments required by the \code{assert()}
+built-in function.
+
+
+
+
+\subsection{Encoder Treename}
+\label{secEncName}
+
+In \brcd{} in order to draw a barcode symbol it's necessary to create an
+\code{Encoder} object
+
+
+\subsection{API reference of Lua modules}
+\label{secAPI}
+
+TODO
+
+\subsection{\code{ga} specification}
+\label{secGA}
+
+This section defines and explains with code examples the \code{ga} instruction
+stream. \code{ga} stands for \emph{graphic assembler}, a sort of essential
+language that describes geometrical object like lines and rectangles mainly for
+a barcode drawing library on a cartesian plane \( (O, x, y) \).
+
+The major goal of any \brcd{} encoder is to create the \code{ga} stream
+corresponding to a vector drawing of a barcode symbol.
+
+In details, a \code{ga} stream is a numeric sequence that like a program defines
+what must be draw. It is not a fully binary sequence---which is a byte stream
+and ideally is what a \code{ga} stream would really be---but a sequence of
+integers or floating point numbers.
+
+In Lua this is very easy to implement. Simply append a numeric value to a table
+that behave as an array. Anyway \code{ga} must be basically a binary format
+almost ready to be sent or received by means of a network channel.
+
+In the Backus–Naur form a valid \code{ga} stream grammar is described by the
+following code:
+\begin{Verbatim}
+<valid ga stream> ::= <instructions>
+<instructions> ::= <instruction>
+                 | <instruction> <instructions>
+<instruction> ::= <opcode>
+                | <opcode> <operands>
+
+<opcode> ::= <state>
+           | <object>
+           | <func>
+<state> ::= 1 .. 31; graphic properties
+<object> ::= 32 .. 239; graphic objects
+<func> ::= 240 .. 255; functions
+
+<operands> ::= <operand>
+             | <operand> <operands>
+<operand> ::= <len>
+            | <coord>
+            | <qty>
+            | <char seq>
+            | <enum>
+            | <abs>
+            | <points>
+            | <bars>
+
+<len> ::= f64; unit measure scaled point sp = 1/65536pt
+<coord> ::= f64; unit measure scaled point sp = 1/65536pt
+<qty> ::= u64
+<char seq> ::= <chars> 0
+<chars> ::= <char>
+          | <char> <chars>
+<char> ::= u64
+<enum> ::= u8
+<abs> ::= f64
+<points> ::= <point>
+           | <point> <points>
+<point> ::= <x coord> <y coord>
+<x coord> ::= <coord> 
+<y coord> ::= <coord>
+<bars> ::= <bar>
+         | <bar> <bars>
+<bar> := <coord> <len>
+
+; u8 unsigned 8 bit integer
+; u64 unsigned 64 bit integer
+; f64 floating point 64 bit number
+\end{Verbatim}
+
+
+Every \code{<instruction>} changes the graphic state---for instance the current
+line width---or defines a graphic object, depending on the \code{opcode} value.
+Coordinates or dimensions must be expressed as \emph{scaled point}, the
+basic unit of measure of \TeX{} equivalent to \( 1/65536\, \)pt.
+
+
+\subsubsection{Hard coded an horizontal line}
+
+The \code{opcode} for the \code{linewidth} operation is 1, while
+for the \code{hline} operation is 33. An horizontal line 6pt width from the
+point (0pt, 0pt) to the point (32pt, 0pt) is represented by this \code{ga}
+stream:
+\begin{Verbatim}
+1 393216 33 0 2097152 0
+\end{Verbatim}
+
+Introducing \code{mnemonic opcode} in \code{opcode} places and separate the
+operations in a multiline fashion, the same sequence become more readable and
+more similar to an assembler listing:
+\begin{Verbatim}
+linewidth 393216   ; set line width to 393216sp
+hline 0 2097152 0  ; draw hline x1 x2 y
+\end{Verbatim}
+
+To prove and visualize the meaning of the stream, we can simply use the native
+graphic driver of \brcd{} compiling this Lua\TeX{} source file:
+\begin{Verbatim}
+% !TeX program = LuaTeX
+\newbox\mybox
+\directlua{
+    local barracuda = require "barracuda"
+    local ga = {1, 393216, 33, 0, 2097152, 0}
+    local drv = barracuda:get_driver()
+    drv:ga_to_hbox(ga, "mybox")
+}\leavevmode\box\mybox
+\bye
+\end{Verbatim}
+
+The result is:\directlua{
+local ga = {1, 393216, 33, 0, 2097152, 0}
+local drv = barracuda:get_driver()
+drv:ga_to_hbox(ga, "mybox")
+}\box\mybox
+
+
+\subsubsection{Encoding \code{ga} with the \code{gaCanvas} class}
+
+A more abstract way to write a \code{ga} stream is provided by the
+\code{gaCanvas} class of the \code{libgeo} module. Every operation with
+identifier \code{opcode} is mapped to a method named \code{encode\_<opcode>()}
+of a canvas object:
+\begin{Verbatim}
+% !TeX program = LuaTeX
+\newbox\mybox
+\directlua{
+    local barracuda = require "barracuda"
+    local canvas = barracuda:new_canvas()
+    local pt = canvas.pt
+    canvas:encode_linewidth(6*pt)
+    canvas:encode_hline(0, 32*pt, 0)
+    local drv = barracuda:get_driver()
+    drv:ga_to_hbox(canvas, "mybox")
+    tex.print("[")
+    for _, n in ipairs(canvas:get_stream()) do
+        tex.print(tostring(n))
+    end
+    tex.print("]")
+} results in \box\mybox
+\bye
+\end{Verbatim}
+
+The stream is printed beside the drawing in the output PDF file. Therefore the
+same \code{ga} stream can also generate a different output, for instance a SVG
+file. For this purpose execute the \code{save()} method of the \code{Driver}
+class (the drawing is showed side-by-side the listing):
+\begin{tcolorbox}[sidebyside]
+\begin{BVerbatim}
+% !TeX program = LuaTeX
+\newbox\mybox
+\directlua{
+    local barracuda = require "barracuda"
+    local canvas = barracuda:new_canvas()
+    local pt = canvas.pt
+    local side = 16*pt
+    local s = side/2 - 1.5*pt
+    local l = side/2 - 2*pt
+    local dim = 4
+    canvas:encode_linewidth(1*pt)
+    canvas:encode_disable_bbox()
+    for c = 0, dim do
+        for r = 0, dim do
+            local x, y = c*side, r*side
+            canvas:encode_hline(x-l, x+l, y-s)
+            canvas:encode_hline(x-l, x+l, y+s)
+            canvas:encode_vline(y-l, y+l, x-s)
+            canvas:encode_vline(y-l, y+l, x+s)
+        end
+    end
+    local b1 = -s - 0.5*pt
+    local b2 = dim*side + s + 0.5*pt
+    canvas:encode_set_bbox(b1, b1, b2, b2)
+    canvas:ga_to_hbox("mybox")
+    canvas:save("svg", "grid")
+}\leavevmode\box\mybox
+\bye
+\end{BVerbatim}
+\tcblower
+\directlua{
+    local canvas = barracuda:new_canvas()
+    local pt = canvas.pt
+    local side = 16*pt
+    local s = side/2 - 1.5*pt
+    local l = side/2 - 2*pt
+    local dim = 4 
+    canvas:encode_linewidth(1*pt)
+    canvas:encode_disable_bbox()
+    for c = 0, dim do
+        for r = 0, dim do
+            local x, y = c*side, r*side
+            canvas:encode_hline(x-l, x+l, y-s)
+            canvas:encode_hline(x-l, x+l, y+s)
+            canvas:encode_vline(y-l, y+l, x-s)
+            canvas:encode_vline(y-l, y+l, x+s)
+        end
+    end
+    local b1 = -s - 0.5*pt
+    local b2 = dim*side + s + 0.5*pt
+    canvas:encode_set_bbox(b1, b1, b2, b2)
+    canvas:ga_to_hbox("mybox")
+}\hfill\box\mybox\hfill{}
+\end{tcolorbox}
+
+An automatic process updates the bounding box of the figure meanwhile the stream
+is read instruction after instruction. The \code{disable\_bbox} operation
+produces a more fast execution and the figure maintains the bounding box
+computed until that point. The \code{set\_bbox} operation imposes a bounding box
+in comparison to the current one of the figure.
+
+The initial bounding box is simply empty. As a consequence, different
+strategies can be used to optimize runtime execution, such as in the previous
+code example, where bounding box is always disabled and it is set up at the last
+\code{canvas} method call. More often than not, we know the bounding box of the
+barcode symbol including quiet zones.
+
+Every encoding method of \code{gaCanvas} class gives two output result: a
+boolean value called \code{ok} plus an error \code{err}. If \code{ok} is
+\code{true} then \code{err} is \code{nil} and, viceversa, when \code{ok} is
+\code{false} then \code{err} is a string describing the error.
+
+The error management is a responsability of the caller. For instance, if we
+decide to stop the execution this format is perfectly suitable for the Lua
+function \code{assert()}, otherwise we can explicity check the output pair:
+\begin{Verbatim}
+local pt = 65536
+assert(canvas:encode_linewidth(6*pt)) --> true, nil
+local ok, err = canvas:encode_hline(nil, 32*pt, 0)
+-- ok = false
+-- err = "[ArgErr] 'x1' number expected"
+\end{Verbatim}
+
+
+\subsubsection{\code{ga} reference}
+\label{secGAtabref}
+
+\noindent
+\begin{tabular}{CLlL}
+\toprule
+\multicolumn{4}{l}{\textbf{Properties of the graphic state}}\\
+OpCode & Mnemonic key & Graphic property & Operands\\
+\midrule
+ 1 & linewidth & Line width      & w <len>\\
+ 2 & linecap   & Line cap style  & e <enum>\\
+   &&& 0: Butt cap\\
+   &&& 1: Round cap\\
+   &&& 2: Projecting square cap\\
+ 3 & linejoin  & Line join style & e <enum>\\
+   &&& 0: Miter join\\
+   &&& 1: Round join\\
+   &&& 2: Bevel join\\
+ 5 & dash\_pattern & Dash pattern line style & p <len> n <qty> [bi <len>]+\\
+   &&& p: phase lenght\\
+   &&& n: number of array element\\
+   &&& bi: dash array lenght\\
+ 6 & reset\_pattern & Set the solid line style & -\\
+\midrule
+29 & enable\_bbox & Compute bounding box & -\\
+30 & disable\_bbox & Do not compute bounding box & -\\
+31 & set\_bbox & Overlap current bounding box & x1 y1 <point> x2 y2 <point>\\
+\bottomrule
+\end{tabular}
+
+\bigskip
+\noindent
+\begin{tabular}{CLlL}
+\toprule
+\multicolumn{4}{l}{\textbf{Lines}}\\
+OpCode & Mnemonic key & Graphic object & Operands\\
+\midrule
+32 & line  & Line            & x1 y1 <point> x2 y2 <point>\\
+33 & hline & Horizontal line & x1 x2 <point> y <coord>\\
+34 & vline & Vertical line   & y1 y2 <point> x <coord>\\
+\bottomrule
+\end{tabular}
+
+\bigskip
+\noindent
+\begin{tabular}{CLlL}
+\toprule
+\multicolumn{4}{l}{\textbf{Group of bars}}\\
+OpCode & Mnemonic key & Graphic object & Operands\\
+\midrule
+36 & vbar & Vertical bars & y1 <coord> y2 <coord> b <qty> [xi wi <bars>]+\\
+   & & & y1: bottom y-coord\\
+   & & & y2: top y-coord\\
+   & & & b: number of bars\\
+   & & & xi: axis x-coord of bars number i\\
+   & & & wi: width of bars number i\\
+37 & hbar & Horizontal bars & x1 <coord> x2 <coord> b <qty> [yi wi <bars>]+\\
+   & & & unimplemented\\
+\midrule
+38 & polyline & Opened polyline & n <qty> [xi yi <points>]+\\
+   & & & n: number of points\\
+   & & & xi: x-coord of point i\\
+   & & & yi: y-coord of point i\\
+39 & c\_polyline & Closed polyline & n <qty> [xi yi <points>]\\
+   & & & unimplemented\\
+\bottomrule
+\end{tabular}
+
+\bigskip
+\noindent
+\begin{tabular}{CLlL}
+\toprule
+\multicolumn{4}{l}{\textbf{Rectangles}}\\
+OpCode & Mnemonic key & Graphic object & Operands\\
+\midrule
+48 & rect & Rectangle & x1 y1 <point> x2 y2 <point>\\
+49 & f\_rect & Filled rectangle & x1 y1 <point> x2 y2 <point>\\
+ &&& unimplemented\\
+50 & rect\_size & Rectangle & x1 y1 <point> w <len> h <len>\\
+ &&& unimplemented\\
+51 & f\_rect\_size & Filled rectangle & x1 y1 <point> w <len> h <len>\\
+ &&& unimplemented\\
+\bottomrule
+\end{tabular}
+
+\bigskip
+\noindent
+\begin{tabular}{CLl}
+\toprule
+\multicolumn{3}{l}{\textbf{Text}}\\
+OpCode & Mnemonic key & Graphic object/Operands\\
+\midrule
+130 & text & A text with several glyphs\\
+    & & \ttfamily ax <abs> ay <abs> xpos ypos <point> [c <chars>]+\\
+\midrule
+131 & text\_xspaced & A text with glyphs equally spaced on its vertical axis\\
+    & & \ttfamily x1 <coord> xgap <len> ay <abs> ypos <coord> [c <chars>]+\\
+\midrule
+132 & text\_xwidth & Glyphs equally spaced on vertical axis between two x coordinates\\
+    & & \ttfamily ay <abs> x1 <coord> x2 <coord> y <coord> c <chars>\\
+\midrule
+140 & \_text\_group & Texts on the same baseline\\
+& & \ttfamily ay <abs> y <coord> n <qty> [xi <coord> ai <abs> ci <chars>]+\\
+& & unimplemented\\
+\bottomrule
+\end{tabular}
+
+
+\subsection{\code{Vbar} class}
+
+This section show you how to draw a group of vertical lines, the main component
+of every 1D barcode symbol. In the \brcd{} jargon a group of vertical lines is
+called \code{Vbar} and is defined by a flat array of pair numbers sequence: the
+first one is the x-coordinate of the bar while the second is its width.
+
+For instance, consider a \code{Vbar} of three bars for which width is a
+multiple of the fixed length called \code{mod}, defined by the array and figure
+showed below:
+\begin{Verbatim}
+-- {     x1,    w1,      x2,    w2,     x3,     w3}
+   {1.5*mod, 3*mod, 5.5*mod, 1*mod, 7.5*mod, 1*mod}
+\end{Verbatim}
+\directlua{
+local libgeo = barracuda:libgeo()
+local Vbar = libgeo.Vbar
+local drv = barracuda:get_driver()
+local mm = drv.mm
+local b = Vbar:from_int(32111, 2*mm)
+local canvas = barracuda:new_canvas()
+canvas:encode_vbar(b, 0, 0, 25*mm)
+drv:ga_to_hbox(canvas, "mybox")
+}
+\begin{center}
+\begin{tikzpicture}
+\foreach \i in {0,2,...,16}
+\draw[help lines] (\i mm, -2mm) -- (\i mm, 28mm);
+\node at (8mm, 12.5mm) {\box\mybox};
+\draw[-{Latex[open]}] (0, 0) -- (20mm, 0);
+\draw[-{Latex[open]}] (0, 0) -- (0, 30mm);
+\draw[white, dashed] (3mm, 0) -- (3mm, 25mm);
+\draw[white, dashed] (11mm, 0) -- (11mm, 25mm);
+\draw[white, dashed] (15mm, 0) -- (15mm, 25mm);
+\end{tikzpicture}
+\end{center}
+
+For clearness, to the drawing were added a gray vertical grid stepping one
+module and white dashed lines at every vbar axis.
+
+Spaces between bars can be seen as white bars. In fact, an integer number can
+represents the sequence of black and white bars with the rule that the single
+digit is the width module multiplier. So, the previous \code{Vbar} can be
+defined by 32111 with module equals to 2 mm.
+
+The class \code{Vbar} of module \code{libgeo} has several constructors one of
+which is \code{from\_int()}. Its arguments are the multiplier integer
+\code{ngen}, the module length \code{mod} and the optional boolean flag
+\code{is\_bar}, true if the first bar is black (default to true):
+\begin{Verbatim}
+b = Vbar:from_int(32111, 2*mm)
+\end{Verbatim}
+
+A \code{Vbar} object has a local axis \( x \) and is unbounded. Constructors
+place the axis origin at the left of the first bar. Bars are infinite vertical
+straight lines. In order to draw a \code{Vbar} addition information must be
+passed to \code{encode\_vbar()} method of the \code{gaCanvas} class: the global
+position of the local origin \( x_0 \), and the bottom and top limit \( y_1 \)
+\( y_2 \):
+\begin{Verbatim}
+canvas:encode_vbar(ovbar, x0, y1, y2)
+\end{Verbatim}
+
+The following listing is the complete source code to draw the \code{Vbar} taken
+as example in this section:
+\begin{Verbatim}
+% !TeX program = LuaTeX
+\newbox\mybox
+\directlua{
+    local barracuda = require "barracuda"
+    local Vbar = barracuda:libgeo().Vbar
+    local drv = barracuda:get_driver()
+    local mm = drv.mm
+    local b = Vbar:from_int(32111, 2*mm)
+    local canvas = barracuda:new_canvas()
+    canvas:encode_vbar(b, 0, 0, 25*mm)
+    drv:ga_to_hbox(canvas, "mybox")
+}\leavevmode\box\mybox
+\bye
+\end{Verbatim}
+
+
+\subsubsection{\code{Vbar} class arithmetic}
+
+Can two \code{Vbar} objects be added? Yes, they can! And also with numbers.
+Thanks to metamethod and metatable feature of Lua, \code{libgeo} module can
+provide arithmetic for \code{Vbar}s. More in detail, to add two \code{Vbar}s
+deploy them side by side while to add a number put a distance between the
+previous or the next object, depending on the order of addends.
+
+Anyway, every sum creates or modifies a \code{VbarQueue} object that can be
+encoded in a \code{ga} stream with the method \code{encode\_vbar\_queue()}. The
+method arguments' are the same needed to encode a \code{Vbar}: an axis position
+\( x_0 \) and the two y-coordinates bound \( y_1 \) and \( y_2 \).
+
+A \code{VbarQueue} code example is the following:
+\begin{tcolorbox}
+\begin{BVerbatim}
+% !TeX program = LuaTeX
+\newbox\mybox
+\directlua{
+    local barracuda = require "barracuda"
+    local Vbar = barracuda:libgeo().Vbar
+    local canvas = barracuda:new_canvas()
+    local mm = canvas.mm
+    local mod = 2 * mm
+    local queue = Vbar:from_int(32111, mod)
+    for _, ngen in ipairs {131, 21312, 11412} do
+        queue = queue + mod + Vbar:from_int(ngen, mod)
+    end
+    canvas:encode_vbar_queue(queue, 0, 0, 25*mm)
+    canvas:ga_to_hbox "mybox"
+}\leavevmode\box\mybox
+\bye
+\end{BVerbatim}
+\tcblower
+\directlua{
+    local Vbar = barracuda:libgeo().Vbar
+    local canvas = barracuda:new_canvas()
+    local mm = canvas.mm
+    local mod = 2 * mm
+    local queue = Vbar:from_int(32111, mod)
+    for _, ngen in ipairs {131, 21312, 11412} do
+        queue = queue + mod + Vbar:from_int(ngen, mod)
+    end
+    canvas:encode_vbar_queue(queue, 0, 0, 25*mm)
+    canvas:ga_to_hbox "mybox"
+}
+\hfill
+\begin{tikzpicture}
+\fill[orange!50!white] (16mm, -3mm) rectangle (18mm, 28mm); %
+\fill[orange!50!white] (28mm, -3mm) rectangle (30mm, 28mm); %
+\fill[orange!50!white] (48mm, -3mm) rectangle (50mm, 28mm); %
+\foreach \i in {0,2,...,68}
+\draw[help lines] (\i mm, -3mm) -- (\i mm, 28mm);
+\node at (34mm, 12.5mm) {\box\mybox};
+\end{tikzpicture}
+\hfill\hbox{}
+
+\footnote{Respect to the showed code some graphical helps has been added: a
+vertical grid marks the module wide steps and light colored bars mark the
+space added between two \code{Vbar}s.}
+\end{tcolorbox}
+
+\subsection{\code{ga} programming}
+
+To provide a better learning experience several \code{ga} stream examples is
+discussed, each of which must be compiled with Lua\TeX{}.
+
+\subsubsection{Example 1: a rectangle}
+
+Suppose we want to draw a simple rectangle. In the \code{ga} reference of
+section~\ref{secGAtabref} there is a dedicated instruction \code{<rect>}.
+Let's give it a try:
+
+\begin{tcolorbox}[
+    title={Example 1: dealing with raw \code{ga} stream},
+    sidebyside,
+]
+\begin{BVerbatim}
+% !TeX program = LuaTeX
+\newbox\mybox
+\directlua{
+    local barracuda = require "barracuda"
+    local pt = 65536
+    local ga = {48, 0, 0, 72*pt, 36*pt}
+    local drv = barracuda:get_driver()
+    drv:ga_to_hbox(ga, "mybox")
+}\leavevmode\box\mybox
+\bye
+\end{BVerbatim}
+\tcblower
+\directlua{
+    local pt = 65536
+    local side = 36*pt
+    local ga = {48, 0, 0, 2*side, side}
+    local drv = barracuda:get_driver()
+    drv:ga_to_hbox(ga, "mybox")
+}\box\mybox
+\end{tcolorbox}
+
+Dealing with low level \code{ga} stream is not necessary. We can use more safely
+a \code{gaCanvas} object running its \code{encode\_rect()} method:
+\begin{Verbatim}
+...
+local canvas = barracuda:new_canvas()
+assert(canvas:encode_rect(0, 0, 2*side, side))
+assert(canvas:ga_to_hbox("mybox"))
+...
+\end{Verbatim}
+
+
+\subsubsection{Example 2: a chessboard}
+
+A more complex drawing is a chessboard. Let's begin to draw a single cell with a
+square 1cm wide:
+\begin{Verbatim}
+% !TeX program = LuaTeX
+\newbox\mybox
+\directlua{
+    local barracuda = require "barracuda"
+    local canvas = barracuda:new_canvas()
+    local mm = canvas.mm
+    local s, t = 7.5*mm, 1.5*mm
+    canvas:encode_linewidth(t)
+    assert(canvas:encode_rect(t/2, t/2, s-t/2, s-t/2))
+    assert(canvas:ga_to_hbox("mybox"))
+}\leavevmode\box\mybox
+\bye
+\end{Verbatim}
+
+Then repeat the game for the entire grid:
+\begin{tcolorbox}
+\begin{BVerbatim}
+% !TeX program = LuaTeX
+\newbox\mybox
+\directlua{
+    local barracuda = require "barracuda"
+    local canvas = barracuda:new_canvas()
+    local mm = canvas.mm
+    local s, t = 6*mm, 1*mm
+    assert(canvas:encode_linewidth(t))
+    for row = 1, 5 do
+        for col = 1, 5 do
+            local l = (row + col)/2
+            if l == math.floor(l) then
+                local x = (col - 1)*s
+                local y = (row - 1)*s
+                local x1, y1 = x + t/2, y + t/2
+                local x2, y2 = x + s - t/2, y + s - t/2
+                assert(canvas:encode_rect(x1, y1, x2, y2))
+            end
+        end
+    end
+    drv:ga_to_hbox(canvas, "mybox")
+}\leavevmode\box\mybox
+\bye
+\end{BVerbatim}
+\vspace*{-10pt}
+\tcblower
+\directlua{
+    local barracuda = require "barracuda"
+    local canvas = barracuda:new_canvas()
+    local mm = canvas.mm
+    local s, t = 6*mm, 1*mm
+    assert(canvas:encode_linewidth(t))
+    for row = 1, 5 do
+        for col = 1, 5 do
+            local l = (row + col)/2
+            if l == math.floor(l) then
+                local x = (col - 1)*s
+                local y = (row - 1)*s
+                local x1, y1 = x + t/2, y + t/2
+                local x2, y2 = x + s - t/2, y + s - t/2
+                assert(canvas:encode_rect(x1, y1, x2, y2))
+            end
+        end
+    end
+    canvas:ga_to_hbox("mybox")
+}\hfill\box\mybox\hfill\hbox{}
+\end{tcolorbox}
+
+\subsubsection{Example 3: a staircase}
+
+A drawing of a zig zag staircase can be represented by a \code{ga} stream with
+a \code{<polyline>} operation. The \code{gaCanvas} method we have to call is
+\code{encode\_polyline()} that accept a Lua table as a flat structure with the
+coordinates of every point of the polyline:
+\begin{BVerbatim}
+{x1, y1, x2, y2, ..., xn, yn}
+\end{BVerbatim}
+
+It is what we do with this code:
+\begin{tcolorbox}
+\begin{BVerbatim}
+% !TeX program = LuaTeX
+\newbox\mybox
+\directlua{
+    local barracuda = require "barracuda"
+    local pt = 65536
+    local side = 16*pt
+    local dim = 5
+    local x, y = 0, 0
+    local point = {x, y}
+    local i = 3
+    for _ = 1, dim do
+        y = y + side
+        point[i] = x; i = i + 1
+        point[i] = y; i = i + 1
+        x = x + side
+        point[i] = x; i = i + 1
+        point[i] = y; i = i + 1
+    end
+    local canvas = barracuda:new_canvas()
+    canvas:encode_linewidth(2.25*pt)
+    canvas:encode_polyline(point)
+    canvas:ga_to_hbox("mybox")
+}\leavevmode\box\mybox
+\bye
+\end{BVerbatim}
+\vspace*{-10pt}
+\tcblower
+\directlua{
+    local pt = 65536
+    local side = 16*pt
+    local dim = 5
+    local x, y = 0, 0
+    local point = {x, y}
+    local i = 3
+    for _ = 1, dim do
+        y = y + side
+        point[i] = x; i = i + 1
+        point[i] = y; i = i + 1
+        x = x + side
+        point[i] = x; i = i + 1
+        point[i] = y; i = i + 1
+    end
+    local canvas = barracuda:new_canvas()
+    canvas:encode_linewidth(2.25*pt)
+    canvas:encode_polyline(point)
+    canvas:ga_to_hbox("mybox")
+}\hfill\box\mybox\hfill\hbox{}
+\end{tcolorbox}
+
+A feature of \code{encode\_<opcode>()} methods is their \emph{polymorphic}
+behavior for their first argument. They accept different types as an object
+of a geometric class or the raw geometric data.
+
+Method \code{encode\_polyline} is not an exception: it accepts a \code{Polyline}
+object provided by the \code{libgeo} module, or instead a flat array of
+coordinates.  For instance the previous code may be re-implement as:
+\begin{Verbatim}
+% !TeX program = LuaTeX
+\newbox\mybox
+\directlua{
+    local barracuda = require "barracuda"
+    local pt = 65536
+    local side = 18*pt
+    local dim = 5
+    local Polyline = barracuda:libgeo().Polyline
+    local pl = Polyline:new(0, 0)
+    for _ = 1, dim do
+        pl:add_relpoint(0, side)
+        pl:add_relpoint(side, 0)
+    end
+    local canvas = barracuda:new_canvas()
+    canvas:encode_linewidth(2.5*pt)
+    canvas:encode_polyline(pl)
+    canvas:ga_to_hbox("mybox")
+}\leavevmode\box\mybox
+\bye
+\end{Verbatim}
+
+Pretty sure that this new version is more clear and intuitive.
+
+
+%\subsubsection{Example 4: }
+
+% A polyline that represents a path of ... Hilbert curve
+% Text pyramid
+
+
+\section{Practical examples and use cases}
+\label{secExample}
+
+Previous sections as shown how \brcd{} is capable to draw simple graphics. This
+section is dedicated to barcode applications.
+
+
+
+\end{document}


Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/barracuda-manual.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/image/8006194056290.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/image/8006194056290.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/image/8006194056290.pdf	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/image/8006194056290.pdf	2022-06-23 20:54:26 UTC (rev 63701)

Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/doc/manual/image/8006194056290.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-barracuda-package/01-barracuda-latex-test.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-barracuda-package/01-barracuda-latex-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-barracuda-package/01-barracuda-latex-test.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-barracuda-package/01-barracuda-latex-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,7 +1,7 @@
 % !TeX program = LuaLaTeX
-% Copyright (C) 2020 Roberto Giacomelli
+% Copyright (C) 2019-2022 Roberto Giacomelli
 
-% test file: make a Code39 barcodes in a LaTeX document
+% test file: make Code39 barcodes in a LaTeX document
 
 \documentclass{article}
 \usepackage{barracuda}
@@ -10,6 +10,17 @@
 A\barracuda{code39}{123QWE}A
 
 B\barracuda[text_vpos='top']{code39}{123QWE}B
-\end{document}
 
+%\barracudasetup[option]{ treename }
 
+\directlua{
+local barracuda = require "barracuda"
+local barcode = barracuda:barcode()
+local code39 = assert(barcode:enc_by_name("code39"))
+assert(code39:set_param{debug_bbox = "qz"})
+}\bigskip
+
+A\barracuda{code39}{123QWE}A
+
+B\barracuda[text_vpos='top']{code39}{123QWE}B
+\end{document}

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-barracuda-package/02-ord_iter-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-barracuda-package/02-ord_iter-test.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-barracuda-package/02-ord_iter-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,5 +1,5 @@
 % !TeX program = LuaTeX
-% Copyright (C) 2020 Roberto Giacomelli
+% Copyright (C) 2019-2022 Roberto Giacomelli
 
 \directlua{
 local barracuda = require "barracuda"

Deleted: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/001-code128-test.lua
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/001-code128-test.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/001-code128-test.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,32 +0,0 @@
--- Copyright (C) 2020 Roberto Giacomelli
-
-local barracuda = require "barracuda"
-local barcode = barracuda:barcode()
-local c128, err = barcode:new_encoder("code128")
-assert(not err, err)
-
-print(c128._NAME)
-print(c128._VERSION)
-
-local info = c128:info()
-print("encoder name = ", info.name)
-print("description = ", info.description)
-for k, tp in ipairs(info.param) do
-    print(k, tp.name, tp.value)
-end
-
-local symb = c128:from_string("123")
-print("Symbol char list:")
-for _, c in ipairs(symb._code_data) do
-    print(c)
-end
-
-local canvas = barracuda:new_canvas()
-
-symb:append_ga(canvas)
-
--- driver library
-local drv = barracuda:get_driver()
-drv:save("svg", canvas, "c128-123")
-
-

Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/001-code128-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/001-code128-test.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/001-code128-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,39 @@
+% !TeX program = LuaTeX
+% Copyright (C) 2019-2022 Roberto Giacomelli
+
+\directlua{
+local barracuda = require "barracuda"
+local barcode = barracuda:barcode()
+local c128 = assert(barcode:new_encoder("code128"))
+print()
+print(c128._NAME)
+print(c128._VERSION)
+
+local info = c128:info()
+print("encoder name = ", info.name)
+print("description = ", info.description)
+for k, tp in ipairs(info.param) do
+    print(k, tp.name, tp.value)
+end
+
+local symb = c128:new("123")
+print("Symbol char list:")
+for _, c in ipairs(symb:get_code()) do
+    print(c)
+end
+print("Symbol hri char list:")
+for _, c in ipairs(symb:get_hri()) do
+    print(c)
+end
+
+
+local canvas = barracuda:new_canvas()
+
+symb:draw(canvas)
+
+% driver library
+local drv = barracuda:get_driver()
+drv:save("svg", canvas, "c128-123")
+}
+\bye
+


Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/001-code128-test.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/002-code128-test.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/002-code128-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/002-code128-test.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/002-code128-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,5 +1,5 @@
 % !TeX program = LuaTeX
-% Copyright (C) 2020 Roberto Giacomelli
+% Copyright (C) 2019-2022 Roberto Giacomelli
 
 \newbox\mybox
 \nopagenumbers
@@ -6,7 +6,7 @@
 
 Code 128 encoder test.
 
-Test 1: one simple barcode with default parameter:
+Test 1: one simple barcode with default parameters:
 
 \directlua{
 barracuda = require "barracuda"
@@ -14,7 +14,7 @@
 
 \directlua{
 local barcode = barracuda:barcode()
-
+barcode:set_param{debug_bbox="symb"}
 local c128, err = barcode:new_encoder("code128")
 assert(not err, err)
 
@@ -22,7 +22,7 @@
 assert(not err, err)
 
 local canvas = barracuda:new_canvas()
-symbo:append_ga(canvas)
+symbo:draw(canvas)
 
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
@@ -51,8 +51,8 @@
 assert(s2.ax == 0, "0 ax is "..tostring(s2.ax))
 
 local canvas = barracuda:new_canvas()
-s1:append_ga(canvas)
-s2:append_ga(canvas)
+s1:draw(canvas)
+s2:draw(canvas)
 
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
@@ -69,13 +69,13 @@
 
 local s, err = c128:from_string("123456"); assert(s, err)
 local canvas = barracuda:new_canvas()
-s:append_ga(canvas)
+s:draw(canvas)
 
 local ok, err = s:set_param("ydim", tex.sp "30mm")
-s:append_ga(canvas, tex.sp "20mm")
+s:draw(canvas, tex.sp "20mm")
 
 local ok, err = s:set_param("ydim", tex.sp "60mm")
-s:append_ga(canvas, tex.sp "40mm")
+s:draw(canvas, tex.sp "40mm")
 
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
@@ -93,14 +93,14 @@
 local s, err = c128:from_string("ABCDEFGHI"); assert(s, err)
 
 local canvas = barracuda:new_canvas()
-local _, err = s:append_ga(canvas); assert(not err, err)
+local _, err = s:draw(canvas); assert(not err, err)
 
 % set ay to 0.5 for the encoder
 local ok, err = c128:set_param("ay", 0.5); assert(ok, err)
-local _, err = s:append_ga(canvas, tex.sp "30mm"); assert(not err, err)
+local _, err = s:draw(canvas, tex.sp "30mm"); assert(not err, err)
 % set locally to the symbol ay to 1.0
 local ok, err = s:set_param("ay", 1)
-local _, err = s:append_ga(canvas, tex.sp "60mm"); assert(not err, err)
+local _, err = s:draw(canvas, tex.sp "60mm"); assert(not err, err)
 
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
@@ -114,14 +114,96 @@
 assert(c128, err)
 local s, e = c128:from_uint(1234567890); assert(s, e)
 local canvas = barracuda:new_canvas()
-local _, errc = s:append_ga(canvas); assert(not errc, errc)
+local _, errc = s:draw(canvas); assert(not errc, errc)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
 drv:save("native", canvas, "02-05-pdfliteral")
 }\box\mybox
 
+Test 6: encode ABC123:
+
+\directlua{
+local barcode = barracuda:barcode()
+local c128, err = barcode:enc_by_name "code128"; assert(c128, err)
+local s, err = c128:from_string("ABC123"); assert(s, err)
+
+local canvas = barracuda:new_canvas()
+local _, err = s:draw(canvas); assert(not err, err)
+
+local drv = barracuda:get_driver()
+drv:ga_to_hbox(canvas, "mybox")
+}\box\mybox
+
+Test 7: encode ABC123999:
+
+\directlua{
+local barcode = barracuda:barcode()
+local c128, err = barcode:enc_by_name "code128"; assert(c128, err)
+local s, err = c128:from_string("ABC123999"); assert(s, err)
+
+local canvas = barracuda:new_canvas()
+local _, err = s:draw(canvas); assert(not err, err)
+
+local drv = barracuda:get_driver()
+drv:ga_to_hbox(canvas, "mybox")
+}\box\mybox
+
+Test 8: encode ABC123456789:
+
+\directlua{
+local barcode = barracuda:barcode()
+local c128, err = barcode:enc_by_name "code128"; assert(c128, err)
+local s, err = c128:from_string("ABC123456789"); assert(s, err)
+
+local canvas = barracuda:new_canvas()
+local _, err = s:draw(canvas); assert(not err, err)
+
+local drv = barracuda:get_driver()
+drv:ga_to_hbox(canvas, "mybox")
+}\box\mybox
+
+Test 9: encode A1B2C3D999:
+
+\directlua{
+local barcode = barracuda:barcode()
+local c128, err = barcode:enc_by_name "code128"; assert(c128, err)
+local s, err = c128:from_string("A1B2C3D999"); assert(s, err)
+
+local canvas = barracuda:new_canvas()
+local _, err = s:draw(canvas); assert(not err, err)
+
+local drv = barracuda:get_driver()
+drv:ga_to_hbox(canvas, "mybox")
+}\box\mybox
+
+Test 10: encode 123abcedfg:
+
+\directlua{
+local barcode = barracuda:barcode()
+local c128, err = barcode:enc_by_name "code128"; assert(c128, err)
+local s, err = c128:from_string("123abcedfg"); assert(s, err)
+
+local canvas = barracuda:new_canvas()
+local _, err = s:draw(canvas); assert(not err, err)
+
+local drv = barracuda:get_driver()
+drv:ga_to_hbox(canvas, "mybox")
+}\box\mybox
+
+Test 11: encode 999Aaaa:
+
+\directlua{
+local barcode = barracuda:barcode()
+barcode:set_param{debug_bbox="none"}
+local c128, err = barcode:enc_by_name "code128"; assert(c128, err)
+local s, err = c128:from_string("999Aaaa"); assert(s, err)
+
+local canvas = barracuda:new_canvas()
+local _, err = s:draw(canvas); assert(not err, err)
+
+local drv = barracuda:get_driver()
+drv:ga_to_hbox(canvas, "mybox")
+}\box\mybox
+
 That's all folks!
-
 \bye
-
-function Driver:save(id_drv, ga, filename, ext) --> ok, err
\ No newline at end of file

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/02-05-pdfliteral.txt
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/02-05-pdfliteral.txt	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code128/02-05-pdfliteral.txt	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,4 +1,8 @@
 q
+1.000000 w
+0 J
+0 j
+[] 0 d
 -53.574521 -14.173154 1.190545 28.346308 re
 -51.788704 -14.173154 0.595272 28.346308 re
 -50.002887 -14.173154 1.785817 28.346308 re
@@ -40,4 +44,8 @@
 -1.190545 -14.173154 1.190545 28.346308 re
 f
 S
+0.100000 w
+[6.000000 3.000000] 3.000000 d
+-53.524521 -14.123154 53.474521 28.246308 re S
+[] 0 d
 Q
\ No newline at end of file

Deleted: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/001-code39-test.lua
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/001-code39-test.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/001-code39-test.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,41 +0,0 @@
--- Copyright (C) 2020 Roberto Giacomelli
--- test Code 39 encoder
-
-local barracuda = require "barracuda"
-
-for k, v in pairs(barracuda) do
-    print(k,v)
-end
-
-local barcode = barracuda:barcode()
-
-local c39, err = barcode:new_encoder("code39")
-assert(not err, err)
-
-print(c39._NAME)
-print(c39._VERSION)
-
-local info = c39:info()
-
-print("encoder name = ", info.name)
-print("description = ", info.description)
-
-for k, tp in ipairs(info.param) do
-    print(k, tp.name, tp.value)
-end
-
-local symb = c39:from_string("123")
-
-print("print internal representation of chars")
-for _, c in ipairs(symb._code_data) do
-    print(c)
-end
-print()
-
-local canvas = barracuda:new_canvas()
-symb:append_ga(canvas)
-
--- native driver
-local drv = barracuda:get_driver()
-
-for _, code in ipairs(canvas._data) do print(code) end

Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/001-code39-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/001-code39-test.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/001-code39-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,39 @@
+% !TeX program = LuaTeX
+% Copyright (C) 2019-2022 Roberto Giacomelli
+% test Code 39 encoder
+
+\directlua{
+local barracuda = require "barracuda"
+
+for k, v in pairs(barracuda) do
+    print(k, v)
+end
+
+local barcode = barracuda:barcode()
+
+local c39, err = barcode:new_encoder("code39")
+assert(not err, err)
+
+print(c39._NAME)
+print(c39._VERSION)
+
+local info = c39:info()
+
+print("encoder name = ", info.name)
+print("description = ", info.description)
+for k, tp in ipairs(info.param) do
+    print(k, tp.name, tp.value)
+end
+
+local symb = c39:from_string("123")
+
+print("print internal representation of chars")
+print(table.concat(symb:get_code(), " "))
+print("end")
+assert(symb:get_hri() == nil)
+
+local canvas = barracuda:new_canvas()
+symb:draw(canvas)
+% canvas:prettyprint_ga()
+}
+\bye


Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/001-code39-test.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/002-code39-test.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/002-code39-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/002-code39-test.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/002-code39-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,5 +1,5 @@
 % !TeX program = LuaTeX
-% Copyright (C) 2020 Roberto Giacomelli
+% Copyright (C) 2019-2022 Roberto Giacomelli
 
 \newbox\mybox
 \nopagenumbers
@@ -19,10 +19,10 @@
 assert(not err, err)
 
 local canvas = barracuda:new_canvas()
-symbol:append_ga(canvas)
+symbol:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}\box\mybox
+}\leavevmode\box\mybox
 
 Test 2: get the reference of the previous encoder and typeset two
 Code 39 symbols on the same canvas, one above to the other:
@@ -36,13 +36,13 @@
 local s2, err = c39:from_string("RTFG746", {text_vpos="top"}); assert(s2, err)
 
 local canvas = barracuda:new_canvas()
-s1:append_ga(canvas)
+s1:draw(canvas)
 
 local h2 = s2:get_param("height")
-s2:append_ga(canvas, 0.0, h2 + tex.sp "5pt")
+s2:draw(canvas, 0.0, h2 + tex.sp "5pt")
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}\box\mybox
+}\leavevmode\box\mybox
 
 Test 3: with the same encoder print a symbol, change globally the height,
 and reprint the same symbol again on the same canvas:
@@ -55,17 +55,17 @@
 local s1, err  = c39:from_string("ZKPQJ31"); assert(s1, err)
 
 local canvas = barracuda:new_canvas()
-s1:append_ga(canvas)
+s1:draw(canvas)
 
 local h = s1:get_param("height")
 c39:set_param("height", 2*h)
 c39:set_param {text_vpos = "top"}
 
-s1:append_ga(canvas, 0.0, h + tex.sp "5pt")
+s1:draw(canvas, 0.0, h + tex.sp "5pt")
 
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}\box\mybox
+}\leavevmode\box\mybox
 
 Test 4: do the same in test 3 but change locally parameters as
 height and text properties:
@@ -78,7 +78,7 @@
 local s1, err  = c39:from_string("0123456789"); assert(s1, err)
 
 local canvas = barracuda:new_canvas()
-s1:append_ga(canvas)
+s1:draw(canvas)
 local h, err = s1:get_param("height"); assert(h, err)
 local ok, err = s1:set_param{
     height = h/2,
@@ -88,27 +88,30 @@
     text_star = true,
     ay = 1,
 }; assert(ok, err)
-s1:append_ga(canvas, 0.0, - tex.sp "5pt")
+s1:draw(canvas, 0.0, - tex.sp "5pt")
 
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}\box\mybox
+}\leavevmode\box\mybox
 
-Test 5: create a new encoder with a large module value:
+Test 5: create a new encoder with a large module value.
 
+It's also activeted the debug\_bbox\_on option.
+
+\bigskip
 \directlua{
 local barcode = barracuda:barcode()
 
-local c39, err = barcode:new_encoder("code39:e2", {module = tex.sp "0.5mm"})
+local c39, err = barcode:new_encoder("code39:e2", {module = tex.sp "0.5mm", debug_bbox_on = true})
 assert(c39, err)
 
 local s1, err  = c39:from_string("02040608"); assert(s1, err)
 
 local canvas = barracuda:new_canvas()
-s1:append_ga(canvas)
+s1:draw(canvas)
 
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}\box\mybox
+}\leavevmode\box\mybox
 
 \bye

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/003-code39-test.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/003-code39-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/003-code39-test.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/003-code39-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,5 +1,5 @@
 % !TeX program = LuaTeX
-% Copyright (C) 2020 Roberto Giacomelli
+% Copyright (C) 2019-2022 Roberto Giacomelli
 
 \newbox\mybox
 \nopagenumbers
@@ -18,33 +18,35 @@
 assert(ok, err)
 
 local canvas = barracuda:new_canvas()
-symbol:append_ga(canvas)
+symbol:draw(canvas)
 
 local ok, err = symbol:set_param("text_hpos", "center")
 assert(ok, err)
-symbol:append_ga(canvas, tex.sp "4.5cm")
+symbol:draw(canvas, tex.sp "4.5cm")
 
 local ok, err = symbol:set_param("text_hpos", "right")
 assert(ok, err)
-symbol:append_ga(canvas, tex.sp "9.0cm")
+symbol:draw(canvas, tex.sp "9.0cm")
 
 local ok, err = c39:set_param("text_vpos", "bottom")
 assert(ok, err)
 
 local ok, err = symbol:set_param("text_hpos", "left")
-symbol:append_ga(canvas, 0, tex.sp "-2.0cm")
+symbol:draw(canvas, 0, tex.sp "-2.0cm")
 
 local ok, err = symbol:set_param("text_hpos", "center")
 assert(ok, err)
-symbol:append_ga(canvas, tex.sp "4.5cm", tex.sp "-2.0cm")
+symbol:draw(canvas, tex.sp "4.5cm", tex.sp "-2.0cm")
 
 local ok, err = symbol:set_param("text_hpos", "right")
 assert(ok, err)
-symbol:append_ga(canvas, tex.sp "9.0cm", tex.sp "-2.0cm")
+symbol:draw(canvas, tex.sp "9.0cm", tex.sp "-2.0cm")
 
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}\box\mybox
+}
+\bigskip
+\leavevmode\box\mybox
 \bye
 
 

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/004-code39-test.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/004-code39-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/004-code39-test.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/004-code39-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,5 +1,5 @@
 % !TeX program = LuaTeX
-% Copyright (C) 2020 Roberto Giacomelli
+% Copyright (C) 2019-2022 Roberto Giacomelli
 
 \newbox\mybox
 \nopagenumbers
@@ -17,11 +17,11 @@
 assert(not err, err)
 
 local canvas = barracuda:new_canvas()
-symbol:append_ga(canvas)
+symbol:draw(canvas)
 
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}\box\mybox
+}\bigskip\leavevmode\box\mybox
 
 \directlua{
 local c39, err = barracuda:barcode()
@@ -33,10 +33,9 @@
 assert(not e, e)
 
 local canvas = barracuda:new_canvas()
-symbol:append_ga(canvas)
+symbol:draw(canvas)
 
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}\box\mybox
-
+}\bigskip\leavevmode\box\mybox
 \bye

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/006-code39-test.lua
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/006-code39-test.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/006-code39-test.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -14,29 +14,29 @@
 assert(ok, err)
 
 local canvas = barracuda:new_canvas()
-symbol:append_ga(canvas)
+symbol:draw(canvas)
 
 local ok, err = symbol:set_param("text_hpos", "center")
 assert(ok, err)
-symbol:append_ga(canvas, 4.5*cm)
+symbol:draw(canvas, 4.5*cm)
 
 local ok, err = symbol:set_param("text_hpos", "right")
 assert(ok, err)
-symbol:append_ga(canvas, 9.0*cm)
+symbol:draw(canvas, 9.0*cm)
 
 local ok, err = c39:set_param("text_vpos", "bottom")
 assert(ok, err)
 
 local ok, err = symbol:set_param("text_hpos", "left")
-symbol:append_ga(canvas, 0, -2.0*cm)
+symbol:draw(canvas, 0, -2.0*cm)
 
 local ok, err = symbol:set_param("text_hpos", "center")
 assert(ok, err)
-symbol:append_ga(canvas, 4.5*cm, -2.0*cm)
+symbol:draw(canvas, 4.5*cm, -2.0*cm)
 
 local ok, err = symbol:set_param("text_hpos", "right")
 assert(ok, err)
-symbol:append_ga(canvas, 9.0*cm, -2.0*cm)
+symbol:draw(canvas, 9.0*cm, -2.0*cm)
 
 local drv = barracuda:get_driver()
 drv:save("svg", canvas, "006-six")

Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/007-code39-test.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/007-code39-test.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/007-code39-test.pdf	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/007-code39-test.pdf	2022-06-23 20:54:26 UTC (rev 63701)

Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/007-code39-test.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/007-code39-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/007-code39-test.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/007-code39-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,39 @@
+% !TeX program = LuaTeX
+% Copyright (C) 2019-2022 Roberto Giacomelli
+
+\newbox\mybox
+\nopagenumbers
+
+\directlua{
+barracuda = require "barracuda"
+local c39 = assert(
+    barracuda:barcode()
+             :new_encoder("code39", {debug_bbox_on = true})
+)
+
+local bars = c39:new {
+    123456,
+    "123456",
+    "ABCDEF",
+    87429,
+    982398,
+    "HDUHBE"
+}
+
+local canvas = barracuda:new_canvas()
+local tx, ty = 0, 0
+local dh = tex.sp "40pt"
+for _, b in ipairs(bars) do
+    b:draw(canvas, tx, ty)
+    ty = ty + dh
+end
+
+local drv = barracuda:get_driver()
+drv:ga_to_hbox(canvas, "mybox")
+}
+
+Test 1: check Barcode recursive costructor new():
+\bigskip
+\leavevmode\box\mybox
+\bye
+


Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-code39/007-code39-test.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/001-13-ean-test.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/001-13-ean-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/001-13-ean-test.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/001-13-ean-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,5 +1,5 @@
 % !TeX program = LuaTeX
-% Copyright (C) 2020 Roberto Giacomelli
+% Copyright (C) 2019-2022 Roberto Giacomelli
 
 \newbox\mybox
 \nopagenumbers
@@ -11,6 +11,7 @@
 \directlua{
 barracuda = require "barracuda"
 local barcode = barracuda:barcode()
+barcode:set_param{debug_bbox="qz"}
 
 local ean13, err = barcode:new_encoder("ean-13")
 assert(not err, err)
@@ -19,7 +20,7 @@
 assert(not err, err)
 
 local canvas = barracuda:new_canvas()
-symbo:append_ga(canvas)
+symbo:draw(canvas)
 
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
@@ -39,7 +40,7 @@
 assert(not err, err)
 
 local canvas = barracuda:new_canvas()
-symbo:append_ga(canvas)
+symbo:draw(canvas)
 
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
@@ -56,7 +57,7 @@
 local symbo, err = ean5:from_string("54495")
 assert(not err, err)
 local canvas = barracuda:new_canvas()
-symbo:append_ga(canvas)
+symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
 }
@@ -72,7 +73,7 @@
 local symbo, err = ean2:from_string("53")
 assert(not err, err)
 local canvas = barracuda:new_canvas()
-symbo:append_ga(canvas)
+symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
 }
@@ -89,7 +90,7 @@
 local symbo, err = ean:from_string(n..c.."12345")
 assert(not err, err)
 local canvas = barracuda:new_canvas()
-symbo:append_ga(canvas)
+symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
 }
@@ -107,7 +108,7 @@
 local symbo, err = ean:from_string(s.."12")
 assert(not err, err)
 local canvas = barracuda:new_canvas()
-symbo:append_ga(canvas)
+symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
 }
@@ -125,7 +126,7 @@
 local symbo, err = ean:from_string(s.."12345")
 assert(not err, err)
 local canvas = barracuda:new_canvas()
-symbo:append_ga(canvas)
+symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
 }
@@ -143,7 +144,7 @@
 local symbo, err = ean:from_string(s.."88")
 assert(not err, err)
 local canvas = barracuda:new_canvas()
-symbo:append_ga(canvas)
+symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
 }
@@ -167,10 +168,10 @@
 local symbo, err = ean:from_string(s); assert(not err, err)
 local ok, err = symbo:set_param("height", tex.sp "5mm"); assert(ok, err)
 local canvas = barracuda:new_canvas()
-symbo:append_ga(canvas)
+symbo:draw(canvas)
 
 local s2, err = ean:from_uint(8001120972163); assert(not err, err)
-s2:append_ga(canvas, tex.sp "45mm", 0)
+s2:draw(canvas, tex.sp "45mm", 0)
 
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
@@ -191,12 +192,12 @@
 local n = 758458535897; local c = ean:checksum(n); local s = n .. c
 local s1, err = ean:from_string(s); assert(not err, err)
 local canvas = barracuda:new_canvas()
-s1:append_ga(canvas)
+s1:draw(canvas)
 local s2, err = ean:from_uint(8001120972163); assert(not err, err)
-s2:append_ga(canvas, tex.sp "40mm", 0)
+s2:draw(canvas, tex.sp "40mm", 0)
 local s3, err = ean:from_uint(8000570000310); assert(not err, err)
 local ok, e = s3:set_param{height = tex.sp "10mm"}; assert(ok, e)
-s3:append_ga(canvas, tex.sp "90mm", 0)
+s3:draw(canvas, tex.sp "90mm", 0)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
 }

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/002-ean-test.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/003-ean-test.pdf
===================================================================
(Binary files differ)

Deleted: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/004-ean-test.lua
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/004-ean-test.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/004-ean-test.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,9 +0,0 @@
-
-local barracuda = require "barracuda"
-barracuda:save("ean-13", "8006194056290", "8006194056290")
-
-
-
-
-
-

Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/004-ean-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/004-ean-test.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/004-ean-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,6 @@
+% !TeX program = LuaTeX
+\directlua{
+local barracuda = require "barracuda"
+barracuda:save("ean-13", "8006194056290", "8006194056290")
+}
+\bye


Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/004-ean-test.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/005-isbn-test.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/006-issn-test.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/006-issn-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/006-issn-test.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/006-issn-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -30,28 +30,30 @@
 
 \vskip10pt
 \leavevmode
-\directlua{barracuda:hbox("ean-issn", "1828-2350", "mybox")}
+\directlua{
+local barcode = barracuda:barcode()
+barcode:set_param("debug_bbox_on", true)
+barracuda:hbox("ean-issn", "1828-2350", "mybox")
+}
 \box\mybox
 
 \vskip10pt
 \leavevmode
-\directlua{barracuda:hbox("ean-issn", "1828-2350 [01]", "mybox")}
+\directlua{
+barracuda:hbox("ean-issn+2", "1828-2350 [01] 22", "mybox")
+barracuda:save("ean-issn+2", "1828-2350 [01] 22", "ars")
+}
 \box\mybox
 
 \vskip10pt
 \leavevmode
-\directlua{barracuda:hbox("ean-issn+5", "1828-2350 [01] 00028", "mybox")}
+\directlua{barracuda:hbox("ean-issn", "1828-2350 [01]", "mybox")}
 \box\mybox
 
 \vskip10pt
 \leavevmode
-\directlua{
-barracuda:hbox("ean-issn+2", "1828-2350 [01] 22", "mybox")
-barracuda:save("ean-issn+2", "1828-2350 [01] 22", "ars")
-}
+\directlua{barracuda:hbox("ean-issn+5", "1828-2350 [01] 00028", "mybox")}
 \box\mybox
 
-
 \bye
 
-

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/8006194056290.svg
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/8006194056290.svg	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/8006194056290.svg	2022-06-23 20:54:26 UTC (rev 63701)
@@ -12,6 +12,14 @@
     <path d="M0.824996 -24.499871V-0.000000" style="stroke-width:0.329998"/>
   </g>
   <g stroke="black">
+    <path d="M15.344919 -24.499871V-0.000000" style="stroke-width:0.329998"/>
+    <path d="M16.004916 -24.499871V-0.000000" style="stroke-width:0.329998"/>
+  </g>
+  <g stroke="black">
+    <path d="M30.524839 -24.499871V-0.000000" style="stroke-width:0.329998"/>
+    <path d="M31.184836 -24.499871V-0.000000" style="stroke-width:0.329998"/>
+  </g>
+  <g stroke="black">
     <path d="M2.309988 -24.499871V-1.649991" style="stroke-width:0.659997"/>
     <path d="M3.134984 -24.499871V-1.649991" style="stroke-width:0.329998"/>
   </g>
@@ -36,10 +44,6 @@
     <path d="M14.519924 -24.499871V-1.649991" style="stroke-width:0.659997"/>
   </g>
   <g stroke="black">
-    <path d="M15.344919 -24.499871V-0.000000" style="stroke-width:0.329998"/>
-    <path d="M16.004916 -24.499871V-0.000000" style="stroke-width:0.329998"/>
-  </g>
-  <g stroke="black">
     <path d="M16.994911 -24.499871V-1.649991" style="stroke-width:0.989995"/>
     <path d="M18.314904 -24.499871V-1.649991" style="stroke-width:0.329998"/>
   </g>
@@ -63,10 +67,6 @@
     <path d="M28.544850 -24.499871V-1.649991" style="stroke-width:0.989995"/>
     <path d="M29.864843 -24.499871V-1.649991" style="stroke-width:0.329998"/>
   </g>
-  <g stroke="black">
-    <path d="M30.524839 -24.499871V-0.000000" style="stroke-width:0.329998"/>
-    <path d="M31.184836 -24.499871V-0.000000" style="stroke-width:0.329998"/>
-  </g>
   <text x="-3.629981" y="0.780007" font-family="Verdana" font-size="2.877000">
   8  </text>
   <text y="0.780007" font-family="Verdana" font-size="2.877000" text-anchor="middle">

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/ars.svg
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/ars.svg	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ean/ars.svg	2022-06-23 20:54:26 UTC (rev 63701)
@@ -12,6 +12,14 @@
     <path d="M0.824996 -24.499871V-0.000000" style="stroke-width:0.329998"/>
   </g>
   <g stroke="black">
+    <path d="M15.344919 -24.499871V-0.000000" style="stroke-width:0.329998"/>
+    <path d="M16.004916 -24.499871V-0.000000" style="stroke-width:0.329998"/>
+  </g>
+  <g stroke="black">
+    <path d="M30.524839 -24.499871V-0.000000" style="stroke-width:0.329998"/>
+    <path d="M31.184836 -24.499871V-0.000000" style="stroke-width:0.329998"/>
+  </g>
+  <g stroke="black">
     <path d="M1.814990 -24.499871V-1.649991" style="stroke-width:0.989995"/>
     <path d="M2.969984 -24.499871V-1.649991" style="stroke-width:0.659997"/>
   </g>
@@ -36,10 +44,6 @@
     <path d="M14.354924 -24.499871V-1.649991" style="stroke-width:0.989995"/>
   </g>
   <g stroke="black">
-    <path d="M15.344919 -24.499871V-0.000000" style="stroke-width:0.329998"/>
-    <path d="M16.004916 -24.499871V-0.000000" style="stroke-width:0.329998"/>
-  </g>
-  <g stroke="black">
     <path d="M16.829911 -24.499871V-1.649991" style="stroke-width:0.659997"/>
     <path d="M17.819906 -24.499871V-1.649991" style="stroke-width:0.659997"/>
   </g>
@@ -63,10 +67,6 @@
     <path d="M28.379851 -24.499871V-1.649991" style="stroke-width:0.659997"/>
     <path d="M29.699844 -24.499871V-1.649991" style="stroke-width:0.659997"/>
   </g>
-  <g stroke="black">
-    <path d="M30.524839 -24.499871V-0.000000" style="stroke-width:0.329998"/>
-    <path d="M31.184836 -24.499871V-0.000000" style="stroke-width:0.329998"/>
-  </g>
   <text x="-3.629981" y="0.780007" font-family="Verdana" font-size="2.877000">
   9  </text>
   <text y="0.780007" font-family="Verdana" font-size="2.877000" text-anchor="middle">

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/001-ga-pdfliteral-test.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/001-ga-pdfliteral-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/001-ga-pdfliteral-test.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/001-ga-pdfliteral-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,7 +1,7 @@
 % !TeX program = LuaTeX
 % test for ga-canvas pdfliteral driver
 %
-% Copyright (C) 2020 Roberto Giacomelli
+% Copyright (C) 2019-2022 Roberto Giacomelli
 % see LICENSE.txt file
 
 ---ga--- is a binary format as an istruction set similar to
@@ -28,35 +28,36 @@
 
 \newbox\mybox
 \directlua{
-    driver = require [[lib-driver.brcd-driver]] % global Lua variables
+    brcd = require "barracuda"
+    driver = brcd:get_driver() % global Lua variables
     pt = tex.sp [[1pt]] % 1pt = 65536sp
 }
 
 Let's start drawing an horizontal line 100pt long:
 \directlua{
-   local ga = {_data = {33, 0*pt, 100*pt, 0*pt}}
+   local ga = {33, 0*pt, 100*pt, 0*pt}
    driver:ga_to_hbox(ga, [[mybox]])
 }\box\mybox
 
 or two different parallel lines 24pt long:
 \directlua{
-   local ga = {_data = {33, 0*pt, 24*pt, 0*pt, 33, 0*pt, 24*pt, 5*pt}}
+   local ga = {33, 0*pt, 24*pt, 0*pt, 33, 0*pt, 24*pt, 5*pt}
    driver:ga_to_hbox(ga, [[mybox]])
 }\box\mybox
 
 and again two horizontal lines 10pt thick, touching a corner:
 \directlua{
-   local ga = {_data = {
+   local ga = {
        1,   10*pt,
        33, -24*pt,  0*pt, -5*pt,
        33,   0*pt, 24*pt,  5*pt,
-   }}
+   }
    driver:ga_to_hbox(ga, [[mybox]])
 }\box\mybox
 
 Several vertical lines with its horizontal limits:
 \directlua{
-   local ga = { _data = {
+   local ga = {
        34, -20*pt, 20*pt,  0*pt,
        34, -15*pt, 15*pt,  5*pt,
        34, -10*pt, 10*pt, 10*pt,
@@ -69,16 +70,16 @@
         1, .05*pt,
        33,   0*pt, 40*pt, -20*pt,
        33,   0*pt, 40*pt,  20*pt,
-   }}
+   }
    driver:ga_to_hbox(ga, [[mybox]])
 }\box\mybox
 
 Finally a little rectangle:
 \directlua{
-   local ga = {_data = {
+   local ga = {
        1, 5*pt,
       48, 0*pt, 0*pt, 15*pt, 10*pt,
-   }}
+   }
    driver:ga_to_hbox(ga, [[mybox]])
 }\box\mybox
 
@@ -86,7 +87,7 @@
 Test number 1: a vbar 2pt width, 20pt height:
 \directlua{
     % vbar: <36> y1 y2 <nbars> x1 w1 x2 w2 ... xn wn
-    local ga = {_data = {36, 0, 20*pt, 1, 0.0, 2*pt}}
+    local ga = {36, 0, 20*pt, 1, 0.0, 2*pt}
     driver:ga_to_hbox(ga, [[mybox]])
 }\box\mybox
 
@@ -98,7 +99,7 @@
         ga[i*2 + 5] = 5*pt + i*20*pt
         ga[i*2 + 6] = 10*pt
     end
-    driver:ga_to_hbox({_data = ga}, [[mybox]])
+    driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
 \bigskip
@@ -117,7 +118,7 @@
         ga[i*2 + 29] = 15*pt + i*20*pt
         ga[i*2 + 30] = 5*pt
     end
-    driver:ga_to_hbox({_data = ga}, [[mybox]])
+    driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
 \bigskip
@@ -132,7 +133,7 @@
         ga[i*2 + 5] = 1*pt + i*4*pt
         ga[i*2 + 6] = 2*pt
     end
-    driver:ga_to_hbox({_data = ga}, [[mybox]])
+    driver:ga_to_hbox(ga, [[mybox]])
 }\vrule A\box\mybox A\vrule
 
 \bigskip
@@ -155,7 +156,7 @@
         ga[i*2 + 59] = 3*pt + i*4*pt
         ga[i*2 + 60] = 2*pt
     end
-    driver:ga_to_hbox({_data = ga}, [[mybox]])
+    driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
 \bigskip
@@ -181,7 +182,7 @@
      25*pt, % x
      10*pt, % w
     }
-    driver:ga_to_hbox({_data = ga}, [[mybox]])
+    driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
 \bigskip
@@ -219,7 +220,7 @@
     ga[52] = 71 % G
     ga[53] = 72 % H
     ga[54] = 0
-    driver:ga_to_hbox({_data = ga}, [[mybox]])
+    driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
 \bigskip
@@ -271,7 +272,7 @@
     ga[66] = 55 % 7
     ga[67] = 56 % 8
     ga[68] = 0
-    driver:ga_to_hbox({_data = ga}, [[mybox]])
+    driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
 \bigskip
@@ -323,7 +324,7 @@
     ga[66] = 55 % 7
     ga[67] = 56 % 8
     ga[68] = 0
-    driver:ga_to_hbox({_data = ga}, [[mybox]])
+    driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
 \bigskip
@@ -356,11 +357,11 @@
     ga[23] =  56 % 8
     ga[24] =  57 % 9
     ga[25] =   0
-    driver:ga_to_hbox({_data = ga}, [[mybox]])
+    driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
 \bigskip
-So far, we have manually build data for ga stream. Next we are going to
+So far, we have manually build data for ga stream. For now on, we are going to
 use the ga-canvas library.
 
 \bigskip
@@ -368,11 +369,9 @@
 
 Test 1: a vbar 2pt width, 20pt height:
 \directlua{
-    gacanvas = require "lib-geo.brcd-gacanvas"
-    local ga = gacanvas:new()
-    local vbar = {_yline = {0.0, 2*pt}}
-    local err = ga:encode_Vbar(vbar, 0.0, 0.0, 20*pt) % x, w
-    assert(not err, err)
+    local ga = brcd:new_canvas()
+    local vbar = {0.0, 2*pt}
+    assert(ga:encode_vbar(vbar, 0.0, 0.0, 20*pt)) % x, w
     driver:ga_to_hbox(ga, [[mybox]])
 }\box\mybox
 
@@ -379,15 +378,13 @@
 \bigskip
 Test 2: ten vbars equally spaced by 10pt:
 \directlua{
-    local ga = gacanvas:new()
-    local data = {}
+    local ga = brcd:new_canvas()
+    local bars = {}
     for i = 0, 9 do
-        data[i*2 + 1] =  5*pt + i*20*pt % x
-        data[i*2 + 2] = 10*pt           % w
+        bars[i*2 + 1] =  5*pt + i*20*pt % x
+        bars[i*2 + 2] = 10*pt           % w
     end
-    local bars = {_yline = data}
-    local err = ga:encode_Vbar(bars, 0.0, 0.0, 10*pt)
-    assert(not err, err)
+    assert(ga:encode_vbar(bars, 0.0, 0.0, 10*pt))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
@@ -404,11 +401,9 @@
         b2[i*2 + 1] = i*20*pt
         b2[i*2 + 2] = 5*pt
     end
-    local ga = gacanvas:new()
-    local err = ga:encode_Vbar({_yline=b1}, 0.0, 0.0, 10*pt)
-    assert(not err, err)
-    err = ga:encode_Vbar({_yline=b2}, 10.0*pt, 2.5*pt, 7.5*pt)
-    assert(not err, err)
+    local ga = brcd:new_canvas()
+    assert(ga:encode_vbar(b1, 0.0, 0.0, 10*pt))
+    assert(ga:encode_vbar(b2, 10.0*pt, 2.5*pt, 7.5*pt))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
@@ -420,9 +415,8 @@
         b[i*2 + 1] = 1*pt + i*4*pt
         b[i*2 + 2] = 2*pt
     end
-    local ga = gacanvas:new()
-    local err = ga:encode_Vbar({_yline=b}, 0.0, 5*pt, 25*pt)
-    assert(not err, err)
+    local ga = brcd:new_canvas()
+    assert(ga:encode_vbar(b, 0.0, 5*pt, 25*pt))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule{ }\box\mybox{ }\vrule
 
@@ -434,11 +428,9 @@
         b[i*2 + 1] = i*4*pt
         b[i*2 + 2] = 2*pt
     end
-    local b = {_yline=b}
-    local ga = gacanvas:new()
-    local err = ga:encode_Vbar(b, 0.0, 5*pt, 25*pt)
-    assert(not err, err)
-    err = ga:encode_Vbar(b, 2*pt, 25*pt, 45*pt, b)
+    local ga = brcd:new_canvas()
+    assert(ga:encode_vbar(b, 0.0, 5*pt, 25*pt))
+    assert(ga:encode_vbar(b, 2*pt, 25*pt, 45*pt, b))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
@@ -445,14 +437,11 @@
 \bigskip
 Test number 6: staircase of bars (manual insertion of data):
 \directlua{
-    local b = {_yline={0.0, 10*pt}}
-    local ga = gacanvas:new()
-    local err = ga:encode_Vbar(b, 0.0, 0.0, 20*pt)
-    assert(not err, err)
-    err = ga:encode_Vbar(b, 10*pt, 20*pt, 40*pt)
-    assert(not err, err)
-    err = ga:encode_Vbar(b, 20*pt, 40*pt, 60*pt)
-    assert(not err, err)
+    local b = {0.0, 10*pt}
+    local ga = brcd:new_canvas()
+    assert(ga:encode_vbar(b, 0.0, 0.0, 20*pt))
+    assert(ga:encode_vbar(b, 10*pt, 20*pt, 40*pt))
+    assert(ga:encode_vbar(b, 20*pt, 40*pt, 60*pt))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
@@ -459,17 +448,14 @@
 \bigskip
 Test number 7: vbars with spaced text, all in three rows:
 \directlua{
-    local b = {}
+    local vb = {}
     for i = 0,7 do
-        b[i*2+1] = i*10*pt
-        b[i*2+2] = 5*pt
+        vb[i*2+1] = i*10*pt
+        vb[i*2+2] = 5*pt
     end
-    local vb = {_yline=b}
-    local ga = gacanvas:new()
-    local err = ga:encode_Vbar(vb, 0.0, 0.0, 20*pt)
-    assert(not err, err)
-    local err = ga:encode_Vbar(vb, 0.0, 30*pt, 50*pt)
-    assert(not err, err)
+    local ga = brcd:new_canvas()
+    assert(ga:encode_vbar(vb, 0.0, 0.0, 20*pt))
+    assert(ga:encode_vbar(vb, 0.0, 30*pt, 50*pt))
     local txt = {codepoint = {
         65, % A
         66, % B
@@ -480,8 +466,7 @@
         71, % G
         72, % H
     }}
-    err = ga:encode_Text_xspaced(txt, 0.0, 10*pt, 25*pt, 0.5)
-    assert(not err, err)
+    assert(ga:encode_Text_xspaced(txt, 0.0, 10*pt, 25*pt, 0.5))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
@@ -493,12 +478,9 @@
         b[i*2+1] = i*10*pt
         b[i*2+2] = 2*pt
     end
-    b = {_yline=b}
-    local ga = gacanvas:new()
-    local err = ga:encode_Vbar(b, 0.0, 0.0, 20*pt)
-    assert(not err, err)
-    local err = ga:encode_Vbar(b, 0.0, 40*pt, 60*pt)
-    assert(not err, err)
+    local ga = brcd:new_canvas()
+    assert(ga:encode_vbar(b, 0.0, 0.0, 20*pt))
+    assert(ga:encode_vbar(b, 0.0, 40*pt, 60*pt))
     local c = { codepoint = {
         65, % A
         66, % B
@@ -509,8 +491,7 @@
         71, % G
         72, % H
     }}
-    err = ga:encode_Text_xspaced(c, 0.0, 10*pt, 30*pt, 0.0)
-    assert(not err, err)
+    assert(ga:encode_Text_xspaced(c, 0.0, 10*pt, 30*pt, 0.0))
     local n = { codepoint = {
         49, % 1
         50, % 2
@@ -521,8 +502,7 @@
         55, % 7
         56, % 8
     }}
-    err = ga:encode_Text_xspaced(n, 0.0, 10*pt, 30*pt, 1.0)
-    assert(not err, err)
+    assert(ga:encode_Text_xspaced(n, 0.0, 10*pt, 30*pt, 1.0))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
@@ -534,12 +514,9 @@
         b[i*2+1] = i*10*pt
         b[i*2+2] = 8*pt
     end
-    b = {_yline = b}
-    local ga = gacanvas:new()
-    local err = ga:encode_Vbar(b, 0.0, 0.0, 20*pt)
-    assert(not err, err)
-    local err = ga:encode_Vbar(b, 0.0, 40*pt, 60*pt)
-    assert(not err, err)
+    local ga = brcd:new_canvas()
+    assert(ga:encode_vbar(b, 0.0, 0.0, 20*pt))
+    assert(ga:encode_vbar(b, 0.0, 40*pt, 60*pt))
     local c = { codepoint = {
         65, % A
         66, % B
@@ -550,8 +527,7 @@
         71, % G
         72, % H
     }}
-    err = ga:encode_Text_xspaced(c, 0.0, 10*pt, 20*pt, 0.0)
-    assert(not err, err)
+    assert(ga:encode_Text_xspaced(c, 0.0, 10*pt, 20*pt, 0.0))
     local n = { codepoint = {
         49, % 1
         50, % 2
@@ -562,8 +538,7 @@
         55, % 7
         56, % 8
     }}
-    err = ga:encode_Text_xspaced(n, 0.0, 10*pt, 40*pt, 1.0)
-    assert(not err, err)
+    assert(ga:encode_Text_xspaced(n, 0.0, 10*pt, 40*pt, 1.0))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule{ }\box\mybox{ }\vrule
 
@@ -582,16 +557,14 @@
         56, % 8
         57, % 9
     }}
-    local ga = gacanvas:new()
-    local err = ga:encode_Text(n, 0, 0, 0.5, 0)
-    assert(not err, err)
+    local ga = brcd:new_canvas()
+    assert(ga:encode_Text(n, 0, 0, 0.5, 0))
     local a = { codepoint = {
         65, % A
         string.byte("Q"), % Q
         67, % C
     }}
-    err = ga:encode_Text(a, 0, 0, 0.5, 1)
-    assert(not err, err)
+    assert(ga:encode_Text(a, 0, 0, 0.5, 1))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
@@ -610,16 +583,14 @@
         56, % 8
         57, % 9
     }}
-    local ga = gacanvas:new()
-    local err = ga:encode_Text(n, 0, 0, 0.5, 1)
-    assert(not err, err)
+    local ga = brcd:new_canvas()
+    assert(ga:encode_Text(n, 0, 0, 0.5, 1))
     local a = { codepoint = {
         65, % A
         string.byte("Q"), % Q
         67, % C
     }}
-    err = ga:encode_Text(a, 0, 0, 0.5, 0)
-    assert(not err, err)
+    assert(ga:encode_Text(a, 0, 0, 0.5, 0))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
@@ -639,9 +610,8 @@
         56, % 8
         57, % 9
     }}
-    local ga = gacanvas:new()
-    local err = ga:encode_Text_xwidth(n, 0, tex.sp "5cm", 0, 0)
-    assert(not err, err)
+    local ga = brcd:new_canvas()
+    assert(ga:encode_Text_xwidth(n, 0, tex.sp "5cm", 0, 0))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
@@ -664,20 +634,14 @@
         56, % 8
         57, % 9
     }}
-    local ga = gacanvas:new()
-    %                                (txt, x1, x2, ypos, ay) --> err
-    local err = ga:encode_Text_xwidth(n, tex.sp "0mm", tex.sp "50mm", 0, 0) 
-    assert(not err, err)
-    local err = ga:encode_Text_xwidth(n, tex.sp "5mm", tex.sp "45mm", tex.sp "3mm", 0)
-    assert(not err, err)
-    local err = ga:encode_Text_xwidth(n, tex.sp "10mm", tex.sp "40mm", tex.sp "6mm", 0)
-    assert(not err, err)
-    local err = ga:encode_Text_xwidth(n, tex.sp "15mm", tex.sp "35mm", tex.sp "9mm", 0)
-    assert(not err, err)
-    local err = ga:encode_Text_xwidth(n, tex.sp "20mm", tex.sp "30mm", tex.sp "12mm", 0)
-    assert(not err, err)
-    local err = ga:encode_Text_xwidth(n, tex.sp "24mm", tex.sp "26mm", tex.sp "15mm", 0)
-    assert(not err, err)
+    local ga = brcd:new_canvas()
+    %                           (txt, x1, x2, ypos, ay) --> ok, err
+    assert(ga:encode_Text_xwidth(n, tex.sp "0mm", tex.sp "50mm", 0, 0))
+    assert(ga:encode_Text_xwidth(n, tex.sp "5mm", tex.sp "45mm", tex.sp "3mm", 0))
+    assert(ga:encode_Text_xwidth(n, tex.sp "10mm", tex.sp "40mm", tex.sp "6mm", 0))
+    assert(ga:encode_Text_xwidth(n, tex.sp "15mm", tex.sp "35mm", tex.sp "9mm", 0))
+    assert(ga:encode_Text_xwidth(n, tex.sp "20mm", tex.sp "30mm", tex.sp "12mm", 0))
+    assert(ga:encode_Text_xwidth(n, tex.sp "24mm", tex.sp "26mm", tex.sp "15mm", 0))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
@@ -691,16 +655,12 @@
         b[i*2 + 1] = i*12*pt
         b[i*2 + 2] = 0.4*pt
     end
-    b = {_yline = b}
     local n = {codepoint = { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,}}
-    local ga = gacanvas:new()
-    %                         (vbar, x0, y1, y2) --> err
-    local err = ga:encode_Vbar(b, 0.0,  0*pt, 25*pt)
-    local err = ga:encode_Vbar(b, 0.0, 32*pt, 42*pt)
-    assert(not err, err)
-    %                            (txt, x1, x2, ypos, ay) --> err
-    local err = ga:encode_Text_xwidth(n, 0*pt, 108*pt, 25*pt, 0)
-    assert(not err, err)
+    local ga = brcd:new_canvas()
+    %                    (vbar, x0, y1, y2) --> ok, err
+    assert(ga:encode_vbar(b, 0.0,  0*pt, 25*pt))
+    %                    (txt, x1, x2, ypos, ay) --> ok, err
+    assert(ga:encode_Text_xwidth(n, 0*pt, 108*pt, 25*pt, 0))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
@@ -711,17 +671,14 @@
         b[i*2 + 1] = i*12*pt
         b[i*2 + 2] = 0.2*pt
     end
-    b = {_yline = b}
     local n = { 48, 49, 50, 51, string.byte([[x]]), 53, 54, 55, 56,}
     n = {codepoint = n}
-    local ga = gacanvas:new()
+    local ga = brcd:new_canvas()
     %                    x0,    y1,    y2, bars
-    local err = ga:encode_Vbar(b, 0.0,  0*pt, 25*pt)
-    local err = ga:encode_Vbar(b, 0.0, 32*pt, 42*pt)
-    assert(not err, err)
-    %                (txt, x1, x2, ypos, ay) --> err
-    local err = ga:encode_Text_xwidth(n, 0*pt, 96*pt, 25*pt, 0)
-    assert(not err, err)
+    assert(ga:encode_vbar(b, 0.0,  0*pt, 25*pt))
+    assert(ga:encode_vbar(b, 0.0, 32*pt, 42*pt))
+    %                (txt, x1, x2, ypos, ay) --> ok, err
+    assert(ga:encode_Text_xwidth(n, 0*pt, 96*pt, 25*pt, 0))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 
@@ -730,10 +687,9 @@
 
 \directlua{
     local n = {codepoint = { 48, 56,}} % 0 and 8
-    local ga = gacanvas:new()
-    %                           (txt, x1, x2, ypos, ay) --> err
-    local err = ga:encode_Text_xwidth(n, 0*pt, 32*pt, 25*pt, 0)
-    assert(not err, err)
+    local ga = brcd:new_canvas()
+    %                   (txt, x1, x2, ypos, ay) --> ok, err
+    assert(ga:encode_Text_xwidth(n, 0*pt, 32*pt, 25*pt, 0))
     driver:ga_to_hbox(ga, [[mybox]])
 }\vrule\box\mybox\vrule
 

Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/002-polyline.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/002-polyline.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/002-polyline.pdf	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/002-polyline.pdf	2022-06-23 20:54:26 UTC (rev 63701)

Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/002-polyline.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/002-polyline.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/002-polyline.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/002-polyline.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,69 @@
+% !TeX program = LuaTeX
+
+\directlua{
+    brcd = require "barracuda"
+}
+\newbox\mybox
+
+Test 1: a simple polyline:
+\directlua{
+    local Polyline = brcd._libgeo.Polyline
+    local p = Polyline:new()
+    p:add_point(0, 0)
+    p:add_point(tex.sp "32pt", 0)
+    p:add_relpoint(tex.sp "16pt", tex.sp "16pt")
+
+    local gaCanvas = brcd._gacanvas
+    local ga = gaCanvas:new()
+    assert(ga:encode_polyline(p))
+
+    local driver = brcd:get_driver()
+    driver:ga_to_hbox(ga, [[mybox]])
+}\vrule\box\mybox\vrule
+
+
+Test 2: a staircase:
+\directlua{
+    local h = tex.sp "18pt"
+    local b = tex.sp "36pt"
+    local Polyline = brcd._libgeo.Polyline
+    local p = Polyline:new()
+    p:add_point(0, 0)
+    for _ = 1, 5 do
+        p:add_relpoint(0, h)
+        p:add_relpoint(b, 0)
+    end
+
+    local gaCanvas = brcd._gacanvas
+    local ga = gaCanvas:new()
+    assert(ga:encode_polyline(p))
+
+    local driver = brcd:get_driver()
+    driver:ga_to_hbox(ga, [[mybox]])
+}\vrule\box\mybox\vrule
+
+Test 3: several regular polygons:
+\directlua{
+    local Polyline = brcd._libgeo.Polyline
+    local l = tex.sp "36pt" % side length
+    local gaCanvas = brcd._gacanvas
+    local ga = gaCanvas:new()
+    ga:encode_linewidth(tex.sp "0.4pt")
+    for n = 3, 13 do
+        local p = Polyline:new()
+        p:add_point(0, 0)
+        local alpha = 2*math.pi/n % angle
+        local a = alpha/2 % regular angles sum
+        for _ = 1, n do
+            local x, y = l * math.cos(a), l * math.sin(a)
+            a = a + alpha
+            p:add_relpoint(x, y)
+        end
+        assert(ga:encode_polyline(p))
+    end
+    local driver = brcd:get_driver()
+    driver:ga_to_hbox(ga, [[mybox]])
+    driver:save("svg", ga, "polygon")
+}\vrule\box\mybox\vrule
+
+\bye


Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/002-polyline.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/polygon.svg
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/polygon.svg	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-pdfliteral/polygon.svg	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Barracuda package (https://github.com/robitex/barracuda) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg"
+  version="1.1"
+  width="52.484243mm" height="52.101574mm"
+  viewBox="-26.242122 -52.101574 52.484243 52.101574"
+>
+  <g stroke="black" stroke-width="0.140582" fill="none">
+    <polyline points="0.000000,-0.000000
+    6.326276,-10.957432
+    -6.326276,-10.957432
+    -0.000000,0.000000"/>
+  </g>
+  <g stroke="black" stroke-width="0.140582" fill="none">
+    <polyline points="0.000000,-0.000000
+    8.946706,-8.946706
+    0.000000,-17.893412
+    -8.946706,-8.946706
+    -0.000000,0.000000"/>
+  </g>
+  <g stroke="black" stroke-width="0.140582" fill="none">
+    <polyline points="0.000000,-0.000000
+    10.236130,-7.436984
+    6.326276,-19.470277
+    -6.326276,-19.470277
+    -10.236130,-7.436984
+    -0.000000,-0.000000"/>
+  </g>
+  <g stroke="black" stroke-width="0.140582" fill="none">
+    <polyline points="0.000000,-0.000000
+    10.957432,-6.326276
+    10.957432,-18.978829
+    0.000000,-25.305106
+    -10.957432,-18.978829
+    -10.957432,-6.326276
+    -0.000000,0.000000"/>
+  </g>
+  <g stroke="black" stroke-width="0.140582" fill="none">
+    <polyline points="0.000000,-0.000000
+    11.399556,-5.489737
+    14.215014,-17.825064
+    6.326276,-27.717228
+    -6.326276,-27.717228
+    -14.215014,-17.825064
+    -11.399556,-5.489737
+    -0.000000,0.000000"/>
+  </g>
+  <g stroke="black" stroke-width="0.140582" fill="none">
+    <polyline points="0.000000,-0.000000
+    11.689435,-4.841922
+    16.531357,-16.531357
+    11.689435,-28.220792
+    0.000000,-33.062714
+    -11.689435,-28.220792
+    -16.531357,-16.531357
+    -11.689435,-4.841922
+    -0.000000,0.000000"/>
+  </g>
+  <g stroke="black" stroke-width="0.140582" fill="none">
+    <polyline points="0.000000,-0.000000
+    11.889511,-4.327428
+    18.215787,-15.284860
+    16.018694,-27.745192
+    6.326276,-35.878097
+    -6.326276,-35.878097
+    -16.018694,-27.745192
+    -18.215787,-15.284860
+    -11.889511,-4.327428
+    0.000000,-0.000000"/>
+  </g>
+  <g stroke="black" stroke-width="0.140582" fill="none">
+    <polyline points="0.000000,-0.000000
+    12.033293,-3.909854
+    19.470277,-14.145984
+    19.470277,-26.798537
+    12.033293,-37.034667
+    0.000000,-40.944521
+    -12.033293,-37.034667
+    -19.470277,-26.798537
+    -19.470277,-14.145984
+    -12.033293,-3.909854
+    -0.000000,0.000000"/>
+  </g>
+  <g stroke="black" stroke-width="0.140582" fill="none">
+    <polyline points="0.000000,-0.000000
+    12.140036,-3.564636
+    20.425696,-13.126798
+    22.226342,-25.650566
+    16.970281,-37.159733
+    6.326276,-44.000219
+    -6.326276,-44.000219
+    -16.970281,-37.159733
+    -22.226342,-25.650566
+    -20.425696,-13.126798
+    -12.140036,-3.564636
+    -0.000000,0.000000"/>
+  </g>
+  <g stroke="black" stroke-width="0.140582" fill="none">
+    <polyline points="0.000000,-0.000000
+    12.221428,-3.274722
+    21.168134,-12.221428
+    24.442855,-24.442855
+    21.168134,-36.664283
+    12.221428,-45.610989
+    0.000000,-48.885711
+    -12.221428,-45.610989
+    -21.168134,-36.664283
+    -24.442855,-24.442855
+    -21.168134,-12.221428
+    -12.221428,-3.274722
+    -0.000000,-0.000000"/>
+  </g>
+  <g stroke="black" stroke-width="0.140582" fill="none">
+    <polyline points="0.000000,-0.000000
+    12.284893,-3.027954
+    21.755465,-11.418149
+    26.242122,-23.248491
+    24.717025,-35.808793
+    17.529556,-46.221640
+    6.326276,-52.101574
+    -6.326276,-52.101574
+    -17.529556,-46.221640
+    -24.717025,-35.808793
+    -26.242122,-23.248491
+    -21.755465,-11.418149
+    -12.284893,-3.027954
+    -0.000000,0.000000"/>
+  </g>
+</svg>
+

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-svg/002-ga-svg-test.lua
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-svg/002-ga-svg-test.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-ga-svg/002-ga-svg-test.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -13,6 +13,6 @@
 assert(not err, err)
 
 local canvas = barracuda:new_canvas()
-symbol:append_ga(canvas)
+symbol:draw(canvas)
 
 driver:save("svg", canvas, "test-code39")
\ No newline at end of file

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/001-i2of5-test.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/001-i2of5-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/001-i2of5-test.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/001-i2of5-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,10 +1,14 @@
 % !TeX program = LuaTeX
-% Copyright (C) 2020 Roberto Giacomelli
+% Copyright (C) 2019-2022 Roberto Giacomelli
 
 \newbox\mybox
 \nopagenumbers
 
-\directlua{barracuda = require "barracuda"}
+\directlua{
+barracuda = require "barracuda"
+local barcode = barracuda:barcode()
+barcode:set_param("debug_bbox", "symb")
+}
 
 Interleaved 2 of 5 encoder test.
 
@@ -12,14 +16,13 @@
 
 \directlua{
 local barcode = barracuda:barcode()
-
 local enc, err = barcode:new_encoder("i2of5"); assert(not err, err)
 local symbo, err = enc:from_uint(54654681); assert(not err, err)
-local canvas = barracuda:new_canvas(); symbo:append_ga(canvas)
+local canvas = barracuda:new_canvas(); symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}
-\vrule A\vrule\box\mybox \vrule A\vrule
+}%
+input code 54654681: \vrule A\vrule\box\mybox \vrule A\vrule
 
 \bigskip
 Test 2: one simple barcode with default parameter:
@@ -28,11 +31,11 @@
 local barcode = barracuda:barcode()
 local enc, err = barcode:enc_by_name("i2of5"); assert(not err, err)
 local symbo, err = enc:from_uint(1234567895); assert(not err, err)
-local canvas = barracuda:new_canvas(); symbo:append_ga(canvas)
+local canvas = barracuda:new_canvas(); symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}
-\vrule A\vrule\box\mybox \vrule A\vrule
+}%
+input code 1234567895: \vrule A\vrule\box\mybox \vrule A\vrule
 
 % check digit tests
 
@@ -104,11 +107,11 @@
 local enc, err = barcode:enc_by_name("i2of5"); assert(not err, err)
 local symbo, err = enc:from_uint(454473, {check_digit_policy="add"})
 assert(not err, err)
-local canvas = barracuda:new_canvas(); symbo:append_ga(canvas)
+local canvas = barracuda:new_canvas(); symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}
-\vrule A\vrule\box\mybox \vrule A\vrule
+}%
+input code 454473: \vrule A\vrule\box\mybox \vrule A\vrule
 
 \bigskip
 Test 4: a second simple barcode with check digit automatically added:
@@ -118,11 +121,11 @@
 local enc, err = barcode:enc_by_name("i2of5"); assert(not err, err)
 local symbo, err = enc:from_uint(74223, {check_digit_policy="add"})
 assert(not err, err)
-local canvas = barracuda:new_canvas(); symbo:append_ga(canvas)
+local canvas = barracuda:new_canvas(); symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}
-\vrule A\vrule\box\mybox \vrule A\vrule
+}%
+input code 74223: \vrule A\vrule\box\mybox \vrule A\vrule
 
 \bigskip
 Test 5: a symbol with native check digits:
@@ -132,11 +135,11 @@
 local enc, err = barcode:enc_by_name("i2of5"); assert(not err, err)
 local symbo, err = enc:from_uint(121891259, {check_digit_policy="verify"})
 assert(not err, err)
-local canvas = barracuda:new_canvas(); symbo:append_ga(canvas)
+local canvas = barracuda:new_canvas(); symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}
-\vrule A\vrule\box\mybox \vrule A\vrule
+}%
+input code 121891259: \vrule A\vrule\box\mybox \vrule A\vrule
 
 \bigskip
 Test 6: bearer bars please:
@@ -144,13 +147,13 @@
 \directlua{
 local barcode = barracuda:barcode()
 local enc, err = barcode:enc_by_name("i2of5"); assert(not err, err)
-local symbo, err = enc:from_uint(747867239, {bearer_bars_enabled = true})
+local symbo, err = enc:from_string("747867239", {bearer_bars_enabled = true})
 assert(not err, err)
-local canvas = barracuda:new_canvas(); symbo:append_ga(canvas)
+local canvas = barracuda:new_canvas(); symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}
-\vrule A\vrule\box\mybox \vrule A\vrule
+}%
+input string "747867239": \vrule A\vrule\box\mybox \vrule A\vrule
 
 \bigskip
 Test 7: bearer bars all around the symbol:
@@ -160,11 +163,11 @@
 local enc, err = barcode:enc_by_name("i2of5"); assert(not err, err)
 local symbo, err = enc:from_uint(986790868, {bearer_bars_enabled = true, bearer_bars_layout="frame"})
 assert(not err, err)
-local canvas = barracuda:new_canvas(); symbo:append_ga(canvas)
+local canvas = barracuda:new_canvas(); symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}
-\vrule A\vrule\box\mybox \vrule A\vrule
+}%
+input code 986790868: \vrule A\vrule\box\mybox \vrule A\vrule
 
 \bigskip
 Test 8: bearer bars all around the symbol (with string costructor):
@@ -174,11 +177,11 @@
 local enc, err = barcode:enc_by_name("i2of5"); assert(not err, err)
 local symbo, err = enc:from_string("986790868", {bearer_bars_enabled = true, bearer_bars_layout="frame"})
 assert(not err, err)
-local canvas = barracuda:new_canvas(); symbo:append_ga(canvas)
+local canvas = barracuda:new_canvas(); symbo:draw(canvas)
 local drv = barracuda:get_driver()
 drv:ga_to_hbox(canvas, "mybox")
-}
-\vrule A\vrule\box\mybox \vrule A\vrule
+}%
+input string "986790868": \vrule A\vrule\box\mybox \vrule A\vrule
 
 That's all folks!
 

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/002-ITF14-test.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/002-ITF14-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/002-ITF14-test.tex	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/002-ITF14-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,5 +1,5 @@
 % !TeX program = LuaTeX
-% Copyright (C) 2020 Roberto Giacomelli
+% Copyright (C) 2019-2022 Roberto Giacomelli
 
 \newbox\mybox
 \nopagenumbers
@@ -15,9 +15,8 @@
 local s1 = assert(enc:from_uint(1234567890123))
 
 local canvas = barracuda:new_canvas()
-s1:append_ga(canvas)
-local drv = barracuda:get_driver()
-drv:ga_to_hbox(canvas, "mybox")
+s1:draw(canvas)
+canvas:ga_to_hbox("mybox")
 }
 \vskip 10pt
 12345678901231 is \vrule A\vrule\box\mybox \vrule A\vrule
@@ -28,9 +27,8 @@
 local s1 = assert(enc:from_string("1234567890123"))
 
 local canvas = barracuda:new_canvas()
-s1:append_ga(canvas)
-local drv = barracuda:get_driver()
-drv:ga_to_hbox(canvas, "mybox")
+s1:draw(canvas)
+canvas:ga_to_hbox("mybox")
 }
 \vskip 10pt
 12345678901231 is \vrule A\vrule\box\mybox \vrule A\vrule
@@ -39,15 +37,12 @@
 local barcode = barracuda:barcode()
 local enc = assert(barcode:enc_by_name("i2of5-ITF14"))
 local s1 = assert(enc:from_string("(12) 34 56 78 90 12 3"))
-
+s1:set_param("debug_bbox_on", true)
 local canvas = barracuda:new_canvas()
-s1:append_ga(canvas)
-local drv = barracuda:get_driver()
-drv:ga_to_hbox(canvas, "mybox")
+s1:draw(canvas)
+canvas:ga_to_hbox("mybox")
+canvas:save("svg", "02-itf14")
 }
 \vskip 10pt
 12345678901231 is \vrule A\vrule\box\mybox \vrule A\vrule
-
 \bye
-
-

Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/02-itf14.svg
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/02-itf14.svg	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-i2of5/02-itf14.svg	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Barracuda package (https://github.com/robitex/barracuda) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg"
+  version="1.1"
+  width="74.497108mm" height="20.349904mm"
+  viewBox="-7.424961 -15.174920 74.497108 20.349904"
+>
+  <g stroke="black">
+    <path d="M0.247499 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M1.237493 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+  </g>
+  <g stroke="black">
+    <path d="M2.598736 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+    <path d="M3.959979 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M5.692470 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M6.682465 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M8.043708 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+  </g>
+  <g stroke="black">
+    <path d="M10.518695 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+    <path d="M12.251186 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+    <path d="M13.612428 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M15.344919 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M16.334914 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+  </g>
+  <g stroke="black">
+    <path d="M18.438653 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+    <path d="M19.799896 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M21.903635 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+    <path d="M24.007374 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M24.997368 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+  </g>
+  <g stroke="black">
+    <path d="M25.987363 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M27.719854 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M28.709849 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M30.071092 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+    <path d="M32.546079 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+  </g>
+  <g stroke="black">
+    <path d="M33.907322 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M35.268564 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+    <path d="M36.629807 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M38.733546 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+    <path d="M40.837285 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+  </g>
+  <g stroke="black">
+    <path d="M42.198528 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+    <path d="M43.559771 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M45.292262 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M46.282256 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M47.643499 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+  </g>
+  <g stroke="black">
+    <path d="M50.118486 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+    <path d="M52.593473 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+    <path d="M53.954716 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M54.944711 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+    <path d="M55.934706 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+  </g>
+  <g stroke="black">
+    <path d="M58.038445 -12.699933V-0.000000" style="stroke-width:1.237493"/>
+    <path d="M59.399687 -12.699933V-0.000000" style="stroke-width:0.494997"/>
+  </g>
+  <rect x="-6.187467" y="-13.937427" width="72.022121" height="15.174920"    fill="none" stroke="black" stroke-width="2.474987"
+  />
+  <text x="29.823593" y="5.174984" font-family="Verdana" font-size="2.877000" text-anchor="middle">
+  (12) 34 56 78 90 12 31  </text>
+  <rect x="-7.407322" y="-15.157281" width="74.461830" height="17.614629"    fill="none" stroke="black" stroke-width="0.035278"
+    stroke-dasharray="2.116667 1.058333"
+    stroke-dashoffset="1.058333"
+  />
+</svg>
+

Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/001-libgeo-test.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/001-libgeo-test.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/001-libgeo-test.pdf	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/001-libgeo-test.pdf	2022-06-23 20:54:26 UTC (rev 63701)

Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/001-libgeo-test.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/001-libgeo-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/001-libgeo-test.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/001-libgeo-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,48 @@
+% !TeX program = LuaTeX
+% test for ga-canvas pdfliteral driver
+%
+% Copyright (C) 2019-2022 Roberto Giacomelli
+% see LICENSE.txt file
+
+\newbox\mybox
+\directlua{
+    barracuda = require [[barracuda]]
+    pt = tex.sp [[1pt]] % 1pt = 65536sp
+}
+
+Test 1: test Archive class and Vbar arithmetic:
+
+\medskip
+\directlua{
+    % retrive the Vbar class
+    local libgeo = barracuda:libgeo()
+    local Vbar = libgeo.Vbar
+    % create three Vbar objects
+    local b1 = Vbar:from_int(22556, 2*pt)
+    local b2 = Vbar:from_int(3134563, 2*pt)
+    local b3 = Vbar:from_int(1111111, 2*pt)
+    % retrive the Archive class
+    local Archive = libgeo.Archive
+    % create a new instance of an archive and insert vbars
+    local archive = Archive:new()
+    assert(archive:insert(b1, 1))
+    assert(archive:insert(b2, 2))
+    assert(archive:insert(b3, 3))
+    % fill a queue (an array) two times
+    local queue = assert(archive:get(1)) + 20*pt
+    queue = queue + assert(archive:get(2)) + 20*pt
+    queue = queue + assert(archive:get(3)) + 20*pt
+    queue = queue + assert(archive:get(1)) + 20*pt
+    queue = queue + assert(archive:get(2)) + 20*pt
+    queue = queue + assert(archive:get(3))
+    % retrive a canvas instance
+    local ga = barracuda:new_canvas()
+    % draw the canvas with the driver component
+    assert(ga:encode_vbar_queue(queue, 0, 0, 30*pt))
+    local driver = barracuda:get_driver()
+    driver:ga_to_hbox(ga, [[mybox]])
+}A\box\mybox A
+
+\bye
+
+    
\ No newline at end of file


Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/001-libgeo-test.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/003-ga-svg-test.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/003-ga-svg-test.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/003-ga-svg-test.pdf	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/003-ga-svg-test.pdf	2022-06-23 20:54:26 UTC (rev 63701)

Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/003-ga-svg-test.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/003-ga-svg-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/003-ga-svg-test.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/003-ga-svg-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,41 @@
+% !TeX program = LuaTeX
+
+\newbox\mybox
+\nopagenumbers
+\directlua{
+local barracuda = require "barracuda"
+local barcode = barracuda:barcode()
+local driver = barracuda:get_driver()
+local mm = driver.mm
+
+local canvas = barracuda:new_canvas()
+canvas:encode_linewidth(1*mm)
+
+canvas:encode_dash_pattern(0, 2*mm)
+canvas:encode_hline(0, 30*mm, 5*mm)
+
+canvas:encode_dash_pattern(0, 2*mm, 4*mm)
+canvas:encode_hline(0, 30*mm, 10*mm)
+
+canvas:encode_dash_pattern(1*mm, 2*mm, 2*mm, 4*mm)
+canvas:encode_hline(0, 30*mm, 15*mm)
+
+canvas:encode_linewidth(0.05*mm)
+canvas:encode_reset_pattern()
+for i=0, 15 do
+    canvas:encode_vline(0, 20*mm, i*2*mm)
+end
+
+canvas:encode_dash_pattern(0.5*mm, 1*mm)
+canvas:encode_polyline{
+    1*mm, 1*mm,
+    29*mm, 1*mm,
+    29*mm, 19*mm,
+    1*mm, 19*mm,
+    1*mm, 1*mm
+}
+
+driver:save("svg", canvas, "test")
+assert(driver:ga_to_hbox(canvas, [[mybox]]))
+}\leavevmode\box\mybox
+\bye
\ No newline at end of file


Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/003-ga-svg-test.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/test.svg
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/test.svg	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-libgeo/test.svg	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Barracuda package (https://github.com/robitex/barracuda) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg"
+  version="1.1"
+  width="30.050000mm" height="20.000000mm"
+  viewBox="-0.025000 -20.000000 30.050000 20.000000"
+>
+  <path d="M0.000000 -5.000000H30.000000"
+    stroke="black" stroke-width="1.000000"
+    stroke-dasharray="2.000000"
+  />
+  <path d="M0.000000 -10.000000H30.000000"
+    stroke="black" stroke-width="1.000000"
+    stroke-dasharray="2.000000 4.000000"
+  />
+  <path d="M0.000000 -15.000000H30.000000"
+    stroke="black" stroke-width="1.000000"
+    stroke-dasharray="2.000000 2.000000 4.000000"
+    stroke-dashoffset="1.000000"
+  />
+  <path d="M0.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M2.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M4.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M6.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M8.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M10.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M12.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M14.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M16.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M18.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M20.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M22.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M24.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M26.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M28.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <path d="M30.000000 -20.000000V-0.000000"
+    stroke="black" stroke-width="0.050000"
+  />
+  <g stroke="black" stroke-width="0.050000" fill="none" stroke-dasharray="1.000000" stroke-dashoffset="0.500000">
+    <polyline points="1.000000,-1.000000
+    29.000000,-1.000000
+    29.000000,-19.000000
+    1.000000,-19.000000
+    1.000000,-1.000000"/>
+  </g>
+</svg>
+

Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/001-upca-test.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/001-upca-test.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/001-upca-test.pdf	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/001-upca-test.pdf	2022-06-23 20:54:26 UTC (rev 63701)

Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/001-upca-test.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/001-upca-test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/001-upca-test.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/001-upca-test.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,41 @@
+% !TeX program = LuaTeX
+% Copyright (C) 2019-2022 Roberto Giacomelli
+
+\newbox\mybox
+\nopagenumbers
+
+UPC encoder test.
+
+Test 1: one simple barcode UPC-A with default parameter:
+
+\directlua{
+barracuda = require "barracuda"
+local barcode = barracuda:barcode()
+barcode:set_param("debug_bbox", "qz")
+local upca, err = barcode:new_encoder("upc-A")
+assert(not err, err)
+
+local symbo, err = upca:from_string("042100005264")
+assert(not err, err)
+
+local canvas = barracuda:new_canvas()
+symbo:draw(canvas)
+
+local drv = barracuda:get_driver()
+drv:ga_to_hbox(canvas, "mybox")
+}
+\vrule A\box\mybox A\vrule
+
+\bigskip\directlua{
+local barcode = barracuda:barcode()
+barcode:set_param("debug_bbox", "none")
+local upca = assert(barcode:enc_by_name("upc-A"))
+
+local symbo = assert(upca:new("012345678905"))
+local canvas = barracuda:new_canvas()
+symbo:draw(canvas)
+
+local drv = barracuda:get_driver()
+drv:ga_to_hbox(canvas, "mybox")
+}\leavevmode\box\mybox
+\bye


Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/001-upca-test.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/002-upca.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/002-upca.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/002-upca.pdf	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/002-upca.pdf	2022-06-23 20:54:26 UTC (rev 63701)

Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/002-upca.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/002-upca.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/002-upca.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/002-upca.tex	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,9 @@
+% !TeX program = LuaLaTeX
+% Copyright (C) 2019-2022 Roberto Giacomelli
+
+\documentclass[border=5pt]{standalone}
+\usepackage{barracuda}
+
+\begin{document}
+\barracuda[debug_bbox="qz"]{upc-A}{121212343430}
+\end{document}
\ No newline at end of file


Property changes on: trunk/Master/texmf-dist/doc/luatex/barracuda/test/test-upc/002-upca.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/scripts/barracuda/barracuda.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/barracuda/barracuda.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/scripts/barracuda/barracuda.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -2,7 +2,7 @@
 --
 -- Encode a message into a barcode symbol, in Lua or within a LuaTeX source file
 --
--- Copyright (C) 2020 Roberto Giacomelli
+-- Copyright (C) 2019-2022 Roberto Giacomelli
 --
 -- 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
@@ -26,8 +26,8 @@
 
 local Barracuda = {
     _NAME        = "barracuda",
-    _VERSION     = "barracuda v0.0.10",
-    _DATE        = "2020-02-04",
+    _VERSION     = "barracuda v0.0.12",
+    _DATE        = "2022-06-23",
     _DESCRIPTION = "Lua library for barcode printing",
     _URL         = "https://github.com/robitex/barracuda",
     _LICENSE     = "GNU GENERAL PUBLIC LICENSE, Version 2, June 1991",
@@ -34,18 +34,28 @@
 }
 
 -- essential sub-module loading
-Barracuda._libgeo   = require "lib-geo.brcd-libgeo"      -- basic vectorial objects
+Barracuda._libgeo   = require "lib-geo.brcd-libgeo"      -- basic vector objects
 Barracuda._gacanvas = require "lib-geo.brcd-gacanvas"    -- ga stream library
 Barracuda._barcode  = require "lib-barcode.brcd-barcode" -- barcode abstract class
+Barracuda._lib_driver = require "lib-driver.brcd-driver" -- abstract driver class
 
 local Barcode = Barracuda._barcode
 Barcode._libgeo = Barracuda._libgeo
 
+-- a reference to Driver class for gaCancas class
+local canvas = Barracuda._gacanvas
+canvas._driver_class = Barracuda._lib_driver
+
 -- return a reference of Barcode abstract class
-function Barracuda:barcode() --> Barcode class object
+function Barracuda:barcode() --> <Barcode class>
     return self._barcode
 end
 
+-- return a reference to the libgeo library
+function Barracuda:libgeo() --> <libgeo library>
+    return self._libgeo
+end
+
 -- encoder costructor (a bridge to Barcode class method)
 function Barracuda:new_encoder(treename, opt) --> object, err
     local barcode = self._barcode
@@ -55,19 +65,15 @@
 
 -- where we place the output driver library
 function Barracuda:get_driver() --> Driver object
-    if not self._lib_driver then
-        self._lib_driver = require "lib-driver.brcd-driver"
-    end
     return self._lib_driver
 end
 
-function Barracuda:new_canvas() --> driver
+function Barracuda:new_canvas() --> canvas
     local gacanvas = self._gacanvas
     return gacanvas:new()
 end
 
 -- high level barcode functions
--- only default options
 -- panic on error
 
 -- save barcode as a graphic external file
@@ -104,7 +110,7 @@
         assert(ok, err)
     end
     local canvas = self:new_canvas()
-    symb:append_ga(canvas)
+    symb:draw(canvas)
     local driver = self:get_driver()
     id_drv = id_drv or "svg"
     local ok, err = driver:save(id_drv, canvas, filename)
@@ -144,7 +150,7 @@
         assert(ok, err)
     end
     local canvas = self:new_canvas()
-    symb:append_ga(canvas)
+    symb:draw(canvas)
     local driver = self:get_driver()
     local ok, err = driver:ga_to_hbox(canvas, box_name)
     assert(ok, err)

Modified: trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-barcode.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-barcode.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-barcode.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,13 +1,8 @@
-
 -- Barcode Abstract Class
--- Copyright (C) 2020 Roberto Giacomelli
+-- Copyright (C) 2019-2022 Roberto Giacomelli
 -- Please see LICENSE.TXT for any legal information about present software
 
-local Barcode = {
-    _VERSION     = "Barcode v0.0.9",
-    _NAME        = "Barcode",
-    _DESCRIPTION = "Barcode abstract class",
-}
+local Barcode = {_classname = "Barcode"}
 Barcode.__index = Barcode
 
 -- barcode_type/submodule name
@@ -16,6 +11,7 @@
     code128 = "lib-barcode.brcd-code128", -- Code128
     ean     = "lib-barcode.brcd-ean",     -- EAN family (ISBN, EAN8, etc)
     i2of5   = "lib-barcode.brcd-i2of5",   -- Interleaved 2 of 5
+    upc     = "lib-barcode.brcd-upc",     -- UPC
 }
 Barcode._builder_instances = {} -- encoder builder instances repository
 Barcode._encoder_instances = {} -- encoder instances repository
@@ -24,6 +20,7 @@
 Barcode._super_par_order = {
     "ax",
     "ay",
+    "debug_bbox",
 }
 Barcode._super_par_def = {}
 local pardef = Barcode._super_par_def
@@ -36,7 +33,7 @@
     default = 0.0,
     unit = "sp", -- scaled point
     isReserved = false,
-    fncheck = function (self, ax, _) --> boolean, err
+    fncheck = function (_self, ax, _) --> boolean, err
         if ax >= 0.0 and ax <= 1.0 then return true, nil end
         return false, "[OutOfRange] 'ax' out of [0, 1] interval"
     end,
@@ -46,13 +43,34 @@
     default = 0.0,
     unit = "sp", -- scaled point
     isReserved = false,
-    fncheck = function (self, ay, _) --> boolean, err
+    fncheck = function (_self, ay, _) --> boolean, err
         if ay >= 0.0 and ay <= 1.0 then return true, nil end
         return false, "[OutOfRange] 'ay' out of [0, 1] interval"
     end,
 }
 
--- Barcode.bbox_to_quietzone -- under assessment
+-- debug only purpose
+-- enable/disable bounding box drawing of symbols
+Barcode.debug_bbox = "none"
+pardef.debug_bbox = {
+    default    = "none",
+    isReserved = false,
+    enum = {
+        none = true, -- do nothing
+        symb = true, -- draw bbox of the symbol
+        qz = true, -- draw a bbox at quietzone border
+        qzsymb = true, -- draw quietzone and symbol bboxes
+    },
+    fncheck    = function (self, e, _) --> boolean, err
+        if type(e) ~= "string" then return false, "[TypeError] not a string" end
+        local keys = self.enum
+        if keys[e] == true then
+            return true, nil
+        else
+            return false, "[Err] enumeration value '"..e.."' not found"
+        end
+    end,
+}
 
 -- Barcode methods
 
@@ -221,7 +239,7 @@
     -- argument checking
     local family, variant, enc_name, err = parse_treename(treename)
     if err then
-        return err
+        return nil, err
     end
     local av_enc = self._available_enc
     local mod_path = av_enc[family]
@@ -254,7 +272,7 @@
     else
         return nil, "[ArgErr] provided 'opt' is not a table"
     end
-    local enc = {} -- the new encoder
+    local enc = {_classname = "Encoder"} -- the new encoder
     enc.__index = enc
     enc._variant = variant
     setmetatable(enc, {
@@ -292,13 +310,14 @@
         end
     end
     if enc._config then -- this must be called after the parameter definition
-        enc:_config()
+        local ok, e = enc:_config()
+        if not ok then return nil, e end
     end
     return enc, nil
 end
 
 -- retrive an encoder object already created
--- 'trename' is the special identifier of the encoder
+-- 'treename' is the special identifier of the encoder
 function Barcode:enc_by_name(treename) --> <encoder object>, <err>
     -- argument checking
     local _family, _variant, _enc_name, err = parse_treename(treename)
@@ -316,25 +335,36 @@
 -- base methods common to all the encoders
 
 -- for numeric only simbology
-function Barcode:_check_char(c) --> elem, err
+-- elem_code : encoded char
+-- elem_text : human readable char
+-- err : error description
+function Barcode:_check_char(c, parse_state) --> elem_code, elem_text, err
     if type(c) ~= "string" or #c ~= 1 then
-        return nil, "[InternalErr] invalid char"
+        return nil, nil, "[InternalErr] invalid char"
     end
+    local process_char = self._process_char
+    if process_char then
+        return process_char(self, c, parse_state)
+    end
     local n = string.byte(c) - 48
     if n < 0 or n > 9 then
-        return nil, "[ArgErr] found a not digit char"
+        return nil, nil, "[ArgErr] found a not digit char"
     end
-    return n, nil
+    return n, nil, nil
 end
 --
-function Barcode:_check_digit(n) --> elem, err
+function Barcode:_check_digit(n, parse_state) --> elem_code, elem_text, err
     if type(n) ~= "number" then
-        return nil, "[ArgErr] not a number"
+        return nil, nil, "[ArgErr: n] not a number"
     end
+    local process_digit = self._process_digit
+    if process_digit then
+        return process_digit(self, n, parse_state)
+    end
     if n < 0 or n > 9 then
-        return nil, "[ArgErr] not a digit"
+        return nil, nil, "[ArgErr: n] not a digit"
     end
-    return n, nil
+    return n, nil, nil
 end
 
 -- not empty string --> Barcode object
@@ -345,22 +375,33 @@
     if #symb == 0 then
         return nil, "[ArgErr] 'symb' is an empty string"
     end
-    local chars = {}
-    local len = 0
-    local parse_state = {}
+    local chars_code = {}
+    local chars_text
+    local parse_state
+    if self._init_parse_state then
+        parse_state = self:_init_parse_state()
+    else
+        parse_state = {}
+    end
     for c in string.gmatch(symb, ".") do
-        local elem, err = self:_check_char(c, parse_state)
+        local elem_code, elem_text, err = self:_check_char(c, parse_state)
         if err then
             return nil, err
-        elseif elem then
-            chars[#chars+1] = elem
-            len = len + 1
+        else
+            if elem_code then
+                chars_code[#chars_code + 1] = elem_code
+            end
+            if elem_text then
+                chars_text = chars_text or {}
+                chars_text[#chars_text + 1] = elem_text
+            end
         end
     end
     -- build the barcode object
     local o = {
-        _code_data = chars, -- array of chars
-        _code_len = len, -- symbol lenght
+        _classname = "BarcodeSymbol",
+        _code_data = chars_code, -- array of chars
+        _code_text = chars_text,
     }
     setmetatable(o, self)
     if opt ~= nil then
@@ -394,42 +435,58 @@
     if opt ~= nil and type(opt) ~= "table" then
         return nil, "[ArgErr] 'opt' is not a table"
     end
-    local digits = {}
-    local parse_state = {}
-    local i = 0
+    local digits_code = {}
+    local digits_text
+    local parse_state
+    if self._init_parse_state then
+        parse_state = self:_init_parse_state()
+    else
+        parse_state = {}
+    end
     if n == 0 then
-        local elem, err = self:_check_digit(0, parse_state)
+        local elem_code, elem_text, err = self:_check_digit(0, parse_state)
         if err then
             return nil, err
         end
-        if elem then
-            digits[1] = elem
-            i = 1
+        if elem_code then
+            digits_code[1] = elem_code
         end
+        if elem_text then
+            digits_text = {elem_text}
+        end
     else
         while n > 0 do
             local d = n % 10
-            local elem, err = self:_check_digit(d, parse_state)
+            local elem_code, elem_text, err = self:_check_digit(d, parse_state)
             if err then
                 return nil, err
             end
-            if elem then
-                i = i + 1
-                digits[i] = elem
+            if elem_code then
+                digits_code[#digits_code + 1] = elem_code
             end
+            if elem_text then
+                digits_text = digits_text or {}
+                digits_text[#digits_text + 1] = elem_text
+            end
             n = (n - d) / 10
         end
-        for k = 1, i/2  do -- reverse the array
-            local d = digits[k]
-            local h = i - k + 1
-            digits[k] = digits[h]
-            digits[h] = d
+        local rev_array = function (a)
+            local len = #a
+            for k = 1, len/2 do -- reverse the array
+                local h = len - k + 1
+                a[k], a[h] = a[h], a[k]
+            end
         end
+        rev_array(digits_code)
+        if digits_text then
+            rev_array(digits_text)
+        end
     end
     -- build the barcode object
     local o = {
-        _code_data = digits, -- array of digits
-        _code_len = i, -- symbol lenght
+        _classname = "BarcodeSymbol",
+        _code_data = digits_code, -- array of digits
+        _code_text = digits_text, -- array of human readable information
     }
     setmetatable(o, self)
     if opt ~= nil then
@@ -449,6 +506,26 @@
     return o, nil
 end
 
+-- recursive general Barcode costructor
+function Barcode:new(code) --> object, err
+    local t = type(code)
+    if t == "string" then
+        return self:from_string(code)
+    elseif t == "number" then
+        return self:from_uint(code)
+    elseif t == "table" then
+        local res = {}
+        for _, c in ipairs(code) do
+            local b, err = self:new(c)
+            if err then return nil, err end
+            res[#res + 1] = b
+        end
+        return res, nil
+    else
+        return nil, "[ArgErr] unsuitable type '"..t.."' for the input code"
+    end
+end
+
 -- check a parameter set
 -- this method check also reserved parameter
 -- argments: {k=v, ...}, "default" | "current"
@@ -532,13 +609,13 @@
         description = self._DESCRIPTION,
         param       = {},
     }
-    local tpar   = info.param
+    local tpar = info.param
     for _, pdef in self:param_ord_iter() do
-        local id   = pdef.pname
+        local id = pdef.pname
         local def = pdef.pdef
         tpar[#tpar + 1] = {
             name       = id,
-            descr      = nil, -- TODO:
+            descr      = def.descr,
             value      = self[id],
             isReserved = def.isReserved,
             unit       = def.unit,
@@ -547,15 +624,35 @@
     return info
 end
 
--- return the code being represented as a string
--- or nil if the method is called from Barcode abstract class
-function Barcode:get_code() --> string|nil
-    local code = self._code_data
-    if code then
-        return table.concat(code)
+-- return internal code representation
+function Barcode:get_code() --> array
+    if self._classname == "BarcodeSymbol" then
+        local code = self._code_data
+        local res = {}
+        for _, c in ipairs(code) do
+            res[#res + 1] = c
+        end
+        return res
+    else
+         error("[Err: OOP] 'BarcodeSymbol' only method")
     end
 end
 
+-- human readable interpretation hri or nil
+function Barcode:get_hri() --> array|nil
+    if self._classname == "BarcodeSymbol" then
+        local code = self._code_text
+        if code == nil then return nil end
+        local res = {}
+        for _, c in ipairs(code) do
+            res[#res + 1] = c
+        end
+        return res
+    else
+         error("[Err: OOP] 'BarcodeSymbol' only method")
+    end
+end
+
 -- make accessible by name parameter values
 -- id: parameter identifier
 function Barcode:get_param(id) --> value, err
@@ -562,8 +659,8 @@
     if type(id) ~= "string" then
         return nil, "[ArgErr] 'id' must be a string"
     end
-    local pardef = self._par_def
-    if not pardef[id] then
+    local par_def = self._par_def
+    if not par_def[id] then
         return nil, "[Err] Parameter '"..id.."' doesn't exist"
     end
     local res = assert(self[id], "[InternalErr] parameter value unreachable")
@@ -622,6 +719,76 @@
     return true, nil
 end
 
+-- canvas is a gaCanvas object
+-- tx, ty is an optional point to place symbol local origin on the canvas plane
+function Barcode:draw(canvas, tx, ty) --> canvas, err
+    local nclass = self._classname
+    if nclass == "Barcode" then
+        error("[ErrOOP:Barcode] method 'draw' must be called only on a Symbol object")
+    end
+    if nclass == "Encoder" then
+        error("[ErrOOP:Encoder] method 'draw' must be called only on a Symbol object")
+    end
+    assert(nclass == "BarcodeSymbol")
+    if canvas._classname ~= "gaCanvas" then
+        return nil, "[ErrOOP:canvas] object 'gaCanvas' expected"
+    end
+    local ga_fn = assert(
+        self._append_ga,
+        "[InternalErr] unimplemented '_append_ga' method"
+    )
+    local bb_info = ga_fn(self, canvas, tx or 0, ty or 0)
+    local dbg_bbox = self.debug_bbox
+    if dbg_bbox == "none" then
+        -- do nothing
+    else
+        -- dashed style: phase = 3bp, dash pattern = 6bp 3bp
+        local bp = canvas.bp
+        local W = bp/10 -- 0.1bp
+        local w = W/2
+        assert(canvas:encode_linewidth(W))
+        assert(canvas:encode_dash_pattern(3*bp, 6*bp, 3*bp))
+        local x1, y1, x2, y2 = bb_info[1], bb_info[2], bb_info[3], bb_info[4]
+        if dbg_bbox == "symb" then
+            assert(canvas:encode_rect(x1 + w, y1 + w, x2 - w, y2 - w))
+        elseif dbg_bbox == "qz" then
+            local q1, q2, q3, q4 = bb_info[5], bb_info[6], bb_info[7], bb_info[8]
+            x1 = x1 - (q1 or 0) + w
+            y1 = y1 - (q2 or 0) + w
+            x2 = x2 + (q3 or 0) - w
+            y2 = y2 + (q4 or 0) - w
+            assert(canvas:encode_rect(x1, y1, x2, y2))
+        elseif dbg_bbox == "qzsymb" then
+            local q1, q2, q3, q4 = bb_info[5], bb_info[6], bb_info[7], bb_info[8]
+            x1 = x1 + w
+            y1 = y1 + w
+            x2 = x2 - w
+            y2 = y2 - w
+            if q1 then
+                assert(canvas:encode_vline(y1, y2, x1))
+                x1 = x1 - q1
+            end
+            if q3 then
+                assert(canvas:encode_vline(y1, y2, x2))
+                x2 = x2 + q3
+            end 
+            if q2 then
+                assert(canvas:encode_hline(x1, x2, y1))
+                y1 = y1 - q2
+            end
+            if q4 then
+                assert(canvas:encode_hline(x1, x2, y2))
+                y2 = y2 + q4
+            end
+            assert(canvas:encode_rect(x1, y1, x2, y2))
+        else
+            error("[InternalErr:debug_bbox] unrecognized enum value")
+        end
+        assert(canvas:encode_reset_pattern())
+    end
+    return canvas
+end
+
 return Barcode
 
 --

Modified: trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-code128.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-code128.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-code128.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,11 +1,11 @@
 -- Code128 barcode generator module
--- Copyright (C) 2020 Roberto Giacomelli
+-- Copyright (C) 2019-2022 Roberto Giacomelli
 --
 -- All dimension must be in scaled point (sp)
 -- every fields that starts with an undercore sign are intended as private
 
 local Code128 = {
-    _VERSION     = "code128 v0.0.5",
+    _VERSION     = "code128 v0.0.6",
     _NAME        = "Code128",
     _DESCRIPTION = "Code128 barcode encoder",
 }
@@ -23,7 +23,7 @@
     111242, 121142, 121241, 114212, 124112, 124211, 411212, 421112, 421211,
     212141, 214121, 412121, 111143, 111341, 131141, 114113, 114311, 411113,
     411311, 113141, 114131, 311141, 411131, 211412, 211214, 211232,
-    2331112, -- this is the stop char at index 106
+    2331112, -- the last number is the stop char at index 106
 }
 
 Code128._codeset = {
@@ -96,197 +96,259 @@
     local mod = self.xdim
     local sc = self._codeset.stopChar -- build the stop char
     local n = self._int_def_bar[sc]
-    local Vbar = self._libgeo.Vbar -- Vbar class
-    self._vbar = {}
-    local b = self._vbar
-    b[sc] = Vbar:from_int(n, mod, true)
+    local repo = self._libgeo.Archive:new()
+    self._vbar_archive = repo
+    local Vbar = self._libgeo.Vbar
+    repo:insert(Vbar:from_int(n, mod, true), 106)
     return true, nil
 end
 
 -- utility functions
 
--- the number of consecutive digits from the index 'i' in the code array
-local function count_digits_from(arr, i)
-    local start = i
-    local dim = #arr 
-    while i <= dim and (arr[i] > 47 and arr[i] < 58) do
-        i = i + 1
-    end
-    return i - start
-end
-
--- evaluate the check digit of the data representation
+-- evaluate the check digit of encoded data
 local function check_digit(code)
     local sum = code[1] -- this is the start character
     for i = 2, #code do
         sum = sum + code[i]*(i-1)
     end
-    return sum % 103
+    code[#code + 1] = sum % 103
 end
 
--- return a pair of boolean the first one is true
--- if a control char and a lower case char occurs in the data
--- and the second one is true if the control char occurs before
--- the lower case char
-local function ctrl_or_lowercase(pos, data) --> boolean, boolean|nil
-    local len = #data
-    local ctrl_occur, lower_occur = false, false
-    for i = pos, len do
-        local c = data[i]
-        if (not ctrl_occur) and (c >= 0 and c < 32) then
-            -- [0,31] control chars
-            if lower_occur then
-                return true, false -- lowercase char < ctrl char
+local function isdigit(char) --> true/false
+    assert(char)
+    return (char > 47) and (char < 58)
+end
+
+local function iscontrol(char) --> true/false
+    assert(char)
+    -- [0,31] control chars interval
+    return char < 32
+end
+
+local function islower(char)
+    assert(char)
+    -- [96, 127] lower case chars
+    return (char > 95) and (char < 128)
+end
+
+-- count digits
+local function digits_group(data, len) --> counting digits
+    local res = {}
+    local last = false
+    for i = len, 1, -1 do
+        local digit = isdigit(data[i])
+        if last then
+            if digit then
+                res[i] = res[i+1] + 1
             else
-                ctrl_occur = true
+                res[i] = 0
+                last = false
             end
-        elseif (not lower_occur) and (c > 95 and c < 128) then
-            -- [96, 127] lower case chars
-            if ctrl_occur then
-                return true, true -- ctrl char < lowercase char
+        else
+            if digit then
+                res[i] = 1
+                last = true
             else
-                lower_occur = true
+                res[i] = 0
             end
         end
     end
-    return false -- no such data
+    return res
 end
 
--- encode the provided char against a codeset
--- in the future this function will consider FN data
-local function encode_char(t, codesetAorB, char_code, codesetA)
-    local code
-    if codesetAorB == codesetA then -- codesetA
-        if char_code < 32 then
-            code = char_code + 64
-        elseif char_code > 31 and char_code < 96 then
-            code = char_code - 32
-        else
-            error("Not implemented or wrong code")
+-- find the first char in the codeset that adhere
+-- with the function argument 'filter'
+local function indexof_char_by(filter, arr, counter) --> index or nil
+    counter = counter or 1
+    local char = arr[counter]
+    while char do
+        if filter(char) then
+            return counter
         end
-    else -- codesetB
-        if char_code > 31 and char_code < 128 then
-            code = char_code - 32
-        else
-            error("Not implemented or wrong code")
-        end
+        counter = counter + 1
+        char = arr[counter]
     end
-    t[#t + 1] = code
 end
 
--- encode the message in a sequence of Code128 symbol minimizing its lenght
-local function encode128(arr, codeset, switch) --> data, err :TODO:
-    local res = {} -- the result array (the check character will be appended)
-    -- find the Start Character A, B, or C
-    local cur_codeset
-    local ndigit = count_digits_from(arr, 1)
-    local len = #arr
-    --local no_ctrl_lower_char
-    if (ndigit == 2 and len == 2) or ndigit > 3 then -- start char code C
-        cur_codeset = codeset.C
+-- determine the Start character
+local function start_codeset_char(codeset, arr, len)
+    assert(len>0)
+    local ctrl = indexof_char_by(iscontrol, arr)
+    local lowc = indexof_char_by(islower, arr)
+    local t_digits = digits_group(arr, len)
+    local first_digits = t_digits[1]
+    -- case 1
+    if (len == 2) and (first_digits == 2) then
+        return lowc, ctrl, codeset.C, t_digits
+    end
+    -- case 2
+    if first_digits >= 4 then
+        return lowc, ctrl, codeset.C, t_digits
+    end
+    -- case 3
+    local cs = codeset.B
+    if (ctrl and lowc) and (ctrl < lowc) then
+        cs = codeset.A
+    end
+    -- case 4
+    return lowc, ctrl, cs, t_digits
+end
+
+-- codeset A char
+local function encode_char_A(res, char)
+    local code
+    if char < 32 then
+        code = char + 64
+    elseif char > 31 and char < 96 then
+        code = char - 32
     else
-        local ok, ctrl_first = ctrl_or_lowercase(1, arr)
-        if ok and ctrl_first then
-            cur_codeset = codeset.A
-        else
-            cur_codeset = codeset.B
-        end
+        error("[InternalErr] Not implemented or wrong code" )
     end
-    res[#res + 1] = cur_codeset
-    local pos = 1 -- symbol's index to encode
-    while pos <= len do
-        if cur_codeset == codeset.C then
-            if arr[pos] < 48 or arr[pos] > 57 then -- not numeric char
-                local ok, ctrl_first = ctrl_or_lowercase(pos, arr)
-                if ok and ctrl_first then
-                    cur_codeset = codeset.A
+    res[#res + 1] = code
+end
+-- codeset B char
+local function encode_char_B(res, char)
+    local code
+    if char > 31 and char < 128 then
+        code = char - 32
+    else
+        error("[InternalErr] Not implemented or wrong code")
+    end
+    res[#res + 1] = code
+end
+
+-- every function encodes a group of chars
+-- A = 103, -- Start char for Codeset A
+-- B = 104, -- Start char for Codeset B
+-- C = 105, -- Start char for Codeset C
+local encode_codeset = {
+    -- A
+    [103] = function (codeset, res, data, index, t_digits, i_low, _ctrl)
+        assert(t_digits[index] < 4, "[InternalErr] in codeset A digits must be less than 4")
+        while data[index] do
+            local char = data[index]
+            if i_low and islower(char) then -- ops a lower case char
+                local next = data[index + 1]
+                local next_next = data[index + 2]
+                if next and next_next then
+                    -- case 5a
+                    if iscontrol(char) and islower(next_next) then
+                        res[#res+1] = codeset.shift
+                        encode_char_B(res, char)
+                        index = index + 1
+                    end
                 else
-                    cur_codeset = codeset.B
+                    -- case 5b
+                    return codeset.B, index
                 end
-                res[#res + 1] = switch[codeset.C][cur_codeset]
             else
-                local imax = pos + 2*math.floor(ndigit/2) - 1
-                for idx = pos, imax, 2 do
-                    res[#res + 1] = (arr[idx] - 48)*10 + arr[idx+1] - 48
-                end
-                pos = pos + imax
-                ndigit = ndigit - imax
-                if ndigit == 1 then
-                    -- cur_codeset setup
-                    local ok, ctrl_first = ctrl_or_lowercase(pos + 1, arr)
-                    if ok and ctrl_first then
-                        cur_codeset = codeset.A
-                    else
-                        cur_codeset = codeset.B
+                local digits = t_digits[index]
+                if digits > 3 then -- go to codeset C
+                    if (digits % 2) == 1 then -- odd number of a group of digits
+                        encode_char_A(res, char)
+                        digits = digits - 1
+                        index = index + 1
                     end
-                    res[#res + 1] = switch[codeset.C][cur_codeset]
+                    return codeset.C, index
                 end
+                encode_char_A(res, char)
+                index = index + 1
             end
-        else --- current codeset is A or B
-            if ndigit > 3 then
-                if ndigit % 2 > 1 then -- odd number of digits
-                    encode_char(res, cur_codeset, arr[pos], codeset.A)
-                    pos = pos + 1
-                    ndigit = ndigit - 1
+        end
+        return nil, index
+    end,
+    -- B
+    [104] = function (codeset, res, data, index, t_digits, _low, i_ctrl)
+        assert(t_digits[index] < 4, "[InternalErr] in codeset B digits must be less than 4")
+        while data[index] do
+            local char = data[index]
+            if i_ctrl and iscontrol(char) then -- ops a control char
+                local next = data[index + 1]
+                local next_next = data[index + 2]
+                if next and next_next then
+                    -- case 4a
+                    if islower(next) and iscontrol(next_next) then
+                        res[#res+1] = codeset.shift
+                        encode_char_A(res, char)
+                        index = index + 1
+                    end
+                else
+                    -- case 4b
+                    return codeset.A, index
                 end
-                res[#res + 1] = switch[cur_codeset][codeset.C]
-                cur_codeset = codeset.C
-            elseif (cur_codeset == codeset.B) and
-                (arr[pos] >= 0 and arr[pos] < 32) then -- ops a control char
-                local ok, ctrl_first = ctrl_or_lowercase(pos + 1, arr)
-                if ok and (not ctrl_first) then -- shift to codeset A
-                    res[#res + 1] = codeset.shift
-                    encode_char(res, codeset.A, arr[pos], codeset.A)
-                    pos = pos + 1
-                    ndigit = count_digits_from(pos, arr)
-                else -- switch to code set A
-                    res[#res + 1] = switch[cur_codeset][codeset.A]
-                    cur_codeset = codeset.A
+            else
+                local digits = t_digits[index]
+                if digits > 3 then -- go to codeset C
+                    if (digits % 2) == 1 then -- odd number of a group of digits
+                        encode_char_B(res, char)
+                        digits = digits - 1
+                        index = index + 1
+                    end
+                    return codeset.C, index
                 end
-            elseif (cur_codeset == codeset.A) and
-                (arr[pos] > 95 and arr[pos] < 128) then -- ops a lower case char
-                local ok, ctrl_first = ctrl_or_lowercase(pos+1, arr)
-                if ok and ctrl_first then -- shift to codeset B
-                    res[#res + 1] = codeset.shift
-                    encode_char(res, codeset.B, arr[pos], codeset.A)
-                    pos = pos + 1
-                    ndigit = count_digits_from(arr, pos)
-                else -- switch to code set B
-                    res[#res + 1] = switch[cur_codeset][codeset.B]
-                    cur_codeset = codeset.B
-                end
-            else
-                -- insert char
-                encode_char(res, cur_codeset, arr[pos], codeset.A)
-                pos = pos + 1
-                ndigit = count_digits_from(arr, pos)
+                encode_char_B(res, char)
+                index = index + 1
             end
         end
+        return nil, index
+    end,
+    -- C
+    [105] = function (codeset, res, data, index, t_digits, i_low, i_ctrl)
+        local digits = t_digits[index]
+        assert(digits > 1, "[InternalErr] at least a pair of digit is required")
+        while digits > 1 do
+            local d1, d2 = data[index], data[index + 1]
+            res[#res + 1] = (d1 - 48)*10 + d2 - 48
+            digits = digits - 2
+            index = index + 2
+        end
+        local res_codeset
+        if i_ctrl and i_low then
+            local ctrl = indexof_char_by(iscontrol, data, index)
+            local low = indexof_char_by(islower, data, index)
+            if low and (ctrl < low) then
+                res_codeset = codeset.A
+            end
+        else
+            res_codeset = codeset.B
+        end
+        return res_codeset, index
+    end,
+}
+
+-- encode the message in a sequence of Code128 symbol minimizing the symbol width
+local function encode128(arr, codeset, switch) --> data, err
+    local len = #arr
+    local i_low, i_ctrl, cur_codeset, t_digits = start_codeset_char(codeset, arr, len)
+    local res = {cur_codeset} -- the result array (the check character will be appended later)
+    local switch_codeset
+    local cur_index = 1
+    while cur_index <= len do
+        if switch_codeset then
+            res[#res+1] = switch[cur_codeset][switch_codeset]
+            cur_codeset = switch_codeset
+        end
+        local fn = assert(encode_codeset[cur_codeset], "[InternalErr] cur_codeset is "..(cur_codeset or "nil"))
+        switch_codeset, cur_index = fn(codeset, res, arr, cur_index, t_digits, i_low, i_ctrl)
     end
-    res[#res + 1] = check_digit(res)
-    res[#res + 1] = codeset.stopChar
-    return res
+    check_digit(res)
+    return res, nil
 end
 
 -- Code 128 internal functions used by Barcode costructors
 
-function Code128:_check_char(c) --> elem, err
-    if type(c) ~= "string" or #c ~= 1 then
-        return nil, "[InternalErr] invalid char"
-    end
+function Code128:_process_char(c) --> char_code, char_text, err
     local b = string.byte(c)
     if b > 127 then
         local fmt = "[unimplemented] the '%d' is an ASCII extented char"
         return nil, string.format(fmt, c)
     end
-    return b, nil
+    return b, c, nil
 end
 
-function Code128:_check_digit(n) --> elem, err
-    if type(n) ~= "number" then
-        return nil, "[InternalErr] invalid digit"
-    end
-    return n + 48, nil
+function Code128:_process_digit(n) --> digit_code, char_text, err
+    local res = n + 48
+    return res, string.char(res), nil
 end
 
 function Code128:_finalize() --> ok, err
@@ -293,17 +355,17 @@
     local chr = assert(self._code_data, "[InternalErr] '_code_data' field is nil")
     local data, err = encode128(chr, self._codeset, self._switch)
     if err then return false, err end
-    -- load dynamically required Vbar objects
-    local vbar = self._vbar
-    local oVbar = self._libgeo.Vbar
+    self._enc_data = data
+    -- dynamically load the required Vbar objects
+    local Repo = self._vbar_archive
+    local Vbar = self._libgeo.Vbar
     for _, c in ipairs(data) do
-        if not vbar[c] then
+        if not Repo:contains_key(c) then
             local n = self._int_def_bar[c]
             local mod = self.xdim
-            vbar[c] = oVbar:from_int(n, mod, true)
+            assert(Repo:insert(Vbar:from_int(n, mod, true), c))
         end
     end
-    self._enc_data = data
     return true, nil
 end
 
@@ -310,34 +372,32 @@
 -- Drawing into the provided channel the geometrical barcode data
 -- tx, ty is the optional translator vector
 -- the function return the canvas reference to allow call chaining
-function Code128:append_ga(canvas, tx, ty) --> canvas
+function Code128:_append_ga(canvas, tx, ty) --> bbox
+    local data = self._enc_data
+    local Repo = self._vbar_archive
+    local queue = self._libgeo.Vbar_queue:new()
+    for _, c in ipairs(data) do
+        queue = queue + Repo:get(c)
+    end
+    local stop = self._codeset.stopChar
+    queue = queue + Repo:get(stop)
     local xdim, h = self.xdim, self.ydim
-    local sw = 11*xdim -- the width of a symbol
-    local data = self._enc_data
-    local w = #data * sw + 2 * xdim -- total symbol width
+    local ns = #data + 1
+    local w = (11*ns + 2) * xdim -- total symbol width
     local ax, ay = self.ax, self.ay
-    local x0 = (tx or 0) - ax * w
-    local y0 = (ty or 0) - ay * h
+    local x0 = tx - ax * w
+    local y0 = ty - ay * h
     local x1 = x0 + w
     local y1 = y0 + h
-    local xpos = x0
     -- drawing the symbol
-    local err
-    err = canvas:start_bbox_group()
-    assert(not err, err)
-    for _, c in ipairs(data) do
-        local vb = self._vbar[c]
-        err = canvas:encode_Vbar(vb, xpos, y0, y1)
-        assert(not err, err)
-        xpos = xpos + sw
-    end
+    assert(canvas:encode_disable_bbox())
+    assert(canvas:encode_vbar_queue(queue, x0, y0, y1))
     -- bounding box setting
     local qz = self.quietzone_factor * xdim
     -- { xmin, ymin, xmax, ymax }
-    err = canvas:stop_bbox_group(x0 - qz, y0, x1 + qz, y1)
-    assert(not err, err)
-    return canvas
+    assert(canvas:encode_set_bbox(x0 - qz, y0, x1 + qz, y1))
+    assert(canvas:encode_enable_bbox())
+    return {x0, y0, x1, y1, qz, nil, qz, nil,}
 end
 
 return Code128
---
\ No newline at end of file

Modified: trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-code39.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-code39.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-code39.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,31 +1,27 @@
 -- Code39 barcode encoder implementation
--- Copyright (C) 2020 Roberto Giacomelli
+-- Copyright (C) 2019-2022 Roberto Giacomelli
 --
 -- All dimensions must be in scaled point (sp)
--- every fields that starts with an undercore sign are intended as private
+-- every field that starts with an underscore sign are intended to be private
 
 local Code39 = {
-    _VERSION     = "code39 v0.0.5",
+    _VERSION     = "code39 v0.0.6",
     _NAME        = "Code39",
     _DESCRIPTION = "Code39 barcode encoder",
 }
 
 Code39._symb_def = {-- symbol definition
-    ["0"] = 112122111, ["1"] = 211112112, ["2"] = 211112211,
-    ["3"] = 111112212, ["4"] = 211122111, ["5"] = 111122112,
-    ["6"] = 111122211, ["7"] = 212112111, ["8"] = 112112112,
-    ["9"] = 112112211, ["A"] = 211211112, ["B"] = 211211211,
-    ["C"] = 111211212, ["D"] = 211221111, ["E"] = 111221112,
-    ["F"] = 111221211, ["G"] = 212211111, ["H"] = 112211112,
-    ["I"] = 112211211, ["J"] = 112221111, ["K"] = 221111112,
-    ["L"] = 221111211, ["M"] = 121111212, ["N"] = 221121111,
-    ["O"] = 121121112, ["P"] = 121121211, ["Q"] = 222111111,
-    ["R"] = 122111112, ["S"] = 122111211, ["T"] = 122121111,
-    ["U"] = 211111122, ["V"] = 211111221, ["W"] = 111111222,
-    ["X"] = 211121121, ["Y"] = 111121122, ["Z"] = 111121221,
-    ["-"] = 212111121, ["."] = 112111122, [" "] = 112111221,
-    ["$"] = 111212121, ["/"] = 121112121, ["+"] = 121211121,
-    ["%"] = 121212111,
+    ["0"] = 112122111, ["1"] = 211112112, ["2"] = 211112211, ["3"] = 111112212,
+    ["4"] = 211122111, ["5"] = 111122112, ["6"] = 111122211, ["7"] = 212112111,
+    ["8"] = 112112112, ["9"] = 112112211, ["A"] = 211211112, ["B"] = 211211211,
+    ["C"] = 111211212, ["D"] = 211221111, ["E"] = 111221112, ["F"] = 111221211,
+    ["G"] = 212211111, ["H"] = 112211112, ["I"] = 112211211, ["J"] = 112221111,
+    ["K"] = 221111112, ["L"] = 221111211, ["M"] = 121111212, ["N"] = 221121111,
+    ["O"] = 121121112, ["P"] = 121121211, ["Q"] = 222111111, ["R"] = 122111112,
+    ["S"] = 122111211, ["T"] = 122121111, ["U"] = 211111122, ["V"] = 211111221,
+    ["W"] = 111111222, ["X"] = 211121121, ["Y"] = 111121122, ["Z"] = 111121221,
+    ["-"] = 212111121, ["."] = 112111122, [" "] = 112111221, ["$"] = 111212121,
+    ["/"] = 121112121, ["+"] = 121211121, ["%"] = 121212111,
 }
 Code39._star_def  = 112121121 -- '*' start/stop character
 
@@ -54,7 +50,7 @@
     -- with label or form design.
     -- The module width (width of narrow element) should be at least 7.5 mils
     -- or 0.1905mm (a mil is 1/1000 inch).
-    default    = 7.5 * 0.0254 * 186467, -- 7.5 mils (sp) unit misure,
+    default    = 10 * 0.0254 * 186467, -- 7.5 mils (sp) unit misure,
     unit       = "sp", -- scaled point
     isReserved = true,
     fncheck    = function (self, mod, _) --> boolean, err
@@ -230,98 +226,83 @@
 
 -- configuration function
 function Code39:_config() --> ok, err
+    local Vbar = self._libgeo.Vbar -- Vbar class
+    local Archive = self._libgeo.Archive -- Archive class
+    local c39_vbars = Archive:new()
+    self._vbar_archive = c39_vbars
     -- build Vbar object for the start/stop symbol
     local mod, ratio = self.module, self.ratio
     local n_star = self._star_def
-    local Vbar = self._libgeo.Vbar -- Vbar class
-    self._vbar = {['*'] = Vbar:from_int_revpair(n_star, mod, mod*ratio)}
+    local star = Vbar:from_int_revpair(n_star, mod, mod*ratio)
+    c39_vbars:insert(star, "*")
     return true, nil
 end
 
+function Code39:_ensure_symbol(c)
+    local Archive = self._vbar_archive
+    if not Archive:contains_key(c) then
+        local Vbar = self._libgeo.Vbar
+        local mod, ratio = self.module, self.ratio
+        local symb_def = self._symb_def
+        local n_def = symb_def[c]
+        local v = Vbar:from_int_revpair(n_def, mod, mod*ratio)
+        Archive:insert(v, c)
+    end
+end
+
 -- overriding Barcode method
-function Code39:_check_char(c) --> elem, err
-    if type(c) ~= "string" or #c ~= 1 then
-        return nil, "[ArgErr] invalid char"
-    end
+function Code39:_process_char(c) --> elem_code, elem_text, err
     local symb_def = self._symb_def
-    local n = symb_def[c]
-    if not n then
+    if not symb_def[c] then
         local fmt = "[ArgErr] '%s' is not a valid Code 39 symbol"
-        return nil, string.format(fmt, c)
+        return nil, nil, string.format(fmt, c)
     end
-    return c, nil
+    self:_ensure_symbol(c)
+    return c, nil, nil
 end
 
 -- overriding Barcode method
-function Code39:_check_digit(n) --> elem, err
-    if type(n) ~= "number" then
-        return nil, "[ArgErr] not a number"
-    end
-    if n < 0 or n > 9 then
-        return nil, "[ArgErr] not a digit"
-    end
-    return string.char(n + 48), nil
+function Code39:_process_digit(n) --> elem_code, elem_text, err
+    local c = string.char(n + 48)
+    self:_ensure_symbol(c)
+    return c, nil, nil
 end
 
-function Code39:_finalize() --> ok, err
-    local v = assert(self._code_data, "[InternalErr] '_code_data' field is nil")
-    local vbar = self._vbar
-    local g_Vbar = self._libgeo.Vbar
-    local mod, ratio = self.module, self.ratio
-    local symb_def = self._symb_def
-    for _, c in ipairs(v) do
-        if not vbar[c] then
-            local n1 = symb_def[c]
-            vbar[c] = g_Vbar:from_int_revpair(n1, mod, mod*ratio)
-        end
-    end
-    return true, nil
-end
-
 -- tx, ty is an optional translator vector
-function Code39:append_ga(canvas, tx, ty) --> canvas
-    local code       = self._code_data
-    local ns         = self._code_len -- number of chars inside the symbol
-    local mod        = self.module
-    local ratio      = self.ratio
-    local interspace = self.interspace
-    local h          = self.height
-    local xs         = mod*(6 + 3*ratio)
-    local xgap       = xs + interspace
-    local w          = xgap*(ns + 1) + xs -- (ns + 2)*xgap - interspace
-    local ax, ay     = self.ax, self.ay
-    local x0         = (tx or 0) - ax * w
-    local y0         = (ty or 0) - ay * h
-    local x1         = x0 + w
-    local y1         = y0 + h
-    local xpos       = x0
-    local err
-    err = canvas:start_bbox_group()
-    assert(not err, err)
-    local vbar = self._vbar
-    -- start/stop symbol
-    local term_vbar = vbar['*']
-    -- draw start symbol
-    err = canvas:encode_Vbar(term_vbar, xpos, y0, y1)
-    assert(not err, err)
-    for _, c in ipairs(code) do -- draw code symbols
-        xpos = xpos + xgap
-        local vb = vbar[c]
-        err = canvas:encode_Vbar(vb, xpos, y0, y1)
-        assert(not err, err)
+function Code39:_append_ga(canvas, tx, ty) --> x1, y1, x2, y2 -- bbox
+    local code = self._code_data
+    local ns = #code -- number of chars inside the symbol
+    local archive = self._vbar_archive
+    local q = assert(archive:get("*")) -- form the vbar queue, actually it is just a Vbar
+    local dx = self.interspace
+    for _, c in ipairs(code) do
+        q = q + dx + assert(archive:get(c))
     end
-    -- draw stop symbol
-    err = canvas:encode_Vbar(term_vbar, xpos + xgap, y0, y1)
-    assert(not err, err)
+    q = q + dx + assert(archive:get("*")) -- final stop char
+    assert(canvas:encode_disable_bbox())
+    -- draw the symbol
+    local ax, ay = self.ax, self.ay
+    local mod    = self.module
+    local ratio  = self.ratio
+    local xs     = mod*(6 + 3*ratio)
+    local xgap   = xs + dx
+    local h      = self.height
+    local w      = xgap*(ns + 1) + xs -- (ns + 2)*xgap - interspace
+    --
+    local x0     = tx - ax * w
+    local x1     = x0 + w
+    local y0     = ty - ay * h
+    local y1     = y0 + h
+    assert(canvas:encode_vbar_queue(q, x0, y0, y1))
     -- bounding box setting
     local qz = self.quietzone
-    err = canvas:stop_bbox_group(x0 - qz, y0, x1 + qz, y1)
-    assert(not err, err)
+    assert(canvas:encode_set_bbox(x0 - qz, y0, x1 + qz, y1))
     -- check height as the minimum of 15% of length
     -- TODO: message could warn the user
     -- if 0.15 * w > h then
         -- message("The height of the barcode is to small")
     -- end
+    assert(canvas:encode_enable_bbox())
     if self.text_enabled then -- human readable text
         local chars; if self.text_star then
             chars = {"*"}
@@ -356,8 +337,7 @@
                 xaxis = xaxis + xgap
             end
             xaxis = xaxis + xs/2
-            err = canvas:encode_Text_xspaced(txt, xaxis, xgap, ypos, tay)
-            assert(not err, err)
+            assert(canvas:encode_Text_xspaced(txt, xaxis, xgap, ypos, tay))
         else
             local xpos, tax
             if txt_hpos == "left" then
@@ -372,12 +352,10 @@
             else
                 error("[InternalErr] wrong option for text_pos")
             end
-            err = canvas:encode_Text(txt, xpos, ypos, tax, tay)
-            assert(not err, err)
+            assert(canvas:encode_Text(txt, xpos, ypos, tax, tay))
         end
     end
-    return canvas
+    return {x0, y0, x1, y1, qz, nil, qz, nil}
 end
 
 return Code39
---
\ No newline at end of file

Modified: trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-ean.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-ean.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-ean.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,10 +1,10 @@
 -- EAN family barcode generator
 --
--- Copyright (C) 2020 Roberto Giacomelli
+-- Copyright (C) 2019-2022 Roberto Giacomelli
 -- see LICENSE.txt file
 
 local EAN = {
-    _VERSION     = "ean v0.0.6",
+    _VERSION     = "ean v0.0.8",
     _NAME        = "ean",
     _DESCRIPTION = "EAN barcode encoder",
 }
@@ -75,6 +75,7 @@
     "text_enabled",
     "text_ygap_factor",
     "text_xgap_factor",
+    "text_guard_enabled",
 }
 EAN._par_def = {}
 local pardef = EAN._par_def
@@ -148,7 +149,7 @@
     end,
 }
 
--- enable/disable a text label upon the barcode symbol
+-- enable/disable human readble text
 pardef.text_enabled = { -- boolean type
     default    = true,
     isReserved = false,
@@ -187,6 +188,30 @@
     end,
 }
 
+pardef.text_guard_enabled = { -- boolean type
+    default    = false,
+    isReserved = false,
+    fncheck    = function (_self, flag, _) --> boolean, err
+        if type(flag) == "boolean" then
+            return true, nil
+        else
+            return false, "[TypeErr] not a boolean value for text_guard_enabled"
+        end
+    end,
+}
+
+EAN._par_def_8 = {} -- ean8 substitute parameters
+local pardef8 = EAN._par_def_8
+pardef8.quietzone_left_factor = pardef.quietzone_right_factor
+
+EAN._par_def_5 = {} -- ean5 add-on substitute parameters
+local pardef5 = EAN._par_def_5
+pardef5.quietzone_left_factor = pardef.quietzone_right_factor
+
+EAN._par_def_2 = {} -- ean2 add-on substitute parameters
+local pardef2 = EAN._par_def_2
+pardef2.quietzone_left_factor = pardef.quietzone_right_factor
+
 -- variant parameters
 EAN._par_variant_order = {
     ["13"]   = {}, -- EAN13
@@ -337,13 +362,13 @@
 -- utility for generic configuration of full symbol, add-on included
 -- n1 length of main symbol, 8 or 13
 -- n2 length of add-on symbol, 2 or 5
-local function config_full(ean, Vbar, mod, n1, n2)
+local function config_full(ean, n1, n2)
     local i1 = tostring(n1)
     local fn_1 = assert(ean._config_variant[i1])
-    fn_1(ean, Vbar, mod)
+    fn_1(ean)
     local i2 = tostring(n2)
     local fn_2 = assert(ean._config_variant[i2])
-    fn_2(ean, Vbar, mod)
+    fn_2(ean)
     ean._main_len = n1
     ean._addon_len = n2
     ean._is_last_checksum = true
@@ -350,88 +375,90 @@
 end
 
 local config_variant = {
-    ["13"] = function (ean13, Vbar, mod)
+    ["13"] = function (ean13)
         ean13._main_len = 13
         ean13._is_last_checksum = true
+        local Vbar = ean13._libgeo.Vbar -- Vbar class
+        local Vbar_archive = ean13._libgeo.Archive -- Archive class
+        local Codeset = Vbar_archive:new()
+        ean13._13_codeset_vbar = Codeset
+        local mod = ean13.mod
+        local stop  = ean13._stop
         local start = ean13._start
-        local stop  = ean13._stop
-        ean13._13_start_stop_vbar  = Vbar:from_int(start[1], mod, start[2])
-        ean13._13_ctrl_center_vbar = Vbar:from_int(stop[1], mod, stop[2])
-        ean13._13_codeset_vbar = {}
-        local tvbar = ean13._13_codeset_vbar
+        Codeset:insert(Vbar:from_int(start[1], mod, start[2]), "start_stop")
+        Codeset:insert(Vbar:from_int(stop[1], mod, stop[2]), "central")
         for i_cs, codetab in ipairs(ean13._symbol) do
-            tvbar[i_cs] = {}
-            local tv = tvbar[i_cs]
             local isbar = ean13._is_first_bar[i_cs]
             for i = 0, 9 do
-                tv[i] = Vbar:from_int(codetab[i], mod, isbar)
+                Codeset:insert(Vbar:from_int(codetab[i], mod, isbar), i_cs, i)
             end
         end
     end,
-    ["8"] = function (ean8, Vbar, mod)
+    ["8"] = function (ean8)
         ean8._main_len = 8
         ean8._is_last_checksum = true
+        local Vbar = ean8._libgeo.Vbar
+        local Vbar_archive = ean8._libgeo.Archive
         local start = ean8._start
         local stop  = ean8._stop
-        ean8._8_start_stop_vbar = Vbar:from_int(start[1], mod, start[2])
-        ean8._8_ctrl_center_vbar = Vbar:from_int(stop[1], mod, stop[2])
-        ean8._8_codeset_vbar = {}
-        local tvbar = ean8._8_codeset_vbar
+        local mod = ean8.mod
+        local Codeset = Vbar_archive:new()
+        ean8._8_codeset_vbar = Codeset
+        Codeset:insert(Vbar:from_int(start[1], mod, start[2]), "start_stop")
+        Codeset:insert(Vbar:from_int(stop[1], mod, stop[2]), "central")
         for k = 1, 3, 2 do -- only codeset A and C (k == 1, 3)
-            tvbar[k] = {}
             local codetab = ean8._symbol[k]
             local isbar = ean8._is_first_bar[k]
-            local tv = tvbar[k]
             for i = 0, 9 do
-                tv[i] = Vbar:from_int(codetab[i], mod, isbar)
+                Codeset:insert(Vbar:from_int(codetab[i], mod, isbar), k, i)
             end
         end
     end,
-    ["5"] = function (ean5, Vbar, mod) -- add-on EAN5
+    ["5"] = function (ean5) -- add-on EAN5
         ean5._main_len = 5
         ean5._is_last_checksum = false
-        ean5._5_start_vbar = Vbar:from_int(112, mod, true)
-        ean5._5_sep_vbar   = Vbar:from_int(11, mod, false)
-        ean5._5_codeset_vbar = {}
-        local tvbar = ean5._5_codeset_vbar
+        local mod = ean5.mod
+        local Vbar = ean5._libgeo.Vbar
+        local Vbar_archive = ean5._libgeo.Archive
+        local Codeset = Vbar_archive:new()
+        Codeset:insert(Vbar:from_int(112, mod, true), "start")
+        Codeset:insert(Vbar:from_int(11, mod, false), "sep")
+        ean5._5_codeset_vbar = Codeset
         local symbols = ean5._symbol
         for c = 1, 2 do
-            tvbar[c] = {}
-            local tcs = tvbar[c]
-            local sb = symbols[c]
             for i = 0, 9 do
-                tcs[i] = Vbar:from_int(sb[i], mod, false)
+                Codeset:insert(Vbar:from_int(symbols[c][i], mod, false), c, i)
             end
         end
     end,
-    ["2"] = function (ean2, Vbar, mod) -- add-on EAN2
+    ["2"] = function (ean2) -- add-on EAN2
         ean2._main_len = 2
         ean2._is_last_checksum = false
-        ean2._2_start_vbar = Vbar:from_int(112, mod, true)
-        ean2._2_sep_vbar   = Vbar:from_int(11, mod, false)
-        ean2._2_codeset_vbar = {}
-        local tvbar = ean2._2_codeset_vbar
+        local mod = ean2.mod
+        local Vbar = ean2._libgeo.Vbar
+        local Vbar_archive = ean2._libgeo.Archive
+        local Codeset = Vbar_archive:new()
+        ean2._2_codeset_vbar = Codeset
+        Codeset:insert(Vbar:from_int(112, mod, true), "start")
+        Codeset:insert(Vbar:from_int(11, mod, false), "sep")
         local symbols = ean2._symbol
         for c = 1, 2 do
-            tvbar[c] = {}
-            local tcs = tvbar[c]
-            local sb = symbols[c]
             for i = 0, 9 do
-                tcs[i] = Vbar:from_int(sb[i], mod, false)
+                Codeset:insert(Vbar:from_int(symbols[c][i], mod, false), c, i)
             end
         end
     end,
     ["13+5"] = function (ean, Vbar, mod) -- EAN13 with EAN5 add-on
-        config_full(ean, Vbar, mod, 13, 5)
+        config_full(ean, 13, 5)
     end,
     ["13+2"] = function(ean, Vbar, mod) -- EAN13 with EAN2 add-on
-        config_full(ean, Vbar, mod, 13, 2)
+        config_full(ean, 13, 2)
     end,
     ["8+5"]  = function(ean, Vbar, mod) -- EAN8 with EAN5 add-on
-        config_full(ean, Vbar, mod, 8, 5)
+        config_full(ean, 8, 5)
     end,
     ["8+2"]  = function(ean, Vbar, mod) -- EAN8 with EAN2 add-on
-        config_full(ean, Vbar, mod, 8, 2)
+        config_full(ean, 8, 2)
     end,
 }
 -- ISBN
@@ -491,58 +518,58 @@
     return sum % 11
 end
 
+local function isbn_parse_state() --> parse state
+    return {
+        is_space = false,
+        is_dash = false,
+        isbn_len = 0,
+    }
+end
+
 -- group char for readibility '-' or ' '
 -- char won't be inserted in the top isbn code
-local function isbn_check_char(_, c, parse_state) --> elem, err
-    if type(c) ~= "string" or #c ~= 1 then
-        return nil, "[InternalErr] invalid char"
-    end
-    if parse_state.isbncode == nil then parse_state.isbncode = {} end
-    local code = parse_state.isbncode
-    if parse_state.isspace == nil then parse_state.isspace = false end
-    if parse_state.isdash == nil then parse_state.isdash = false end
-    if parse_state.isbn_len == nil then parse_state.isbn_len = 0 end
+local function isbn_process_char(_, c, parse_state) --> elem_code, elem_text, err
     local isbn_len = parse_state.isbn_len
     if c == "-" then
         if isbn_len == 0 then
-            return nil, "[ArgErr] an initial dash is not allowed"
+            return nil, nil, "[ArgErr] an initial dash is not allowed"
         end
-        if parse_state.isdash then
-            return nil, "[ArgErr] two consecutive dash char found"
+        if parse_state.is_dash then
+            return nil, nil, "[ArgErr] found two consecutive dash"
         end
-        parse_state.isdash = true
-        return nil, nil
+        parse_state.is_dash = true
+        return nil, c, nil
     elseif c == " " then
         if isbn_len == 0 then
-            return nil, "[ArgErr] an initial space is not allowed"
+            return nil, nil, "[ArgErr] an initial space is not allowed"
         end
-        parse_state.isspace = true
-        return nil, nil
+        if parse_state.is_space then
+            return nil, nil, nil
+        else
+            parse_state.is_space = true
+            return nil, c, nil
+        end
     elseif c == "X" then -- ISBN-10 checksum for 10
-        code[#code + 1] = c
         isbn_len = isbn_len + 1
         parse_state.isbn_len = isbn_len
         if isbn_len ~= 10 then
-            return nil, "[ArgErr] found a checksum 'X' in a wrong position"
+            return nil, nil, "[ArgErr] found a checksum 'X' in a wrong position"
         end
-        return 10, nil
+        return 10, c, nil
     else -- c is at this point eventually a digit
         local n = string.byte(c) - 48
         if n < 0 or n > 9 then
-            return nil, "[ArgErr] found a not digit or a not grouping char"
+            return nil, nil, "[ArgErr] found a not digit or a not group char"
         end
-        if parse_state.isdash then -- close a group
-            code[#code + 1] = "-"
-            parse_state.isdash = false
-            parse_state.isspace = false
-        elseif parse_state.isspace then
-            code[#code + 1] = " "
-            parse_state.isspace = false
+        if parse_state.is_dash then -- close a group
+            parse_state.is_dash = false
+            parse_state.is_space = false
+        elseif parse_state.is_space then
+            parse_state.is_space = false
         end
-        code[#code + 1] = c
         isbn_len = isbn_len + 1
         parse_state.isbn_len = isbn_len
-        return n, nil
+        return n, c, nil
     end
 end
 
@@ -550,7 +577,8 @@
 -- parsed
 local function isbn_finalize(enc, parse_state) --> ok, err
     local var = enc._variant
-    local code_len = enc._code_len
+    local code_data = enc._code_data
+    local code_len = #code_data
     local isbn_len = parse_state.isbn_len
     local l1, l2
     if var == "isbn" then
@@ -559,7 +587,7 @@
         elseif isbn_len == 13 then
             l1 = 13
         else
-            return false, "[ArgErr] unsuitable ISBN code length"
+            return false, "[ArgErr] wrong ISBN code length of "..isbn_len
         end
         assert(l1 == code_len)
     elseif var == "isbn+5" then
@@ -569,7 +597,7 @@
         elseif isbn_len == 18 then
             l1, l2 = 13, 5
         else
-            return false, "[ArgErr] unsuitable ISBN+5 code length"
+            return false, "[ArgErr] wrong ISBN+5 code length of "..isbn_len
         end
         assert(l1 + l2 == code_len)
     elseif var == "isbn+2" then
@@ -579,13 +607,12 @@
         elseif isbn_len == 15 then
             l1, l2 = 13, 2
         else
-            return false, "[ArgErr] unsuitable ISBN+2 code length"
+            return false, "[ArgErr] wrong ISBN+2 code length of "..isbn_len
         end
         assert(l1 + l2 == code_len)
     else
         error("[InternalErr] unexpected ISBN variant code")
     end
-    local code_data = enc._code_data
     local isbn_auto = false
     if l1 == 10 then -- isbn 10 to 13 conversion
         local ck = isbn_checksum(code_data)
@@ -606,7 +633,7 @@
             return false, "[ArgErr] unmatched ISBN 13 checksum"
         end
     end
-    local isbncode = parse_state.isbncode
+    local isbncode = enc._code_text
     if l2 then -- nils the add-on digits
         local i = #isbncode
         while l2 > 0 do
@@ -631,7 +658,6 @@
         return false, "[ArgErr] too many groups found in the ISBN code"
     end
     if g > 0 then isbn_auto = true end
-    enc._isbncode = isbncode
     enc._isbntxt_on = isbn_auto
     return true, nil
 end
@@ -660,84 +686,86 @@
     return n, false
 end
 
+local function issn_parse_state()
+    return {
+        is_dash = false,
+        is_group_open = false,
+        is_group_close = false,
+        ed_var_len = 0,
+        ed_var_arr = {},
+        code_len = 0,
+        addon_len = 0,
+    }
+end
+
 -- ISSN dddd-dddx[dd] or 13-long array
 -- spaces is always ignored
-local function issn_check_char(enc, c, parse_state) --> elem, err
-    if (type(c) ~= "string") or (#c ~= 1) then
-        return nil, "[InternalErr] invalid char"
-    end
-    if parse_state.is_dash == nil then parse_state.is_dash = false end
-    if parse_state.is_group_open == nil then parse_state.is_group_open = false end
-    if parse_state.is_group_close == nil then parse_state.is_group_close = false end
-    if parse_state.ed_var_len == nil then parse_state.ed_var_len = 0 end
-    if parse_state.ed_var_arr == nil then parse_state.ed_var_arr = {} end
-    if parse_state.code_len == nil then parse_state.code_len = 0 end
-    if parse_state.addon_len == nil then parse_state.addon_len = 0 end
+local function issn_process_char(enc, c, parse_state) --> e_data, e_txt, err
     local addon_len = enc._addon_len
-    -- edition variant part
+    -- `edition variant` input code part
     if c == " " then
-        return nil, nil -- ignore all spaces
+        return nil, nil, nil -- ignore all spaces
     end
     if parse_state.is_group_close then
         if addon_len then
             if parse_state.addon_len == enc._addon_len then
-                return nil, "[ArgErr] too many chars in the ISSN input code"
+                return nil, nil, "[ArgErr] too many chars in the ISSN input code"
             end
             local n, e = to_n(c)
             if e then
-                return nil, "[ArgErr] non digit char after a edition variant group"
+                return nil, nil, "[ArgErr] non digit char after an edition variant group"
             end
             parse_state.addon_len = parse_state.addon_len + 1
-            return n, nil
+            return n, n, nil
         else
-            return nil, "[ArgErr] too many chars in the ISSN input code"
+            return nil, nil, "[ArgErr] too many chars in the ISSN input code"
         end
     end
     -- code part
     if c == "-" then
         if parse_state.is_dash then
-            return nil, "[ArgErr] two or more dash char in the input code"
+            return nil, nil, "[ArgErr] two or more dash chars in the input code"
         end
         if parse_state.code_len ~= 4 then
-            return nil, "[ArgErr] incorrect position for a dash sign"
+            return nil, nil, "[ArgErr] incorrect position for a dash sign"
         end
         parse_state.is_dash = true
-        return nil, nil
+        return nil, c, nil
     elseif c == "[" then -- two digits edition variant group opening
         if parse_state.code_len ~= 8 then
-            return nil, "[ArgErr] not a 8 digits long code for the ISSN input"
+            return nil, nil, "[ArgErr] not a 8-digits long code for the ISSN input"
         end
         parse_state.is_group_open = true
-        return nil, nil
+        return nil, nil, nil
     elseif c == "]" then -- two digits edition variant closing
         if not parse_state.is_group_open then
-            return nil, "[ArgErr] found a ']' without a '['"
+            return nil, nil, "[ArgErr] found a ']' without an opened '['"
         end
         if parse_state.ed_var_len ~= 2 then
-            return nil, "[ArgErr] edition variant group must be two digits long"
+            return nil, nil, "[ArgErr] edition variant group must be two digits long"
         end
         parse_state.is_group_open = false
         parse_state.is_group_close = true
-        return nil, nil
+        return nil, nil, nil
     elseif c == "X" then -- 8th ISSN checksum digit
         if parse_state.code_len ~= 7 then
-            return nil, "[ArgErr] incorrect position for checksum digit 'X'"
+            return nil, nil, "[ArgErr] incorrect position for checksum digit 'X'"
         end
         parse_state.code_len = 8
-        return 10, nil
-    else -- at this point 'c' can be only a digit
+        return 10, c, nil
+    else -- at this point 'c' may be only a digit
         local n, e = to_n(c)
         if e then
-            return nil, "[ArgErr] found a non digit in code part"
+            return nil, nil, "[ArgErr] found a non digit in code part"
         end
         if parse_state.is_group_open then
             if parse_state.ed_var_len == 2 then
-                return nil, "[ArgErr] group digits are more than two"
+                return nil, nil, "[ArgErr] group digits are more than two"
             end
             parse_state.ed_var_len = parse_state.ed_var_len + 1
             local t = parse_state.ed_var_arr
             t[#t + 1] = n
-            return nil, nil
+            return nil, c, nil
         end
         if parse_state.is_dash then
             if addon_len then
@@ -745,13 +773,13 @@
                     parse_state.code_len = parse_state.code_len + 1
                 else
                     if parse_state.addon_len == addon_len then
-                        return nil, "[ArgErr] too many digits for a 8 + "..addon_len.." ISSN input code"
+                        return nil, nil, "[ArgErr] too many digits for a 8 + "..addon_len.." ISSN input code"
                     end
                     parse_state.addon_len = parse_state.addon_len + 1
                 end
             else
                 if parse_state.code_len == 8 then
-                    return nil, "[ArgErr] too many digits found for a 8 digits long ISSN input code"
+                    return nil, nil, "[ArgErr] too many digits found for a 8 digits long ISSN input code"
                 end
                 parse_state.code_len = parse_state.code_len + 1
             end
@@ -758,16 +786,16 @@
         else
             if addon_len then
                 if parse_state.code_len == (13 + addon_len) then
-                    return nil, "[ArgErr] too many digits in ISSN input code"
+                    return nil, nil, "[ArgErr] too many digits in ISSN input code"
                 end
             else
                 if parse_state.code_len == 13 then
-                    return nil, "[ArgErr] too many digits in a 13 digits long ISSN input code"
+                    return nil, nil, "[ArgErr] too many digits in a 13 digits long ISSN input code"
                 end
             end
             parse_state.code_len = parse_state.code_len + 1
         end
-        return n, nil
+        return n, n, nil
     end
 end
 
@@ -822,7 +850,7 @@
         return false, "[ArgErr] unclosed edition variant group in ISSN input code"
     end
     local data = enc._code_data
-    local code_len = enc._code_len
+    local code_len = #data
     local addon_len = enc._addon_len
     local main_len = code_len - (addon_len or 0)
     if main_len == 8 then
@@ -862,12 +890,12 @@
     local l1 = enc._main_len
     local l2 = enc._addon_len
     local ok_len = l1 + (l2 or 0)
-    local symb_len = enc._code_len
+    local data = enc._code_data
+    local symb_len = #data
     if symb_len ~= ok_len then
         return false, "[ArgErr] not a "..ok_len.."-digit long array"
     end
     if enc._is_last_checksum then -- is the last digit ok?
-        local data = enc._code_data
         local ck = checksum_8_13(data, l1 - 1)
         if ck ~= data[l1] then
             return false, "[Err] wrong checksum digit"
@@ -881,7 +909,7 @@
 function EAN:_config() --> ok, err
     local variant = self._variant
     if not variant then
-        return false, "[Err] variant is mandatory for EAN family"
+        return false, "[Err] variant is mandatory for the EAN family"
     end
     local plus = variant:find("+")
     local v1
@@ -894,13 +922,13 @@
         self._sub_variant_1 = v1
     end
     local fnconfig = self._config_variant[variant]
-    local VbarClass = self._libgeo.Vbar -- Vbar class
-    local mod = self.mod
-    fnconfig(self, VbarClass, mod)
+    fnconfig(self)
     if v1 == "isbn" then
-        self._check_char = isbn_check_char
+        self._process_char = isbn_process_char
+        self._init_parse_state = isbn_parse_state
     elseif v1 == "issn" then
-        self._check_char = issn_check_char
+        self._process_char = issn_process_char
+        self._init_parse_state = issn_parse_state
     end
     return true, nil
 end
@@ -987,51 +1015,39 @@
 
 -- draw EAN13 symbol
 fn_append_ga_variant["13"] = function (ean, canvas, tx, ty, ax, ay)
-    local code       = ean._code_data
-    local mod        = ean.mod
-    local bars_depth = mod * ean.bars_depth_factor
-    local w, h       = 95*mod, ean.height + bars_depth
-    local x0         = (tx or 0) - ax * w
-    local y0         = (ty or 0) - ay * h
-    local x1         = x0 + w
-    local y1         = y0 + h
-    local xpos       = x0 -- current insertion x-coord
-    local ys         = y0 + bars_depth
-    local s_width    = 7*mod
-    local code_seq   = ean._codeset_seq[code[1]]
-    -- draw the start symbol
-    local err
-    err = canvas:start_bbox_group(); assert(not err, err)
-    local be = ean._13_start_stop_vbar
-    err = canvas:encode_Vbar(be, xpos, y0, y1); assert(not err, err)
-    xpos = xpos + 3*mod
-    -- draw the first 6 numbers
+    local Codeset = ean._13_codeset_vbar
+    local mod = ean.mod
+    local queue_0 = assert(Codeset:get("start_stop")) +
+        42*mod +
+        assert(Codeset:get("central")) +
+        42*mod +
+        assert(Codeset:get("start_stop"))
+    local code = ean._code_data
+    local code_seq = ean._codeset_seq[code[1]]
+    local queue_1 = ean._libgeo.Vbar_queue:new()
     for i = 2, 7 do
-        local codeset = code_seq[i-1]
-        local n = code[i]
-        local vbar = ean._13_codeset_vbar[codeset][n]
-        err = canvas:encode_Vbar(vbar, xpos, ys, y1); assert(not err, err)
-        xpos = xpos + s_width
+        queue_1 = queue_1 + assert(Codeset:get(code_seq[i-1], code[i]))
     end
-    -- draw the control symbol
-    local ctrl = ean._13_ctrl_center_vbar
-    err = canvas:encode_Vbar(ctrl, xpos, y0, y1); assert(not err, err)
-    xpos = xpos + 5*mod
-    -- draw the last 6 numbers
+    queue_1 = queue_1 + 5*mod
     for i = 8, 13 do
-        local codeset = code_seq[i-1]
-        local n = code[i]
-        local vbar = ean._13_codeset_vbar[codeset][n]
-        err = canvas:encode_Vbar(vbar, xpos, ys, y1); assert(not err, err)
-        xpos = xpos + s_width
+        queue_1 = queue_1 + assert(Codeset:get(code_seq[i-1], code[i]))
     end
-    -- draw the stop char
-    err = canvas:encode_Vbar(be, xpos, y0, y1); assert(not err, err)
+    local bars_depth = mod * ean.bars_depth_factor
+    local w, h = 95*mod, ean.height + bars_depth
+    local x0   = tx - ax * w
+    local y0   = ty - ay * h
+    local x1   = x0 + w
+    local y1   = y0 + h
+    local ys   = y0 + bars_depth
+    -- draw the symbol
+    assert(canvas:encode_disable_bbox())
+    assert(canvas:encode_vbar_queue(queue_0, x0, y0, y1))
+    assert(canvas:encode_vbar_queue(queue_1, x0 + 3*mod, ys, y1))
     -- bounding box set up
     local qzl = ean.quietzone_left_factor * mod
     local qzr = ean.quietzone_right_factor * mod
-    err = canvas:stop_bbox_group(x0 - qzl, y0, x1 + qzr, y1)
-    assert(not err, err)
+    assert(canvas:encode_set_bbox(x0 - qzl, y0, x1 + qzr, y1))
+    assert(canvas:encode_enable_bbox())
     if ean.text_enabled then -- human readable text
         local Text  = ean._libgeo.Text
         local txt_1 = Text:from_digit_array(code, 1,  1)
@@ -1039,16 +1055,30 @@
         local txt_3 = Text:from_digit_array(code, 8, 13)
         local y_bl = ys - ean.text_ygap_factor * mod
         local mx = ean.text_xgap_factor
-        err = canvas:encode_Text(txt_1, x0 - qzl, y_bl, 0, 1)
-        assert(not err, err)
+        assert(canvas:encode_Text(txt_1, x0 - qzl, y_bl, 0, 1))
         local x2_1 = x0 + (3+mx)*mod
         local x2_2 = x0 + (46-mx)*mod
-        err = canvas:encode_Text_xwidth(txt_2, x2_1, x2_2, y_bl, 1)
-        assert(not err, err)
+        assert(canvas:encode_Text_xwidth(txt_2, x2_1, x2_2, y_bl, 1))
         local x3_1 = x0 + (49+mx)*mod
         local x3_2 = x0 + (92-mx)*mod
-        err = canvas:encode_Text_xwidth(txt_3, x3_1, x3_2, y_bl, 1)
-        assert(not err, err)
+        assert(canvas:encode_Text_xwidth(txt_3, x3_1, x3_2, y_bl, 1))
+        if ean.text_guard_enabled and (not ean._addon_len) then
+            local Polyline = ean._libgeo.Polyline
+            local mm = 186467.98
+            local alpha = 36 * math.pi/180
+            local pw = 0.30*mm
+            local dx = pw/(2*math.sin(alpha))
+            local dy = (pw/2) * math.cos(alpha)
+            local px = x1 + qzr - dx
+            local pb = 1.55*mm
+            local ph = pb * math.tan(alpha)
+            local p = Polyline:new()
+            p:add_point(px - pb, y_bl - 2*ph - dy)
+            p:add_point(px, y_bl - ph - dy)
+            p:add_point(px - pb, y_bl - dy)
+            assert(canvas:encode_linewidth(pw))
+            assert(canvas:encode_polyline(p))
+        end
         local istxt = false
         if ean.text_isbn_enabled then
             if ean.text_isbn_enabled == "auto" then
@@ -1060,7 +1090,7 @@
             end
         end
         if istxt then
-            local isbn = assert(ean._isbncode, "[InternalErr] ISBN text not found")
+            local isbn = assert(ean._code_text, "[InternalErr] ISBN text not found")
             local descr = {"I", "S", "B", "N", " ",}
             for _, d in ipairs(isbn) do
                 descr[#descr + 1] = d
@@ -1068,13 +1098,12 @@
             local isbn_txt = Text:from_chars(descr)
             local x_isbn = x0 + 47.5 * mod
             local y_isbn = y1 + ean.text_isbn_ygap_factor * mod
-            err = canvas:encode_Text(isbn_txt, x_isbn, y_isbn, 0.5, 0)
-            assert(not err, err)
+            assert(canvas:encode_Text(isbn_txt, x_isbn, y_isbn, 0.5, 0))
         end
         -- issn text
         if ean.text_issn_enabled then
             local hri = {"I", "S", "S", "N", " "}
-            local txt = assert(ean._code_text, "[IternalErr] _code_text not found")
+            local txt = assert(ean._code_text, "[InternalErr] _code_text not found")
             for i = 1, 4 do
                 hri[i + 5] = txt[i]
             end
@@ -1085,59 +1114,46 @@
             local issn_txt = Text:from_chars(hri)
             local x_issn = x0 + 47.5 * mod
             local y_issn = y1 + ean.text_issn_ygap_factor * mod
-            err = canvas:encode_Text(issn_txt, x_issn, y_issn, 0.5, 0)
-            assert(not err, err)
+            assert(canvas:encode_Text(issn_txt, x_issn, y_issn, 0.5, 0))
         end
     end
+    return {x0, y0, x1, y1, qzl, nil, qzr, nil,}
 end
 
 -- draw EAN8 symbol
 fn_append_ga_variant["8"] = function (ean, canvas, tx, ty, ax, ay)
-    local code       = ean._code_data
-    local mod        = ean.mod
-    local bars_depth = mod * ean.bars_depth_factor
-    local w, h       = 67*mod, ean.height + bars_depth
-    local x0         = (tx or 0) - ax * w
-    local y0         = (ty or 0) - ay * h
-    local x1         = x0 + w
-    local y1         = y0 + h
-    local xpos       = x0 -- current insertion x-coord
-    local ys         = y0 + bars_depth
-    local s_width    = 7*mod
-    -- draw the start symbol
-    local err
-    err = canvas:start_bbox_group(); assert(not err, err)
-    local be = ean._8_start_stop_vbar
-    err = canvas:encode_Vbar(be, xpos, y0, y1); assert(not err, err)
-    xpos = xpos + 3*mod
-    -- draw the first 4 numbers
-    local t_vbar = ean._8_codeset_vbar
+    local Codeset = ean._8_codeset_vbar
+    local mod = ean.mod
+    local q0 = assert(Codeset:get("start_stop")) + 28*mod +
+        assert(Codeset:get("central")) + 28*mod +
+        assert(Codeset:get("start_stop"))
+    local code = ean._code_data
     local cs14 = ean._codeset14_8
+    local q1 = ean._libgeo.Vbar_queue:new()
     for i = 1, 4 do
-        local n = code[i]
-        local vbar = t_vbar[cs14][n]
-        err = canvas:encode_Vbar(vbar, xpos, ys, y1); assert(not err, err)
-        xpos = xpos + s_width
+        q1 = q1 + assert(Codeset:get(cs14, code[i]))
     end
-    -- draw the control symbol
-    local ctrl = ean._8_ctrl_center_vbar
-    err = canvas:encode_Vbar(ctrl, xpos, y0, y1); assert(not err, err)
-    xpos = xpos + 5*mod
-    -- draw the product code
+    q1 = q1 + 5*mod
     local cs58 = ean._codeset58_8
     for i = 5, 8 do
-        local n    = code[i]
-        local vbar = t_vbar[cs58][n]
-        err = canvas:encode_Vbar(vbar, xpos, ys, y1); assert(not err, err)
-        xpos = xpos + s_width
+        q1 = q1 + assert(Codeset:get(cs58, code[i]))
     end
-    -- draw the stop char
-    err = canvas:encode_Vbar(be, xpos, y0, y1); assert(not err, err)
+    local bars_depth = mod * ean.bars_depth_factor
+    local w, h = 67*mod, ean.height + bars_depth
+    local x0   = tx - ax * w
+    local y0   = ty - ay * h
+    local x1   = x0 + w
+    local y1   = y0 + h
+    local ys   = y0 + bars_depth
+    -- draw the symbol
+    assert(canvas:encode_disable_bbox())
+    assert(canvas:encode_vbar_queue(q0, x0, y0, y1))
+    assert(canvas:encode_vbar_queue(q1, x0 + 3*mod, ys, y1))
     -- bounding box set up
     local qzl = ean.quietzone_left_factor * mod
     local qzr = ean.quietzone_right_factor * mod
-    err = canvas:stop_bbox_group(x0 - qzl, y0, x1 + qzr, y1)
-    assert(not err, err)
+    assert(canvas:encode_set_bbox(x0 - qzl, y0, x1 + qzr, y1))
+    assert(canvas:encode_enable_bbox())
     if ean.text_enabled then -- human readable text
         local Text  = ean._libgeo.Text
         local t_1 = Text:from_digit_array(code, 1, 4)
@@ -1146,18 +1162,40 @@
         local mx    = ean.text_xgap_factor
         local x1_1 = x0 + ( 3 + mx)*mod
         local x1_2 = x0 + (32 - mx)*mod
-        err = canvas:encode_Text_xwidth(t_1, x1_1, x1_2, y_bl, 1)
-        assert(not err, err)
+        assert(canvas:encode_Text_xwidth(t_1, x1_1, x1_2, y_bl, 1))
         local x2_1 = x0 + (35+mx)*mod
         local x2_2 = x0 + (64-mx)*mod
-        err = canvas:encode_Text_xwidth(t_2, x2_1, x2_2, y_bl, 1)
-        assert(not err, err)
+        assert(canvas:encode_Text_xwidth(t_2, x2_1, x2_2, y_bl, 1))
+        if ean.text_guard_enabled and (not ean._addon_len) then
+            local Polyline = ean._libgeo.Polyline
+            local mm = 186467.98
+            local alpha = 36 * math.pi/180
+            local pw = 0.30*mm
+            local pb = 1.55*mm
+            local ph = pb * math.tan(alpha)
+            local dx = pw/(2*math.sin(alpha))
+            local dy = (pw/2) * math.cos(alpha)
+            local px1, px2 = x0 - qzl + dx, x1 + qzr - dx
+            local p1 = Polyline:new()
+            p1:add_point(px1 + pb, y_bl - 2*ph - dy)
+            p1:add_point(px1, y_bl - ph - dy)
+            p1:add_point(px1 + pb, y_bl - dy)
+            local p2 = Polyline:new()
+            p2:add_point(px2 - pb, y_bl - 2*ph - dy)
+            p2:add_point(px2, y_bl - ph - dy)
+            p2:add_point(px2 - pb, y_bl - dy)
+            assert(canvas:encode_linewidth(pw))
+            assert(canvas:encode_polyline(p1))
+            assert(canvas:encode_polyline(p2))
+        end
     end
+    return {x0, y0, x1, y1, qzl, nil, qzr, nil,}
 end
 
 -- draw EAN5 add-on symbol
 fn_append_ga_variant["5"] = function (ean, canvas, tx, ty, ax, ay, h)
-    local code = ean._code_data
+    local Codeset = ean._5_codeset_vbar
+    local queue = assert(Codeset:get("start"))
     local l1 = ean._main_len
     local i1; if l1 == 5 then
         i1 = 1
@@ -1165,45 +1203,33 @@
         i1 = l1 + 1
     end
     local i2 = i1 + 4
-    local mod    = ean.mod
-    local w      = 47*mod
-    h = h or ean.height
-    local x0     = (tx or 0) - ax * w
-    local y0     = (ty or 0) - ay * h
-    local x1     = x0 + w
-    local y1     = y0 + h
-    local xpos   = x0 -- current insertion x-coord
-    local sym_w  = 7*mod
-    local sep_w  = 2*mod
-    -- draw the start symbol
-    local err
-    err = canvas:start_bbox_group(); assert(not err, err)
-    local start = ean._5_start_vbar
-    err = canvas:encode_Vbar(start, xpos, y0, y1); assert(not err, err)
-    xpos = xpos + 4*mod
+    local mod = ean.mod
+    -- draw the five digits
+    local code = ean._code_data
     local ck = checksum_5_2(code, i1, 5)
-    local codeset = ean._codeset_5[ck]
-    local sep    = ean._5_sep_vbar
-    local t_vbar = ean._5_codeset_vbar
-    -- draw the five digits
+    local cset = ean._codeset_5[ck]
     local k = 0
     for i = i1, i2 do
         k = k + 1
-        local cs = codeset[k] -- 1 or 2
-        local d = code[i]
-        local vbar = t_vbar[cs][d]
-        err = canvas:encode_Vbar(vbar, xpos, y0, y1); assert(not err, err)
-        xpos = xpos + sym_w
+        queue = queue + assert(Codeset:get(cset[k], code[i]))
         if k < 5 then
-            err = canvas:encode_Vbar(sep, xpos, y0, y1); assert(not err, err)
-            xpos = xpos + sep_w
+            queue = queue + assert(Codeset:get("sep"))
         end
     end
+    local w = 47*mod
+    h = h or ean.height
+    local x0 = tx - ax * w
+    local y0 = ty - ay * h
+    local x1 = x0 + w
+    local y1 = y0 + h
+    -- draw the symbol
+    assert(canvas:encode_disable_bbox())
+    assert(canvas:encode_vbar_queue(queue, x0, y0, y1))
     -- bounding box set up
     local qzl = ean.quietzone_left_factor * mod
     local qzr = ean.quietzone_right_factor * mod
-    err = canvas:stop_bbox_group(x0 - qzl, y0, x1 + qzr, y1)
-    assert(not err, err)
+    assert(canvas:encode_set_bbox(x0 - qzl, y0, x1 + qzr, y1))
+    assert(canvas:encode_enable_bbox())
     if ean.text_enabled then -- human readable text
         local Text = ean._libgeo.Text
         local txt  = Text:from_digit_array(code, i1, i2)
@@ -1210,14 +1236,30 @@
         local y_bl = y1 + ean.text_ygap_factor * mod
         local x1_1 = x0 + 3*mod
         local x1_2 = x1 - 3*mod
-        err = canvas:encode_Text_xwidth(txt, x1_1, x1_2, y_bl, 0)
-        assert(not err, err)
+        assert(canvas:encode_Text_xwidth(txt, x1_1, x1_2, y_bl, 0))
+        if ean.text_guard_enabled then
+            local Polyline = ean._libgeo.Polyline
+            local mm = 186467.98
+            local alpha = 36 * math.pi/180
+            local pw = 0.30*mm
+            local dx = pw/(2*math.sin(alpha))
+            local dy = (pw/2) * math.cos(alpha)
+            local px = x1 + qzr - dx
+            local pb = 1.55*mm
+            local ph = pb * math.tan(alpha)
+            local p = Polyline:new()
+            p:add_point(px - pb, y_bl + dy)
+            p:add_point(px, y_bl + ph + dy)
+            p:add_point(px - pb, y_bl + 2*ph + dy)
+            assert(canvas:encode_linewidth(pw))
+            assert(canvas:encode_polyline(p))
+        end
     end
+    return {x0, y0, x1, y1, qzl, nil, qzr, nil,}
 end
 
 -- draw EAN2 symbol
 fn_append_ga_variant["2"] = function (ean, canvas, tx, ty, ax, ay, h)
-    local code = ean._code_data
     local l1 = ean._main_len
     local i1; if l1 == 2 then
         i1 = 1
@@ -1224,22 +1266,7 @@
     else
         i1 = l1 + 1
     end
-    local mod = ean.mod
-    local w = 20*mod
-    h = h or ean.height
-    local x0 = (tx or 0.0) - ax * w
-    local y0 = (ty or 0.0) - ay * h
-    local x1 = x0 + w
-    local y1 = y0 + h
-    local xpos = x0 -- current insertion x-coord
-    local sym_w = 7*mod
-    local sep_w = 2*mod
-    -- draw the start symbol
-    local err
-    err = canvas:start_bbox_group(); assert(not err, err)
-    local start = ean._2_start_vbar
-    err = canvas:encode_Vbar(start, xpos, y0, y1); assert(not err, err)
-    xpos = xpos + 4*mod
+    local code = ean._code_data
     local r = checksum_5_2(code, i1, 2)
     local s1, s2
     if r == 0 then     -- LL scheme
@@ -1251,22 +1278,26 @@
     else -- r == 3     -- GG scheme
         s1, s2 = 2, 2
     end
-    local t_vbar = ean._2_codeset_vbar
-    local d1 = code[i1] -- render the first digit
-    local vb1 = t_vbar[s1][d1]
-    err = canvas:encode_Vbar(vb1, xpos, y0, y1); assert(not err, err)
-    xpos = xpos + sym_w
-    local sep  = ean._2_sep_vbar
-    err = canvas:encode_Vbar(sep, xpos, y0, y1); assert(not err, err)
-    xpos = xpos + sep_w
-    local d2 = code[i1 + 1] -- render the second digit
-    local vb2 = t_vbar[s2][d2]
-    err = canvas:encode_Vbar(vb2, xpos, y0, y1); assert(not err, err)
+    local Codeset = ean._2_codeset_vbar
+    local queue = assert(Codeset:get("start")) +
+        assert(Codeset:get(s1, code[i1])) + -- first digit
+        assert(Codeset:get("sep")) +
+        assert(Codeset:get(s2, code[i1 + 1])) -- second digit
+    -- draw the symbol
+    local mod = ean.mod
+    local w = 20*mod
+    h = h or ean.height
+    local x0 = tx - ax * w
+    local y0 = ty - ay * h
+    local x1 = x0 + w
+    local y1 = y0 + h
+    assert(canvas:encode_disable_bbox())
+    assert(canvas:encode_vbar_queue(queue, x0, y0, y1))
     -- bounding box set up
     local qzl = ean.quietzone_left_factor * mod
     local qzr = ean.quietzone_right_factor * mod
-    err = canvas:stop_bbox_group(x0 - qzl, y0, x1 + qzr, y1)
-    assert(not err, err)
+    assert(canvas:encode_set_bbox(x0 - qzl, y0, x1 + qzr, y1))
+    assert(canvas:encode_enable_bbox())
     if ean.text_enabled then -- human readable text
         local Text  = ean._libgeo.Text
         local txt = Text:from_digit_array(code, i1, i1 + 1)
@@ -1273,9 +1304,26 @@
         local y_bl = y1 + ean.text_ygap_factor * mod
         local x1_1 = x0 + 3*mod
         local x1_2 = x1 - 3*mod
-        err = canvas:encode_Text_xwidth(txt, x1_1, x1_2, y_bl, 0)
-        assert(not err, err)
+        assert(canvas:encode_Text_xwidth(txt, x1_1, x1_2, y_bl, 0))
+        if ean.text_guard_enabled then
+            local Polyline = ean._libgeo.Polyline
+            local mm = 186467.98
+            local alpha = 36 * math.pi/180
+            local pw = 0.30*mm
+            local dx = pw/(2*math.sin(alpha))
+            local dy = (pw/2) * math.cos(alpha)
+            local px = x1 + qzr - dx
+            local pb = 1.55*mm
+            local ph = pb * math.tan(alpha)
+            local p = Polyline:new()
+            p:add_point(px - pb, y_bl + dy)
+            p:add_point(px, y_bl + ph + dy)
+            p:add_point(px - pb, y_bl + 2*ph + dy)
+            assert(canvas:encode_linewidth(pw))
+            assert(canvas:encode_polyline(p))
+        end
     end
+    return {x0, y0, x1, y1, qzl, nil, qzr, nil,}
 end
 
 fn_append_ga_variant["13+5"] = function (ean, canvas, tx, ty, ax, ay)
@@ -1283,14 +1331,15 @@
     local bars_depth = mod * ean.bars_depth_factor
     local h = ean.height + bars_depth
     local w = (142 + ean.addon_xgap_factor) * mod
-    local x0 = (tx or 0) - ax * w
-    local y0 = (ty or 0) - ay * h
+    local x0 = tx - ax * w
+    local y0 = ty - ay * h
     local x1 = x0 + w
     local fn_ga = ean._append_ga_variant
     local fn_1 = fn_ga["13"]
     local fn_2 = fn_ga["5"]
-    fn_1(ean, canvas, x0, y0, 0, 0)
-    fn_2(ean, canvas, x1, y0, 1, 0, 0.85 * h)
+    local b1 = fn_1(ean, canvas, x0, y0, 0, 0)
+    local b2 = fn_2(ean, canvas, x1, y0, 1, 0, 0.85 * h)
+    return {b1[1], b1[2], b2[3], b1[4], b1[5], nil, b2[7], nil,}
 end
 
 fn_append_ga_variant["13+2"] = function (ean, canvas, tx, ty, ax, ay)
@@ -1298,14 +1347,15 @@
     local bars_depth = mod * ean.bars_depth_factor
     local h = ean.height + bars_depth
     local w = (115 + ean.addon_xgap_factor) * mod
-    local x0 = (tx or 0) - ax * w
-    local y0 = (ty or 0) - ay * h
+    local x0 = tx - ax * w
+    local y0 = ty - ay * h
     local x1 = x0 + w
     local fn_ga = ean._append_ga_variant
     local fn_1 = fn_ga["13"]
     local fn_2 = fn_ga["2"]
-    fn_1(ean, canvas, x0, y0, 0, 0)
-    fn_2(ean, canvas, x1, y0, 1, 0, 0.85 * h)
+    local b1 = fn_1(ean, canvas, x0, y0, 0, 0)
+    local b2 = fn_2(ean, canvas, x1, y0, 1, 0, 0.85 * h)
+    return {b1[1], b1[2], b2[3], b1[4], b1[5], nil, b2[7], nil,}
 end
 
 fn_append_ga_variant["8+5"] = function (ean, canvas, tx, ty, ax, ay)
@@ -1313,14 +1363,15 @@
     local bars_depth = mod * ean.bars_depth_factor
     local h = ean.height + bars_depth
     local w = (114 + ean.addon_xgap_factor) * mod
-    local x0 = (tx or 0) - ax * w
-    local y0 = (ty or 0) - ay * h
+    local x0 = tx - ax * w
+    local y0 = ty - ay * h
     local x1 = x0 + w
     local fn_ga = ean._append_ga_variant
     local fn_1 = fn_ga["8"]
     local fn_2 = fn_ga["5"]
-    fn_1(ean, canvas, x0, y0, 0, 0)
-    fn_2(ean, canvas, x1, y0, 1, 0, 0.85 * h)
+    local b1 = fn_1(ean, canvas, x0, y0, 0, 0)
+    local b2 = fn_2(ean, canvas, x1, y0, 1, 0, 0.85 * h)
+    return {b1[1], b1[2], b2[3], b1[4], b1[5], nil, b2[7], nil,}
 end
 
 fn_append_ga_variant["8+2"] = function (ean, canvas, tx, ty, ax, ay)
@@ -1328,14 +1379,15 @@
     local bars_depth = mod * ean.bars_depth_factor
     local h = ean.height + bars_depth
     local w = (87 + ean.addon_xgap_factor) * mod
-    local x0 = (tx or 0) - ax * w
-    local y0 = (ty or 0) - ay * h
+    local x0 = tx - ax * w
+    local y0 = ty - ay * h
     local x1 = x0 + w
     local fn_ga = ean._append_ga_variant
     local fn_1 = fn_ga["8"]
     local fn_2 = fn_ga["2"]
-    fn_1(ean, canvas, x0, y0, 0, 0)
-    fn_2(ean, canvas, x1, y0, 1, 0, 0.85 * h)
+    local b1 = fn_1(ean, canvas, x0, y0, 0, 0)
+    local b2 = fn_2(ean, canvas, x1, y0, 1, 0, 0.85 * h)
+    return {b1[1], b1[2], b2[3], b1[4], b1[5], nil, b2[7], nil,}
 end
 
 -- ISBN
@@ -1350,12 +1402,11 @@
 -- Drawing into the provided channel geometrical data
 -- tx, ty is the optional translation vector
 -- the function return the canvas reference to allow call chaining
-function EAN:append_ga(canvas, tx, ty) --> canvas
+function EAN:_append_ga(canvas, tx, ty) --> bbox
     local var = self._variant
     local fn_append_ga = assert(self._append_ga_variant[var])
     local ax, ay = self.ax, self.ay
-    fn_append_ga(self, canvas, tx, ty, ax, ay)
-    return canvas
+    return fn_append_ga(self, canvas, tx, ty, ax, ay)
 end
 
 return EAN

Modified: trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-i2of5.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-i2of5.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-i2of5.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,6 +1,6 @@
 -- Interleaved 2 of 5 (ITF) barcode generator
 --
--- Copyright (C) 2020 Roberto Giacomelli
+-- Copyright (C) 2019-2022 Roberto Giacomelli
 -- see LICENSE.txt file
 
 local ITF = { -- main container
@@ -13,7 +13,7 @@
     ITF14 = true, -- ITF 14 GS1 specification
 }
 
-ITF._start = 111 -- nnnn
+ITF._start = 1111 -- nnnn
 ITF._stop = 112 -- Wnn (integer must be in reverse order)
 
 ITF._pattern = { -- true -> narrow, false -> Wide
@@ -40,6 +40,7 @@
     "bearer_bars_enabled",
     "bearer_bars_thickness",
     "bearer_bars_layout",
+    "text_enabled",
 }
 ITF._par_def = {}
 local pardef = ITF._par_def
@@ -194,6 +195,19 @@
     end,
 }
 
+-- human readable information
+pardef.text_enabled = { -- boolean type
+    default    = true,
+    isReserved = false,
+    fncheck    = function (self, flag, _) --> boolean, err
+        if type(flag) == "boolean" then
+            return true, nil
+        else
+            return false, "[TypeErr] option 'text_enabled' is not a boolean value"
+        end
+    end,
+}
+
 -- ITF14: variant based on GS1 specification, see
 -- https://www.gs1.org/sites/default/files/docs/barcodes/GS1_General_Specifications.pdf
 -- GS1 ITF14 parameters vary in range and preferred value on the specific
@@ -300,7 +314,7 @@
 -- SHALL be a minimum of twice the width of a narrow bar (dark bar) and need
 -- only appear at the top and bottom of the symbol, butting directly against
 -- the top and bottom of the symbol bars (dark bars).
-pardef.bearer_bars_thickness = { -- dimension
+itf14_pdef.bearer_bars_thickness = { -- dimension
     default    = 5 * 0.495 * 186467, -- 5 modules
     unit       = "sp", -- scaled point
     isReserved = false,
@@ -388,38 +402,40 @@
     end
 end
 
+local function itf14_parse_state()
+    return {
+        is_space = false,
+        is_popen = false,
+        itf14_len = 0,
+    }
+end
+
 -- group char for readibility '(' or ')' or ' '
-local function itf14_check_char(enc, c, parse_state) --> elem, err
-    if type(c) ~= "string" or #c ~= 1 then
-        return nil, "[InternalErr] invalid char"
-    end
-    if parse_state.itf14_code == nil then parse_state.itf14_code = {} end
-    local code = parse_state.itf14_code
-    if parse_state.is_space == nil then parse_state.is_space = false end
-    if parse_state.is_popen == nil then parse_state.is_popen = false end
-    if parse_state.itf14_len == nil then parse_state.itf14_len = 0 end
-    local itf14_len = parse_state.itf14_len
+local function itf14_process_char(_, c, parse_state) --> e_data, e_text, err
+    local len14 = parse_state.itf14_len
     -- parsing
     if c == " " then
-        if itf14_len == 0 then -- ignore initial spaces
-            return nil, nil
+        if (len14 == 0) or (len14 == 14) then -- ignore initial or final spaces
+            return nil, nil, nil
         end
-        parse_state.is_space = true
-        return nil, nil
+        if parse_state.is_space then -- ignore more than one consecutive space
+            return nil, nil, nil
+        else
+            parse_state.is_space = true
+            return nil, c, nil
+        end
     elseif c == "(" then
         if parse_state.is_popen then
-            return nil, "[Err] a parenthesis group is already open"
+            return nil, nil, "[Err] a parenthesis is already opened"
         end
         parse_state.is_popen = true
-        code[#code + 1] = c
-        return nil, nil
+        return nil, c, nil
     elseif c == ")" then
         if not parse_state.is_popen then
-            return nil, "[Err] found a closing parenthesis without an opening one"
+            return nil, nil, "[Err] found a closing parenthesis without an opening one"
         end
         parse_state.is_popen = false
-        code[#code + 1] = c
-        return nil, nil
+        return nil, c, nil
     else -- c is at this point eventually a digit
         local n = string.byte(c) - 48
         if n < 0 or n > 9 then
@@ -426,13 +442,10 @@
             return nil, "[ArgErr] found a not digit or a not grouping char"
         end
         if parse_state.is_space then
-            code[#code + 1] = " "
             parse_state.is_space = false
         end
-        code[#code + 1] = c
-        itf14_len = itf14_len + 1
-        parse_state.itf14_len = itf14_len
-        return n, nil
+        parse_state.itf14_len = len14 + 1
+        return n, c, nil
     end
 end
 
@@ -443,11 +456,12 @@
     local wide = narrow * self.ratio
     -- start symbol
     local Vbar = self._libgeo.Vbar -- Vbar class
-    self._vbar_start = Vbar:from_int_revpair(self._start, narrow, wide)
-    self._vbar_stop = Vbar:from_int_revpair(self._stop, narrow, wide)
+    local archive = self._libgeo.Archive -- Vbar_archive class
+    local Repo = archive:new()
+    self._vbar_data = Repo
+    Repo:insert(Vbar:from_int_revpair(self._start, narrow, wide), "start")
+    Repo:insert(Vbar:from_int_revpair(self._stop, narrow, wide), "stop")
     -- build every possible pair of digits from 00 to 99
-    self._vbar_data = {}
-    local vbar = self._vbar_data
     local pattern = self._pattern
     for dec = 0, 9 do
         for unit = 0, 9 do
@@ -454,12 +468,13 @@
             local t1 = pattern[dec]
             local t2 = pattern[unit]
             local n = dec*10 + unit
-            vbar[n] = Vbar:from_two_tab(t1, t2, narrow, wide)
+            Repo:insert(Vbar:from_two_tab(t1, t2, narrow, wide), n)
         end
     end
     local variant = self._variant
     if variant == "ITF14" then
-        self._check_char = itf14_check_char
+        self._process_char = itf14_process_char
+        self._init_parse_state = itf14_parse_state
     end
     return true, nil
 end
@@ -467,21 +482,24 @@
 -- internal methods for constructors
 
 -- input code post processing for ITF14 variant
-local function itf14_finalize(enc) --> ok, err
+local function itf14_finalize(enc, parse_state) --> ok, err
+    if parse_state.is_popen then
+        return false, "[ArgErr] unclosed group in input code"
+    end
     -- check digit action
     local policy = enc.check_digit_policy
-    local slen = enc._code_len
     local digits = enc._code_data
+    local slen = #digits
     local is_add
     if policy == "verify" then
         if slen ~= 14 then
-            return nil, "[DataErr] incorrect input lenght of "..slen..
+            return false, "[DataErr] incorrect input lenght of "..slen..
                 " respect to 14 (checksum policy 'verify')" 
         end
         is_add = false
     elseif policy == "add" then
         if slen ~= 13 then
-            return nil, "[DataErr] incorrect input lenght of "..slen..
+            return false, "[DataErr] incorrect input lenght of "..slen..
                 " respect to 13 (checksum policy 'add')" 
         end
         is_add = true
@@ -491,8 +509,8 @@
         elseif slen == 13 then
             is_add = true
         else
-            return nil, "[DataErr] incorrect input lenght of "..slen..
-                " respect to the policy '"..policy.."'"
+            return false, "[DataErr] incorrect input lenght of "..slen..
+                " respect to the current policy '"..policy.."'"
         end
     else
         return false, "[InternalErr] incorrect policy enum value '"..policy.."'"
@@ -499,10 +517,19 @@
     end
     assert(type(is_add) == "boolean")
     local cs = checkdigit(digits, 13, enc.check_digit_method)
-    if is_add then
+    if is_add then -- add the final checkdigit
         digits[14] = cs
-        enc._code_len = 14
-    else
+        local dtxt = enc._code_text
+        if dtxt then
+            local len = #dtxt
+            local last = dtxt[len]
+            if last == " " then
+                dtxt[len] = cs
+            else
+                dtxt[len + 1] = cs
+            end
+        end
+    else -- check only the final digit
         if cs ~= digits[14] then
             return false, "[DataErr] last digit is not equal to checksum"
         end
@@ -514,13 +541,13 @@
 local function basic_finalize(enc) --> ok, err
     -- check digit action
     local policy = enc.check_digit_policy
-    local slen = enc._code_len
+    local digits = enc._code_data
+    local slen = #digits
     local is_even = (slen % 2 == 0)
-    local digits = enc._code_data
+
     if policy == "none" then
         if not is_even then
             rshift(digits) -- add a heading zero for padding
-            slen = slen + 1
         end
     elseif policy == "add" then
         if is_even then
@@ -541,16 +568,15 @@
     else
         return false, "[InternalError] wrong enum value"
     end
-    enc._code_len = slen
     return true, nil
 end
 
 -- input code post processing
-function ITF:_finalize() --> ok, err
+function ITF:_finalize(parse_state) --> ok, err
     local var = self._variant
     if var then
         assert(var == "ITF14")
-        return itf14_finalize(self)
+        return itf14_finalize(self, parse_state)
     else
         return basic_finalize(self)
     end
@@ -569,59 +595,74 @@
 
 -- drawing function
 -- tx, ty is an optional translator vector
-function ITF:append_ga(canvas, tx, ty) --> canvas
-    local err = canvas:start_bbox_group(); assert(not err, err)
+function ITF:_append_ga(canvas, tx, ty) --> bbox
+    local Repo = self._vbar_data
+    local queue = assert(Repo:get("start")) -- build the vbars queue
+    local digits = self._code_data
+    local n = #digits
+    for i = 1, n, 2 do
+        local index = 10 * digits[i] + digits[i+1]
+        queue = queue + assert(Repo:get(index))
+    end
+    queue = queue + assert(Repo:get("stop"))
     -- draw the start symbol
     local xdim = self.module
     local ratio = self.ratio
-    local symb_len = 2 * xdim * (3 + 2*ratio)
-    local x0 = tx or 0
-    local xpos = x0
-    local y0 = ty or 0
-    local y1 = y0 + self.height
-    local start = self._vbar_start
-    local err
-    err = canvas:encode_Vbar(start, xpos, y0, y1); assert(not err, err)
-    xpos = xpos + 4 * xdim
-    -- draw the code symbol
-    local digits = self._code_data
-    local vbars = self._vbar_data
-    for i = 1, #digits, 2 do
-        local index = 10 * digits[i] + digits[i+1]
-        local b = vbars[index]
-        err = canvas:encode_Vbar(b, xpos, y0, y1); assert(not err, err)
-        xpos = xpos + symb_len
-    end
-    -- draw the stop symbol
-    local stop = self._vbar_stop
-    err = canvas:encode_Vbar(stop, xpos, y0, y1); assert(not err, err)
+    local w = xdim * (6 + ratio + n * (3 + 2 * ratio))
+    local ax, ay = self.ax, self.ay
+    local h = self.height
+    local x0 = tx - w * ax
+    local y0 = ty - h * ay
+    local y1 = y0 + h
+    assert(canvas:encode_disable_bbox())
+    assert(canvas:encode_vbar_queue(queue, x0, y0, y1))
     -- bounding box setting
-    local x1 = xpos + (2 + ratio)*xdim
+    local x1 = x0 + w
     local qz = self.quietzone
-    if self._variant then
+    if self._variant == "ITF14" then -- "ITF14"
         qz = qz * xdim
     end
-    local b1x,  b1y = x0 - qz, y0
-    local b2x,  b2y = x1 + qz, y1
+    local b1x, b1y = x0 - qz, y0
+    local b2x, b2y = x1 + qz, y1
+    local bq1, bq3 = qz, qz
+    local bq2, bq4
     if self.bearer_bars_enabled then
-        local w = self.bearer_bars_thickness
-        err = canvas:encode_linethick(w); assert(not err, err)
-        b1y, b2y = b1y - w, b2y + w
+        local t = self.bearer_bars_thickness
+        local t2 = t/2
+        assert(canvas:encode_linewidth(t))
+        b1y, b2y = b1y - t, b2y + t
+        bq2, bq4 = t, t
         local layout = self.bearer_bars_layout
         if layout == "hbar" then
-            err = canvas:encode_hline(b1x, b2x, y0 - w/2); assert(not err, err)
-            err = canvas:encode_hline(b1x, b2x, y1 + w/2); assert(not err, err)
+            assert(canvas:encode_hline(b1x, b2x, y0 - t2))
+            assert(canvas:encode_hline(b1x, b2x, y1 + t2))
         elseif layout == "frame" then
-            err = canvas:encode_rectangle(b1x - w/2, y0 - w/2, b2x + w/2, y1 + w/2)
-            assert(not err, err)
-            b1x, b2x = b1x - w, b2x + w
+            assert(canvas:encode_rect(b1x - t2, y0 - t2, b2x + t2, y1 + t2))
+            b1x, b2x = b1x - t, b2x + t
+            bq1, bq3 = bq1 + t, bq3 + t
         else
-            error("[IntenalErr] bearer bars layout option is wrong")
+            error("[InternalErr] unexpected bearer bars layout option value")
         end
     end
-    local err = canvas:stop_bbox_group(b1x, b1y, b2x, b2y)
-    assert(not err, err)
-    return canvas
+    assert(canvas:encode_set_bbox(b1x, b1y, b2x, b2y))
+    assert(canvas:encode_enable_bbox())
+    if self.text_enabled then
+        local Text = self._libgeo.Text
+        local t
+        if self._variant == "ITF14" then
+            local code = self._code_text
+            if code == nil then
+                code = self._code_data
+            end
+            t = Text:from_chars(code)
+        else
+            t = Text:from_digit_array(self._code_data)
+        end
+        local y_top = b1y -  0.6 * 186467 -- mm
+        local x_top = (b1x + b2x)/2
+        assert(canvas:encode_Text(t, x_top, y_top, 0.50, 1))
+    end
+    return {x0, y0, x1, y1, bq1, bq2, bq3, bq4,}
 end
 
 return ITF

Added: trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-upc.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-upc.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-upc.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -0,0 +1,251 @@
+-- Universal Product Code
+-- UPC family barcode generator
+--
+-- Copyright (C) 2019-2022 Roberto Giacomelli
+-- see LICENSE.txt file
+
+local UPC = {
+    _VERSION     = "upc v0.0.2",
+    _NAME        = "upc",
+    _DESCRIPTION = "UPC barcode encoder",
+}
+
+UPC._pattern = {[0] = 3211, 2221, 2122, 1411, 1132, 1231, 1114, 1312, 1213, 3112,}
+UPC._sepbar = 111
+
+UPC._id_variant = {
+    A = true, -- UPC-A
+}
+
+-- common family parameters
+UPC._par_order = {
+    "mod",
+    "height",
+    "bars_depth_factor",
+    "quietzone_factor",
+    "text_enabled",
+    "text_ygap_factor",
+    "text_xgap_factor",
+}
+UPC._par_def = {}
+local pardef = UPC._par_def
+
+-- from Wikipedia https://en.wikipedia.org/wiki/Universal_Product_Code
+-- The x-dimension for the UPC-A at the nominal size is 0.33 mm (0.013").
+-- UPC-A can be reduced or magnified anywhere from 80% to 200%.
+-- standard module is 0.33 mm but it may vary from 0.264 to 0.66mm
+pardef.mod = {
+    default    = 0.33 * 186467, -- (mm to sp) X dimension (original value 0.33)
+    unit       = "sp", -- scaled point
+    isReserved = true,
+    fncheck    = function (_self, x, _) --> boolean, err
+        local mm = 186467
+        local min, max = 0.264*mm, 0.660*mm
+        if x < min then
+            return false, "[OutOfRange] too small value for mod"
+        elseif x > max then
+            return false, "[OutOfRange] too big value for mod"
+        end
+        return true, nil
+    end,
+}
+
+-- Nominal symbol height for UPC-A is 25.9 mm (1.02")
+pardef.height = {
+    default    = 25.9 * 186467,
+    unit       = "sp",
+    isReserved = false,
+    fncheck    = function (self, h, _enc) --> boolean, err
+        if h > 0 then
+            return true, nil
+        else
+            return false, "[OutOfRange] non positive value for height"
+        end
+    end,
+}
+
+-- The bars forming the S (start), M (middle), and E (end) guard patterns, are
+-- extended downwards by 5 times x-dimension, with a resulting nominal symbol
+-- height of 27.55 mm (1.08")
+pardef.bars_depth_factor = {
+    default    = 5,
+    unit       = "absolute-number",
+    isReserved = false,
+    fncheck    = function (_self, b, _) --> boolean, err
+        if b >= 0 then
+            return true, nil
+        else
+            return false, "[OutOfRange] non positive value for bars_depth_factor"
+        end
+    end,
+}
+
+-- A quiet zone, with a width of at least 9 times the x-dimension, must be
+-- present on each side of the scannable area of the UPC-A barcode.
+pardef.quietzone_factor = {
+    default    = 9,
+    unit       = "absolute-number",
+    isReserved = false,
+    fncheck    = function (_self, qzf, _) --> boolean, err
+        if qzf > 0 then
+            return true, nil
+        else
+            return false, "[OutOfRange] non positive value for quietzone_right_factor"
+        end
+    end,
+}
+
+-- enable/disable human readble text
+pardef.text_enabled = { -- boolean type
+    default    = true,
+    isReserved = false,
+    fncheck    = function (_self, flag, _) --> boolean, err
+        if type(flag) == "boolean" then
+            return true, nil
+        else
+            return false, "[TypeErr] not a boolean value for text_enabled"
+        end
+    end,
+}
+
+-- vertical gap from text and symbol baseline
+pardef.text_ygap_factor = {
+    default    = 1.0,
+    unit       = "absolute-number",
+    isReserved = false,
+    fncheck    = function (_self, t, _) --> boolean, err
+        if t >= 0 then
+            return true, nil
+        else
+            return false, "[OutOfRange] non positive value for text_ygap_factor"
+        end
+    end,
+}
+
+-- horizontal gap from text and symbol bars
+pardef.text_xgap_factor = {
+    default    = 0.75,
+    unit       = "absolute-number",
+    isReserved = false,
+    fncheck    = function (_self, t, _) --> boolean, err
+        if t >= 0 then
+            return true, nil
+        else
+            return false, "[OutOfRange] non positive value for text_xgap_factor"
+        end
+    end,
+}
+
+-- utility function
+
+-- the checksum of UPC-A
+-- 'data' is an array of digits
+local function checkdigit_A(data) --> checksum, ok
+    local s = 0
+    for i = 1, 11, 2 do
+        s = s + data[i]
+    end
+    s = 3*s
+    for i = 2, 10, 2 do
+        s = s + data[i]
+    end
+    local res = s % 10
+    if res > 0  then
+        res = 10 - res
+    end
+    return res, data[12] == res
+end
+
+-- internal methods for Barcode costructors
+
+-- config function called at the moment of encoder construction
+function UPC:_config() --> ok, err
+    local variant = self._variant
+    if not variant then
+        return false, "[Err] variant is mandatory for the UPC family"
+    end
+    local Vbar = self._libgeo.Vbar -- Vbar class
+    local Vbar_archive = self._libgeo.Archive -- Archive class
+    local Codeset = Vbar_archive:new()
+    self._upca_codeset = Codeset
+    local mod = self.mod
+    local sepbar = self._sepbar
+    Codeset:insert(Vbar:from_int(sepbar, mod), "sepbar")
+    local symb = self._pattern
+    for i = 0, 9 do
+        Codeset:insert(Vbar:from_int(symb[i], mod, false), 0, i)
+        Codeset:insert(Vbar:from_int(symb[i], mod, true), 1, i)
+    end
+    return true, nil
+end
+
+-- function called every time an input UPC-A code has been completely parsed
+function UPC:_finalize() --> ok, err
+    local data = self._code_data
+    local symb_len = #data
+    if symb_len ~= 12 then
+        return false, "[ArgErr] not a 12-digit long array"
+    end
+    local ck, ok = checkdigit_A(data)
+    if not ok then -- is the last digit ok?
+        return false,
+        "[Err] incorrect last digit "..data[12]..", the checksum is "..ck
+    end
+    return true, nil
+end
+
+-- Drawing into the provided channel geometrical data
+-- tx, ty is the optional translation vector
+-- the function return the canvas reference to allow call chaining
+function UPC:_append_ga(canvas, tx, ty) --> bbox
+    local Codeset = self._upca_codeset
+    local code = self._code_data
+    local mod = self.mod
+    local sepbar = assert(Codeset:get("sepbar"))
+    local queue_0 = sepbar + assert(Codeset:get(0, code[1])) +
+        36*mod + sepbar + 36*mod +
+        assert(Codeset:get(1, code[12])) + sepbar
+    local queue_1 = 10*mod
+    for i = 2, 6 do
+        queue_1 = queue_1 + assert(Codeset:get(0, code[i]))
+    end
+    queue_1 = queue_1 + 5*mod
+    for i = 7, 11 do
+        queue_1 = queue_1 + assert(Codeset:get(1, code[i]))
+    end
+    local bars_depth = mod * self.bars_depth_factor
+    local w, h = 95*mod, self.height + bars_depth
+    local x0 = tx - self.ax * w
+    local y0 = ty - self.ay * h
+    local x1 = x0 + w
+    local y1 = y0 + h
+    local ys = y0 + bars_depth
+    -- draw the symbol
+    assert(canvas:encode_disable_bbox())
+    assert(canvas:encode_vbar_queue(queue_0, x0, y0, y1))
+    assert(canvas:encode_vbar_queue(queue_1, x0, ys, y1))
+    -- bounding box set up
+    local qz = self.quietzone_factor * mod
+    assert(canvas:encode_set_bbox(x0 - qz, y0, x1 + qz, y1))
+    assert(canvas:encode_enable_bbox())
+    if self.text_enabled then -- human readable text
+        local Text  = self._libgeo.Text
+        local txt_1 = Text:from_digit_array(code, 1,  1)
+        local txt_2 = Text:from_digit_array(code, 2,  6)
+        local txt_3 = Text:from_digit_array(code, 7, 11)
+        local txt_4 = Text:from_digit_array(code, 12, 12)
+        local y_bl = ys - self.text_ygap_factor * mod
+        assert(canvas:encode_Text(txt_1, x0 - qz, y_bl, 0, 1))
+        local mx = self.text_xgap_factor
+        local x2_1 = x0 + (10+mx)*mod
+        local x2_2 = x0 + (46-mx)*mod
+        assert(canvas:encode_Text_xwidth(txt_2, x2_1, x2_2, y_bl, 1))
+        local x3_1 = x0 + (49+mx)*mod
+        local x3_2 = x0 + (85-mx)*mod
+        assert(canvas:encode_Text_xwidth(txt_3, x3_1, x3_2, y_bl, 1))
+        assert(canvas:encode_Text(txt_4, x1 + qz, y_bl, 1, 1))
+    end
+    return {x0, y0, x1, y1, qz, nil, qz, nil,}
+end
+
+return UPC


Property changes on: trunk/Master/texmf-dist/scripts/barracuda/lib-barcode/brcd-upc.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-driver.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-driver.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-driver.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -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 @@
     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 @@
     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 @@
     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 @@
     -- 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,18 +173,15 @@
 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
@@ -142,20 +188,47 @@
     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)
+    -- 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,
+    [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) -- end_bbox_group
-        assert(st.bb_on == false)
-        st.bb_on = true
+    [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 @@
         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 @@
             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 @@
         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 @@
             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 @@
         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 @@
             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

Modified: trunk/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-pdfliteral.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-pdfliteral.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-pdfliteral.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -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 @@
     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 @@
     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 @@
 -- 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 @@
     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)

Modified: trunk/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-svg.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-svg.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/scripts/barracuda/lib-driver/brcd-drv-svg.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -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 @@
     }
     -- 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 @@
     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,11 +50,26 @@
 -- 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
 
--- draw an horizontal line
+-- 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 <hline> opcode
 -- 33 <x1: DIM> <x2: DIM> <y: DIM>
 function SVG.append_033(st, bf, xt, x1, x2, y)
     local lvl = st.ident_lvl
@@ -66,14 +76,29 @@
     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 @@
     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 @@
     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>

Modified: trunk/Master/texmf-dist/scripts/barracuda/lib-geo/brcd-gacanvas.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/barracuda/lib-geo/brcd-gacanvas.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/scripts/barracuda/lib-geo/brcd-gacanvas.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,86 +1,208 @@
 -- class gaCanvas
--- Copyright (C) 2020 Roberto Giacomelli
+-- Copyright (C) 2019-2022 Roberto Giacomelli
+-- <ga> encoding functions (see barracuda-manual.pdf)
 
--- ga -- basic function
-
-local gaCanvas = {
-    _VERSION     = "gacanvas v0.0.4",
-    _NAME        = "gaCanvas",
-    _DESCRIPTION = "A library for dealing with ga stream",
-}
+local gaCanvas = {_classname = "gaCanvas"}
 gaCanvas.__index = gaCanvas
+gaCanvas.mm = 186467.98110236 -- conversion factor sp -> mm (millimeter)
+gaCanvas.bp = 65781.76 -- conversion factor sp -> bp (big point)
+gaCanvas.pt = 65536 -- sp -> pt
 
 -- ga specification: see the file ga-grammar.pdf in the doc directory
 
 -- gaCanvas constructor
 function gaCanvas:new() --> object
-    local o = {
-        _data = {},
-        _v    = 100, -- version of the ga format
-    }
+    local drv = assert(self._driver_class)
+    -- graphic state fields returned by Driver:default_style() method
+    -- linewidth
+    -- linecap
+    -- linejoin
+    -- dashpattern
+    -- dashphase
+    local o = assert(drv:default_style()) -- initial graphic state
+    o._version = 100  -- version of the ga format
+    o._data = {} -- ga stream array
+    o.bb_on = true
     setmetatable(o, self)
     return o
 end
 
--- Ipothetical another constructor
+-- save graphic data in an external file with the 'id_drv' format
+-- id_drv::= string, specific driver output identifier
+-- filename ::= string, file name
+-- ext ::= string, file extension (optional, default SVG)
+function gaCanvas:save(id_drv, filename, ext) --> ok, err
+    local driver = self._driver_class
+    return driver:save(id_drv, self, filename, ext)
+end
+
+-- insert a ga drawing in a TeX hbox
+-- PDFnative only function
+-- boxname ::= string
+function gaCanvas:ga_to_hbox(boxname) --> ok, err
+    local driver = self._driver_class
+    return driver:ga_to_hbox(self, boxname)
+end
+
+-- return a clone of the <ga> stream array
+function gaCanvas:get_stream() --> table (as a flat array)
+    local data = self._data
+    local t = {}
+    for _, v in ipairs(data) do
+        t[#t + 1] = v
+    end
+    return t
+end
+
+-- Ipothetical further constructor
 -- function gaCanvas:from_tcp_server() --> err
 -- end
 
+-- function gaCanvas:get_bbox()
+-- end
+
+-- function gaCanvas:check() --> ok, err 
+-- end
+
 -- line width: opcode <1> <w: DIM>
-function gaCanvas:encode_linethick(w) --> err
-    if type(w) ~= "number" then return "[ArgErr] 'w' number expected" end
-    if w < 0 then return "[ArgErr] negative value for 'w'" end
+function gaCanvas:encode_linewidth(w) --> ok, err
+    if type(w) ~= "number" then
+        return false, "[ArgErr 'w'] number expected"
+    end
+    if w < 0 then return false, "[ArgErr: w] negative number not allowed" end
+    self.linewidth = w
     local data = self._data
     data[#data + 1] = 1 -- opcode for line thickness
     data[#data + 1] = w
+    return true, nil
 end
 
--- line cap style: opcode <2> <cap: u8>
--- 0 Butt cap
--- 1 Round cap
--- 2 Projecting square cap
-function gaCanvas:encode_linecap(cap) --> err
-    if type(cap) ~= "number" then return "[ArgErr] 'cap' arg number expected" end
-    if cap == 0 or cap == 1 or cap == 2 then
-        local data = self._data
-        data[#data + 1] = 2 -- opcode for line cap style
-        data[#data + 1] = cap
+-- line cap style: opcode <2> cap <u8>|<enum>
+-- 0 | "butt": Butt cap
+-- 1 | "round": Round cap
+-- 2 | "proj": Projecting square cap
+function gaCanvas:encode_linecap(cap) --> ok, err
+    local tcap = type(cap)
+    local cap_res
+    if tcap == "number" then
+        if cap == 0 or cap == 1 or cap == 2 then
+            cap_res = cap
+        else
+            return false, "[ArgErr: cap] 0, 1 or 2 expected"
+        end
+    elseif tcap == "string" then
+        if cap == "butt" then
+            cap_res = 0
+        elseif cap == "round" then
+            cap_res = 1
+        elseif cap == "proj" then
+            cap_res = 2
+        else
+            return false, "[ArgErr: cap] 'butt', 'round' or 'proj' expected"
+        end
     else
-        return "[ArgErr] invalid value for 'cap'"
+        return false, "[ArgErr: cap] number or string expected"
     end
+    self.linecap = cap_res
+    local data = self._data
+    data[#data + 1] = 2 -- opcode for line cap style
+    data[#data + 1] = cap_res
+    return true, nil
 end
 
--- line cap style: opcode <3> <join: u8>
--- 0 Miter join
--- 1 Round join
--- 2 Bevel join
-function gaCanvas:encode_linejoin(join) --> err
-    if type(join) ~= "number" then return "[ArgErr] 'join' arg number expected" end
-    if join == 0 or join == 1 or join == 2 then
-        local data = self._data
-        data[#data + 1] = 3 -- opcode for line join style
-        data[#data + 1] = join
+-- line join style: opcode <3> join <u8>|<enum>
+-- 0 | "miter" : Miter join
+-- 1 | "round" : Round join
+-- 2 | "bevel" : Bevel join
+function gaCanvas:encode_linejoin(join) --> ok, err
+    local tjoin = type(join)
+    local join_res
+    if tjoin == "number" then
+        if join == 0 or join == 1 or join == 2 then
+            join_res = join
+        else
+            return false, "[ArgErr: join] 0, 1 or 2 integer expected"
+        end
+    elseif tjoin == "string" then
+        if join == "miter" then
+            join_res = 0
+        elseif join == "round" then
+            join_res = 1
+        elseif join == "bevel" then
+            join_res = 2
+        else
+            return false, "[ArgErr: join] '"..join.."' join style not found"
+        end
     else
-        return "[ArgErr] invalid value for 'join'"
+        return false, "[ArgErr: join] number or string expected"
     end
+    self.linejoin = join_res
+    local data = self._data
+    data[#data + 1] = 3 -- opcode for line join style
+    data[#data + 1] = join_res
+    return true, nil
 end
 
+-- 5 <dash_pattern>, Dash pattern line style, p <len> n <qty> bi <len>
+-- p: phase lenght
+-- n: number of array element
+-- [bi]: dash array of dash and gap lenghts
+function gaCanvas:encode_dash_pattern(p, ...) --> ok, err
+    if type(p) ~= "number" then return false, "[ArgErr: phase] number expected" end
+    local t = {...}
+    for i, v in ipairs(t) do
+        if type(v) ~= "number" then
+            return false, "[ArgErr: array] found a not number value at index " .. i
+        end
+    end
+    self.dash_pattern = t
+    self.dash_phase = p
+    local n = #t
+    local d = self._data
+    d[#d + 1] = 5
+    d[#d + 1] = p
+    d[#d + 1] = n
+    for _, b in ipairs(t) do
+        d[#d + 1] = b
+    end
+    return true, nil
+end
+
+-- 6 <reset_pattern>, set the continous line style
+function gaCanvas:encode_reset_pattern() --> ok, err
+    self.dash_pattern = nil
+    self.dash_phase = nil
+    local d = self._data
+    d[#d + 1] = 6
+    return true, nil
+end
+
+-- checking the bounding box from now on
+-- opcode: <29>
+function gaCanvas:encode_enable_bbox() --> ok, err
+    self.bb_on = true
+    local data = self._data
+    data[#data + 1] = 29
+    return true, nil
+end
+
 -- Stop checking the bounding box
 -- opcode: <30>
-function gaCanvas:start_bbox_group() --> err
+function gaCanvas:encode_disable_bbox() --> ok, err
+    self.bb_on = false
     local data = self._data
     data[#data + 1] = 30
+    return true, nil
 end
 
--- restart checking the bounding box
--- and insert the specified bb for the entire object group
+-- insert a figure bbox
 -- code: <31> x1 y1 x2 y2
-function gaCanvas:stop_bbox_group(x1, y1, x2, y2) --> err
-    if type(x1) ~= "number" then return "[ArgErr] 'x1' number expected" end
-    if type(y1) ~= "number" then return "[ArgErr] 'y1' number expected" end
-    if type(x2) ~= "number" then return "[ArgErr] 'x2' number expected" end
-    if type(y2) ~= "number" then return "[ArgErr] 'y2' number expected" end
-    if x1 > x2 then x1, x2 = x2, x1 end -- reorder coordinates
+function gaCanvas:encode_set_bbox(x1, y1, x2, y2) --> ok, err
+    if type(x1) ~= "number" then return false, "[ArgErr: x1] number expected" end
+    if type(y1) ~= "number" then return false, "[ArgErr: y1] number expected" end
+    if type(x2) ~= "number" then return false, "[ArgErr: x2] number expected" end
+    if type(y2) ~= "number" then return false, "[ArgErr: y2] number expected" end
+    if x1 > x2 then x1, x2 = x2, x1 end -- re-order coordinates
     if y1 > y2 then y1, y2 = y2, y1 end
     local data = self._data
     data[#data + 1] = 31 -- bounding box of the object group
@@ -88,15 +210,28 @@
     data[#data + 1] = y1
     data[#data + 1] = x2
     data[#data + 1] = y2
+    return true, nil
 end
 
 -- insert a line from point (x1, y1) to the point (x2, y2)
+-- tx optional translator x-vector
+-- ty optional translator y-vector
 -- <32> x1 y1 x2 y2
-function gaCanvas:encode_line(x1, y1, x2, y2) --> err
-    if type(x1) ~= "number" then return "[ArgErr] 'x1' number expected" end
-    if type(y1) ~= "number" then return "[ArgErr] 'y1' number expected" end
-    if type(x2) ~= "number" then return "[ArgErr] 'x2' number expected" end
-    if type(y2) ~= "number" then return "[ArgErr] 'y2' number expected" end
+function gaCanvas:encode_line(x1, y1, x2, y2, tx, ty) --> ok, err
+    if type(x1) ~= "number" then return false, "[ArgErr: x1] number expected" end
+    if type(y1) ~= "number" then return false, "[ArgErr: y1] number expected" end
+    if type(x2) ~= "number" then return false, "[ArgErr: x2] number expected" end
+    if type(y2) ~= "number" then return false, "[ArgErr: y2] number expected" end
+    if tx ~= nil then
+        if type(tx) ~= "number" then return false, "[ArgErr: tx] number expected" end
+        x1 = x1 + tx
+        x2 = x2 + tx
+    end
+    if ty ~= nil then
+        if type(ty) ~= "number" then return false, "[ArgErr: ty] number expected" end
+        y1 = y1 + ty
+        y2 = y2 + ty
+    end
     local data = self._data
     data[#data + 1] = 32 -- append line data
     data[#data + 1] = x1
@@ -103,28 +238,126 @@
     data[#data + 1] = y1
     data[#data + 1] = x2
     data[#data + 1] = y2
+    return true, nil
 end
 
 -- insert an horizontal line from point (x1, y) to point (x2, y)
+-- tx optional translator x-vector
+-- ty optional translator y-vector
 -- <33> x1 x2 y
-function gaCanvas:encode_hline(x1, x2, y) --> err
-    if type(x1) ~= "number" then return "[ArgErr] 'x1' number expected" end
-    if type(x2) ~= "number" then return "[ArgErr] 'x2' number expected" end
-    if type(y) ~= "number" then return "[ArgErr] 'y2' number expected" end
+function gaCanvas:encode_hline(x1, x2, y, tx, ty) --> ok, err
+    if type(x1) ~= "number" then return false, "[ArgErr: x1] number expected" end
+    if type(x2) ~= "number" then return false, "[ArgErr: x2] number expected" end
+    if type(y) ~= "number" then return false, "[ArgErr: y] number expected" end
+    if tx ~= nil then
+        if type(tx) ~= "number" then return false, "[ArgErr: tx] number expected" end
+        x1 = x1 + tx
+        x2 = x2 + tx
+    end
+    if ty ~= nil then
+        if type(ty) ~= "number" then return false, "[ArgErr: ty] number expected" end
+        y = y + ty
+    end
     local data = self._data
     data[#data + 1] = 33 -- append hline data
     data[#data + 1] = x1
     data[#data + 1] = x2
     data[#data + 1] = y
+    return true, nil
 end
 
+-- vline, Vertical line, from point (x, y1) to point (x, y2)
+-- tx optional translator x-vector
+-- ty optional translator y-vector
+-- <34> y1 y2 x
+function gaCanvas:encode_vline(y1, y2, x, tx, ty) --> ok, err
+    if type(y1) ~= "number" then return false, "[ArgErr] 'y1' number expected" end
+    if type(y2) ~= "number" then return false, "[ArgErr] 'y2' number expected" end
+    if type(x) ~= "number" then return false, "[ArgErr] 'x' number expected" end
+    if tx ~= nil then
+        if type(tx) ~= "number" then return false, "[ArgErr: tx] number expected" end
+        x = x + tx
+    end
+    if ty ~= nil then
+        if type(ty) ~= "number" then return false, "[ArgErr: ty] number expected" end
+        y1 = y1 + ty
+        y2 = y2 + ty
+    end
+    local data = self._data
+    data[#data + 1] = 34 -- append vline data
+    data[#data + 1] = y1
+    data[#data + 1] = y2
+    data[#data + 1] = x
+    return true, nil
+end
+
+-- insert an open polyline
+-- tx optional translator x-vector
+-- ty optional translator y-vector
+-- <38> <n> x1 y1 x2, y2, ... , xn, yn
+function gaCanvas:encode_polyline(point, tx, ty) --> ok, err
+    if type(point) ~= "table" then
+        return false, "[ArgErr: point] table expected"
+    end
+    local n, p
+    if point._classname == "Polyline" then
+        n, p = point:get_points()
+    else
+        local len = #point
+        if len == 0 then return false, "[Err] 'point' is an empty table" end
+        if (len % 2) ~= 0 then
+            return false, "[Err] 'point' is not an even long array"
+        end
+        n = len/2
+        for _, coord in ipairs(point) do
+            if type(coord) ~= "number" then
+                return false, "[Err] found a non-number in the 'point' array"
+            end
+        end
+        p = point
+    end
+    if n < 2 then return
+        false, "[Err] a polyline must have at least two points"
+    end
+    if tx ~= nil then
+        if type(tx) ~= "number" then return false, "[ArgErr: tx] number expected" end
+    else
+        tx = 0
+    end
+    if ty ~= nil then
+        if type(ty) ~= "number" then return false, "[ArgErr: ty] number expected" end
+    else
+        ty = 0
+    end
+    local data = self._data
+    data[#data + 1] = 38
+    data[#data + 1] = n
+    for i = 1, 2*n, 2 do
+        data[#data + 1] = p[i] + tx
+        data[#data + 1] = p[i + 1] + ty
+    end
+    return true, nil
+end
+
 -- insert a rectangle from point (x1, x2) to (x2, y2)
+-- tx optional translator x-vector
+-- ty optional translator y-vector
 -- <48> <x1: DIM> <y1: DIM> <x2: DIM> <y2: DIM>
-function gaCanvas:encode_rectangle(x1, y1, x2, y2) --> err
-    if type(x1) ~= "number" then return "[ArgErr] 'x1' number expected" end
-    if type(y1) ~= "number" then return "[ArgErr] 'y1' number expected" end
-    if type(x2) ~= "number" then return "[ArgErr] 'x2' number expected" end
-    if type(y2) ~= "number" then return "[ArgErr] 'y2' number expected" end
+function gaCanvas:encode_rect(x1, y1, x2, y2, tx, ty) --> ok, err
+    if type(x1) ~= "number" then return false, "[ArgErr] 'x1' number expected" end
+    if type(y1) ~= "number" then return false, "[ArgErr] 'y1' number expected" end
+    if type(x2) ~= "number" then return false, "[ArgErr] 'x2' number expected" end
+    if type(y2) ~= "number" then return false, "[ArgErr] 'y2' number expected" end
+    if tx ~= nil then
+        if type(tx) ~= "number" then return false, "[ArgErr: tx] number expected" end
+        x1 = x1 + tx
+        x2 = x2 + tx
+    end
+    if ty ~= nil then
+        if type(ty) ~= "number" then return false, "[ArgErr: ty] number expected" end
+        y1 = y1 + ty
+        y2 = y2 + ty
+    end
     local d = self._data
     d[#d + 1] = 48 -- append rectangle data
     d[#d + 1] = x1
@@ -131,70 +364,130 @@
     d[#d + 1] = y1
     d[#d + 1] = x2
     d[#d + 1] = y2
+    return true, nil
 end
 
 -- Vbar object: opcode <36>
+-- tx optional translator x-vector
+-- ty optional translator y-vector
 -- x0, y1, y2 ordinates
-function gaCanvas:encode_Vbar(vbar, x0, y1, y2) --> err
+function gaCanvas:encode_vbar(vbar, x0, y1, y2, tx, ty) --> ok, err
     if type(vbar) ~= "table" then
-        return "[ArgErr] table expected for 'vbar'"
+        return false, "[ArgErr: vbar] table expected"
     end
     if x0 == nil then
         x0 = 0
     elseif type(x0) ~= "number" then
-        return "[ArgErr] 'x0' number expected"
+        return false, "[ArgErr: x0] number expected"
     end
-    if type(y1) ~= "number" then return "[ArgErr] 'y1' number expected" end
-    if type(y2) ~= "number" then return "[ArgErr] 'y2' number expected" end
+    if type(y1) ~= "number" then return false, "[ArgErr: y1] number expected" end
+    if type(y2) ~= "number" then return false, "[ArgErr: y2] number expected" end
     -- ordinates
-    if y1 == y2 then return "[ArgErr] 'y1' 'y2' are the same value" end
+    if y1 == y2 then return false, "[ArgErr: y1, y2] same value" end
     if y1 > y2 then y1, y2 = y2, y1 end
-    local bars = assert(vbar._yline, "[InternalErr] no '_yline' field")
-    local bdim = #bars
-    if bdim == 0 then return "[InternalErr] number of bars is zero" end
-    if bdim % 2 ~= 0 then
-        return "[InternalErr] '_yline' does not have an even number of elements"
+    local bdim, bars
+    if vbar._classname == "Vbar" then
+        bdim, bars = vbar:get_bars()
+        bdim = 2*bdim
+    else
+        bdim = #vbar
+        if bdim % 2 ~= 0 then -- bdim must be even
+            return false, "[Err: vbar] found an odd array of elements"
+        end
+        bars = vbar
     end
+    if bdim == 0 then return false, "[Err: vbar] the number of bars is zero" end
+    if tx ~= nil then
+        if type(tx) ~= "number" then return false, "[ArgErr: tx] number expected" end
+        x0 = x0 + tx
+    end
+    if ty ~= nil then
+        if type(ty) ~= "number" then return false, "[ArgErr: ty] number expected" end
+        y1 = y1 + ty
+        y2 = y2 + ty
+    end
     local data = self._data
     data[#data + 1] = 36 -- vbar sequence start
     data[#data + 1] = y1
     data[#data + 1] = y2
-    data[#data + 1] = bdim / 2 -- the number of bars <x_i t_i>
+    data[#data + 1] = bdim/2 -- the number of bars, pair <x_i, w_i>
     for i = 1, bdim, 2 do
         local coord = bars[i]
         local width = bars[i + 1]
         if type(coord) ~= "number" then
-            return "[Err] a coordinates is not a number"
+            return false, "[Err] a coordinates is not a number"
         end
         if type(width) ~= "number" then
-            return "[Err] a width is not a number"
+            return false, "[Err] a width is not a number"
         end
         data[#data + 1] = coord + x0
         data[#data + 1] = width
     end
+    return true, nil
 end
 
--- [text] <130> ax ay x y chars
-function gaCanvas:encode_Text(txt, xpos, ypos, ax, ay) --> err
+-- print a Vbar queue starting at x position 'xpos', between the horizontal line
+-- tx optional translator x-vector
+-- ty optional translator y-vector
+-- at y0 and y1 y-coordinates
+function gaCanvas:encode_vbar_queue(queue, xpos, y0, y1, tx, ty) --> ok, err
+    -- check arg
+    if type(queue) ~= "table" then
+        return false, "[ArgErr: queue] table expected"
+    end
+    if type(xpos) ~= "number" then
+        return false, "[ArgErr: xpos] number expected"
+    end
+    if type(y0) ~= "number" then
+        return false, "[ArgErr: y0] number expected"
+    end
+    if type(y1) ~= "number" then
+        return false, "[ArgErr: y1] number expected"
+    end
+    local i = 2
+    while queue[i] do
+        local x = queue[i - 1] + xpos
+        local vbar = queue[i]
+        local _, err = self:encode_vbar(vbar, x, y0, y1, tx, ty)
+        if err then return false, err end
+        i = i + 2
+    end
+    return true, nil
+end
+
+-- tx optional translator x-vector
+-- ty optional translator y-vector
+-- [text] <130> ax ay xpos ypos chars
+function gaCanvas:encode_Text(txt, xpos, ypos, ax, ay, tx, ty) --> ok, err
     if type(txt) ~= "table" then
-        return "[ArgErr] 'txt' object table expected"
+        return false, "[ArgErr: txt] object table expected"
     end
     if type(xpos) ~= "number" then
-        return "[ArgErr] 'xpos' number expected"
+        return false, "[ArgErr: xpos] number expected"
     end
     if type(ypos) ~= "number" then
-        return "[ArgErr] 'ypos' number expected"
+        return false, "[ArgErr: ypos] number expected"
     end
     if ax == nil then
         ax = 0
     elseif type(ax) ~= "number" then
-        return "[ArgErr] 'ax' number expected"
+        return false, "[ArgErr: ax] number expected"
     end
     if ay == nil then
         ay = 0
     elseif type(ay) ~= "number" then
-        return "[ArgErr] 'ay' number expected"
+        return false, "[ArgErr: ay] number expected"
     end
+    if tx ~= nil then
+        if type(tx) ~= "number" then return false, "[ArgErr: tx] number expected" end
+        xpos = xpos + tx
+    end
+    if ty ~= nil then
+        if type(ty) ~= "number" then return false, "[ArgErr: ty] number expected" end
+        ypos = ypos + ty
+    end
+    local chars = assert(txt.codepoint, "[InternalErr: txt] no 'codepoint' found")
+    if #chars == 0 then return false, "[InternalErr: txt] no chars found" end
     local data = self._data
     data[#data + 1] = 130
     data[#data + 1] = ax -- relative anchor x-coordinate
@@ -201,37 +494,47 @@
     data[#data + 1] = ay -- relative anchor y-coordinate
     data[#data + 1] = xpos -- text x-coordinate
     data[#data + 1] = ypos -- text y-coordinate
-    local chars = assert(txt.codepoint, "[InternalErr] no 'codepoint' field in txt")
-    if #chars == 0 then return "[InternalErr] 'txt' has no chars" end
     for _, c in ipairs(chars) do
         data[#data + 1] = c
     end
     data[#data + 1] = 0 -- end string signal
+    return true, nil
 end
 
 -- glyphs equally spaced along the baseline
+-- tx optional translator x-vector
+-- ty optional translator y-vector
 -- [text_xspaced] <131> x1 xgap ay ypos chars
-function gaCanvas:encode_Text_xspaced(txt, x1, xgap, ypos, ay) --> err
-    if type(txt)~= "table" then return "[ArgErr] 'txt' object table expected" end
-    local chars = assert(txt.codepoint, "[InternalErr] no 'codepoint' field in txt")
-    if #chars == 0 then return "[InternalErr] 'txt' has no chars" end
-    if type(x1) ~= "number" then return "[ArgErr] 'x1' number expected" end
-    if type(xgap) ~= "number" then return "[ArgErr] 'xgap' number expected" end
+function gaCanvas:encode_Text_xspaced(txt, x1, xgap, ypos, ay, tx, ty) --> ok, err
+    if type(txt)~= "table" then return false, "[ArgErr: txt] object table expected" end
+    local chars = assert(txt.codepoint, "[InternalErr: txt] no 'codepoint' found")
+    local n = #chars
+    if n == 0 then return false, "[InternalErr: txt] no chars found" end
+    if type(x1) ~= "number" then return false, "[ArgErr: x1] number expected" end
+    if type(xgap) ~= "number" then return false, "[ArgErr: xgap] number expected" end
     if xgap < 0 then
         local n = #chars
         x1 = x1 + (n - 1) * xgap
         xgap = -xgap
     end
-    if type(ypos) ~= "number" then return "[ArgErr] 'ypos' number expected" end
+    if type(ypos) ~= "number" then return false, "[ArgErr: ypos] number expected" end
     if ay == nil then
         ay = 0
     elseif type(ay) ~= "number" then
-        return "[ArgErr] 'ay' number expected"
+        return false, "[ArgErr: ay] number expected"
     end
+    if tx ~= nil then
+        if type(tx) ~= "number" then return false, "[ArgErr: tx] number expected" end
+        x1 = x1 + tx
+    end
+    if ty ~= nil then
+        if type(ty) ~= "number" then return false, "[ArgErr: ty] number expected" end
+        ypos = ypos + ty
+    end
     local data = self._data
     data[#data + 1] = 131
     data[#data + 1] = x1   -- x-coordinate of the first axis from left to right
-    data[#data + 1] = xgap -- axial distance among gliphs
+    data[#data + 1] = xgap -- axial distance between gliphs
     data[#data + 1] = ay   -- anchor relative y-coordinate
     data[#data + 1] = ypos -- text y-coordinate
     for _, c in ipairs(chars) do
@@ -238,24 +541,37 @@
         data[#data + 1] = c
     end
     data[#data + 1] = 0 -- end string signal
+    return true, nil
 end
 
 -- text_xwidth
+-- tx optional translator x-vector
+-- ty optional translator y-vector
 -- text equally spaced but within [x1, x2] coordinate interval
 -- <132> <ay: FLOAT> <x1: DIM> <x2: DIM> <y: DIM> <c: CHARS>
-function gaCanvas:encode_Text_xwidth(txt, x1, x2, ypos, ay) --> err
-    if type(txt)~= "table" then return "[ArgErr] 'txt' object table expected" end
-    if type(x1) ~= "number" then return "[ArgErr] 'x1' number expected" end
-    if type(x2) ~= "number" then return "[ArgErr] 'x2' number expected" end
-    if type(ypos) ~= "number" then return "[ArgErr] 'ypos' number expected" end
+function gaCanvas:encode_Text_xwidth(txt, x1, x2, ypos, ay, tx, ty) --> ok, err
+    if type(txt)~= "table" then return false, "[ArgErr: txt] object table expected" end
+    if type(x1) ~= "number" then return false, "[ArgErr: x1] number expected" end
+    if type(x2) ~= "number" then return false, "[ArgErr: x2] number expected" end
+    if type(ypos) ~= "number" then return false, "[ArgErr: ypos] number expected" end
     if ay == nil then
         ay = 0
     elseif type(ay) ~= "number" then
-        return "[ArgErr] 'ay' number expected"
+        return false, "[ArgErr: ay] number expected"
     end
-    local chars = assert(txt.codepoint, "[InternalErr] no 'codepoint' field in txt")
-    if #chars == 0 then return "[InternalErr] 'txt' has no chars" end
+    local chars = assert(txt.codepoint, "[InternalErr: txt] no 'codepoint' found")
+    if #chars == 0 then return false, "[InternalErr: txt] no chars found" end
     if x1 > x2 then x1, x2 = x2, x1 end -- reorder coordinates
+
+    if tx ~= nil then
+        if type(tx) ~= "number" then return false, "[ArgErr: tx] number expected" end
+        x1 = x1 + tx
+        x2 = x2 + tx
+    end
+    if ty ~= nil then
+        if type(ty) ~= "number" then return false, "[ArgErr: ty] number expected" end
+        ypos = ypos + ty
+    end
     local data = self._data
     data[#data + 1] = 132
     data[#data + 1] = ay -- anchor relative y-coordinate
@@ -266,6 +582,7 @@
         data[#data + 1] = c
     end
     data[#data + 1] = 0 -- end string signal
+    return true, nil
 end
 
 -- experimental code section
@@ -272,14 +589,15 @@
 -- new opcodes under assessment
 
 -- [start_text_group] 140
-function gaCanvas:start_text_group() --> err
+function gaCanvas:start_text_group() --> ok, err
     local data = self._data
     data[#data + 1] = 140
+    return true, nil
 end
 
 -- [gtext] 141
-function gaCanvas:gtext(chars) --> err
-    if type(chars) ~= "table" then return "[ArgErr] 'chars' table expected" end
+function gaCanvas:gtext(chars) --> ok, err
+    if type(chars) ~= "table" then return false, "[ArgErr: chars] table expected" end
     local data = self._data
     data[#data + 1] = 141
     for _, c in ipairs(chars) do
@@ -286,12 +604,13 @@
         data[#data + 1] = c
     end
     data[#data + 1] = 0 -- end string signal
+    return true, nil
 end
 
 -- [gtext_spaced] 142 gap string
-function gaCanvas:gtext_spaced(gap, chars) --> err
-    if type(gap) ~= "number" then return "[ArgErr] 'gap' number expected" end
-    if type(chars) ~= "table" then return "[ArgErr] 'chars' table expected" end
+function gaCanvas:gtext_spaced(gap, chars) --> ok, err
+    if type(gap) ~= "number" then return false, "[ArgErr: gap] number expected" end
+    if type(chars) ~= "table" then return false, "[ArgErr: chars] table expected" end
     local data = self._data
     data[#data + 1] = 142
     data[#data + 1] = gap
@@ -299,23 +618,25 @@
         data[#data + 1] = c
     end
     data[#data + 1] = 0 -- end string signal
+    return true, nil
 end
 
 -- [gtext_space] 143 gap 
-function gaCanvas:gtext_gap(gap) --> err
-    if type(gap) ~= "number" then return "[ArgErr] 'gap' number expected" end
+function gaCanvas:gtext_gap(gap) --> ok, err
+    if type(gap) ~= "number" then return false, "[ArgErr: gap] number expected" end
     local data = self._data
     data[#data + 1] = 143
     data[#data + 1] = gap
+    return true, nil
 end
 
 
 -- [end_text_group] 149 ax ay x y
-function gaCanvas:end_text_group(xpos, ypos, ax, ay) --> err
-    if type(xpos) ~= "number" then return "[ArgErr] 'xpos' number expected" end
-    if type(ypos) ~= "number" then return "[ArgErr] 'ypos' number expected" end
-    if type(ax) ~= "number" then return "[ArgErr] 'ax' number expected" end
-    if type(ay) ~= "number" then return "[ArgErr] 'ay' number expected" end
+function gaCanvas:end_text_group(xpos, ypos, ax, ay) --> ok, err
+    if type(xpos) ~= "number" then return false, "[ArgErr: xpos] '' number expected" end
+    if type(ypos) ~= "number" then return false, "[ArgErr: ypos] number expected" end
+    if type(ax) ~= "number" then return false, "[ArgErr: ax] number expected" end
+    if type(ay) ~= "number" then return false, "[ArgErr: ay] number expected" end
     local data = self._data
     data[#data + 1] = 149
     data[#data + 1] = ax   -- anchor relative x-coordinate
@@ -322,19 +643,7 @@
     data[#data + 1] = ay   -- anchor relative y-coordinate
     data[#data + 1] = xpos -- text x-coordinate
     data[#data + 1] = ypos -- text y-coordinate
+    return true, nil
 end
 
--- amazing...
-function gaCanvas:to_string() --> string
-
-end
-
-function gaCanvas:get_bbox()
-
-end
-
-function gaCanvas:check() --> boolean, err
-    
-end
-
 return gaCanvas

Modified: trunk/Master/texmf-dist/scripts/barracuda/lib-geo/brcd-libgeo.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/barracuda/lib-geo/brcd-libgeo.lua	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/scripts/barracuda/lib-geo/brcd-libgeo.lua	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,20 +1,137 @@
-
+-- this file is part of barracuda project
+-- Copyright (C) 2019-2022 Roberto Giacomelli
+-- see https://github.com/robitex/barracuda
+--
 -- libgeo simple Geometric Library
--- Copyright (C) 2018 Roberto Giacomelli
 
--- All dimension must be in scaled point (sp)
-
+-- All dimension must be in scaled point (sp) a TeX unit equal to 1/65536pt
 local libgeo = {
-    _VERSION     = "libgeo v0.0.3",
+    _VERSION     = "libgeo v0.0.6",
     _NAME        = "libgeo",
     _DESCRIPTION = "simple geometric library",
 }
 
--- VBar class
+-- a simple tree structured Archive class
+libgeo.Archive = {_classname = "Archive"}
+local Archive = libgeo.Archive
+Archive.__index = Archive
+
+function Archive:new() --> object
+    local o = {
+        _archive = {}
+    }
+    setmetatable(o, self)
+    return o
+end
+
+function Archive:insert(o, ...) --> ok, err
+    if type(o) ~= "table" then
+        return false, "[Err] "
+    end
+    local a = self._archive
+    local keys = {...}
+    for i = 1, (#keys - 1) do -- dive into the tree
+        local k = keys[i]
+        local leaf = a[k]
+        if not leaf then
+            a[k] = {}
+            leaf = a[k]
+        end
+        a = leaf
+    end
+    local k = keys[#keys]
+    if a[k] ~= nil then
+        return false, "[Err] an object "
+    end
+    a[k] = o
+    return true, nil
+end
+
+function Archive:contains_key(...) --> boolean
+    local a = self._archive
+    for _, k in ipairs{...} do
+        local leaf = a[k]
+        if leaf == nil then
+            return false
+        end
+        a = leaf
+    end
+    return true
+end
+
+function Archive:get(...) --> object, err
+    local a = self._archive
+    for _, k in ipairs{...} do
+        local leaf = a[k]
+        if leaf == nil then
+            return nil, "[Err] key '"..k.."' not found"
+        end
+        a = leaf
+    end
+    return a, nil
+end
+
+-- Queue Class
+local VbarQueue = {_classname = "VbarQueue"}
+libgeo.Vbar_queue = VbarQueue
+VbarQueue.__index = VbarQueue
+
+function VbarQueue:new()
+   local o = { 0 }
+   setmetatable(o, self)
+   return o
+end
+
+VbarQueue.__add = function (lhs, rhs)
+    if type(lhs) == "number" then -- dist + queue
+        local i = 1
+        while rhs[i] do
+            rhs[i] = rhs[i] + lhs
+            i = i + 2
+        end
+        return rhs
+    else -- queue + object
+        if type(rhs) == "number" then
+           lhs[#lhs] = lhs[#lhs] + rhs
+           return lhs
+        elseif type(rhs) == "table" then
+            if rhs._classname == "VbarQueue" then -- queue + queue
+                local q = {}
+                for _, v in ipairs(lhs) do
+                    q[#q + 1] = v
+                end
+                local w = lhs[#lhs]
+                for i = 1, #rhs/2 do
+                    q[#q + 1] = rhs[i] + w
+                    q[#q + 1] = rhs[i + 1]
+                end
+                return q
+            elseif rhs._classname == "Vbar" then -- queue + vbar
+                local w = lhs[#lhs]
+                lhs[#lhs + 1] = rhs
+                lhs[#lhs + 1] = w + rhs._x_lim
+                return lhs
+            else
+                error("[Err] unsupported object type for queue operation")
+            end
+        else
+            error("[Err] unsupported type for queue operation")
+        end
+    end
+end
+
+function VbarQueue:width()
+    return self[#self] - self[1]
+end
+
+-- Vbar class
 -- a pure geometric entity of several infinite vertical lines
-libgeo.Vbar = {}
+libgeo.Vbar = {_classname = "Vbar"}
 local Vbar = libgeo.Vbar
 Vbar.__index = Vbar
+Vbar.__add = function (lhs, rhs)
+    return VbarQueue:new() + lhs + rhs
+end
 
 -- Vbar costructors
 
@@ -23,6 +140,7 @@
     assert(type(yl_arr) == "table", "'yline_array' is a mandatory arg")
     -- stream scanning
     local i = 1
+    local nbars = 0
     local xlim = 0.0
     while yl_arr[i] do
         local x = yl_arr[i]; i = i + 1
@@ -30,12 +148,14 @@
         assert(type(x) == "number", "[InternalErr] not a number")
         assert(type(w) == "number", "[InternalErr] not a number")
         xlim = x + w/2
+        nbars = nbars + 1
     end
     assert(i % 2 == 0, "[InternalErr] the index is not even")
-    assert(i > 0, "[InternalErr] empty array")
+    assert(nbars > 0, "[InternalErr] empty array")
     local o = {
         _yline = yl_arr, -- [<xcenter>, <width>, ...] flat array
         _x_lim = xlim,   -- right external bounding box coordinates
+        _nbars = nbars,  -- number of bars
     }
     setmetatable(o, self)
     return o
@@ -57,6 +177,7 @@
         digits[#digits + 1] = d
         ngen = (ngen - d)/10
     end
+    local nbars = 0
     local x0 = 0.0 -- axis reference
     local yl = {}
     for k = #digits, 1, -1 do
@@ -65,13 +186,16 @@
         if is_bar then    -- bar
             yl[#yl + 1] = x0 + w/2
             yl[#yl + 1] = w
+            nbars = nbars + 1
         end
         x0 = x0 + w
         is_bar = not is_bar
     end
+    assert(nbars > 0, "[InternalErr] no bars")
     local o = {
         _yline = yl, -- [<xcenter>, <width>, ...] flat array
         _x_lim = x0, -- right external coordinate
+        _nbars = nbars,  -- number of bars
     }
     setmetatable(o, self)
     return o
@@ -86,7 +210,8 @@
     if is_bar == nil then is_bar = true else
         assert(type(is_bar) == "boolean", "Invalid argument for is_bar")
     end
-    -- 
+    --
+    local nbars = 0
     local x0 = 0.0 -- axis reference
     local i = 0
     local yl = {}
@@ -96,6 +221,7 @@
         if is_bar then -- bar
             i = i + 1; yl[i] = x0 + w/2
             i = i + 1; yl[i] = w
+            nbars = nbars + 1
         end
         x0 = x0 + w
         is_bar = not is_bar
@@ -102,9 +228,11 @@
         ngen = (ngen - d)/10
     end
     assert(not is_bar, "[InternalErr] the last element in not a bar")
+    assert(nbars > 0, "[InternalErr] no bars")
     local o = {
         _yline = yl,   -- [<xcenter>, <width>, ...] flat array
         _x_lim = x0, -- right external coordinate
+        _nbars = nbars,  -- number of bars
     }
     setmetatable(o, self)
     return o
@@ -126,8 +254,9 @@
     else
         assert(type(is_bar) == "boolean", "Invalid argument for 'is_bar'")
     end
+    local nbars = 0
     local yl = {}
-	local x0 = 0.0
+    local x0 = 0.0
     local k = 0
     while ngen > 0 do
         local d = ngen % 10 -- digit
@@ -140,14 +269,16 @@
         if is_bar then -- bars
             k = k + 1; yl[k] = x0 + w/2 -- xcenter
             k = k + 1; yl[k] = w        -- width
+            nbars = nbars + 1
         end
         is_bar = not is_bar
         x0 = x0 + w
     end
-    assert(not is_bar, "[InternalErr] the last element is not a bar")
+    assert(nbars > 0, "[InternalErr] no bars")
     local o = {
         _yline = yl, -- [<xcenter>, <width>, ...] flat array
         _x_lim = x0, -- external x coordinate
+        _nbars = nbars, -- number of bars
     }
     setmetatable(o, self)
     return o
@@ -162,6 +293,7 @@
     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 nbars = 0
     local x0 = 0.0 -- x-coordinate
     local yl = {}
     for i = 1, #tbar do
@@ -176,6 +308,7 @@
             yl[#yl + 1] = MOD -- bar width
             x0 = x0 + MOD
         end
+        nbars = nbars + 1
         local is_narrow_space = tspace[i]
         assert(type(is_narrow_space) == "boolean", "[InternalErr] found a not boolean value")
         if is_narrow_space then
@@ -184,17 +317,76 @@
             x0 = x0 + MOD
         end
     end
+    assert(nbars > 0, "[InternalErr] no bars")
     local o = {
         _yline = yl, -- [<xcenter>, <width>, ...] flat array
         _x_lim = x0, -- external x coordinate
+        _nbars = nbars, -- number of bars
     }
     setmetatable(o, self)
     return o
 end
 
+function Vbar:get_bars() --> nbars, <coordinates flat array>
+    return self._nbars, self._yline
+end
+
+-- Polyline class
+local Polyline = {_classname = "Polyline"}
+Polyline.__index = Polyline
+libgeo.Polyline = Polyline
+
+-- optional argument a first point (x, y)
+function Polyline:new(x, y) --> <Polyline>
+    local o = {
+        _point = {},
+        _n = 0,
+    }
+    setmetatable(o, self)
+    if x ~= nil then
+        assert(type(x) == "number", "[Polyline:new()] Invalid type for x-coordinate")
+        assert(type(y) == "number", "[Polyline:new()] Invalid type for y-coordinate")
+        self:add_point(x, y)
+    end
+    return o
+end
+
+-- get a clone of points' coordinates
+function Polyline:get_points()
+    local res = {}
+    local p = self._point
+    for i, c in ipairs(p) do
+        res[i] = c
+    end
+    return self._n, res
+end
+
+-- append a new point with absolute coordinates
+function Polyline:add_point(x, y)
+    assert(type(x) == "number", "[Polyline:add_point()] Invalid type for x-coordinate")
+    assert(type(y) == "number", "[Polyline:add_point()] Invalid type for y-coordinate")
+    local point = self._point
+    point[#point + 1] = x
+    point[#point + 1] = y
+    self._n = self._n + 1
+end
+
+-- append a new point with relative coordinates respect to the last one
+function Polyline:add_relpoint(x, y)
+    assert(type(x) == "number", "Invalid type for x-coordinate")
+    assert(type(y) == "number", "Invalid type for y-coordinate")
+    local point = self._point
+    local n = self._n
+    assert(n > 0, "Attempt to add a relative point to an empty polyline")
+    local i = 2 * n
+    point[#point + 1] = point[i - 1] + x
+    point[#point + 1] = point[i] + y
+    self._n = n + 1
+end
+
 -- Text class
 
-libgeo.Text = {}
+libgeo.Text = {_classname="Text"}
 local Text = libgeo.Text
 Text.__index = Text
 

Modified: trunk/Master/texmf-dist/tex/luatex/barracuda/barracuda.sty
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/barracuda/barracuda.sty	2022-06-22 23:50:00 UTC (rev 63700)
+++ trunk/Master/texmf-dist/tex/luatex/barracuda/barracuda.sty	2022-06-23 20:54:26 UTC (rev 63701)
@@ -1,6 +1,6 @@
 %
 \NeedsTeXFormat{LaTeX2e}[2009/06/27]
-\ProvidesPackage{barracuda}[2020/01/15 v0.0.10 a barcode typesetting package]%
+\ProvidesPackage{barracuda}[2022/06/23 v0.0.12 a barcode typesetting package]%
 \newbox\barracudabox
 \newcommand\barracuda[3][_brcdempty_=true]{\directlua{
     local barracuda = require "barracuda"



More information about the tex-live-commits mailing list.