You've already forked lazarus-ccr
lazbarcodes: MaxiCode improvements. Still issues with svg and eps output. Symbol.Primary not yet implemented.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8225 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -59,11 +59,6 @@
|
|||||||
<Debugging>
|
<Debugging>
|
||||||
<DebugInfoType Value="dsDwarf2Set"/>
|
<DebugInfoType Value="dsDwarf2Set"/>
|
||||||
</Debugging>
|
</Debugging>
|
||||||
<Options>
|
|
||||||
<Win32>
|
|
||||||
<GraphicApplication Value="True"/>
|
|
||||||
</Win32>
|
|
||||||
</Options>
|
|
||||||
</Linking>
|
</Linking>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
<Debugging>
|
<Debugging>
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
{ lbc_maxicode.pas - Handles the MaxiCode symbology
|
||||||
|
|
||||||
|
Based on Zint (done by Robin Stuart and the Zint team)
|
||||||
|
http://github.com/zint/zint
|
||||||
|
and Pascal adaption by TheUnknownOnes
|
||||||
|
http://theunknownones.net
|
||||||
|
|
||||||
|
Refactoring: W. Pamler
|
||||||
|
}
|
||||||
|
|
||||||
unit lbc_MaxiCode;
|
unit lbc_MaxiCode;
|
||||||
|
|
||||||
{$IFDEF FPC}
|
{$IFDEF FPC}
|
||||||
@ -843,7 +853,6 @@ begin
|
|||||||
bit_pattern[3] := (maxi_codeword[block-1] and $04) shr 2;
|
bit_pattern[3] := (maxi_codeword[block-1] and $04) shr 2;
|
||||||
bit_pattern[4] := (maxi_codeword[block-1] and $02) shr 1;
|
bit_pattern[4] := (maxi_codeword[block-1] and $02) shr 1;
|
||||||
bit_pattern[5] := (maxi_codeword[block-1] and $01);
|
bit_pattern[5] := (maxi_codeword[block-1] and $01);
|
||||||
|
|
||||||
if bit_pattern[bit] <> 0 then
|
if bit_pattern[bit] <> 0 then
|
||||||
set_module(ASymbol, i, j);
|
set_module(ASymbol, i, j);
|
||||||
end;
|
end;
|
||||||
|
@ -218,7 +218,7 @@ type
|
|||||||
procedure Render(AWidth, AHeight: Integer); virtual;
|
procedure Render(AWidth, AHeight: Integer); virtual;
|
||||||
procedure RenderBearerBars(AWidth, AHeight, ABorder: Integer; var ALastLine: PZintRenderline);
|
procedure RenderBearerBars(AWidth, AHeight, ABorder: Integer; var ALastLine: PZintRenderline);
|
||||||
procedure RenderBox(AWidth, AHeight, ABorder: Integer; var ALastLine: PZintRenderLine);
|
procedure RenderBox(AWidth, AHeight, ABorder: Integer; var ALastLine: PZintRenderLine);
|
||||||
procedure RenderSymbol(xLeft, yTop, ASymbolHeight, {%H-}ATextHeight, AFactor: Integer); virtual;
|
procedure RenderSymbol(xLeft, yTop, ASymbolWidth, ASymbolHeight, {%H-}ATextHeight, AFactor: Integer); virtual;
|
||||||
procedure RenderText(ASymbolWidth, ASymbolStart, ATextPos: Integer); virtual;
|
procedure RenderText(ASymbolWidth, ASymbolStart, ATextPos: Integer); virtual;
|
||||||
property AddCheckSum: Boolean read FAddCheckSum write SetAddCheckSum default true;
|
property AddCheckSum: Boolean read FAddCheckSum write SetAddCheckSum default true;
|
||||||
property DisplayCheckSum: Boolean read FDisplayCheckSum write SetDisplayCheckSum default false;
|
property DisplayCheckSum: Boolean read FDisplayCheckSum write SetDisplayCheckSum default false;
|
||||||
@ -352,7 +352,7 @@ type
|
|||||||
function GetRightText: String;
|
function GetRightText: String;
|
||||||
function GetSampleText: String; override;
|
function GetSampleText: String; override;
|
||||||
function InternalGenerate: Integer; override;
|
function InternalGenerate: Integer; override;
|
||||||
procedure RenderSymbol(xLeft, yTop, AHeight, ATextHeight, AFactor: Integer); override;
|
procedure RenderSymbol(xLeft, yTop, ASymbolWidth, ASymbolHeight, ATextHeight, AFactor: Integer); override;
|
||||||
procedure RenderText(ASymbolWidth, ASymbolStart, ATextPos: Integer); override;
|
procedure RenderText(ASymbolWidth, ASymbolStart, ATextPos: Integer); override;
|
||||||
procedure SetRecommendedSymbolSizeParams; override;
|
procedure SetRecommendedSymbolSizeParams; override;
|
||||||
function UPC_EAN_Flag: Integer;
|
function UPC_EAN_Flag: Integer;
|
||||||
@ -621,7 +621,7 @@ type
|
|||||||
procedure DrawBarcode(ADrawer: TBasicBarcodeDrawer; AFactor: Double); override;
|
procedure DrawBarcode(ADrawer: TBasicBarcodeDrawer; AFactor: Double); override;
|
||||||
class function GetControlClassDefaultSize: TSize; override;
|
class function GetControlClassDefaultSize: TSize; override;
|
||||||
function InternalGenerate: Integer; override;
|
function InternalGenerate: Integer; override;
|
||||||
procedure RenderSymbol(xLeft, yTop, {%H-}ASymbolHeight, {%H-}ATextHeight, AFactor: Integer); override;
|
procedure RenderSymbol(xLeft, yTop, ASymbolWidth, ASymbolHeight, {%H-}ATextHeight, AFactor: Integer); override;
|
||||||
procedure SetRecommendedSymbolSizeParams; override;
|
procedure SetRecommendedSymbolSizeParams; override;
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
@ -1622,7 +1622,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
// Render bars and spaces
|
// Render bars and spaces
|
||||||
RenderSymbol(x, border, hsymbol, htext, factor);
|
RenderSymbol(x, border, wsymbol, hsymbol, htext, factor);
|
||||||
|
|
||||||
// Render the human-readable text
|
// Render the human-readable text
|
||||||
if FShowHumanReadableText then
|
if FShowHumanReadableText then
|
||||||
@ -1684,10 +1684,12 @@ end;
|
|||||||
|
|
||||||
{ Renders bars and spaces.
|
{ Renders bars and spaces.
|
||||||
- xLeft, yTop: left/top corner of the first bar
|
- xLeft, yTop: left/top corner of the first bar
|
||||||
|
- ASymbolWidth: width of the entire symbol (without border and whitespace)
|
||||||
- ASymbolHeight: height of the entire symbol (without text)
|
- ASymbolHeight: height of the entire symbol (without text)
|
||||||
- ATextHeight: height of the human-readable text. Needed by EAN code bar extensions.
|
- ATextHeight: height of the human-readable text. Needed by EAN code bar extensions.
|
||||||
- AFactor: current scaling factor with respect to pixels }
|
- AFactor: current scaling factor with respect to pixels }
|
||||||
procedure TSimpleBarcode.RenderSymbol(xLeft, yTop, ASymbolHeight, ATextHeight, AFactor: Integer);
|
procedure TSimpleBarcode.RenderSymbol(xLeft, yTop, ASymbolWidth, ASymbolHeight,
|
||||||
|
ATextHeight, AFactor: Integer);
|
||||||
var
|
var
|
||||||
i: Integer; // general loop variable
|
i: Integer; // general loop variable
|
||||||
x, y: Integer; // coordinates of the left/top corner of the currently rendered bar.
|
x, y: Integer; // coordinates of the left/top corner of the currently rendered bar.
|
||||||
@ -2218,7 +2220,8 @@ end;
|
|||||||
|
|
||||||
{ Is overridden to handle the bar extensions of most of the UPC/EAN codes, i.e.
|
{ Is overridden to handle the bar extensions of most of the UPC/EAN codes, i.e.
|
||||||
some bars are drawn longer than the others.}
|
some bars are drawn longer than the others.}
|
||||||
procedure TBarcodeEAN.RenderSymbol(xLeft, yTop, AHeight, ATextHeight, AFactor: Integer);
|
procedure TBarcodeEAN.RenderSymbol(xLeft, yTop, ASymbolWidth, ASymbolHeight,
|
||||||
|
ATextHeight, AFactor: Integer);
|
||||||
var
|
var
|
||||||
i, n: Integer;
|
i, n: Integer;
|
||||||
line: PZintRenderLine;
|
line: PZintRenderLine;
|
||||||
@ -3193,8 +3196,8 @@ end;
|
|||||||
{ TBarcodeMaxiCode }
|
{ TBarcodeMaxiCode }
|
||||||
|
|
||||||
const
|
const
|
||||||
H_HEXAGON = 2.0/sqrt(3.0);
|
W_HEXAGON = 2.0;
|
||||||
W_HEXAGON = 1.0;
|
H_HEXAGON = 4.0/sqrt(3.0);
|
||||||
|
|
||||||
constructor TBarcodeMaxiCode.Create(AOwner: TComponent);
|
constructor TBarcodeMaxiCode.Create(AOwner: TComponent);
|
||||||
begin
|
begin
|
||||||
@ -3236,7 +3239,7 @@ procedure TBarcodeMaxiCode.CalcSize(AFactor: Integer;
|
|||||||
begin
|
begin
|
||||||
// +2 for an empty hexagon around the symbol
|
// +2 for an empty hexagon around the symbol
|
||||||
ASymbolWidth := round(W_HEXAGON * (FSymbol^.Width + 2) * AFactor);
|
ASymbolWidth := round(W_HEXAGON * (FSymbol^.Width + 2) * AFactor);
|
||||||
ASymbolHeight := round(H_HEXAGON * (FSymbol^.Rows + 2) * AFactor);
|
ASymbolHeight := round(H_HEXAGON * 0.75 * (FSymbol^.Rows + 1.5) * AFactor);
|
||||||
|
|
||||||
// No human-readable text
|
// No human-readable text
|
||||||
ATextWidth := 0;
|
ATextWidth := 0;
|
||||||
@ -3267,8 +3270,10 @@ end;
|
|||||||
|
|
||||||
procedure TBarcodeMaxiCode.DrawBarcode(ADrawer: TBasicBarcodeDrawer; AFactor: Double);
|
procedure TBarcodeMaxiCode.DrawBarcode(ADrawer: TBasicBarcodeDrawer; AFactor: Double);
|
||||||
var
|
var
|
||||||
|
ring: PZintRenderRing;
|
||||||
hexagon: PZintRenderHexagon;
|
hexagon: PZintRenderHexagon;
|
||||||
wx: Double;
|
wx: Double;
|
||||||
|
rInner, rOuter: Double;
|
||||||
begin
|
begin
|
||||||
// Prepare drawer
|
// Prepare drawer
|
||||||
if FBackgroundColor = clDefault then
|
if FBackgroundColor = clDefault then
|
||||||
@ -3290,6 +3295,16 @@ begin
|
|||||||
else
|
else
|
||||||
wx := AFactor * FScale;
|
wx := AFactor * FScale;
|
||||||
|
|
||||||
|
// Draw the rings
|
||||||
|
ring := FSymbol^.Rendered^.rings;
|
||||||
|
while Assigned(ring) do
|
||||||
|
begin
|
||||||
|
rInner := ring^.radius - ring^.line_width/2;
|
||||||
|
rOuter := ring^.radius + ring^.line_width/2;
|
||||||
|
ADrawer.DrawRing(ring^.x, ring^.y, rOuter, rInner);
|
||||||
|
ring := ring^.Next;
|
||||||
|
end;
|
||||||
|
|
||||||
// Draw the hexagons
|
// Draw the hexagons
|
||||||
hexagon := FSymbol^.Rendered^.hexagons;
|
hexagon := FSymbol^.Rendered^.hexagons;
|
||||||
while Assigned(hexagon) do begin
|
while Assigned(hexagon) do begin
|
||||||
@ -3306,7 +3321,7 @@ begin
|
|||||||
Result.CX := 88;
|
Result.CX := 88;
|
||||||
Result.CY := 88;
|
Result.CY := 88;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TBarcodeMaxiCode.InternalGenerate: Integer;
|
function TBarcodeMaxiCode.InternalGenerate: Integer;
|
||||||
begin
|
begin
|
||||||
FSymbol^.option_1 := ord(FMode);
|
FSymbol^.option_1 := ord(FMode);
|
||||||
@ -3315,17 +3330,47 @@ begin
|
|||||||
Result := maxicode(FSymbol, @FText[1], Length(FText));
|
Result := maxicode(FSymbol, @FText[1], Length(FText));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TBarcodeMaxiCode.RenderSymbol(xLeft, yTop, ASymbolHeight, {%H-}ATextHeight, AFactor: Integer);
|
(*
|
||||||
|
function TBarcodeMaxiCode.InternalGenerate: Integer;
|
||||||
|
var
|
||||||
|
txt: array of byte;
|
||||||
|
begin
|
||||||
|
FSymbol^.option_1 := ord(FMode);
|
||||||
|
|
||||||
|
setLength(txt, Length(FText)+1);
|
||||||
|
Move(FText[1], txt[0], Length(txt));
|
||||||
|
txt[Length(txt)] := 0;
|
||||||
|
|
||||||
|
Result := maxicode(FSymbol, txt, Length(FText));
|
||||||
|
end;
|
||||||
|
*)
|
||||||
|
procedure TBarcodeMaxiCode.RenderSymbol(xLeft, yTop, ASymbolWidth, ASymbolHeight,
|
||||||
|
{%H-}ATextHeight, AFactor: Integer);
|
||||||
var
|
var
|
||||||
ring, last_ring: PZintRenderRing;
|
ring, last_ring: PZintRenderRing;
|
||||||
hexagon, last_hexagon: PZintRenderHexagon;
|
hexagon, last_hexagon: PZintRenderHexagon;
|
||||||
i, j: Integer;
|
i, j: Integer;
|
||||||
x, y: Double;
|
x, y: Double;
|
||||||
xFactor, yFactor: Double;
|
xc, yc: Double;
|
||||||
|
xFactor, yFactor, linewidth: Double;
|
||||||
begin
|
begin
|
||||||
|
xFactor := W_HEXAGON * AFactor;
|
||||||
|
yFactor := H_HEXAGON * AFactor * 0.75;
|
||||||
|
|
||||||
|
// Rings
|
||||||
|
xc := xLeft + ASymbolWidth / 2 - xFactor*0.5;
|
||||||
|
yc := yTop + ASymbolHeight / 2;
|
||||||
|
last_ring := nil;
|
||||||
|
// The radius coefficients are empirical values derived from Zint code
|
||||||
|
linewidth := 0.8816 * xFactor;
|
||||||
|
ring := render_plot_create_ring(xc, yc, 0.9659*xFactor, linewidth);
|
||||||
|
render_plot_add_ring(FSymbol, ring, @last_ring);
|
||||||
|
ring := render_plot_create_ring(xc, yc, 2.500*xFactor, linewidth);
|
||||||
|
render_plot_add_ring(FSymbol, ring, @last_ring);
|
||||||
|
ring := render_plot_create_ring(xc, yc, 4.0227*xFactor, linewidth);
|
||||||
|
render_plot_add_ring(FSymbol, ring, @last_ring);
|
||||||
|
|
||||||
// Hexagons
|
// Hexagons
|
||||||
xFactor := H_HEXAGON * AFactor;
|
|
||||||
yFactor := W_HEXAGON * AFactor;
|
|
||||||
last_hexagon := nil;
|
last_hexagon := nil;
|
||||||
for j := 0 to FSymbol^.Rows - 1 do
|
for j := 0 to FSymbol^.Rows - 1 do
|
||||||
begin
|
begin
|
||||||
@ -3333,9 +3378,10 @@ begin
|
|||||||
for i := 0 to FSymbol^.Width - 1 do
|
for i := 0 to FSymbol^.Width - 1 do
|
||||||
if module_is_set(FSymbol, j, i) then
|
if module_is_set(FSymbol, j, i) then
|
||||||
begin
|
begin
|
||||||
x := xFactor * (i + 1) + xLeft;
|
if odd(j) then
|
||||||
if odd(i) then
|
x := xFactor * (i + 2) + xLeft
|
||||||
x := x + xFactor * 0.5;
|
else
|
||||||
|
x := xFactor * (i + 1.5) + xLeft;
|
||||||
hexagon := render_plot_create_hexagon(x, y);
|
hexagon := render_plot_create_hexagon(x, y);
|
||||||
render_plot_add_hexagon(FSymbol, hexagon, @last_hexagon);
|
render_plot_add_hexagon(FSymbol, hexagon, @last_hexagon);
|
||||||
end;
|
end;
|
||||||
|
@ -27,7 +27,7 @@ type
|
|||||||
procedure EndDrawing; virtual; abstract;
|
procedure EndDrawing; virtual; abstract;
|
||||||
procedure DrawBar(x1, y1, x2, y2: Double); virtual; abstract;
|
procedure DrawBar(x1, y1, x2, y2: Double); virtual; abstract;
|
||||||
procedure DrawCenteredText(x, y: Double; const AText: String); virtual; abstract;
|
procedure DrawCenteredText(x, y: Double; const AText: String); virtual; abstract;
|
||||||
procedure DrawHexagon(x, y, r: Double); virtual; abstract;
|
procedure DrawHexagon(x, y, wx: Double); virtual; abstract;
|
||||||
procedure DrawRing(x, y, rOuter, rInner: Double); virtual; abstract;
|
procedure DrawRing(x, y, rOuter, rInner: Double); virtual; abstract;
|
||||||
property BackColor: TColor read FBackColor write FBackColor;
|
property BackColor: TColor read FBackColor write FBackColor;
|
||||||
property BarColor: TColor read FBarColor write FBarColor;
|
property BarColor: TColor read FBarColor write FBarColor;
|
||||||
@ -53,7 +53,7 @@ type
|
|||||||
procedure EndDrawing; override;
|
procedure EndDrawing; override;
|
||||||
procedure DrawBar(x1, y1, x2, y2: double); override;
|
procedure DrawBar(x1, y1, x2, y2: double); override;
|
||||||
procedure DrawCenteredText(x, y: double; const AText: String); override;
|
procedure DrawCenteredText(x, y: double; const AText: String); override;
|
||||||
procedure DrawHexagon(x, y, r: Double); override;
|
procedure DrawHexagon(x, y, wx: Double); override;
|
||||||
procedure DrawRing(x, y, rOuter, rInner: Double); override;
|
procedure DrawRing(x, y, rOuter, rInner: Double); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ type
|
|||||||
procedure EndDrawing; override;
|
procedure EndDrawing; override;
|
||||||
procedure DrawBar(x1, y1, x2, y2: double); override;
|
procedure DrawBar(x1, y1, x2, y2: double); override;
|
||||||
procedure DrawCenteredText(x, y: double; const AText: String); override;
|
procedure DrawCenteredText(x, y: double; const AText: String); override;
|
||||||
procedure DrawHexagon(x, y, r: Double); override;
|
procedure DrawHexagon(x, y, wx: Double); override;
|
||||||
procedure DrawRing(x, y, rOuter, rInner: Double); override;
|
procedure DrawRing(x, y, rOuter, rInner: Double); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -181,13 +181,13 @@ begin
|
|||||||
FCanvas.TextOut(round(x - w/2), round(y), AText);
|
FCanvas.TextOut(round(x - w/2), round(y), AText);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCanvasBarcodeDrawer.DrawHexagon(x, y, r: Double);
|
procedure TCanvasBarcodeDrawer.DrawHexagon(x, y, wx: Double);
|
||||||
var
|
var
|
||||||
P: array[0..5] of TPoint;
|
P: array[0..5] of TPoint;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
for i := 0 to 5 do
|
for i := 0 to 5 do
|
||||||
P[i] := Point(round(x + HEXAGON[i].X*r), round(y + HEXAGON[i].Y*r));
|
P[i] := Point(round(x + HEXAGON[i].X * wx), round(y + HEXAGON[i].Y * wx));
|
||||||
FCanvas.Brush.Color := FBarColor;
|
FCanvas.Brush.Color := FBarColor;
|
||||||
FCanvas.Brush.Style := bsSolid;
|
FCanvas.Brush.Style := bsSolid;
|
||||||
FCanvas.Pen.Style := psClear;
|
FCanvas.Pen.Style := psClear;
|
||||||
@ -200,6 +200,8 @@ var
|
|||||||
begin
|
begin
|
||||||
FCanvas.Pen.Color := FBarColor;
|
FCanvas.Pen.Color := FBarColor;
|
||||||
FCanvas.Pen.Style := psSolid;
|
FCanvas.Pen.Style := psSolid;
|
||||||
|
FCanvas.Brush.Style := bsClear;
|
||||||
|
|
||||||
if rOuter > rInner then
|
if rOuter > rInner then
|
||||||
FCanvas.Pen.Width := round(rOuter - rInner)
|
FCanvas.Pen.Width := round(rOuter - rInner)
|
||||||
else
|
else
|
||||||
@ -298,15 +300,15 @@ begin
|
|||||||
));
|
));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSvgBarcodeDrawer.DrawHexagon(x, y, r: Double);
|
procedure TSvgBarcodeDrawer.DrawHexagon(x, y, wx: Double);
|
||||||
var
|
var
|
||||||
P: array[0..5] of TDblPoint;
|
P: array[0..5] of TDblPoint;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
for i := 0 to 5 do
|
for i := 0 to 5 do
|
||||||
begin
|
begin
|
||||||
P[i].X := x + HEXAGON[i].X*r;
|
P[i].X := x + HEXAGON[i].X * wx;
|
||||||
P[i].Y := y + HEXAGON[i].Y*r;
|
P[i].Y := y + HEXAGON[i].Y * wx;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
FList.Add(Format(
|
FList.Add(Format(
|
||||||
@ -421,8 +423,8 @@ var
|
|||||||
begin
|
begin
|
||||||
for i := 0 to 5 do
|
for i := 0 to 5 do
|
||||||
begin
|
begin
|
||||||
P[i].X := x + HEXAGON[i].X*wx;
|
P[i].X := x + HEXAGON[i].X * wx;
|
||||||
P[i].Y := y + HEXAGON[i].Y*wx;
|
P[i].Y := y + HEXAGON[i].Y * wx;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if FStoredColor <> FBarColor then
|
if FStoredColor <> FBarColor then
|
||||||
|
Reference in New Issue
Block a user