qrdemo.pp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. {*
  2. * QR Code generator demo (Pascal)
  3. *
  4. * Run this command-line program with no arguments. The program
  5. * computes a demonstration QR Codes and print it to the console.
  6. *
  7. * Pascal Version: Copyright (c) Michael Van Canneyt ([email protected])
  8. * Copyright (c) Project Nayuki. (MIT License)
  9. * https://www.nayuki.io/page/qr-code-generator-library
  10. *
  11. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  12. * this software and associated documentation files (the "Software"), to deal in
  13. * the Software without restriction, including without limitation the rights to
  14. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  15. * the Software, and to permit persons to whom the Software is furnished to do so,
  16. * subject to the following conditions:
  17. * - The above copyright notice and this permission notice shall be included in
  18. * all copies or substantial portions of the Software.
  19. * - The Software is provided "as is", without warranty of any kind, express or
  20. * implied, including but not limited to the warranties of merchantability,
  21. * fitness for a particular purpose and noninfringement. In no event shall the
  22. * authors or copyright holders be liable for any claim, damages or other
  23. * liability, whether in an action of contract, tort or otherwise, arising from,
  24. * out of or in connection with the Software or the use or other dealings in the
  25. * Software.
  26. */
  27. }
  28. {$mode objfpc}
  29. {$h+}
  30. {$CODEPAGE UTF8}
  31. uses fpqrcodegen, sysutils;
  32. // Prints the given QR Code to the console.
  33. Procedure printqr (qrcode : TQRBuffer);
  34. var
  35. size : cardinal;
  36. border: byte;
  37. x,y : Integer;
  38. begin
  39. Size:=QRgetSize(qrcode);
  40. border:=4;
  41. For Y:=-Border to size+Border-1 do
  42. begin
  43. For x:=-Border to size+Border-1 do
  44. if (X>=0) and (Y>=0) and QRgetModule(qrcode, x, y) then
  45. write('##')
  46. else
  47. Write(' ');
  48. writeln;
  49. end;
  50. end;
  51. // Creates a single QR Code, then prints it to the console.
  52. procedure doBasicDemo;
  53. var
  54. aText : string;
  55. errCorLvl : TQRErrorLevelCorrection;
  56. tempbuffer,
  57. qrcode: TQRBuffer;
  58. begin
  59. SetLength(tempBuffer,QRBUFFER_LEN_MAX);
  60. SetLength(qrCode,QRBUFFER_LEN_MAX);
  61. aText:='Hello, world!'; // User-supplied text
  62. errCorLvl:=EccLOW; // Error correction level
  63. if QRencodeText(atext, tempBuffer, qrcode, errCorLvl, QRVERSIONMIN, QRVERSIONMAX, mpAUTO, true) then
  64. printQr(qrcode);
  65. end;
  66. // Creates a variety of QR Codes that exercise different features of the library, and prints each one to the console.
  67. procedure doVarietyDemo;
  68. const
  69. UTF8Encoded : Array[0..34] of byte =
  70. ($E3,$81,$93,$E3,$82,$93,$E3,$81,$AB,$E3,$81,$A1,Ord('w'),Ord('a'),$E3,$80,$81,$E4,$B8,$96,$E7,$95,$8C,$EF,$BC,$81,$20,$CE,$B1,$CE,$B2,$CE,$B3,$CE,$B4);
  71. var
  72. atext : UTF8String;
  73. tempbuffer,
  74. qrcode: TQRBuffer;
  75. procedure ResetBuffer;
  76. begin
  77. FillChar(tempBuffer[0],QRBUFFER_LEN_MAX,0);
  78. FillChar(qrCode[0],QRBUFFER_LEN_MAX,0);
  79. end;
  80. begin
  81. // Project Nayuki URL
  82. SetLength(tempBuffer,QRBUFFER_LEN_MAX);
  83. SetLength(qrCode,QRBUFFER_LEN_MAX);
  84. if QRencodeText('https://www.nayuki.io/', tempBuffer, qrcode,
  85. EccHIGH, QRVERSIONMIN, QRVERSIONMAX, mp3, true) then
  86. PrintQr(qrCode);
  87. // Numeric mode encoding (3.33 bits per digit)
  88. ResetBuffer;
  89. if QRencodeText('314159265358979323846264338327950288419716939937510', tempBuffer, qrcode,
  90. EccMEDIUM, QRVERSIONMIN, QRVERSIONMAX, mpAUTO, true) then
  91. printQr(qrcode);
  92. // Alphanumeric mode encoding (5.5 bits per character)
  93. ResetBuffer;
  94. if QRencodeText('DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/', tempBuffer, qrcode,
  95. eccHIGH, QRVERSIONMIN, QRVERSIONMAX, mpAUTO, true) then
  96. printQr(qrcode);
  97. ResetBuffer;
  98. // Unicode text as UTF-8, and different masks
  99. SetLength(aText,Length(UTF8Encoded));
  100. Move(UTF8Encoded[0],atext[1],Length(UTF8Encoded));
  101. if QRencodeText(atext, tempBuffer, qrcode,
  102. eccQUARTILE, QRVERSIONMIN, QRVERSIONMAX, mp0, true) then
  103. printQr(qrcode);
  104. ResetBuffer;
  105. if QRencodeText(atext, tempBuffer, qrcode,
  106. eccQUARTILE, QRVERSIONMIN, QRVERSIONMAX, mp1, true) then
  107. printQr(qrcode);
  108. ResetBuffer;
  109. if QRencodeText(atext, tempBuffer, qrcode,
  110. eccQUARTILE, QRVERSIONMIN, QRVERSIONMAX, mp5, true) then
  111. printQr(qrcode);
  112. ResetBuffer;
  113. if QRencodeText(atext, tempBuffer, qrcode,
  114. eccQUARTILE, QRVERSIONMIN, QRVERSIONMAX, mp7, true) then
  115. printQr(qrcode);
  116. ResetBuffer;
  117. // Moderately large QR Code using longer text (from Lewis Carroll's Alice in Wonderland)
  118. atext :=
  119. 'Alice was beginning to get very tired of sitting by her sister on the bank, '
  120. +'and of having nothing to do: once or twice she had peeped into the book her sister was reading, '
  121. +'but it had no pictures or conversations in it, ''and what is the use of a book,'' thought Alice '
  122. +'''without pictures or conversations?'' So she was considering in her own mind (as well as she could, '
  123. +'for the hot day made her feel very sleepy and stupid), whether the pleasure of making a '
  124. +'daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly '
  125. +'a White Rabbit with pink eyes ran close by her.';
  126. Writeln(atext);
  127. if QRencodeText(atext, tempBuffer, qrcode, eccHIGH, QRVERSIONMIN, QRVERSIONMAX, mpAUTO, true) then
  128. printQr(qrcode);
  129. end;
  130. procedure doSegmentDemo;
  131. const
  132. kanjiChars : Array[0..28] of word = ( // Kanji mode encoding (13 bits per character)
  133. $0035, $1002, $0FC0, $0AED, $0AD7,
  134. $015C, $0147, $0129, $0059, $01BD,
  135. $018D, $018A, $0036, $0141, $0144,
  136. $0001, $0000, $0249, $0240, $0249,
  137. $0000, $0104, $0105, $0113, $0115,
  138. $0000, $0208, $01FF, $0008);
  139. var
  140. aText,silver0,silver1,golden0,golden1,golden2 : String;
  141. tempbuffer,
  142. qrcode: TQRBuffer;
  143. bytes,
  144. segbuf0,
  145. segbuf1,
  146. segbuf2 : TQRBuffer;
  147. seg : TQRSegment;
  148. segs : TQRSegmentArray;
  149. segs2 : TQRSegmentArray;
  150. len, I,j : integer;
  151. begin
  152. SetLength(tempBuffer,QRBUFFER_LEN_MAX);
  153. SetLength(qrCode,QRBUFFER_LEN_MAX);
  154. // Illustration 'silver'
  155. silver0 := 'THE SQUARE ROOT OF 2 IS 1.';
  156. silver1 := '41421356237309504880168872420969807856967187537694807317667973799';
  157. aText:=silver0+Silver1;
  158. if QRencodeText(aText, tempBuffer, qrcode, EccLOW, QRVERSIONMIN, QRVERSIONMAX, mpAUTO, true) then
  159. printQr(qrcode);
  160. SetLength(segBuf0,QRcalcSegmentBufferSize(mALPHANUMERIC, length(silver0)));
  161. SetLength(segBuf1,QRcalcSegmentBufferSize(mNUMERIC, length(silver1)));
  162. SetLength(Segs,2);
  163. segs[0]:=QRmakeAlphanumeric(silver0, segBuf0);
  164. segs[1]:=QRmakeNumeric(silver1, segBuf1);
  165. if QRencodeSegments(segs, eccLOW, tempBuffer, qrcode) then
  166. printQr(qrcode);
  167. // Illustration "golden"
  168. SetLength(Segbuf0,0);
  169. SetLength(Segbuf1,0);
  170. golden0 := 'Golden ratio '#$CF#$86' = 1.';
  171. golden1 := '6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374';
  172. golden2 := '......';
  173. atext:=Golden0+Golden1+Golden2;
  174. if QRencodeText(aText, tempBuffer, qrcode, EccLOW, QRVERSIONMIN, QRVERSIONMAX, mpAUTO, true) then
  175. printQr(qrcode);
  176. SetLength(bytes,Length(golden0));
  177. for I:=1 to Length(golden0) do
  178. bytes[i-1]:=Ord(golden0[i]);
  179. SetLength(segBuf0,QRcalcSegmentBufferSize(mBYTE, length(golden0)));
  180. SetLength(segBuf1,QRcalcSegmentBufferSize(mNUMERIC, length(golden1)));
  181. SetLength(segBuf2,QRcalcSegmentBufferSize(mALPHANUMERIC, length(golden2)));
  182. SetLength(Segs2,3);
  183. segs2[0]:=QRmakeBytes(bytes, segBuf0);
  184. segs2[1]:=QRmakeNumeric(golden1, segBuf1);
  185. segs2[2]:=QRmakeAlphanumeric(golden2, segBuf2);
  186. SetLength(bytes,0);
  187. if QRencodeSegments(segs2,EccLOW, tempBuffer, qrcode) then
  188. PrintQR(qrCode);
  189. // Illustration "Madoka": kanji, kana, Greek, Cyrillic, full-width Latin characters
  190. SetLength(segBuf0,0);
  191. SetLength(segBuf1,0);
  192. SetLength(segBuf2,0);
  193. atext:= // Encoded in UTF-8
  194. #$E3#$80#$8C#$E9#$AD#$94#$E6#$B3#$95#$E5+
  195. #$B0#$91#$E5#$A5#$B3#$E3#$81#$BE#$E3#$81+
  196. #$A9#$E3#$81#$8B#$E2#$98#$86#$E3#$83#$9E+
  197. #$E3#$82#$AE#$E3#$82#$AB#$E3#$80#$8D#$E3+
  198. #$81#$A3#$E3#$81#$A6#$E3#$80#$81#$E3#$80+
  199. #$80#$D0#$98#$D0#$90#$D0#$98#$E3#$80#$80+
  200. #$EF#$BD#$84#$EF#$BD#$85#$EF#$BD#$93#$EF+
  201. #$BD#$95#$E3#$80#$80#$CE#$BA#$CE#$B1#$EF+
  202. #$BC#$9F;
  203. if QRencodeText(aText, tempBuffer, qrcode, eccLOW, QRVERSIONMIN, QRVERSIONMAX, mpAUTO, true) then
  204. printQr(qrcode);
  205. len:= SizeOf(kanjiChars) div sizeof(Word);
  206. SetLength(segBuf0,QRcalcSegmentBufferSize(mKANJI, len));
  207. seg.mode := mKANJI;
  208. seg.numChars := len;
  209. seg.bitLength := 0;
  210. for I:=0 to Len-1 do
  211. for j:=12 downto 0 do
  212. begin
  213. segBuf0[seg.bitLength shr 3]:=segBuf0[seg.bitLength shr 3] or ((kanjiChars[i] shr j) and 1) shl (7 - (seg.bitLength and 7));
  214. inc(seg.bitLength);
  215. end;
  216. seg.data:=segBuf0;
  217. SetLength(segs,1);
  218. segs[0]:=Seg;
  219. if QRencodeSegments(segs,eccLOW, tempBuffer, qrcode) then
  220. printQr(qrcode);
  221. end;
  222. begin
  223. doBasicDemo();
  224. doVarietyDemo();
  225. doSegmentDemo();
  226. end.