fpimgbarcode.pp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. {
  2. This file is part of the Free Pascal FCL library.
  3. Copyright (c) 2017 by Michael Van Canneyt
  4. member of the Free Pascal development team
  5. Barcode drawing routines.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit FPImgBarCode;
  13. {$mode objfpc}{$H+}
  14. interface
  15. uses
  16. Classes, SysUtils, fpcanvas, fpimage, types, fpbarcode;
  17. Type
  18. // So people don't need to include fpBarcode
  19. TBarcodeEncoding = fpbarcode.TBarcodeEncoding;
  20. { TFPDrawBarCode }
  21. TFPDrawBarCode = Class
  22. private
  23. FCanvas: TFPCustomCanvas;
  24. FClipping: Boolean;
  25. FEncoding: TBarcodeEncoding;
  26. FImage: TFPCustomImage;
  27. FRect: TRect;
  28. FText: String;
  29. FUnitWidth: Integer;
  30. FWeight: Double;
  31. FFreeCanvas : Boolean;
  32. FWidths : TBarWidthArray;
  33. procedure SetCanvas(AValue: TFPCustomCanvas);
  34. procedure SetEncoding(AValue: TBarcodeEncoding);
  35. procedure SetImage(AValue: TFPCustomImage);
  36. procedure SetUnitWidth(AValue: Integer);
  37. procedure SetWeight(AValue: Double);
  38. Protected
  39. procedure CheckFreeCanvas;
  40. Procedure CalcWidths; virtual;
  41. Property FreeCanvas : Boolean Read FFreeCanvas Write FFreeCanvas;
  42. Public
  43. Constructor Create; virtual;
  44. Destructor Destroy; override;
  45. procedure CheckCanvas; virtual;
  46. // Returns true if the text was drawn, false if not.
  47. Function Draw : Boolean; virtual;
  48. // Returns true if the text can be drawn using current encoding, false if not
  49. Function AllowDraw : Boolean;
  50. // Informational: calc width of text using current parameters. -1 if the text cannot be drawn.
  51. Function CalcWidth : Integer;
  52. // One of Image or Canvas must be set.
  53. Property Image : TFPCustomImage Read FImage Write SetImage;
  54. Property Canvas : TFPCustomCanvas Read FCanvas Write SetCanvas;
  55. // Rectangle in which to draw
  56. Property Rect : TRect Read FRect Write FRect;
  57. // Unit width of a bar
  58. Property UnitWidth : Integer Read FUnitWidth Write SetUnitWidth;
  59. // Weight to use when calculating bar widths.
  60. Property Weight : Double Read FWeight Write SetWeight;
  61. // Encoding to use
  62. Property Encoding : TBarcodeEncoding Read FEncoding Write SetEncoding;
  63. // Text to draw.
  64. Property Text : String Read FText Write FText;
  65. // If true, the barcode will be clipped if it falls outside rect.
  66. Property Clipping : Boolean Read FClipping Write FClipping;
  67. end;
  68. Function DrawBarCode(Img : TFPCustomImage; S : String; E : TBarcodeEncoding; aWidth : Integer = 1; AWeight : Double = 2.0) : Boolean;
  69. Function DrawBarCode(Img : TFPCustomImage; Rect : TRect; S : String; E : TBarcodeEncoding; aWidth : Integer = 1; AWeight : Double = 2.0) : Boolean;
  70. implementation
  71. uses
  72. FPImgCanv;
  73. Function DrawBarCode(Img : TFPCustomImage; S : String; E : TBarcodeEncoding; aWidth : Integer = 1; AWeight : Double = 2.0) : Boolean;
  74. Var
  75. T : TRect;
  76. begin
  77. T.Left:=0;
  78. T.Top:=0;
  79. T.Right:=Img.Width-1;
  80. T.Bottom:=Img.Height-1;
  81. Result:=DrawBarCode(Img,T,S,E,aWidth,aWeight);
  82. end;
  83. Function DrawBarCode(Img : TFPCustomImage; Rect : TRect; S : String; E : TBarcodeEncoding; aWidth : Integer = 1; AWeight : Double = 2.0) : Boolean;
  84. Var
  85. DBC : TFPDrawBarCode;
  86. begin
  87. DBC:=TFPDrawBarCode.Create;
  88. try
  89. DBC.Rect:=Rect;
  90. DBC.UnitWidth:=aWidth;
  91. DBC.Weight:=aWeight;
  92. DBC.Encoding:=E;
  93. DBC.Text:=S;
  94. DBC.Image:=Img;
  95. Result:=DBC.Draw;
  96. finally
  97. DBC.Free;
  98. end;
  99. end;
  100. { TFPDrawBarCode }
  101. procedure TFPDrawBarCode.CheckFreeCanvas;
  102. begin
  103. if FFreeCanvas then
  104. FreeAndNil(FCanvas)
  105. else
  106. FCanvas:=Nil;
  107. end;
  108. procedure TFPDrawBarCode.SetImage(AValue: TFPCustomImage);
  109. begin
  110. if FImage=AValue then Exit;
  111. FImage:=AValue;
  112. CheckFreeCanvas;
  113. end;
  114. procedure TFPDrawBarCode.SetUnitWidth(AValue: Integer);
  115. begin
  116. if FUnitWidth=AValue then Exit;
  117. FUnitWidth:=AValue;
  118. CalcWidths;
  119. end;
  120. procedure TFPDrawBarCode.SetWeight(AValue: Double);
  121. begin
  122. if FWeight=AValue then Exit;
  123. FWeight:=AValue;
  124. CalcWidths;
  125. end;
  126. procedure TFPDrawBarCode.CalcWidths;
  127. begin
  128. FWidths:=CalcBarWidths(FEncoding,UnitWidth,Weight);
  129. end;
  130. procedure TFPDrawBarCode.SetCanvas(AValue: TFPCustomCanvas);
  131. begin
  132. if FCanvas=AValue then Exit;
  133. CheckFreeCanvas;
  134. FCanvas:=AValue;
  135. end;
  136. procedure TFPDrawBarCode.SetEncoding(AValue: TBarcodeEncoding);
  137. begin
  138. if FEncoding=AValue then Exit;
  139. FEncoding:=AValue;
  140. CalcWidths;
  141. end;
  142. constructor TFPDrawBarCode.Create;
  143. begin
  144. FUnitWidth:=1;
  145. FWeight:=2.0;
  146. FEncoding:=beEAN8;
  147. CalcWidths;
  148. end;
  149. Destructor TFPDrawBarCode.Destroy;
  150. begin
  151. CheckFreeCanvas;
  152. end;
  153. procedure TFPDrawBarCode.CheckCanvas;
  154. begin
  155. if (FCanvas=Nil) then
  156. begin
  157. FCanvas:=TFPImageCanvas.create(FImage);
  158. FFreeCanvas:=True;
  159. end;
  160. end;
  161. Function TFPDrawBarCode.Draw : Boolean;
  162. Var
  163. Cnv : TFPCustomCanvas;
  164. I,L,MaxWidth, W, H : integer;
  165. xOffset: integer;
  166. BarRect : TRect;
  167. BP : TBarParams;
  168. Data : TBarTypeArray;
  169. begin
  170. Result:=AllowDraw;
  171. if not Result then
  172. exit;
  173. CheckCanvas;
  174. Cnv:=FCanvas;
  175. Data:=StringToBarTypeArray(Text,FEncoding);
  176. xOffset := 0;
  177. Cnv.Brush.FPColor := colWhite;
  178. Cnv.Brush.Style:=bsSolid;
  179. Cnv.FillRect(Rect);
  180. Cnv.Pen.Width := 1;
  181. I:=0;
  182. L:=Length(Data);
  183. MaxWidth:=Rect.Right-Rect.Left;
  184. While (I<L) and (Not Clipping or (XOffset<MaxWidth)) do
  185. begin
  186. BP:=BarTypeToBarParams(Data[i]);
  187. case BP.c of
  188. bcBlack : Cnv.Pen.FPColor := colBlack;
  189. bcWhite : Cnv.Pen.FPColor := colWhite;
  190. end;
  191. W:=FWidths[BP.w];
  192. Cnv.Brush.FPColor:=Cnv.Pen.FPColor;
  193. H:=Rect.Bottom-Rect.Top;
  194. if BP.h=bhTwoFifth then
  195. H:=H*2 div 5;
  196. BarRect.Left:=Rect.Left+xOffset;
  197. BarRect.Top:=Rect.Top;
  198. BarRect.Bottom:=Rect.Top+H;
  199. BarRect.Right:=BarRect.Left + W-1;
  200. if (Not Clipping or (BarRect.Right<=MaxWidth)) then
  201. Cnv.FillRect(BarRect);
  202. xOffset:=xOffset + W;
  203. Inc(I);
  204. end;
  205. end;
  206. function TFPDrawBarCode.AllowDraw: Boolean;
  207. begin
  208. Result:=StringAllowsBarEncoding(FText,FEncoding);
  209. end;
  210. function TFPDrawBarCode.CalcWidth: Integer;
  211. begin
  212. if AllowDraw then
  213. Result:=CalcStringWidthInBarCodeEncoding(FText,FEncoding,UnitWidth,Weight)
  214. else
  215. Result:=-1;
  216. end;
  217. end.