1 | unit udrawers;
|
---|
2 |
|
---|
3 | {$mode objfpc}{$H+}
|
---|
4 |
|
---|
5 | interface
|
---|
6 |
|
---|
7 | uses
|
---|
8 | Classes, SysUtils, Graphics, Forms;
|
---|
9 |
|
---|
10 | type
|
---|
11 |
|
---|
12 | { TBasicBarcodeDrawer }
|
---|
13 |
|
---|
14 | TBasicBarcodeDrawer = class
|
---|
15 | private
|
---|
16 | FBackColor: TColor;
|
---|
17 | FBarColor: TColor;
|
---|
18 | FTextColor: TColor;
|
---|
19 | FFontName: String;
|
---|
20 | FFontSize: Integer;
|
---|
21 | FFontStyle: TFontStyles;
|
---|
22 | FWidth: Double;
|
---|
23 | FHeight: Double;
|
---|
24 | public
|
---|
25 | constructor Create(AWidth, AHeight: Double);
|
---|
26 | procedure BeginDrawing; virtual; abstract;
|
---|
27 | procedure EndDrawing; virtual; abstract;
|
---|
28 | procedure DrawBar(x1, y1, x2, y2: Double); virtual; abstract;
|
---|
29 | procedure DrawCenteredText(x, y: Double; const AText: String); virtual; abstract;
|
---|
30 | property BackColor: TColor read FBackColor write FBackColor;
|
---|
31 | property BarColor: TColor read FBarColor write FBarColor;
|
---|
32 | property TextColor: TColor read FTextColor write FTextColor;
|
---|
33 | property FontName: String read FFontName write FFontName;
|
---|
34 | property FontSize: Integer read FFontSize write FFontSize;
|
---|
35 | property FontStyle: TFontStyles read FFontStyle write FFontStyle;
|
---|
36 | property Width: Double read FWidth;
|
---|
37 | property Height: Double read FHeight;
|
---|
38 | end;
|
---|
39 |
|
---|
40 |
|
---|
41 | { TCanvasBarcodeDrawer }
|
---|
42 |
|
---|
43 | TCanvasBarcodeDrawer = class(TBasicBarcodeDrawer)
|
---|
44 | private
|
---|
45 | FCanvas: TCanvas;
|
---|
46 | protected
|
---|
47 | property Canvas: TCanvas read FCanvas;
|
---|
48 | public
|
---|
49 | constructor Create(ACanvas: TCanvas; AWidth, AHeight: Double);
|
---|
50 | procedure BeginDrawing; override;
|
---|
51 | procedure EndDrawing; override;
|
---|
52 | procedure DrawBar(x1, y1, x2, y2: double); override;
|
---|
53 | procedure DrawCenteredText(x, y: double; const AText: String); override;
|
---|
54 | end;
|
---|
55 |
|
---|
56 |
|
---|
57 | { TTextBarcodeDrawer }
|
---|
58 |
|
---|
59 | TTextBarcodeDrawer = class(TBasicBarcodeDrawer)
|
---|
60 | protected
|
---|
61 | FList: TStrings;
|
---|
62 | FTitle: String;
|
---|
63 | FFormatSettings: TFormatSettings;
|
---|
64 | public
|
---|
65 | constructor Create(AWidth, AHeight: Double; const ATitle: String);
|
---|
66 | destructor Destroy; override;
|
---|
67 | procedure SaveToFile(const AFileName: String);
|
---|
68 | procedure SaveToStream(const AStream: TStream);
|
---|
69 | end;
|
---|
70 |
|
---|
71 |
|
---|
72 | { TSvgBarcodeDrawer }
|
---|
73 |
|
---|
74 | TSvgBarcodeDrawer = class(TTextBarcodeDrawer)
|
---|
75 | private
|
---|
76 | function SvgColor(AColor: TColor): String;
|
---|
77 | public
|
---|
78 | procedure BeginDrawing; override;
|
---|
79 | procedure EndDrawing; override;
|
---|
80 | procedure DrawBar(x1, y1, x2, y2: double); override;
|
---|
81 | procedure DrawCenteredText(x, y: double; const AText: String); override;
|
---|
82 | end;
|
---|
83 |
|
---|
84 | { TEpsBarcodeDrawer }
|
---|
85 |
|
---|
86 | TEpsBarcodeDrawer = class(TTextBarcodeDrawer)
|
---|
87 | private
|
---|
88 | FStoredColor: TColor;
|
---|
89 | procedure EpsColor(AColor: TColor; out R,G,B: Double);
|
---|
90 | public
|
---|
91 | procedure BeginDrawing; override;
|
---|
92 | procedure EndDrawing; override;
|
---|
93 | procedure DrawBar(x1, y1, x2, y2: Double); override;
|
---|
94 | procedure DrawCenteredText(x, y: Double; const AText: String); override;
|
---|
95 | end;
|
---|
96 |
|
---|
97 |
|
---|
98 | implementation
|
---|
99 |
|
---|
100 | { TBasicBarcodeDrawer }
|
---|
101 |
|
---|
102 | constructor TBasicBarcodeDrawer.Create(AWidth, AHeight: Double);
|
---|
103 | begin
|
---|
104 | inherited Create;
|
---|
105 |
|
---|
106 | FWidth := AWidth;
|
---|
107 | FHeight := AHeight;
|
---|
108 |
|
---|
109 | FBarColor := clBlack;
|
---|
110 | FTextColor := clBlack;
|
---|
111 | FFontName := Screen.MenuFont.Name;
|
---|
112 | FFontSize := 10;
|
---|
113 | FFontStyle := [];
|
---|
114 | end;
|
---|
115 |
|
---|
116 |
|
---|
117 | { TCanvasBarcodeDrawer }
|
---|
118 |
|
---|
119 | constructor TCanvasBarcodeDrawer.Create(ACanvas: TCanvas; AWidth, AHeight: Double);
|
---|
120 | begin
|
---|
121 | inherited Create(AWidth, AHeight);
|
---|
122 | FCanvas := ACanvas;
|
---|
123 | end;
|
---|
124 |
|
---|
125 | // Fill the background
|
---|
126 | procedure TCanvasBarcodeDrawer.BeginDrawing;
|
---|
127 | begin
|
---|
128 | FCanvas.Brush.Color := FBackColor;
|
---|
129 | FCanvas.Brush.Style := bsSolid;
|
---|
130 | FCanvas.FillRect(0, 0, round(FWidth), round(FHeight));
|
---|
131 | end;
|
---|
132 |
|
---|
133 | procedure TCanvasBarcodeDrawer.EndDrawing;
|
---|
134 | begin
|
---|
135 | // Nothing to do in this drawer
|
---|
136 | end;
|
---|
137 |
|
---|
138 | procedure TCanvasBarcodeDrawer.DrawBar(x1, y1, x2, y2: double);
|
---|
139 | begin
|
---|
140 | FCanvas.Brush.Color := FBarColor;
|
---|
141 | FCanvas.Brush.Style := bsSolid;
|
---|
142 | FCanvas.FillRect(round(x1), round(y1), round(x2), round(y2));
|
---|
143 | end;
|
---|
144 |
|
---|
145 | procedure TCanvasBarcodeDrawer.DrawCenteredText(x, y: double; const AText: String);
|
---|
146 | var
|
---|
147 | w: Integer;
|
---|
148 | begin
|
---|
149 | FCanvas.Font.Name := FFontName;
|
---|
150 | FCanvas.Font.Size := FFontSize;
|
---|
151 | FCanvas.Font.Style := FFontStyle;
|
---|
152 | FCanvas.Font.Color := FTextColor;
|
---|
153 | FCanvas.Brush.Style := bsClear;
|
---|
154 | w := FCanvas.TextWidth(AText);
|
---|
155 | FCanvas.TextOut(round(x - w/2), round(y), AText);
|
---|
156 | end;
|
---|
157 |
|
---|
158 |
|
---|
159 | { TTextBarcodeDrawer }
|
---|
160 |
|
---|
161 | constructor TTextBarcodeDrawer.Create(AWidth, AHeight: Double; const ATitle: String);
|
---|
162 | begin
|
---|
163 | inherited Create(AWidth, AHeight);
|
---|
164 | FTitle := ATitle;
|
---|
165 | FList := TStringList.Create;
|
---|
166 | FFormatSettings := DefaultFormatSettings;
|
---|
167 | FFormatSettings.DecimalSeparator := '.';
|
---|
168 | end;
|
---|
169 |
|
---|
170 | destructor TTextBarcodeDrawer.Destroy;
|
---|
171 | begin
|
---|
172 | FList.Free;
|
---|
173 | inherited;
|
---|
174 | end;
|
---|
175 |
|
---|
176 | procedure TTextBarcodeDrawer.SaveToFile(const AFileName: String);
|
---|
177 | begin
|
---|
178 | FList.SaveToFile(AFileName);
|
---|
179 | end;
|
---|
180 |
|
---|
181 | procedure TTextBarcodeDrawer.SaveToStream(const AStream: TStream);
|
---|
182 | begin
|
---|
183 | FList.SaveToStream(AStream);
|
---|
184 | end;
|
---|
185 |
|
---|
186 |
|
---|
187 |
|
---|
188 | { TSvgBarcodeDrawer
|
---|
189 | Units are millimeters. }
|
---|
190 |
|
---|
191 | procedure TSvgBarcodeDrawer.BeginDrawing;
|
---|
192 | begin
|
---|
193 | // svg header
|
---|
194 | FList.Add(
|
---|
195 | '<?xml version="1.0" standalone="no"?>'
|
---|
196 | );
|
---|
197 | FList.Add(
|
---|
198 | '<!DOCTYPE svg PUBLIC "-//W3C/DTD SVG 1.1/EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'
|
---|
199 | );
|
---|
200 | FList.Add(Format(
|
---|
201 | '<svg width="%.3fmm" height="%.3fmm" version="1.1" xmlns="http://www.w3.org/2000/svg">', [
|
---|
202 | FWidth, FHeight],
|
---|
203 | FFormatSettings
|
---|
204 | ));
|
---|
205 |
|
---|
206 | if FTitle <> '' then
|
---|
207 | FList.Add(' <desc>%s</desc>', [FTitle])
|
---|
208 | else
|
---|
209 | FList.Add(' <desc>Symbol generated by LazBarcodes</desc>');
|
---|
210 |
|
---|
211 | // Background
|
---|
212 | FList.Add(
|
---|
213 | ' <rect width="100%%" height="100%%" fill="#%s"/>', [SvgColor(FBackColor)]);
|
---|
214 |
|
---|
215 | // Begin group for symbol and text
|
---|
216 | FList.Add(
|
---|
217 | ' <g id="barcode">');
|
---|
218 | end;
|
---|
219 |
|
---|
220 | procedure TSvgBarcodeDrawer.EndDrawing;
|
---|
221 | begin
|
---|
222 | FList.Add(' </g>');
|
---|
223 | FList.Add('</svg>');
|
---|
224 | end;
|
---|
225 |
|
---|
226 | procedure TSvgBarcodeDrawer.DrawBar(x1, y1, x2, y2: Double);
|
---|
227 | begin
|
---|
228 | FList.Add(Format(
|
---|
229 | ' <rect x="%.3fmm" y="%.3fmm" width="%.3fmm" height="%.3fmm" fill="#%s" />', [
|
---|
230 | x1, y1, x2-x1, y2-y1, SvgColor(FBarColor)],
|
---|
231 | FFormatSettings
|
---|
232 | ));
|
---|
233 | end;
|
---|
234 |
|
---|
235 | procedure TSvgBarcodeDrawer.DrawCenteredText(x, y: Double; const AText: String);
|
---|
236 | begin
|
---|
237 | // Move the text start point by a font height because svg vertical position
|
---|
238 | // refers to the font baseline while LCL refers to the top.
|
---|
239 | y := y + FFontSize / 72 * 25.4; // Convert Fontsize (pts) to mm
|
---|
240 | FList.Add(Format(
|
---|
241 | ' <text x="%.3fmm" y="%.3fmm" text-anchor="middle" font-family="%s" font-size="%.1fpt" fill="#%s">%s</text>', [
|
---|
242 | x, y, FFontName, 1.0*FFontSize, SvgColor(FTextColor), AText],
|
---|
243 | FFormatSettings
|
---|
244 | ));
|
---|
245 | end;
|
---|
246 |
|
---|
247 | function TSvgBarcodeDrawer.SvgColor(AColor: TColor): String;
|
---|
248 | type
|
---|
249 | TRgb = packed record
|
---|
250 | R, G, B: Byte;
|
---|
251 | end;
|
---|
252 | var
|
---|
253 | rgb: TRgb absolute AColor;
|
---|
254 | begin
|
---|
255 | Result := Format('%.2x%.2x%.2x', [rgb.R, rgb.G, rgb.B]);
|
---|
256 | end;
|
---|
257 |
|
---|
258 |
|
---|
259 | { TEpsBarcodeDrawer
|
---|
260 | Units are poins (1 pt = 1/72 inch)
|
---|
261 | Check generated eps files with https://www.fviewer.com/de/view-eps. }
|
---|
262 |
|
---|
263 | procedure TEpsBarcodeDrawer.BeginDrawing;
|
---|
264 | var
|
---|
265 | R, G, B: Double;
|
---|
266 | begin
|
---|
267 | // Start writing the header
|
---|
268 | FList.Add('%!PS-Adobe-3.0 EPSF-3.0');
|
---|
269 |
|
---|
270 | FList.Add('%%Creator: LazBarcodes');
|
---|
271 |
|
---|
272 | if FTitle <> '' then
|
---|
273 | FList.Add('%%%%Title: %s', [FTitle])
|
---|
274 | else
|
---|
275 | FList.Add('%%Title: Symbol generated by LazBarcodes');
|
---|
276 | FList.Add('%%Pages: 1');
|
---|
277 | FList.Add(Format('%%%%BoundingBox: 0 0 %.2f %.2f', [FWidth, FHeight], FFormatSettings));
|
---|
278 | FList.Add('%%EndComments');
|
---|
279 |
|
---|
280 | // Background
|
---|
281 | EpsColor(FBackColor, R,G,B);
|
---|
282 | FList.Add(Format('%.2f %.2f %.2f setrgbcolor', [R, G, B], FFormatSettings));
|
---|
283 | FList.Add(Format('%.2f %.2f %.2f %.2f rectfill', [0.0, 0.0, 1.0*FWidth, 1.0*FHeight], FFormatSettings));
|
---|
284 |
|
---|
285 | // Set bar color
|
---|
286 | EpsColor(FBarColor, R,G,B);
|
---|
287 | FList.Add(Format('%.2f %.2f %.2f setrgbcolor', [R, G, B], FFormatSettings));
|
---|
288 | FStoredColor := FBarColor;
|
---|
289 |
|
---|
290 | // Set font
|
---|
291 | // Todo: Find out how the real font name can be used. Most of the Windows
|
---|
292 | // fonts are not accepted.
|
---|
293 | FList.Add(Format('/mainfont /%s findfont %.2f scalefont def', ['Helvetica', 1.0*FFontSize], FFormatSettings));
|
---|
294 | Flist.Add('mainfont setfont');
|
---|
295 | end;
|
---|
296 |
|
---|
297 | procedure TEpsBarcodeDrawer.EndDrawing;
|
---|
298 | begin
|
---|
299 | FList.Add('');
|
---|
300 | FList.Add('showpage');
|
---|
301 | end;
|
---|
302 |
|
---|
303 | procedure TEpsBarcodeDrawer.DrawBar(x1, y1, x2, y2: Double);
|
---|
304 | var
|
---|
305 | R, G, B: Double;
|
---|
306 | begin
|
---|
307 | if FStoredColor <> FBarColor then
|
---|
308 | begin
|
---|
309 | EpsColor(FBarColor, R,G,B);
|
---|
310 | FList.Add(Format('%.2f %.2f %.2f setrgbcolor', [R, G, B], FFormatSettings));
|
---|
311 | FStoredColor := FBarColor;
|
---|
312 | end;
|
---|
313 | FList.Add(Format('%0:.2f %1:.2f moveto %0:.2f %2:.2f lineto %3:.2f setlinewidth stroke',
|
---|
314 | [(x1 + x2) / 2, FHeight-y1, FHeight-y2, abs(x2 - x1)], FFormatSettings));
|
---|
315 | end;
|
---|
316 |
|
---|
317 | procedure TEpsBarcodeDrawer.DrawCenteredText(x, y: Double; const AText: String);
|
---|
318 | var
|
---|
319 | R, G, B: Double;
|
---|
320 | begin
|
---|
321 | if FStoredColor <> FTextColor then
|
---|
322 | begin
|
---|
323 | EpsColor(FTextColor, R,G,B);
|
---|
324 | FList.Add(Format('%.2f %.2f %.2f setrgbcolor', [R, G, B], FFormatSettings));
|
---|
325 | FStoredColor := FTextColor;
|
---|
326 | end;
|
---|
327 |
|
---|
328 | FList.Add(Format('%.2f %.2f moveto', [x, FHeight-y], FFormatSettings));
|
---|
329 | FList.Add(Format('(%s) dup stringwidth pop 2 div neg -%.2f rmoveto show', [AText, 1.0*FFontSize], FFormatSettings));
|
---|
330 | end;
|
---|
331 |
|
---|
332 | procedure TEpsBarcodeDrawer.EpsColor(AColor: TColor; out R,G,B: Double);
|
---|
333 | type
|
---|
334 | TRgb = packed record
|
---|
335 | R, G, B: Byte;
|
---|
336 | end;
|
---|
337 | var
|
---|
338 | rgb: TRgb absolute AColor;
|
---|
339 | begin
|
---|
340 | R := rgb.R / 255;
|
---|
341 | G := rgb.G / 255;
|
---|
342 | B := rgb.B / 255;
|
---|
343 | end;
|
---|
344 |
|
---|
345 | end.
|
---|