hy-app 0.5.9 → 0.5.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. package/components/hy-action-sheet/hy-action-sheet.vue +200 -200
  2. package/components/hy-action-sheet/props.ts +71 -71
  3. package/components/hy-action-sheet/typing.d.ts +64 -64
  4. package/components/hy-address-picker/hy-address-picker.vue +1 -1
  5. package/components/hy-address-picker/props.ts +100 -100
  6. package/components/hy-address-picker/typing.d.ts +16 -16
  7. package/components/hy-avatar/hy-avatar.vue +163 -163
  8. package/components/hy-avatar/props.ts +78 -78
  9. package/components/hy-avatar/typing.d.ts +4 -4
  10. package/components/hy-back-top/hy-back-top.vue +90 -90
  11. package/components/hy-back-top/props.ts +60 -60
  12. package/components/hy-back-top/typing.d.ts +4 -4
  13. package/components/hy-badge/hy-badge.vue +97 -97
  14. package/components/hy-badge/props.ts +82 -82
  15. package/components/hy-badge/typing.d.ts +9 -9
  16. package/components/hy-button/hy-button.vue +275 -275
  17. package/components/hy-button/props.ts +135 -135
  18. package/components/hy-button/typing.d.ts +30 -30
  19. package/components/hy-calendar/header.vue +60 -60
  20. package/components/hy-calendar/hy-calendar.vue +362 -362
  21. package/components/hy-calendar/month.vue +537 -537
  22. package/components/hy-calendar/props.ts +159 -159
  23. package/components/hy-calendar/typing.d.ts +6 -6
  24. package/components/hy-card/hy-card.vue +161 -161
  25. package/components/hy-card/props.ts +122 -122
  26. package/components/hy-card/typing.d.ts +12 -12
  27. package/components/hy-cell/hy-cell.vue +33 -33
  28. package/components/hy-cell/props.ts +54 -54
  29. package/components/hy-cell/typing.d.ts +4 -4
  30. package/components/hy-cell-item/hy-cell-item.vue +161 -161
  31. package/components/hy-cell-item/props.ts +66 -66
  32. package/components/hy-cell-item/typing.d.ts +7 -7
  33. package/components/hy-check-button/hy-check-button.vue +96 -96
  34. package/components/hy-check-button/props.ts +74 -74
  35. package/components/hy-check-button/typing.d.ts +44 -44
  36. package/components/hy-checkbox/hy-checkbox.vue +227 -227
  37. package/components/hy-checkbox/props.ts +96 -96
  38. package/components/hy-checkbox/typing.d.ts +8 -8
  39. package/components/hy-checkbox-group/hy-checkbox-group.vue +45 -45
  40. package/components/hy-checkbox-group/props.ts +80 -80
  41. package/components/hy-checkbox-group/typing.d.ts +6 -6
  42. package/components/hy-checkbox-item/hy-checkbox-item.vue +199 -199
  43. package/components/hy-checkbox-item/props.ts +24 -24
  44. package/components/hy-checkbox-item/typing.d.ts +7 -7
  45. package/components/hy-code-input/hy-code-input.vue +231 -231
  46. package/components/hy-code-input/props.ts +88 -88
  47. package/components/hy-code-input/typing.d.ts +8 -8
  48. package/components/hy-config-provider/hy-config-provider.vue +53 -53
  49. package/components/hy-config-provider/props.ts +28 -28
  50. package/components/hy-count-down/hy-count-down.vue +170 -170
  51. package/components/hy-count-down/index.ts +52 -52
  52. package/components/hy-count-down/props.ts +32 -32
  53. package/components/hy-count-down/typing.d.ts +14 -14
  54. package/components/hy-count-to/hy-count-to.vue +218 -218
  55. package/components/hy-count-to/props.ts +62 -62
  56. package/components/hy-count-to/typing.d.ts +4 -4
  57. package/components/hy-coupon/hy-coupon.vue +172 -172
  58. package/components/hy-coupon/index.scss +171 -171
  59. package/components/hy-coupon/props.ts +103 -103
  60. package/components/hy-coupon/typing.d.ts +14 -14
  61. package/components/hy-datetime-picker/hy-datetime-picker.vue +521 -521
  62. package/components/hy-datetime-picker/props.ts +142 -142
  63. package/components/hy-datetime-picker/typing.d.ts +20 -20
  64. package/components/hy-divider/hy-divider.vue +132 -132
  65. package/components/hy-divider/props.ts +80 -80
  66. package/components/hy-dropdown/hy-dropdown.vue +60 -60
  67. package/components/hy-dropdown/props.ts +40 -40
  68. package/components/hy-dropdown-item/hy-dropdown-item.vue +206 -206
  69. package/components/hy-dropdown-item/props.ts +21 -21
  70. package/components/hy-dropdown-item/typing.d.ts +17 -17
  71. package/components/hy-empty/hy-empty.vue +116 -116
  72. package/components/hy-empty/icon.ts +72 -72
  73. package/components/hy-empty/props.ts +60 -60
  74. package/components/hy-empty/typing.d.ts +38 -38
  75. package/components/hy-flex/hy-flex.vue +53 -53
  76. package/components/hy-flex/index.scss +8 -8
  77. package/components/hy-flex/props.ts +58 -58
  78. package/components/hy-flex/typing.d.ts +21 -21
  79. package/components/hy-float-button/hy-float-button.vue +378 -378
  80. package/components/hy-float-button/props.ts +111 -111
  81. package/components/hy-float-button/typing.d.ts +35 -35
  82. package/components/hy-folding-panel/hy-folding-panel.vue +109 -109
  83. package/components/hy-folding-panel/props.ts +42 -42
  84. package/components/hy-folding-panel/typing.d.ts +19 -19
  85. package/components/hy-folding-panel-item/hy-folding-panel-item.vue +183 -183
  86. package/components/hy-folding-panel-item/props.ts +81 -81
  87. package/components/hy-folding-panel-item/typing.d.ts +37 -37
  88. package/components/hy-form/hy-form.vue +220 -220
  89. package/components/hy-form/props.ts +37 -37
  90. package/components/hy-form/typing.d.ts +41 -41
  91. package/components/hy-form-group/hy-form-group.vue +333 -333
  92. package/components/hy-form-group/props.ts +105 -105
  93. package/components/hy-form-item/hy-form-item.vue +176 -176
  94. package/components/hy-form-item/index.scss +0 -1
  95. package/components/hy-form-item/props.ts +25 -25
  96. package/components/hy-form-item/typing.d.ts +30 -30
  97. package/components/hy-grid/hy-grid.vue +109 -109
  98. package/components/hy-grid/props.ts +60 -60
  99. package/components/hy-grid/typing.d.ts +35 -35
  100. package/components/hy-icon/hy-icon.vue +112 -112
  101. package/components/hy-icon/index.scss +0 -3
  102. package/components/hy-icon/props.ts +79 -79
  103. package/components/hy-icon/typing.d.ts +9 -9
  104. package/components/hy-image/hy-image.vue +192 -192
  105. package/components/hy-image/props.ts +107 -107
  106. package/components/hy-image/typing.d.ts +10 -10
  107. package/components/hy-input/hy-input.vue +333 -333
  108. package/components/hy-input/index.scss +5 -0
  109. package/components/hy-input/props.ts +186 -186
  110. package/components/hy-input/typing.d.ts +31 -31
  111. package/components/hy-line/hy-line.vue +55 -55
  112. package/components/hy-line/props.ts +43 -43
  113. package/components/hy-line-progress/hy-line-progress.vue +102 -102
  114. package/components/hy-line-progress/index.scss +1 -0
  115. package/components/hy-line-progress/props.ts +33 -33
  116. package/components/hy-list/hy-list.vue +226 -226
  117. package/components/hy-list/props.ts +69 -69
  118. package/components/hy-list/typing.d.ts +6 -6
  119. package/components/hy-loading/hy-loading.vue +107 -107
  120. package/components/hy-loading/props.ts +65 -65
  121. package/components/hy-menu/hy-menu.vue +159 -159
  122. package/components/hy-menu/props.ts +44 -44
  123. package/components/hy-menu/typing.d.ts +34 -34
  124. package/components/hy-modal/hy-modal.vue +173 -173
  125. package/components/hy-modal/props.ts +90 -90
  126. package/components/hy-modal/typing.d.ts +11 -11
  127. package/components/hy-navbar/hy-navbar.vue +144 -144
  128. package/components/hy-navbar/props.ts +78 -78
  129. package/components/hy-navbar/typing.d.ts +6 -6
  130. package/components/hy-notice-bar/hy-column-notice.vue +94 -94
  131. package/components/hy-notice-bar/hy-notice-bar.vue +96 -96
  132. package/components/hy-notice-bar/hy-row-notice.vue +121 -121
  133. package/components/hy-notice-bar/props.ts +85 -85
  134. package/components/hy-notice-bar/typing.d.ts +8 -8
  135. package/components/hy-notify/hy-notify.vue +174 -174
  136. package/components/hy-notify/props.ts +51 -51
  137. package/components/hy-number-step/hy-number-step.vue +367 -367
  138. package/components/hy-number-step/props.ts +112 -112
  139. package/components/hy-number-step/typing.d.ts +16 -16
  140. package/components/hy-overlay/hy-overlay.vue +60 -60
  141. package/components/hy-overlay/props.ts +33 -33
  142. package/components/hy-overlay/typing.d.ts +4 -4
  143. package/components/hy-pagination/hy-pagination.vue +135 -135
  144. package/components/hy-pagination/props.ts +55 -55
  145. package/components/hy-pagination/typing.d.ts +10 -10
  146. package/components/hy-picker/hy-picker.vue +7 -5
  147. package/components/hy-picker/props.ts +7 -2
  148. package/components/hy-picker/typing.d.ts +9 -5
  149. package/components/hy-popover/hy-popover.vue +251 -251
  150. package/components/hy-popover/props.ts +51 -51
  151. package/components/hy-popover/typing.d.ts +39 -39
  152. package/components/hy-popup/hy-popup.vue +197 -197
  153. package/components/hy-popup/props.ts +85 -85
  154. package/components/hy-popup/typing.d.ts +10 -10
  155. package/components/hy-price/hy-price.vue +79 -79
  156. package/components/hy-price/props.ts +54 -54
  157. package/components/hy-price/typing.d.ts +4 -4
  158. package/components/hy-qrcode/hy-qrcode.vue +216 -216
  159. package/components/hy-qrcode/props.ts +70 -70
  160. package/components/hy-qrcode/qrcode.js +1304 -1304
  161. package/components/hy-qrcode/typing.d.ts +8 -8
  162. package/components/hy-radio/hy-radio.vue +226 -226
  163. package/components/hy-radio/props.ts +1 -1
  164. package/components/hy-radio/typing.d.ts +8 -8
  165. package/components/hy-rate/hy-rate.vue +239 -239
  166. package/components/hy-rate/props.ts +77 -77
  167. package/components/hy-rate/typing.d.ts +6 -6
  168. package/components/hy-read-more/hy-read-more.vue +130 -130
  169. package/components/hy-read-more/props.ts +45 -45
  170. package/components/hy-read-more/typing.d.ts +6 -6
  171. package/components/hy-rolling-num/hy-rolling-num.vue +188 -188
  172. package/components/hy-rolling-num/props.ts +68 -68
  173. package/components/hy-scroll-list/hy-scroll-list.vue +123 -123
  174. package/components/hy-scroll-list/props.ts +22 -22
  175. package/components/hy-scroll-list/typing.d.ts +6 -6
  176. package/components/hy-search/hy-search.vue +221 -221
  177. package/components/hy-search/props.ts +131 -131
  178. package/components/hy-search/typing.d.ts +22 -22
  179. package/components/hy-signature/hy-signature.vue +640 -640
  180. package/components/hy-signature/props.ts +118 -118
  181. package/components/hy-signature/typing.d.ts +93 -93
  182. package/components/hy-slider/hy-slider.vue +444 -444
  183. package/components/hy-slider/props.ts +77 -77
  184. package/components/hy-slider/typing.d.ts +10 -10
  185. package/components/hy-status-bar/hy-status-bar.vue +41 -41
  186. package/components/hy-status-bar/props.ts +8 -8
  187. package/components/hy-status-bar/typing.d.ts +12 -12
  188. package/components/hy-steps/hy-steps.vue +267 -267
  189. package/components/hy-steps/props.ts +49 -49
  190. package/components/hy-steps/typing.d.ts +21 -21
  191. package/components/hy-sticky/hy-sticky.vue +226 -226
  192. package/components/hy-sticky/props.ts +24 -24
  193. package/components/hy-sticky/typing.d.ts +4 -4
  194. package/components/hy-submit-bar/hy-submit-bar.vue +189 -189
  195. package/components/hy-submit-bar/props.ts +91 -91
  196. package/components/hy-submit-bar/typing.d.ts +24 -24
  197. package/components/hy-subsection/hy-subsection.vue +207 -207
  198. package/components/hy-subsection/props.ts +52 -52
  199. package/components/hy-subsection/typing.d.ts +13 -13
  200. package/components/hy-swipe-action/hy-swipe-action.vue +323 -323
  201. package/components/hy-swipe-action/index.ts +25 -25
  202. package/components/hy-swipe-action/props.ts +47 -47
  203. package/components/hy-swipe-action/typing.d.ts +25 -25
  204. package/components/hy-swiper/hy-swiper-indicator.vue +75 -75
  205. package/components/hy-swiper/hy-swiper.vue +224 -224
  206. package/components/hy-swiper/props.ts +128 -128
  207. package/components/hy-swiper/typing.d.ts +26 -26
  208. package/components/hy-switch/hy-switch.vue +173 -173
  209. package/components/hy-switch/props.ts +61 -61
  210. package/components/hy-switch/typing.d.ts +8 -8
  211. package/components/hy-tabbar/hy-tabbar.vue +136 -136
  212. package/components/hy-tabbar/props.ts +59 -59
  213. package/components/hy-tabbar/typing.d.ts +21 -21
  214. package/components/hy-tabbar-group/hy-tabbar-group.vue +87 -87
  215. package/components/hy-tabbar-group/props.ts +78 -78
  216. package/components/hy-tabbar-group/typing.d.ts +16 -16
  217. package/components/hy-tabbar-item/hy-tabbar-item.vue +103 -103
  218. package/components/hy-tabbar-item/typing.d.ts +10 -10
  219. package/components/hy-table/hy-table.vue +358 -358
  220. package/components/hy-table/props.ts +47 -47
  221. package/components/hy-table/typing.d.ts +34 -34
  222. package/components/hy-tabs/hy-tabs.vue +335 -335
  223. package/components/hy-tabs/props.ts +77 -77
  224. package/components/hy-tabs/typing.d.ts +33 -33
  225. package/components/hy-tag/hy-tag.vue +174 -174
  226. package/components/hy-tag/props.ts +89 -89
  227. package/components/hy-tag/typing.d.ts +13 -13
  228. package/components/hy-text/hy-text.vue +237 -237
  229. package/components/hy-text/props.ts +115 -115
  230. package/components/hy-text/typing.d.ts +6 -6
  231. package/components/hy-textarea/hy-textarea.vue +197 -197
  232. package/components/hy-textarea/index.scss +5 -0
  233. package/components/hy-textarea/props.ts +116 -116
  234. package/components/hy-textarea/typing.d.ts +22 -22
  235. package/components/hy-toast/hy-toast.vue +190 -190
  236. package/components/hy-toast/typing.d.ts +38 -38
  237. package/components/hy-tooltip/hy-tooltip.vue +277 -277
  238. package/components/hy-tooltip/props.ts +78 -78
  239. package/components/hy-tooltip/typing.d.ts +4 -4
  240. package/components/hy-transition/hy-transition.vue +157 -157
  241. package/components/hy-transition/props.ts +32 -32
  242. package/components/hy-transition/typing.d.ts +16 -16
  243. package/components/hy-upload/hy-upload.vue +385 -385
  244. package/components/hy-upload/props.ts +132 -132
  245. package/components/hy-upload/typing.d.ts +65 -65
  246. package/components/hy-warn/hy-warn.vue +115 -115
  247. package/components/hy-warn/props.ts +49 -49
  248. package/components/hy-warn/typing.d.ts +6 -6
  249. package/components/hy-waterfall/hy-waterfall.vue +191 -191
  250. package/components/hy-waterfall/props.ts +21 -21
  251. package/components/hy-watermark/hy-watermark.vue +978 -978
  252. package/components/hy-watermark/props.ts +104 -104
  253. package/components/index.ts +183 -183
  254. package/global.d.ts +91 -91
  255. package/index.ts +1 -1
  256. package/libs/api/http.ts +140 -140
  257. package/libs/api/index.ts +1 -1
  258. package/libs/common/index.ts +2 -2
  259. package/libs/common/queue.ts +28 -28
  260. package/libs/composables/index.ts +6 -6
  261. package/libs/composables/usePopover.ts +241 -241
  262. package/libs/composables/useQueue.ts +53 -53
  263. package/libs/composables/useShakeService.ts +64 -64
  264. package/libs/composables/useShare.ts +42 -42
  265. package/libs/composables/useToast.ts +45 -45
  266. package/libs/composables/useTouch.ts +51 -51
  267. package/libs/config/color.ts +7 -7
  268. package/libs/config/icon.ts +430 -430
  269. package/libs/config/index.ts +2 -2
  270. package/libs/css/iconfont.css +443 -443
  271. package/libs/css/theme.scss +1 -1
  272. package/libs/global/index.ts +6 -6
  273. package/libs/global/register-properties.ts +37 -37
  274. package/libs/index.ts +7 -7
  275. package/libs/typing/index.ts +4 -4
  276. package/libs/typing/modules/common.d.ts +139 -139
  277. package/libs/typing/modules/enum.ts +67 -67
  278. package/libs/typing/modules/form.ts +5 -1
  279. package/libs/typing/modules/http.ts +17 -17
  280. package/libs/typing/modules/icon.d.ts +366 -366
  281. package/libs/typing/modules/rect.ts +10 -10
  282. package/libs/utils/base64.ts +119 -119
  283. package/libs/utils/calendar.js +1021 -1021
  284. package/libs/utils/colorGradient.ts +112 -112
  285. package/libs/utils/index.ts +5 -5
  286. package/libs/utils/inside.ts +350 -361
  287. package/libs/utils/inspect.ts +171 -171
  288. package/libs/utils/utils.ts +521 -521
  289. package/package.json +18 -18
  290. package/web-types.json +1 -1
@@ -1,1304 +1,1304 @@
1
- let QRCode = {}
2
- ;(function () {
3
- /**
4
- * 获取单个字符的utf8编码
5
- * unicode BMP平面约65535个字符
6
- * @param {num} code
7
- * return {array}
8
- */
9
- function unicodeFormat8(code) {
10
- // 1 byte
11
- var c0, c1, c2
12
- if (code < 128) {
13
- return [code]
14
- // 2 bytes
15
- } else if (code < 2048) {
16
- c0 = 192 + (code >> 6)
17
- c1 = 128 + (code & 63)
18
- return [c0, c1]
19
- // 3 bytes
20
- } else {
21
- c0 = 224 + (code >> 12)
22
- c1 = 128 + ((code >> 6) & 63)
23
- c2 = 128 + (code & 63)
24
- return [c0, c1, c2]
25
- }
26
- }
27
- /**
28
- * 获取字符串的utf8编码字节串
29
- * @param {string} string
30
- * @return {array}
31
- */
32
- function getUTF8Bytes(string) {
33
- var utf8codes = []
34
- for (var i = 0; i < string.length; i++) {
35
- var code = string.charCodeAt(i)
36
- var utf8 = unicodeFormat8(code)
37
- for (var j = 0; j < utf8.length; j++) {
38
- utf8codes.push(utf8[j])
39
- }
40
- }
41
- return utf8codes
42
- }
43
- /**
44
- * 二维码算法实现
45
- * @param {string} data 要编码的信息字符串
46
- * @param {num} errorCorrectLevel 纠错等级
47
- */
48
- function QRCodeAlg(data, errorCorrectLevel) {
49
- this.typeNumber = -1 //版本
50
- this.errorCorrectLevel = errorCorrectLevel
51
- this.modules = null //二维矩阵,存放最终结果
52
- this.moduleCount = 0 //矩阵大小
53
- this.dataCache = null //数据缓存
54
- this.rsBlocks = null //版本数据信息
55
- this.totalDataCount = -1 //可使用的数据量
56
- this.data = data
57
- this.utf8bytes = getUTF8Bytes(data)
58
- this.make()
59
- }
60
- QRCodeAlg.prototype = {
61
- constructor: QRCodeAlg,
62
- /**
63
- * 获取二维码矩阵大小
64
- * @return {num} 矩阵大小
65
- */
66
- getModuleCount: function () {
67
- return this.moduleCount
68
- },
69
- /**
70
- * 编码
71
- */
72
- make: function () {
73
- this.getRightType()
74
- this.dataCache = this.createData()
75
- this.createQrcode()
76
- },
77
- /**
78
- * 设置二位矩阵功能图形
79
- * @param {bool} test 表示是否在寻找最好掩膜阶段
80
- * @param {num} maskPattern 掩膜的版本
81
- */
82
- makeImpl: function (maskPattern) {
83
- this.moduleCount = this.typeNumber * 4 + 17
84
- this.modules = new Array(this.moduleCount)
85
- for (var row = 0; row < this.moduleCount; row++) {
86
- this.modules[row] = new Array(this.moduleCount)
87
- }
88
- this.setupPositionProbePattern(0, 0)
89
- this.setupPositionProbePattern(this.moduleCount - 7, 0)
90
- this.setupPositionProbePattern(0, this.moduleCount - 7)
91
- this.setupPositionAdjustPattern()
92
- this.setupTimingPattern()
93
- this.setupTypeInfo(true, maskPattern)
94
- if (this.typeNumber >= 7) {
95
- this.setupTypeNumber(true)
96
- }
97
- this.mapData(this.dataCache, maskPattern)
98
- },
99
- /**
100
- * 设置二维码的位置探测图形
101
- * @param {num} row 探测图形的中心横坐标
102
- * @param {num} col 探测图形的中心纵坐标
103
- */
104
- setupPositionProbePattern: function (row, col) {
105
- for (var r = -1; r <= 7; r++) {
106
- if (row + r <= -1 || this.moduleCount <= row + r) continue
107
- for (var c = -1; c <= 7; c++) {
108
- if (col + c <= -1 || this.moduleCount <= col + c) continue
109
- if (
110
- (0 <= r && r <= 6 && (c == 0 || c == 6)) ||
111
- (0 <= c && c <= 6 && (r == 0 || r == 6)) ||
112
- (2 <= r && r <= 4 && 2 <= c && c <= 4)
113
- ) {
114
- this.modules[row + r][col + c] = true
115
- } else {
116
- this.modules[row + r][col + c] = false
117
- }
118
- }
119
- }
120
- },
121
- /**
122
- * 创建二维码
123
- * @return {[type]} [description]
124
- */
125
- createQrcode: function () {
126
- var minLostPoint = 0
127
- var pattern = 0
128
- var bestModules = null
129
- for (var i = 0; i < 8; i++) {
130
- this.makeImpl(i)
131
- var lostPoint = QRUtil.getLostPoint(this)
132
- if (i == 0 || minLostPoint > lostPoint) {
133
- minLostPoint = lostPoint
134
- pattern = i
135
- bestModules = this.modules
136
- }
137
- }
138
- this.modules = bestModules
139
- this.setupTypeInfo(false, pattern)
140
- if (this.typeNumber >= 7) {
141
- this.setupTypeNumber(false)
142
- }
143
- },
144
- /**
145
- * 设置定位图形
146
- * @return {[type]} [description]
147
- */
148
- setupTimingPattern: function () {
149
- for (var r = 8; r < this.moduleCount - 8; r++) {
150
- if (this.modules[r][6] != null) {
151
- continue
152
- }
153
- this.modules[r][6] = r % 2 == 0
154
- if (this.modules[6][r] != null) {
155
- continue
156
- }
157
- this.modules[6][r] = r % 2 == 0
158
- }
159
- },
160
- /**
161
- * 设置矫正图形
162
- * @return {[type]} [description]
163
- */
164
- setupPositionAdjustPattern: function () {
165
- var pos = QRUtil.getPatternPosition(this.typeNumber)
166
- for (var i = 0; i < pos.length; i++) {
167
- for (var j = 0; j < pos.length; j++) {
168
- var row = pos[i]
169
- var col = pos[j]
170
- if (this.modules[row][col] != null) {
171
- continue
172
- }
173
- for (var r = -2; r <= 2; r++) {
174
- for (var c = -2; c <= 2; c++) {
175
- if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) {
176
- this.modules[row + r][col + c] = true
177
- } else {
178
- this.modules[row + r][col + c] = false
179
- }
180
- }
181
- }
182
- }
183
- }
184
- },
185
- /**
186
- * 设置版本信息(7以上版本才有)
187
- * @param {bool} test 是否处于判断最佳掩膜阶段
188
- * @return {[type]} [description]
189
- */
190
- setupTypeNumber: function (test) {
191
- var bits = QRUtil.getBCHTypeNumber(this.typeNumber)
192
- for (var i = 0; i < 18; i++) {
193
- var mod = !test && ((bits >> i) & 1) == 1
194
- this.modules[Math.floor(i / 3)][(i % 3) + this.moduleCount - 8 - 3] = mod
195
- this.modules[(i % 3) + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod
196
- }
197
- },
198
- /**
199
- * 设置格式信息(纠错等级和掩膜版本)
200
- * @param {bool} test
201
- * @param {num} maskPattern 掩膜版本
202
- * @return {}
203
- */
204
- setupTypeInfo: function (test, maskPattern) {
205
- var data = (QRErrorCorrectLevel[this.errorCorrectLevel] << 3) | maskPattern
206
- var bits = QRUtil.getBCHTypeInfo(data)
207
- // vertical
208
- for (var i = 0; i < 15; i++) {
209
- var mod = !test && ((bits >> i) & 1) == 1
210
- if (i < 6) {
211
- this.modules[i][8] = mod
212
- } else if (i < 8) {
213
- this.modules[i + 1][8] = mod
214
- } else {
215
- this.modules[this.moduleCount - 15 + i][8] = mod
216
- }
217
- // horizontal
218
- var mod = !test && ((bits >> i) & 1) == 1
219
- if (i < 8) {
220
- this.modules[8][this.moduleCount - i - 1] = mod
221
- } else if (i < 9) {
222
- this.modules[8][15 - i - 1 + 1] = mod
223
- } else {
224
- this.modules[8][15 - i - 1] = mod
225
- }
226
- }
227
- // fixed module
228
- this.modules[this.moduleCount - 8][8] = !test
229
- },
230
- /**
231
- * 数据编码
232
- * @return {[type]} [description]
233
- */
234
- createData: function () {
235
- var buffer = new QRBitBuffer()
236
- var lengthBits = this.typeNumber > 9 ? 16 : 8
237
- buffer.put(4, 4) //添加模式
238
- buffer.put(this.utf8bytes.length, lengthBits)
239
- for (var i = 0, l = this.utf8bytes.length; i < l; i++) {
240
- buffer.put(this.utf8bytes[i], 8)
241
- }
242
- if (buffer.length + 4 <= this.totalDataCount * 8) {
243
- buffer.put(0, 4)
244
- }
245
- // padding
246
- while (buffer.length % 8 != 0) {
247
- buffer.putBit(false)
248
- }
249
- // padding
250
- while (true) {
251
- if (buffer.length >= this.totalDataCount * 8) {
252
- break
253
- }
254
- buffer.put(QRCodeAlg.PAD0, 8)
255
- if (buffer.length >= this.totalDataCount * 8) {
256
- break
257
- }
258
- buffer.put(QRCodeAlg.PAD1, 8)
259
- }
260
- return this.createBytes(buffer)
261
- },
262
- /**
263
- * 纠错码编码
264
- * @param {buffer} buffer 数据编码
265
- * @return {[type]}
266
- */
267
- createBytes: function (buffer) {
268
- var offset = 0
269
- var maxDcCount = 0
270
- var maxEcCount = 0
271
- var length = this.rsBlock.length / 3
272
- var rsBlocks = new Array()
273
- for (var i = 0; i < length; i++) {
274
- var count = this.rsBlock[i * 3 + 0]
275
- var totalCount = this.rsBlock[i * 3 + 1]
276
- var dataCount = this.rsBlock[i * 3 + 2]
277
- for (var j = 0; j < count; j++) {
278
- rsBlocks.push([dataCount, totalCount])
279
- }
280
- }
281
- var dcdata = new Array(rsBlocks.length)
282
- var ecdata = new Array(rsBlocks.length)
283
- for (var r = 0; r < rsBlocks.length; r++) {
284
- var dcCount = rsBlocks[r][0]
285
- var ecCount = rsBlocks[r][1] - dcCount
286
- maxDcCount = Math.max(maxDcCount, dcCount)
287
- maxEcCount = Math.max(maxEcCount, ecCount)
288
- dcdata[r] = new Array(dcCount)
289
- for (var i = 0; i < dcdata[r].length; i++) {
290
- dcdata[r][i] = 0xff & buffer.buffer[i + offset]
291
- }
292
- offset += dcCount
293
- var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount)
294
- var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1)
295
- var modPoly = rawPoly.mod(rsPoly)
296
- ecdata[r] = new Array(rsPoly.getLength() - 1)
297
- for (var i = 0; i < ecdata[r].length; i++) {
298
- var modIndex = i + modPoly.getLength() - ecdata[r].length
299
- ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0
300
- }
301
- }
302
- var data = new Array(this.totalDataCount)
303
- var index = 0
304
- for (var i = 0; i < maxDcCount; i++) {
305
- for (var r = 0; r < rsBlocks.length; r++) {
306
- if (i < dcdata[r].length) {
307
- data[index++] = dcdata[r][i]
308
- }
309
- }
310
- }
311
- for (var i = 0; i < maxEcCount; i++) {
312
- for (var r = 0; r < rsBlocks.length; r++) {
313
- if (i < ecdata[r].length) {
314
- data[index++] = ecdata[r][i]
315
- }
316
- }
317
- }
318
- return data
319
- },
320
- /**
321
- * 布置模块,构建最终信息
322
- * @param {} data
323
- * @param {} maskPattern
324
- * @return {}
325
- */
326
- mapData: function (data, maskPattern) {
327
- var inc = -1
328
- var row = this.moduleCount - 1
329
- var bitIndex = 7
330
- var byteIndex = 0
331
- for (var col = this.moduleCount - 1; col > 0; col -= 2) {
332
- if (col == 6) col--
333
- while (true) {
334
- for (var c = 0; c < 2; c++) {
335
- if (this.modules[row][col - c] == null) {
336
- var dark = false
337
- if (byteIndex < data.length) {
338
- dark = ((data[byteIndex] >>> bitIndex) & 1) == 1
339
- }
340
- var mask = QRUtil.getMask(maskPattern, row, col - c)
341
- if (mask) {
342
- dark = !dark
343
- }
344
- this.modules[row][col - c] = dark
345
- bitIndex--
346
- if (bitIndex == -1) {
347
- byteIndex++
348
- bitIndex = 7
349
- }
350
- }
351
- }
352
- row += inc
353
- if (row < 0 || this.moduleCount <= row) {
354
- row -= inc
355
- inc = -inc
356
- break
357
- }
358
- }
359
- }
360
- }
361
- }
362
- /**
363
- * 填充字段
364
- */
365
- QRCodeAlg.PAD0 = 0xec
366
- QRCodeAlg.PAD1 = 0x11
367
- //---------------------------------------------------------------------
368
- // 纠错等级对应的编码
369
- //---------------------------------------------------------------------
370
- var QRErrorCorrectLevel = [1, 0, 3, 2]
371
- //---------------------------------------------------------------------
372
- // 掩膜版本
373
- //---------------------------------------------------------------------
374
- var QRMaskPattern = {
375
- PATTERN000: 0,
376
- PATTERN001: 1,
377
- PATTERN010: 2,
378
- PATTERN011: 3,
379
- PATTERN100: 4,
380
- PATTERN101: 5,
381
- PATTERN110: 6,
382
- PATTERN111: 7
383
- }
384
- //---------------------------------------------------------------------
385
- // 工具类
386
- //---------------------------------------------------------------------
387
- var QRUtil = {
388
- /*
389
- 每个版本矫正图形的位置
390
- */
391
- PATTERN_POSITION_TABLE: [
392
- [],
393
- [6, 18],
394
- [6, 22],
395
- [6, 26],
396
- [6, 30],
397
- [6, 34],
398
- [6, 22, 38],
399
- [6, 24, 42],
400
- [6, 26, 46],
401
- [6, 28, 50],
402
- [6, 30, 54],
403
- [6, 32, 58],
404
- [6, 34, 62],
405
- [6, 26, 46, 66],
406
- [6, 26, 48, 70],
407
- [6, 26, 50, 74],
408
- [6, 30, 54, 78],
409
- [6, 30, 56, 82],
410
- [6, 30, 58, 86],
411
- [6, 34, 62, 90],
412
- [6, 28, 50, 72, 94],
413
- [6, 26, 50, 74, 98],
414
- [6, 30, 54, 78, 102],
415
- [6, 28, 54, 80, 106],
416
- [6, 32, 58, 84, 110],
417
- [6, 30, 58, 86, 114],
418
- [6, 34, 62, 90, 118],
419
- [6, 26, 50, 74, 98, 122],
420
- [6, 30, 54, 78, 102, 126],
421
- [6, 26, 52, 78, 104, 130],
422
- [6, 30, 56, 82, 108, 134],
423
- [6, 34, 60, 86, 112, 138],
424
- [6, 30, 58, 86, 114, 142],
425
- [6, 34, 62, 90, 118, 146],
426
- [6, 30, 54, 78, 102, 126, 150],
427
- [6, 24, 50, 76, 102, 128, 154],
428
- [6, 28, 54, 80, 106, 132, 158],
429
- [6, 32, 58, 84, 110, 136, 162],
430
- [6, 26, 54, 82, 110, 138, 166],
431
- [6, 30, 58, 86, 114, 142, 170]
432
- ],
433
- G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
434
- G18:
435
- (1 << 12) |
436
- (1 << 11) |
437
- (1 << 10) |
438
- (1 << 9) |
439
- (1 << 8) |
440
- (1 << 5) |
441
- (1 << 2) |
442
- (1 << 0),
443
- G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
444
- /*
445
- BCH编码格式信息
446
- */
447
- getBCHTypeInfo: function (data) {
448
- var d = data << 10
449
- while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
450
- d ^= QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15))
451
- }
452
- return ((data << 10) | d) ^ QRUtil.G15_MASK
453
- },
454
- /*
455
- BCH编码版本信息
456
- */
457
- getBCHTypeNumber: function (data) {
458
- var d = data << 12
459
- while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
460
- d ^= QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18))
461
- }
462
- return (data << 12) | d
463
- },
464
- /*
465
- 获取BCH位信息
466
- */
467
- getBCHDigit: function (data) {
468
- var digit = 0
469
- while (data != 0) {
470
- digit++
471
- data >>>= 1
472
- }
473
- return digit
474
- },
475
- /*
476
- 获取版本对应的矫正图形位置
477
- */
478
- getPatternPosition: function (typeNumber) {
479
- return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]
480
- },
481
- /*
482
- 掩膜算法
483
- */
484
- getMask: function (maskPattern, i, j) {
485
- switch (maskPattern) {
486
- case QRMaskPattern.PATTERN000:
487
- return (i + j) % 2 == 0
488
- case QRMaskPattern.PATTERN001:
489
- return i % 2 == 0
490
- case QRMaskPattern.PATTERN010:
491
- return j % 3 == 0
492
- case QRMaskPattern.PATTERN011:
493
- return (i + j) % 3 == 0
494
- case QRMaskPattern.PATTERN100:
495
- return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0
496
- case QRMaskPattern.PATTERN101:
497
- return ((i * j) % 2) + ((i * j) % 3) == 0
498
- case QRMaskPattern.PATTERN110:
499
- return (((i * j) % 2) + ((i * j) % 3)) % 2 == 0
500
- case QRMaskPattern.PATTERN111:
501
- return (((i * j) % 3) + ((i + j) % 2)) % 2 == 0
502
- default:
503
- throw new Error('bad maskPattern:' + maskPattern)
504
- }
505
- },
506
- /*
507
- 获取RS的纠错多项式
508
- */
509
- getErrorCorrectPolynomial: function (errorCorrectLength) {
510
- var a = new QRPolynomial([1], 0)
511
- for (var i = 0; i < errorCorrectLength; i++) {
512
- a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0))
513
- }
514
- return a
515
- },
516
- /*
517
- 获取评价
518
- */
519
- getLostPoint: function (qrCode) {
520
- var moduleCount = qrCode.getModuleCount(),
521
- lostPoint = 0,
522
- darkCount = 0
523
- for (var row = 0; row < moduleCount; row++) {
524
- var sameCount = 0
525
- var head = qrCode.modules[row][0]
526
- for (var col = 0; col < moduleCount; col++) {
527
- var current = qrCode.modules[row][col]
528
- //level 3 评价
529
- if (col < moduleCount - 6) {
530
- if (
531
- current &&
532
- !qrCode.modules[row][col + 1] &&
533
- qrCode.modules[row][col + 2] &&
534
- qrCode.modules[row][col + 3] &&
535
- qrCode.modules[row][col + 4] &&
536
- !qrCode.modules[row][col + 5] &&
537
- qrCode.modules[row][col + 6]
538
- ) {
539
- if (col < moduleCount - 10) {
540
- if (
541
- qrCode.modules[row][col + 7] &&
542
- qrCode.modules[row][col + 8] &&
543
- qrCode.modules[row][col + 9] &&
544
- qrCode.modules[row][col + 10]
545
- ) {
546
- lostPoint += 40
547
- }
548
- } else if (col > 3) {
549
- if (
550
- qrCode.modules[row][col - 1] &&
551
- qrCode.modules[row][col - 2] &&
552
- qrCode.modules[row][col - 3] &&
553
- qrCode.modules[row][col - 4]
554
- ) {
555
- lostPoint += 40
556
- }
557
- }
558
- }
559
- }
560
- //level 2 评价
561
- if (row < moduleCount - 1 && col < moduleCount - 1) {
562
- var count = 0
563
- if (current) count++
564
- if (qrCode.modules[row + 1][col]) count++
565
- if (qrCode.modules[row][col + 1]) count++
566
- if (qrCode.modules[row + 1][col + 1]) count++
567
- if (count == 0 || count == 4) {
568
- lostPoint += 3
569
- }
570
- }
571
- //level 1 评价
572
- if (head ^ current) {
573
- sameCount++
574
- } else {
575
- head = current
576
- if (sameCount >= 5) {
577
- lostPoint += 3 + sameCount - 5
578
- }
579
- sameCount = 1
580
- }
581
- //level 4 评价
582
- if (current) {
583
- darkCount++
584
- }
585
- }
586
- }
587
- for (var col = 0; col < moduleCount; col++) {
588
- var sameCount = 0
589
- var head = qrCode.modules[0][col]
590
- for (var row = 0; row < moduleCount; row++) {
591
- var current = qrCode.modules[row][col]
592
- //level 3 评价
593
- if (row < moduleCount - 6) {
594
- if (
595
- current &&
596
- !qrCode.modules[row + 1][col] &&
597
- qrCode.modules[row + 2][col] &&
598
- qrCode.modules[row + 3][col] &&
599
- qrCode.modules[row + 4][col] &&
600
- !qrCode.modules[row + 5][col] &&
601
- qrCode.modules[row + 6][col]
602
- ) {
603
- if (row < moduleCount - 10) {
604
- if (
605
- qrCode.modules[row + 7][col] &&
606
- qrCode.modules[row + 8][col] &&
607
- qrCode.modules[row + 9][col] &&
608
- qrCode.modules[row + 10][col]
609
- ) {
610
- lostPoint += 40
611
- }
612
- } else if (row > 3) {
613
- if (
614
- qrCode.modules[row - 1][col] &&
615
- qrCode.modules[row - 2][col] &&
616
- qrCode.modules[row - 3][col] &&
617
- qrCode.modules[row - 4][col]
618
- ) {
619
- lostPoint += 40
620
- }
621
- }
622
- }
623
- }
624
- //level 1 评价
625
- if (head ^ current) {
626
- sameCount++
627
- } else {
628
- head = current
629
- if (sameCount >= 5) {
630
- lostPoint += 3 + sameCount - 5
631
- }
632
- sameCount = 1
633
- }
634
- }
635
- }
636
- // LEVEL4
637
- var ratio = Math.abs((100 * darkCount) / moduleCount / moduleCount - 50) / 5
638
- lostPoint += ratio * 10
639
- return lostPoint
640
- }
641
- }
642
- //---------------------------------------------------------------------
643
- // QRMath使用的数学工具
644
- //---------------------------------------------------------------------
645
- var QRMath = {
646
- /*
647
- 将n转化为a^m
648
- */
649
- glog: function (n) {
650
- if (n < 1) {
651
- throw new Error('glog(' + n + ')')
652
- }
653
- return QRMath.LOG_TABLE[n]
654
- },
655
- /*
656
- 将a^m转化为n
657
- */
658
- gexp: function (n) {
659
- while (n < 0) {
660
- n += 255
661
- }
662
- while (n >= 256) {
663
- n -= 255
664
- }
665
- return QRMath.EXP_TABLE[n]
666
- },
667
- EXP_TABLE: new Array(256),
668
- LOG_TABLE: new Array(256)
669
- }
670
- for (var i = 0; i < 8; i++) {
671
- QRMath.EXP_TABLE[i] = 1 << i
672
- }
673
- for (var i = 8; i < 256; i++) {
674
- QRMath.EXP_TABLE[i] =
675
- QRMath.EXP_TABLE[i - 4] ^
676
- QRMath.EXP_TABLE[i - 5] ^
677
- QRMath.EXP_TABLE[i - 6] ^
678
- QRMath.EXP_TABLE[i - 8]
679
- }
680
- for (var i = 0; i < 255; i++) {
681
- QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i
682
- }
683
- //---------------------------------------------------------------------
684
- // QRPolynomial 多项式
685
- //---------------------------------------------------------------------
686
- /**
687
- * 多项式类
688
- * @param {Array} num 系数
689
- * @param {num} shift a^shift
690
- */
691
- function QRPolynomial(num, shift) {
692
- if (num.length == undefined) {
693
- throw new Error(num.length + '/' + shift)
694
- }
695
- var offset = 0
696
- while (offset < num.length && num[offset] == 0) {
697
- offset++
698
- }
699
- this.num = new Array(num.length - offset + shift)
700
- for (var i = 0; i < num.length - offset; i++) {
701
- this.num[i] = num[i + offset]
702
- }
703
- }
704
- QRPolynomial.prototype = {
705
- get: function (index) {
706
- return this.num[index]
707
- },
708
- getLength: function () {
709
- return this.num.length
710
- },
711
- /**
712
- * 多项式乘法
713
- * @param {QRPolynomial} e 被乘多项式
714
- * @return {[type]} [description]
715
- */
716
- multiply: function (e) {
717
- var num = new Array(this.getLength() + e.getLength() - 1)
718
- for (var i = 0; i < this.getLength(); i++) {
719
- for (var j = 0; j < e.getLength(); j++) {
720
- num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)))
721
- }
722
- }
723
- return new QRPolynomial(num, 0)
724
- },
725
- /**
726
- * 多项式模运算
727
- * @param {QRPolynomial} e 模多项式
728
- * @return {}
729
- */
730
- mod: function (e) {
731
- var tl = this.getLength(),
732
- el = e.getLength()
733
- if (tl - el < 0) {
734
- return this
735
- }
736
- var num = new Array(tl)
737
- for (var i = 0; i < tl; i++) {
738
- num[i] = this.get(i)
739
- }
740
- while (num.length >= el) {
741
- var ratio = QRMath.glog(num[0]) - QRMath.glog(e.get(0))
742
-
743
- for (var i = 0; i < e.getLength(); i++) {
744
- num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio)
745
- }
746
- while (num[0] == 0) {
747
- num.shift()
748
- }
749
- }
750
- return new QRPolynomial(num, 0)
751
- }
752
- }
753
-
754
- //---------------------------------------------------------------------
755
- // RS_BLOCK_TABLE
756
- //---------------------------------------------------------------------
757
- /*
758
- 二维码各个版本信息[块数, 每块中的数据块数, 每块中的信息块数]
759
- */
760
- var RS_BLOCK_TABLE = [
761
- // L
762
- // M
763
- // Q
764
- // H
765
- // 1
766
- [1, 26, 19],
767
- [1, 26, 16],
768
- [1, 26, 13],
769
- [1, 26, 9],
770
-
771
- // 2
772
- [1, 44, 34],
773
- [1, 44, 28],
774
- [1, 44, 22],
775
- [1, 44, 16],
776
-
777
- // 3
778
- [1, 70, 55],
779
- [1, 70, 44],
780
- [2, 35, 17],
781
- [2, 35, 13],
782
-
783
- // 4
784
- [1, 100, 80],
785
- [2, 50, 32],
786
- [2, 50, 24],
787
- [4, 25, 9],
788
-
789
- // 5
790
- [1, 134, 108],
791
- [2, 67, 43],
792
- [2, 33, 15, 2, 34, 16],
793
- [2, 33, 11, 2, 34, 12],
794
-
795
- // 6
796
- [2, 86, 68],
797
- [4, 43, 27],
798
- [4, 43, 19],
799
- [4, 43, 15],
800
-
801
- // 7
802
- [2, 98, 78],
803
- [4, 49, 31],
804
- [2, 32, 14, 4, 33, 15],
805
- [4, 39, 13, 1, 40, 14],
806
-
807
- // 8
808
- [2, 121, 97],
809
- [2, 60, 38, 2, 61, 39],
810
- [4, 40, 18, 2, 41, 19],
811
- [4, 40, 14, 2, 41, 15],
812
-
813
- // 9
814
- [2, 146, 116],
815
- [3, 58, 36, 2, 59, 37],
816
- [4, 36, 16, 4, 37, 17],
817
- [4, 36, 12, 4, 37, 13],
818
-
819
- // 10
820
- [2, 86, 68, 2, 87, 69],
821
- [4, 69, 43, 1, 70, 44],
822
- [6, 43, 19, 2, 44, 20],
823
- [6, 43, 15, 2, 44, 16],
824
-
825
- // 11
826
- [4, 101, 81],
827
- [1, 80, 50, 4, 81, 51],
828
- [4, 50, 22, 4, 51, 23],
829
- [3, 36, 12, 8, 37, 13],
830
-
831
- // 12
832
- [2, 116, 92, 2, 117, 93],
833
- [6, 58, 36, 2, 59, 37],
834
- [4, 46, 20, 6, 47, 21],
835
- [7, 42, 14, 4, 43, 15],
836
-
837
- // 13
838
- [4, 133, 107],
839
- [8, 59, 37, 1, 60, 38],
840
- [8, 44, 20, 4, 45, 21],
841
- [12, 33, 11, 4, 34, 12],
842
-
843
- // 14
844
- [3, 145, 115, 1, 146, 116],
845
- [4, 64, 40, 5, 65, 41],
846
- [11, 36, 16, 5, 37, 17],
847
- [11, 36, 12, 5, 37, 13],
848
-
849
- // 15
850
- [5, 109, 87, 1, 110, 88],
851
- [5, 65, 41, 5, 66, 42],
852
- [5, 54, 24, 7, 55, 25],
853
- [11, 36, 12],
854
-
855
- // 16
856
- [5, 122, 98, 1, 123, 99],
857
- [7, 73, 45, 3, 74, 46],
858
- [15, 43, 19, 2, 44, 20],
859
- [3, 45, 15, 13, 46, 16],
860
-
861
- // 17
862
- [1, 135, 107, 5, 136, 108],
863
- [10, 74, 46, 1, 75, 47],
864
- [1, 50, 22, 15, 51, 23],
865
- [2, 42, 14, 17, 43, 15],
866
-
867
- // 18
868
- [5, 150, 120, 1, 151, 121],
869
- [9, 69, 43, 4, 70, 44],
870
- [17, 50, 22, 1, 51, 23],
871
- [2, 42, 14, 19, 43, 15],
872
-
873
- // 19
874
- [3, 141, 113, 4, 142, 114],
875
- [3, 70, 44, 11, 71, 45],
876
- [17, 47, 21, 4, 48, 22],
877
- [9, 39, 13, 16, 40, 14],
878
-
879
- // 20
880
- [3, 135, 107, 5, 136, 108],
881
- [3, 67, 41, 13, 68, 42],
882
- [15, 54, 24, 5, 55, 25],
883
- [15, 43, 15, 10, 44, 16],
884
-
885
- // 21
886
- [4, 144, 116, 4, 145, 117],
887
- [17, 68, 42],
888
- [17, 50, 22, 6, 51, 23],
889
- [19, 46, 16, 6, 47, 17],
890
-
891
- // 22
892
- [2, 139, 111, 7, 140, 112],
893
- [17, 74, 46],
894
- [7, 54, 24, 16, 55, 25],
895
- [34, 37, 13],
896
-
897
- // 23
898
- [4, 151, 121, 5, 152, 122],
899
- [4, 75, 47, 14, 76, 48],
900
- [11, 54, 24, 14, 55, 25],
901
- [16, 45, 15, 14, 46, 16],
902
-
903
- // 24
904
- [6, 147, 117, 4, 148, 118],
905
- [6, 73, 45, 14, 74, 46],
906
- [11, 54, 24, 16, 55, 25],
907
- [30, 46, 16, 2, 47, 17],
908
-
909
- // 25
910
- [8, 132, 106, 4, 133, 107],
911
- [8, 75, 47, 13, 76, 48],
912
- [7, 54, 24, 22, 55, 25],
913
- [22, 45, 15, 13, 46, 16],
914
-
915
- // 26
916
- [10, 142, 114, 2, 143, 115],
917
- [19, 74, 46, 4, 75, 47],
918
- [28, 50, 22, 6, 51, 23],
919
- [33, 46, 16, 4, 47, 17],
920
-
921
- // 27
922
- [8, 152, 122, 4, 153, 123],
923
- [22, 73, 45, 3, 74, 46],
924
- [8, 53, 23, 26, 54, 24],
925
- [12, 45, 15, 28, 46, 16],
926
-
927
- // 28
928
- [3, 147, 117, 10, 148, 118],
929
- [3, 73, 45, 23, 74, 46],
930
- [4, 54, 24, 31, 55, 25],
931
- [11, 45, 15, 31, 46, 16],
932
-
933
- // 29
934
- [7, 146, 116, 7, 147, 117],
935
- [21, 73, 45, 7, 74, 46],
936
- [1, 53, 23, 37, 54, 24],
937
- [19, 45, 15, 26, 46, 16],
938
-
939
- // 30
940
- [5, 145, 115, 10, 146, 116],
941
- [19, 75, 47, 10, 76, 48],
942
- [15, 54, 24, 25, 55, 25],
943
- [23, 45, 15, 25, 46, 16],
944
-
945
- // 31
946
- [13, 145, 115, 3, 146, 116],
947
- [2, 74, 46, 29, 75, 47],
948
- [42, 54, 24, 1, 55, 25],
949
- [23, 45, 15, 28, 46, 16],
950
-
951
- // 32
952
- [17, 145, 115],
953
- [10, 74, 46, 23, 75, 47],
954
- [10, 54, 24, 35, 55, 25],
955
- [19, 45, 15, 35, 46, 16],
956
-
957
- // 33
958
- [17, 145, 115, 1, 146, 116],
959
- [14, 74, 46, 21, 75, 47],
960
- [29, 54, 24, 19, 55, 25],
961
- [11, 45, 15, 46, 46, 16],
962
-
963
- // 34
964
- [13, 145, 115, 6, 146, 116],
965
- [14, 74, 46, 23, 75, 47],
966
- [44, 54, 24, 7, 55, 25],
967
- [59, 46, 16, 1, 47, 17],
968
-
969
- // 35
970
- [12, 151, 121, 7, 152, 122],
971
- [12, 75, 47, 26, 76, 48],
972
- [39, 54, 24, 14, 55, 25],
973
- [22, 45, 15, 41, 46, 16],
974
-
975
- // 36
976
- [6, 151, 121, 14, 152, 122],
977
- [6, 75, 47, 34, 76, 48],
978
- [46, 54, 24, 10, 55, 25],
979
- [2, 45, 15, 64, 46, 16],
980
-
981
- // 37
982
- [17, 152, 122, 4, 153, 123],
983
- [29, 74, 46, 14, 75, 47],
984
- [49, 54, 24, 10, 55, 25],
985
- [24, 45, 15, 46, 46, 16],
986
-
987
- // 38
988
- [4, 152, 122, 18, 153, 123],
989
- [13, 74, 46, 32, 75, 47],
990
- [48, 54, 24, 14, 55, 25],
991
- [42, 45, 15, 32, 46, 16],
992
-
993
- // 39
994
- [20, 147, 117, 4, 148, 118],
995
- [40, 75, 47, 7, 76, 48],
996
- [43, 54, 24, 22, 55, 25],
997
- [10, 45, 15, 67, 46, 16],
998
-
999
- // 40
1000
- [19, 148, 118, 6, 149, 119],
1001
- [18, 75, 47, 31, 76, 48],
1002
- [34, 54, 24, 34, 55, 25],
1003
- [20, 45, 15, 61, 46, 16]
1004
- ]
1005
-
1006
- /**
1007
- * 根据数据获取对应版本
1008
- * @return {[type]} [description]
1009
- */
1010
- QRCodeAlg.prototype.getRightType = function () {
1011
- for (var typeNumber = 1; typeNumber < 41; typeNumber++) {
1012
- var rsBlock = RS_BLOCK_TABLE[(typeNumber - 1) * 4 + this.errorCorrectLevel]
1013
- if (rsBlock == undefined) {
1014
- throw new Error(
1015
- 'bad rs block @ typeNumber:' +
1016
- typeNumber +
1017
- '/errorCorrectLevel:' +
1018
- this.errorCorrectLevel
1019
- )
1020
- }
1021
- var length = rsBlock.length / 3
1022
- var totalDataCount = 0
1023
- for (var i = 0; i < length; i++) {
1024
- var count = rsBlock[i * 3 + 0]
1025
- var dataCount = rsBlock[i * 3 + 2]
1026
- totalDataCount += dataCount * count
1027
- }
1028
- var lengthBytes = typeNumber > 9 ? 2 : 1
1029
- if (this.utf8bytes.length + lengthBytes < totalDataCount || typeNumber == 40) {
1030
- this.typeNumber = typeNumber
1031
- this.rsBlock = rsBlock
1032
- this.totalDataCount = totalDataCount
1033
- break
1034
- }
1035
- }
1036
- }
1037
-
1038
- //---------------------------------------------------------------------
1039
- // QRBitBuffer
1040
- //---------------------------------------------------------------------
1041
- function QRBitBuffer() {
1042
- this.buffer = new Array()
1043
- this.length = 0
1044
- }
1045
- QRBitBuffer.prototype = {
1046
- get: function (index) {
1047
- var bufIndex = Math.floor(index / 8)
1048
- return (this.buffer[bufIndex] >>> (7 - (index % 8))) & 1
1049
- },
1050
- put: function (num, length) {
1051
- for (var i = 0; i < length; i++) {
1052
- this.putBit((num >>> (length - i - 1)) & 1)
1053
- }
1054
- },
1055
- putBit: function (bit) {
1056
- var bufIndex = Math.floor(this.length / 8)
1057
- if (this.buffer.length <= bufIndex) {
1058
- this.buffer.push(0)
1059
- }
1060
- if (bit) {
1061
- this.buffer[bufIndex] |= 0x80 >>> this.length % 8
1062
- }
1063
- this.length++
1064
- }
1065
- }
1066
-
1067
- // xzedit
1068
- let qrcodeAlgObjCache = []
1069
- /**
1070
- * 二维码构造函数,主要用于绘制
1071
- * @param {参数列表} opt 传递参数
1072
- * @return {}
1073
- */
1074
- QRCode = function (opt) {
1075
- //设置默认参数
1076
- this.options = {
1077
- text: '',
1078
- size: 256,
1079
- correctLevel: 3,
1080
- background: '#ffffff',
1081
- foreground: '#000000',
1082
- pdground: '#000000',
1083
- image: '',
1084
- imageSize: 30,
1085
- canvasId: opt.canvasId,
1086
- nvueContext: opt.nvueContext,
1087
- context: opt.context,
1088
- usingComponents: opt.usingComponents,
1089
- showLoading: opt.showLoading,
1090
- loadingText: opt.loadingText
1091
- }
1092
- if (typeof opt === 'string') {
1093
- // 只编码ASCII字符串
1094
- opt = {
1095
- text: opt
1096
- }
1097
- }
1098
- if (opt) {
1099
- for (var i in opt) {
1100
- this.options[i] = opt[i]
1101
- }
1102
- }
1103
- //使用QRCodeAlg创建二维码结构
1104
- var qrCodeAlg = null
1105
- for (var i = 0, l = qrcodeAlgObjCache.length; i < l; i++) {
1106
- if (
1107
- qrcodeAlgObjCache[i].text == this.options.text &&
1108
- qrcodeAlgObjCache[i].text.correctLevel == this.options.correctLevel
1109
- ) {
1110
- qrCodeAlg = qrcodeAlgObjCache[i].obj
1111
- break
1112
- }
1113
- }
1114
- if (i == l) {
1115
- qrCodeAlg = new QRCodeAlg(this.options.text, this.options.correctLevel)
1116
- qrcodeAlgObjCache.push({
1117
- text: this.options.text,
1118
- correctLevel: this.options.correctLevel,
1119
- obj: qrCodeAlg
1120
- })
1121
- }
1122
- /**
1123
- * 计算矩阵点的前景色
1124
- * @param {Obj} config
1125
- * @param {Number} config.row 点x坐标
1126
- * @param {Number} config.col 点y坐标
1127
- * @param {Number} config.count 矩阵大小
1128
- * @param {Number} config.options 组件的options
1129
- * @return {String}
1130
- */
1131
- let getForeGround = function (config) {
1132
- var options = config.options
1133
- if (
1134
- options.pdground &&
1135
- ((config.row > 1 && config.row < 5 && config.col > 1 && config.col < 5) ||
1136
- (config.row > config.count - 6 &&
1137
- config.row < config.count - 2 &&
1138
- config.col > 1 &&
1139
- config.col < 5) ||
1140
- (config.row > 1 &&
1141
- config.row < 5 &&
1142
- config.col > config.count - 6 &&
1143
- config.col < config.count - 2))
1144
- ) {
1145
- return options.pdground
1146
- }
1147
- return options.foreground
1148
- }
1149
- // 创建canvas
1150
- let createCanvas = function (options) {
1151
- if (options.showLoading) {
1152
- uni.showLoading({
1153
- title: options.loadingText,
1154
- mask: true
1155
- })
1156
- }
1157
- var ctx = ''
1158
- if (options.nvueContext) {
1159
- ctx = options.nvueContext
1160
- } else {
1161
- ctx = uni.createCanvasContext(options.canvasId, options.context)
1162
- }
1163
- var count = qrCodeAlg.getModuleCount()
1164
- var ratioSize = options.size
1165
- var ratioImgSize = options.imageSize
1166
- //计算每个点的长宽
1167
- var tileW = (ratioSize / count).toPrecision(4)
1168
- var tileH = (ratioSize / count).toPrecision(4)
1169
- //绘制
1170
- for (var row = 0; row < count; row++) {
1171
- for (var col = 0; col < count; col++) {
1172
- var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW)
1173
- var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW)
1174
- var foreground = getForeGround({
1175
- row: row,
1176
- col: col,
1177
- count: count,
1178
- options: options
1179
- })
1180
- ctx.setFillStyle(qrCodeAlg.modules[row][col] ? foreground : options.background)
1181
- ctx.fillRect(Math.round(col * tileW), Math.round(row * tileH), w, h)
1182
- }
1183
- }
1184
- if (options.image) {
1185
- var x = Number(((ratioSize - ratioImgSize) / 2).toFixed(2))
1186
- var y = Number(((ratioSize - ratioImgSize) / 2).toFixed(2))
1187
- drawRoundedRect(ctx, x, y, ratioImgSize, ratioImgSize, 2, 6, true, true)
1188
- ctx.drawImage(options.image, x, y, ratioImgSize, ratioImgSize)
1189
- // 画圆角矩形
1190
- function drawRoundedRect(ctxi, x, y, width, height, r, lineWidth, fill, stroke) {
1191
- ctxi.setLineWidth(lineWidth)
1192
- ctxi.setFillStyle(options.background)
1193
- ctxi.setStrokeStyle(options.background)
1194
- ctxi.beginPath() // draw top and top right corner
1195
- ctxi.moveTo(x + r, y)
1196
- ctxi.arcTo(x + width, y, x + width, y + r, r) // draw right side and bottom right corner
1197
- ctxi.arcTo(x + width, y + height, x + width - r, y + height, r) // draw bottom and bottom left corner
1198
- ctxi.arcTo(x, y + height, x, y + height - r, r) // draw left and top left corner
1199
- ctxi.arcTo(x, y, x + r, y, r)
1200
- ctxi.closePath()
1201
- if (fill) {
1202
- ctxi.fill()
1203
- }
1204
- if (stroke) {
1205
- ctxi.stroke()
1206
- }
1207
- }
1208
- }
1209
- setTimeout(
1210
- () => {
1211
- ctx.draw(true, () => {
1212
- // 保存到临时区域
1213
- setTimeout(() => {
1214
- if (options.nvueContext) {
1215
- ctx.toTempFilePath(
1216
- 0,
1217
- 0,
1218
- options.width,
1219
- options.height,
1220
- options.width,
1221
- options.height,
1222
- '',
1223
- 1,
1224
- function (res) {
1225
- if (options.cbResult) {
1226
- options.cbResult(res.tempFilePath)
1227
- }
1228
- }
1229
- )
1230
- } else {
1231
- uni.canvasToTempFilePath(
1232
- {
1233
- width: options.width,
1234
- height: options.height,
1235
- destWidth: options.width,
1236
- destHeight: options.height,
1237
- canvasId: options.canvasId,
1238
- quality: Number(1),
1239
- success: function (res) {
1240
- if (options.cbResult) {
1241
- // 由于官方还没有统一此接口的输出字段,所以先判定下 支付宝为 res.apFilePath
1242
- if (!empty(res.tempFilePath)) {
1243
- options.cbResult(res.tempFilePath)
1244
- } else if (!empty(res.apFilePath)) {
1245
- options.cbResult(res.apFilePath)
1246
- } else {
1247
- options.cbResult(res.tempFilePath)
1248
- }
1249
- }
1250
- },
1251
- fail: function (res) {
1252
- if (options.cbResult) {
1253
- options.cbResult(res)
1254
- }
1255
- },
1256
- complete: function () {
1257
- uni.hideLoading()
1258
- }
1259
- },
1260
- options.context
1261
- )
1262
- }
1263
- }, options.text.length + 100)
1264
- })
1265
- },
1266
- options.usingComponents ? 0 : 150
1267
- )
1268
- }
1269
- createCanvas(this.options)
1270
- // 空判定
1271
- let empty = function (v) {
1272
- let tp = typeof v,
1273
- rt = false
1274
- if (tp == 'number' && String(v) == '') {
1275
- rt = true
1276
- } else if (tp == 'undefined') {
1277
- rt = true
1278
- } else if (tp == 'object') {
1279
- if (JSON.stringify(v) == '{}' || JSON.stringify(v) == '[]' || v == null) rt = true
1280
- } else if (tp == 'string') {
1281
- if (v == '' || v == 'undefined' || v == 'null' || v == '{}' || v == '[]') rt = true
1282
- } else if (tp == 'function') {
1283
- rt = false
1284
- }
1285
- return rt
1286
- }
1287
- }
1288
- QRCode.prototype.clear = function (fn) {
1289
- var ctx = ''
1290
- if (options.nvueContext) {
1291
- ctx = options.nvueContext
1292
- } else {
1293
- uni.createCanvasContext(this.options.canvasId, this.options.context)
1294
- }
1295
- ctx.clearRect(0, 0, this.options.size, this.options.size)
1296
- ctx.draw(false, () => {
1297
- if (fn) {
1298
- fn()
1299
- }
1300
- })
1301
- }
1302
- })()
1303
-
1304
- export default QRCode
1
+ let QRCode = {}
2
+ ;(function () {
3
+ /**
4
+ * 获取单个字符的utf8编码
5
+ * unicode BMP平面约65535个字符
6
+ * @param {num} code
7
+ * return {array}
8
+ */
9
+ function unicodeFormat8(code) {
10
+ // 1 byte
11
+ var c0, c1, c2
12
+ if (code < 128) {
13
+ return [code]
14
+ // 2 bytes
15
+ } else if (code < 2048) {
16
+ c0 = 192 + (code >> 6)
17
+ c1 = 128 + (code & 63)
18
+ return [c0, c1]
19
+ // 3 bytes
20
+ } else {
21
+ c0 = 224 + (code >> 12)
22
+ c1 = 128 + ((code >> 6) & 63)
23
+ c2 = 128 + (code & 63)
24
+ return [c0, c1, c2]
25
+ }
26
+ }
27
+ /**
28
+ * 获取字符串的utf8编码字节串
29
+ * @param {string} string
30
+ * @return {array}
31
+ */
32
+ function getUTF8Bytes(string) {
33
+ var utf8codes = []
34
+ for (var i = 0; i < string.length; i++) {
35
+ var code = string.charCodeAt(i)
36
+ var utf8 = unicodeFormat8(code)
37
+ for (var j = 0; j < utf8.length; j++) {
38
+ utf8codes.push(utf8[j])
39
+ }
40
+ }
41
+ return utf8codes
42
+ }
43
+ /**
44
+ * 二维码算法实现
45
+ * @param {string} data 要编码的信息字符串
46
+ * @param {num} errorCorrectLevel 纠错等级
47
+ */
48
+ function QRCodeAlg(data, errorCorrectLevel) {
49
+ this.typeNumber = -1 //版本
50
+ this.errorCorrectLevel = errorCorrectLevel
51
+ this.modules = null //二维矩阵,存放最终结果
52
+ this.moduleCount = 0 //矩阵大小
53
+ this.dataCache = null //数据缓存
54
+ this.rsBlocks = null //版本数据信息
55
+ this.totalDataCount = -1 //可使用的数据量
56
+ this.data = data
57
+ this.utf8bytes = getUTF8Bytes(data)
58
+ this.make()
59
+ }
60
+ QRCodeAlg.prototype = {
61
+ constructor: QRCodeAlg,
62
+ /**
63
+ * 获取二维码矩阵大小
64
+ * @return {num} 矩阵大小
65
+ */
66
+ getModuleCount: function () {
67
+ return this.moduleCount
68
+ },
69
+ /**
70
+ * 编码
71
+ */
72
+ make: function () {
73
+ this.getRightType()
74
+ this.dataCache = this.createData()
75
+ this.createQrcode()
76
+ },
77
+ /**
78
+ * 设置二位矩阵功能图形
79
+ * @param {bool} test 表示是否在寻找最好掩膜阶段
80
+ * @param {num} maskPattern 掩膜的版本
81
+ */
82
+ makeImpl: function (maskPattern) {
83
+ this.moduleCount = this.typeNumber * 4 + 17
84
+ this.modules = new Array(this.moduleCount)
85
+ for (var row = 0; row < this.moduleCount; row++) {
86
+ this.modules[row] = new Array(this.moduleCount)
87
+ }
88
+ this.setupPositionProbePattern(0, 0)
89
+ this.setupPositionProbePattern(this.moduleCount - 7, 0)
90
+ this.setupPositionProbePattern(0, this.moduleCount - 7)
91
+ this.setupPositionAdjustPattern()
92
+ this.setupTimingPattern()
93
+ this.setupTypeInfo(true, maskPattern)
94
+ if (this.typeNumber >= 7) {
95
+ this.setupTypeNumber(true)
96
+ }
97
+ this.mapData(this.dataCache, maskPattern)
98
+ },
99
+ /**
100
+ * 设置二维码的位置探测图形
101
+ * @param {num} row 探测图形的中心横坐标
102
+ * @param {num} col 探测图形的中心纵坐标
103
+ */
104
+ setupPositionProbePattern: function (row, col) {
105
+ for (var r = -1; r <= 7; r++) {
106
+ if (row + r <= -1 || this.moduleCount <= row + r) continue
107
+ for (var c = -1; c <= 7; c++) {
108
+ if (col + c <= -1 || this.moduleCount <= col + c) continue
109
+ if (
110
+ (0 <= r && r <= 6 && (c == 0 || c == 6)) ||
111
+ (0 <= c && c <= 6 && (r == 0 || r == 6)) ||
112
+ (2 <= r && r <= 4 && 2 <= c && c <= 4)
113
+ ) {
114
+ this.modules[row + r][col + c] = true
115
+ } else {
116
+ this.modules[row + r][col + c] = false
117
+ }
118
+ }
119
+ }
120
+ },
121
+ /**
122
+ * 创建二维码
123
+ * @return {[type]} [description]
124
+ */
125
+ createQrcode: function () {
126
+ var minLostPoint = 0
127
+ var pattern = 0
128
+ var bestModules = null
129
+ for (var i = 0; i < 8; i++) {
130
+ this.makeImpl(i)
131
+ var lostPoint = QRUtil.getLostPoint(this)
132
+ if (i == 0 || minLostPoint > lostPoint) {
133
+ minLostPoint = lostPoint
134
+ pattern = i
135
+ bestModules = this.modules
136
+ }
137
+ }
138
+ this.modules = bestModules
139
+ this.setupTypeInfo(false, pattern)
140
+ if (this.typeNumber >= 7) {
141
+ this.setupTypeNumber(false)
142
+ }
143
+ },
144
+ /**
145
+ * 设置定位图形
146
+ * @return {[type]} [description]
147
+ */
148
+ setupTimingPattern: function () {
149
+ for (var r = 8; r < this.moduleCount - 8; r++) {
150
+ if (this.modules[r][6] != null) {
151
+ continue
152
+ }
153
+ this.modules[r][6] = r % 2 == 0
154
+ if (this.modules[6][r] != null) {
155
+ continue
156
+ }
157
+ this.modules[6][r] = r % 2 == 0
158
+ }
159
+ },
160
+ /**
161
+ * 设置矫正图形
162
+ * @return {[type]} [description]
163
+ */
164
+ setupPositionAdjustPattern: function () {
165
+ var pos = QRUtil.getPatternPosition(this.typeNumber)
166
+ for (var i = 0; i < pos.length; i++) {
167
+ for (var j = 0; j < pos.length; j++) {
168
+ var row = pos[i]
169
+ var col = pos[j]
170
+ if (this.modules[row][col] != null) {
171
+ continue
172
+ }
173
+ for (var r = -2; r <= 2; r++) {
174
+ for (var c = -2; c <= 2; c++) {
175
+ if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) {
176
+ this.modules[row + r][col + c] = true
177
+ } else {
178
+ this.modules[row + r][col + c] = false
179
+ }
180
+ }
181
+ }
182
+ }
183
+ }
184
+ },
185
+ /**
186
+ * 设置版本信息(7以上版本才有)
187
+ * @param {bool} test 是否处于判断最佳掩膜阶段
188
+ * @return {[type]} [description]
189
+ */
190
+ setupTypeNumber: function (test) {
191
+ var bits = QRUtil.getBCHTypeNumber(this.typeNumber)
192
+ for (var i = 0; i < 18; i++) {
193
+ var mod = !test && ((bits >> i) & 1) == 1
194
+ this.modules[Math.floor(i / 3)][(i % 3) + this.moduleCount - 8 - 3] = mod
195
+ this.modules[(i % 3) + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod
196
+ }
197
+ },
198
+ /**
199
+ * 设置格式信息(纠错等级和掩膜版本)
200
+ * @param {bool} test
201
+ * @param {num} maskPattern 掩膜版本
202
+ * @return {}
203
+ */
204
+ setupTypeInfo: function (test, maskPattern) {
205
+ var data = (QRErrorCorrectLevel[this.errorCorrectLevel] << 3) | maskPattern
206
+ var bits = QRUtil.getBCHTypeInfo(data)
207
+ // vertical
208
+ for (var i = 0; i < 15; i++) {
209
+ var mod = !test && ((bits >> i) & 1) == 1
210
+ if (i < 6) {
211
+ this.modules[i][8] = mod
212
+ } else if (i < 8) {
213
+ this.modules[i + 1][8] = mod
214
+ } else {
215
+ this.modules[this.moduleCount - 15 + i][8] = mod
216
+ }
217
+ // horizontal
218
+ var mod = !test && ((bits >> i) & 1) == 1
219
+ if (i < 8) {
220
+ this.modules[8][this.moduleCount - i - 1] = mod
221
+ } else if (i < 9) {
222
+ this.modules[8][15 - i - 1 + 1] = mod
223
+ } else {
224
+ this.modules[8][15 - i - 1] = mod
225
+ }
226
+ }
227
+ // fixed module
228
+ this.modules[this.moduleCount - 8][8] = !test
229
+ },
230
+ /**
231
+ * 数据编码
232
+ * @return {[type]} [description]
233
+ */
234
+ createData: function () {
235
+ var buffer = new QRBitBuffer()
236
+ var lengthBits = this.typeNumber > 9 ? 16 : 8
237
+ buffer.put(4, 4) //添加模式
238
+ buffer.put(this.utf8bytes.length, lengthBits)
239
+ for (var i = 0, l = this.utf8bytes.length; i < l; i++) {
240
+ buffer.put(this.utf8bytes[i], 8)
241
+ }
242
+ if (buffer.length + 4 <= this.totalDataCount * 8) {
243
+ buffer.put(0, 4)
244
+ }
245
+ // padding
246
+ while (buffer.length % 8 != 0) {
247
+ buffer.putBit(false)
248
+ }
249
+ // padding
250
+ while (true) {
251
+ if (buffer.length >= this.totalDataCount * 8) {
252
+ break
253
+ }
254
+ buffer.put(QRCodeAlg.PAD0, 8)
255
+ if (buffer.length >= this.totalDataCount * 8) {
256
+ break
257
+ }
258
+ buffer.put(QRCodeAlg.PAD1, 8)
259
+ }
260
+ return this.createBytes(buffer)
261
+ },
262
+ /**
263
+ * 纠错码编码
264
+ * @param {buffer} buffer 数据编码
265
+ * @return {[type]}
266
+ */
267
+ createBytes: function (buffer) {
268
+ var offset = 0
269
+ var maxDcCount = 0
270
+ var maxEcCount = 0
271
+ var length = this.rsBlock.length / 3
272
+ var rsBlocks = new Array()
273
+ for (var i = 0; i < length; i++) {
274
+ var count = this.rsBlock[i * 3 + 0]
275
+ var totalCount = this.rsBlock[i * 3 + 1]
276
+ var dataCount = this.rsBlock[i * 3 + 2]
277
+ for (var j = 0; j < count; j++) {
278
+ rsBlocks.push([dataCount, totalCount])
279
+ }
280
+ }
281
+ var dcdata = new Array(rsBlocks.length)
282
+ var ecdata = new Array(rsBlocks.length)
283
+ for (var r = 0; r < rsBlocks.length; r++) {
284
+ var dcCount = rsBlocks[r][0]
285
+ var ecCount = rsBlocks[r][1] - dcCount
286
+ maxDcCount = Math.max(maxDcCount, dcCount)
287
+ maxEcCount = Math.max(maxEcCount, ecCount)
288
+ dcdata[r] = new Array(dcCount)
289
+ for (var i = 0; i < dcdata[r].length; i++) {
290
+ dcdata[r][i] = 0xff & buffer.buffer[i + offset]
291
+ }
292
+ offset += dcCount
293
+ var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount)
294
+ var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1)
295
+ var modPoly = rawPoly.mod(rsPoly)
296
+ ecdata[r] = new Array(rsPoly.getLength() - 1)
297
+ for (var i = 0; i < ecdata[r].length; i++) {
298
+ var modIndex = i + modPoly.getLength() - ecdata[r].length
299
+ ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0
300
+ }
301
+ }
302
+ var data = new Array(this.totalDataCount)
303
+ var index = 0
304
+ for (var i = 0; i < maxDcCount; i++) {
305
+ for (var r = 0; r < rsBlocks.length; r++) {
306
+ if (i < dcdata[r].length) {
307
+ data[index++] = dcdata[r][i]
308
+ }
309
+ }
310
+ }
311
+ for (var i = 0; i < maxEcCount; i++) {
312
+ for (var r = 0; r < rsBlocks.length; r++) {
313
+ if (i < ecdata[r].length) {
314
+ data[index++] = ecdata[r][i]
315
+ }
316
+ }
317
+ }
318
+ return data
319
+ },
320
+ /**
321
+ * 布置模块,构建最终信息
322
+ * @param {} data
323
+ * @param {} maskPattern
324
+ * @return {}
325
+ */
326
+ mapData: function (data, maskPattern) {
327
+ var inc = -1
328
+ var row = this.moduleCount - 1
329
+ var bitIndex = 7
330
+ var byteIndex = 0
331
+ for (var col = this.moduleCount - 1; col > 0; col -= 2) {
332
+ if (col == 6) col--
333
+ while (true) {
334
+ for (var c = 0; c < 2; c++) {
335
+ if (this.modules[row][col - c] == null) {
336
+ var dark = false
337
+ if (byteIndex < data.length) {
338
+ dark = ((data[byteIndex] >>> bitIndex) & 1) == 1
339
+ }
340
+ var mask = QRUtil.getMask(maskPattern, row, col - c)
341
+ if (mask) {
342
+ dark = !dark
343
+ }
344
+ this.modules[row][col - c] = dark
345
+ bitIndex--
346
+ if (bitIndex == -1) {
347
+ byteIndex++
348
+ bitIndex = 7
349
+ }
350
+ }
351
+ }
352
+ row += inc
353
+ if (row < 0 || this.moduleCount <= row) {
354
+ row -= inc
355
+ inc = -inc
356
+ break
357
+ }
358
+ }
359
+ }
360
+ }
361
+ }
362
+ /**
363
+ * 填充字段
364
+ */
365
+ QRCodeAlg.PAD0 = 0xec
366
+ QRCodeAlg.PAD1 = 0x11
367
+ //---------------------------------------------------------------------
368
+ // 纠错等级对应的编码
369
+ //---------------------------------------------------------------------
370
+ var QRErrorCorrectLevel = [1, 0, 3, 2]
371
+ //---------------------------------------------------------------------
372
+ // 掩膜版本
373
+ //---------------------------------------------------------------------
374
+ var QRMaskPattern = {
375
+ PATTERN000: 0,
376
+ PATTERN001: 1,
377
+ PATTERN010: 2,
378
+ PATTERN011: 3,
379
+ PATTERN100: 4,
380
+ PATTERN101: 5,
381
+ PATTERN110: 6,
382
+ PATTERN111: 7
383
+ }
384
+ //---------------------------------------------------------------------
385
+ // 工具类
386
+ //---------------------------------------------------------------------
387
+ var QRUtil = {
388
+ /*
389
+ 每个版本矫正图形的位置
390
+ */
391
+ PATTERN_POSITION_TABLE: [
392
+ [],
393
+ [6, 18],
394
+ [6, 22],
395
+ [6, 26],
396
+ [6, 30],
397
+ [6, 34],
398
+ [6, 22, 38],
399
+ [6, 24, 42],
400
+ [6, 26, 46],
401
+ [6, 28, 50],
402
+ [6, 30, 54],
403
+ [6, 32, 58],
404
+ [6, 34, 62],
405
+ [6, 26, 46, 66],
406
+ [6, 26, 48, 70],
407
+ [6, 26, 50, 74],
408
+ [6, 30, 54, 78],
409
+ [6, 30, 56, 82],
410
+ [6, 30, 58, 86],
411
+ [6, 34, 62, 90],
412
+ [6, 28, 50, 72, 94],
413
+ [6, 26, 50, 74, 98],
414
+ [6, 30, 54, 78, 102],
415
+ [6, 28, 54, 80, 106],
416
+ [6, 32, 58, 84, 110],
417
+ [6, 30, 58, 86, 114],
418
+ [6, 34, 62, 90, 118],
419
+ [6, 26, 50, 74, 98, 122],
420
+ [6, 30, 54, 78, 102, 126],
421
+ [6, 26, 52, 78, 104, 130],
422
+ [6, 30, 56, 82, 108, 134],
423
+ [6, 34, 60, 86, 112, 138],
424
+ [6, 30, 58, 86, 114, 142],
425
+ [6, 34, 62, 90, 118, 146],
426
+ [6, 30, 54, 78, 102, 126, 150],
427
+ [6, 24, 50, 76, 102, 128, 154],
428
+ [6, 28, 54, 80, 106, 132, 158],
429
+ [6, 32, 58, 84, 110, 136, 162],
430
+ [6, 26, 54, 82, 110, 138, 166],
431
+ [6, 30, 58, 86, 114, 142, 170]
432
+ ],
433
+ G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
434
+ G18:
435
+ (1 << 12) |
436
+ (1 << 11) |
437
+ (1 << 10) |
438
+ (1 << 9) |
439
+ (1 << 8) |
440
+ (1 << 5) |
441
+ (1 << 2) |
442
+ (1 << 0),
443
+ G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
444
+ /*
445
+ BCH编码格式信息
446
+ */
447
+ getBCHTypeInfo: function (data) {
448
+ var d = data << 10
449
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
450
+ d ^= QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15))
451
+ }
452
+ return ((data << 10) | d) ^ QRUtil.G15_MASK
453
+ },
454
+ /*
455
+ BCH编码版本信息
456
+ */
457
+ getBCHTypeNumber: function (data) {
458
+ var d = data << 12
459
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
460
+ d ^= QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18))
461
+ }
462
+ return (data << 12) | d
463
+ },
464
+ /*
465
+ 获取BCH位信息
466
+ */
467
+ getBCHDigit: function (data) {
468
+ var digit = 0
469
+ while (data != 0) {
470
+ digit++
471
+ data >>>= 1
472
+ }
473
+ return digit
474
+ },
475
+ /*
476
+ 获取版本对应的矫正图形位置
477
+ */
478
+ getPatternPosition: function (typeNumber) {
479
+ return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]
480
+ },
481
+ /*
482
+ 掩膜算法
483
+ */
484
+ getMask: function (maskPattern, i, j) {
485
+ switch (maskPattern) {
486
+ case QRMaskPattern.PATTERN000:
487
+ return (i + j) % 2 == 0
488
+ case QRMaskPattern.PATTERN001:
489
+ return i % 2 == 0
490
+ case QRMaskPattern.PATTERN010:
491
+ return j % 3 == 0
492
+ case QRMaskPattern.PATTERN011:
493
+ return (i + j) % 3 == 0
494
+ case QRMaskPattern.PATTERN100:
495
+ return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0
496
+ case QRMaskPattern.PATTERN101:
497
+ return ((i * j) % 2) + ((i * j) % 3) == 0
498
+ case QRMaskPattern.PATTERN110:
499
+ return (((i * j) % 2) + ((i * j) % 3)) % 2 == 0
500
+ case QRMaskPattern.PATTERN111:
501
+ return (((i * j) % 3) + ((i + j) % 2)) % 2 == 0
502
+ default:
503
+ throw new Error('bad maskPattern:' + maskPattern)
504
+ }
505
+ },
506
+ /*
507
+ 获取RS的纠错多项式
508
+ */
509
+ getErrorCorrectPolynomial: function (errorCorrectLength) {
510
+ var a = new QRPolynomial([1], 0)
511
+ for (var i = 0; i < errorCorrectLength; i++) {
512
+ a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0))
513
+ }
514
+ return a
515
+ },
516
+ /*
517
+ 获取评价
518
+ */
519
+ getLostPoint: function (qrCode) {
520
+ var moduleCount = qrCode.getModuleCount(),
521
+ lostPoint = 0,
522
+ darkCount = 0
523
+ for (var row = 0; row < moduleCount; row++) {
524
+ var sameCount = 0
525
+ var head = qrCode.modules[row][0]
526
+ for (var col = 0; col < moduleCount; col++) {
527
+ var current = qrCode.modules[row][col]
528
+ //level 3 评价
529
+ if (col < moduleCount - 6) {
530
+ if (
531
+ current &&
532
+ !qrCode.modules[row][col + 1] &&
533
+ qrCode.modules[row][col + 2] &&
534
+ qrCode.modules[row][col + 3] &&
535
+ qrCode.modules[row][col + 4] &&
536
+ !qrCode.modules[row][col + 5] &&
537
+ qrCode.modules[row][col + 6]
538
+ ) {
539
+ if (col < moduleCount - 10) {
540
+ if (
541
+ qrCode.modules[row][col + 7] &&
542
+ qrCode.modules[row][col + 8] &&
543
+ qrCode.modules[row][col + 9] &&
544
+ qrCode.modules[row][col + 10]
545
+ ) {
546
+ lostPoint += 40
547
+ }
548
+ } else if (col > 3) {
549
+ if (
550
+ qrCode.modules[row][col - 1] &&
551
+ qrCode.modules[row][col - 2] &&
552
+ qrCode.modules[row][col - 3] &&
553
+ qrCode.modules[row][col - 4]
554
+ ) {
555
+ lostPoint += 40
556
+ }
557
+ }
558
+ }
559
+ }
560
+ //level 2 评价
561
+ if (row < moduleCount - 1 && col < moduleCount - 1) {
562
+ var count = 0
563
+ if (current) count++
564
+ if (qrCode.modules[row + 1][col]) count++
565
+ if (qrCode.modules[row][col + 1]) count++
566
+ if (qrCode.modules[row + 1][col + 1]) count++
567
+ if (count == 0 || count == 4) {
568
+ lostPoint += 3
569
+ }
570
+ }
571
+ //level 1 评价
572
+ if (head ^ current) {
573
+ sameCount++
574
+ } else {
575
+ head = current
576
+ if (sameCount >= 5) {
577
+ lostPoint += 3 + sameCount - 5
578
+ }
579
+ sameCount = 1
580
+ }
581
+ //level 4 评价
582
+ if (current) {
583
+ darkCount++
584
+ }
585
+ }
586
+ }
587
+ for (var col = 0; col < moduleCount; col++) {
588
+ var sameCount = 0
589
+ var head = qrCode.modules[0][col]
590
+ for (var row = 0; row < moduleCount; row++) {
591
+ var current = qrCode.modules[row][col]
592
+ //level 3 评价
593
+ if (row < moduleCount - 6) {
594
+ if (
595
+ current &&
596
+ !qrCode.modules[row + 1][col] &&
597
+ qrCode.modules[row + 2][col] &&
598
+ qrCode.modules[row + 3][col] &&
599
+ qrCode.modules[row + 4][col] &&
600
+ !qrCode.modules[row + 5][col] &&
601
+ qrCode.modules[row + 6][col]
602
+ ) {
603
+ if (row < moduleCount - 10) {
604
+ if (
605
+ qrCode.modules[row + 7][col] &&
606
+ qrCode.modules[row + 8][col] &&
607
+ qrCode.modules[row + 9][col] &&
608
+ qrCode.modules[row + 10][col]
609
+ ) {
610
+ lostPoint += 40
611
+ }
612
+ } else if (row > 3) {
613
+ if (
614
+ qrCode.modules[row - 1][col] &&
615
+ qrCode.modules[row - 2][col] &&
616
+ qrCode.modules[row - 3][col] &&
617
+ qrCode.modules[row - 4][col]
618
+ ) {
619
+ lostPoint += 40
620
+ }
621
+ }
622
+ }
623
+ }
624
+ //level 1 评价
625
+ if (head ^ current) {
626
+ sameCount++
627
+ } else {
628
+ head = current
629
+ if (sameCount >= 5) {
630
+ lostPoint += 3 + sameCount - 5
631
+ }
632
+ sameCount = 1
633
+ }
634
+ }
635
+ }
636
+ // LEVEL4
637
+ var ratio = Math.abs((100 * darkCount) / moduleCount / moduleCount - 50) / 5
638
+ lostPoint += ratio * 10
639
+ return lostPoint
640
+ }
641
+ }
642
+ //---------------------------------------------------------------------
643
+ // QRMath使用的数学工具
644
+ //---------------------------------------------------------------------
645
+ var QRMath = {
646
+ /*
647
+ 将n转化为a^m
648
+ */
649
+ glog: function (n) {
650
+ if (n < 1) {
651
+ throw new Error('glog(' + n + ')')
652
+ }
653
+ return QRMath.LOG_TABLE[n]
654
+ },
655
+ /*
656
+ 将a^m转化为n
657
+ */
658
+ gexp: function (n) {
659
+ while (n < 0) {
660
+ n += 255
661
+ }
662
+ while (n >= 256) {
663
+ n -= 255
664
+ }
665
+ return QRMath.EXP_TABLE[n]
666
+ },
667
+ EXP_TABLE: new Array(256),
668
+ LOG_TABLE: new Array(256)
669
+ }
670
+ for (var i = 0; i < 8; i++) {
671
+ QRMath.EXP_TABLE[i] = 1 << i
672
+ }
673
+ for (var i = 8; i < 256; i++) {
674
+ QRMath.EXP_TABLE[i] =
675
+ QRMath.EXP_TABLE[i - 4] ^
676
+ QRMath.EXP_TABLE[i - 5] ^
677
+ QRMath.EXP_TABLE[i - 6] ^
678
+ QRMath.EXP_TABLE[i - 8]
679
+ }
680
+ for (var i = 0; i < 255; i++) {
681
+ QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i
682
+ }
683
+ //---------------------------------------------------------------------
684
+ // QRPolynomial 多项式
685
+ //---------------------------------------------------------------------
686
+ /**
687
+ * 多项式类
688
+ * @param {Array} num 系数
689
+ * @param {num} shift a^shift
690
+ */
691
+ function QRPolynomial(num, shift) {
692
+ if (num.length == undefined) {
693
+ throw new Error(num.length + '/' + shift)
694
+ }
695
+ var offset = 0
696
+ while (offset < num.length && num[offset] == 0) {
697
+ offset++
698
+ }
699
+ this.num = new Array(num.length - offset + shift)
700
+ for (var i = 0; i < num.length - offset; i++) {
701
+ this.num[i] = num[i + offset]
702
+ }
703
+ }
704
+ QRPolynomial.prototype = {
705
+ get: function (index) {
706
+ return this.num[index]
707
+ },
708
+ getLength: function () {
709
+ return this.num.length
710
+ },
711
+ /**
712
+ * 多项式乘法
713
+ * @param {QRPolynomial} e 被乘多项式
714
+ * @return {[type]} [description]
715
+ */
716
+ multiply: function (e) {
717
+ var num = new Array(this.getLength() + e.getLength() - 1)
718
+ for (var i = 0; i < this.getLength(); i++) {
719
+ for (var j = 0; j < e.getLength(); j++) {
720
+ num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)))
721
+ }
722
+ }
723
+ return new QRPolynomial(num, 0)
724
+ },
725
+ /**
726
+ * 多项式模运算
727
+ * @param {QRPolynomial} e 模多项式
728
+ * @return {}
729
+ */
730
+ mod: function (e) {
731
+ var tl = this.getLength(),
732
+ el = e.getLength()
733
+ if (tl - el < 0) {
734
+ return this
735
+ }
736
+ var num = new Array(tl)
737
+ for (var i = 0; i < tl; i++) {
738
+ num[i] = this.get(i)
739
+ }
740
+ while (num.length >= el) {
741
+ var ratio = QRMath.glog(num[0]) - QRMath.glog(e.get(0))
742
+
743
+ for (var i = 0; i < e.getLength(); i++) {
744
+ num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio)
745
+ }
746
+ while (num[0] == 0) {
747
+ num.shift()
748
+ }
749
+ }
750
+ return new QRPolynomial(num, 0)
751
+ }
752
+ }
753
+
754
+ //---------------------------------------------------------------------
755
+ // RS_BLOCK_TABLE
756
+ //---------------------------------------------------------------------
757
+ /*
758
+ 二维码各个版本信息[块数, 每块中的数据块数, 每块中的信息块数]
759
+ */
760
+ var RS_BLOCK_TABLE = [
761
+ // L
762
+ // M
763
+ // Q
764
+ // H
765
+ // 1
766
+ [1, 26, 19],
767
+ [1, 26, 16],
768
+ [1, 26, 13],
769
+ [1, 26, 9],
770
+
771
+ // 2
772
+ [1, 44, 34],
773
+ [1, 44, 28],
774
+ [1, 44, 22],
775
+ [1, 44, 16],
776
+
777
+ // 3
778
+ [1, 70, 55],
779
+ [1, 70, 44],
780
+ [2, 35, 17],
781
+ [2, 35, 13],
782
+
783
+ // 4
784
+ [1, 100, 80],
785
+ [2, 50, 32],
786
+ [2, 50, 24],
787
+ [4, 25, 9],
788
+
789
+ // 5
790
+ [1, 134, 108],
791
+ [2, 67, 43],
792
+ [2, 33, 15, 2, 34, 16],
793
+ [2, 33, 11, 2, 34, 12],
794
+
795
+ // 6
796
+ [2, 86, 68],
797
+ [4, 43, 27],
798
+ [4, 43, 19],
799
+ [4, 43, 15],
800
+
801
+ // 7
802
+ [2, 98, 78],
803
+ [4, 49, 31],
804
+ [2, 32, 14, 4, 33, 15],
805
+ [4, 39, 13, 1, 40, 14],
806
+
807
+ // 8
808
+ [2, 121, 97],
809
+ [2, 60, 38, 2, 61, 39],
810
+ [4, 40, 18, 2, 41, 19],
811
+ [4, 40, 14, 2, 41, 15],
812
+
813
+ // 9
814
+ [2, 146, 116],
815
+ [3, 58, 36, 2, 59, 37],
816
+ [4, 36, 16, 4, 37, 17],
817
+ [4, 36, 12, 4, 37, 13],
818
+
819
+ // 10
820
+ [2, 86, 68, 2, 87, 69],
821
+ [4, 69, 43, 1, 70, 44],
822
+ [6, 43, 19, 2, 44, 20],
823
+ [6, 43, 15, 2, 44, 16],
824
+
825
+ // 11
826
+ [4, 101, 81],
827
+ [1, 80, 50, 4, 81, 51],
828
+ [4, 50, 22, 4, 51, 23],
829
+ [3, 36, 12, 8, 37, 13],
830
+
831
+ // 12
832
+ [2, 116, 92, 2, 117, 93],
833
+ [6, 58, 36, 2, 59, 37],
834
+ [4, 46, 20, 6, 47, 21],
835
+ [7, 42, 14, 4, 43, 15],
836
+
837
+ // 13
838
+ [4, 133, 107],
839
+ [8, 59, 37, 1, 60, 38],
840
+ [8, 44, 20, 4, 45, 21],
841
+ [12, 33, 11, 4, 34, 12],
842
+
843
+ // 14
844
+ [3, 145, 115, 1, 146, 116],
845
+ [4, 64, 40, 5, 65, 41],
846
+ [11, 36, 16, 5, 37, 17],
847
+ [11, 36, 12, 5, 37, 13],
848
+
849
+ // 15
850
+ [5, 109, 87, 1, 110, 88],
851
+ [5, 65, 41, 5, 66, 42],
852
+ [5, 54, 24, 7, 55, 25],
853
+ [11, 36, 12],
854
+
855
+ // 16
856
+ [5, 122, 98, 1, 123, 99],
857
+ [7, 73, 45, 3, 74, 46],
858
+ [15, 43, 19, 2, 44, 20],
859
+ [3, 45, 15, 13, 46, 16],
860
+
861
+ // 17
862
+ [1, 135, 107, 5, 136, 108],
863
+ [10, 74, 46, 1, 75, 47],
864
+ [1, 50, 22, 15, 51, 23],
865
+ [2, 42, 14, 17, 43, 15],
866
+
867
+ // 18
868
+ [5, 150, 120, 1, 151, 121],
869
+ [9, 69, 43, 4, 70, 44],
870
+ [17, 50, 22, 1, 51, 23],
871
+ [2, 42, 14, 19, 43, 15],
872
+
873
+ // 19
874
+ [3, 141, 113, 4, 142, 114],
875
+ [3, 70, 44, 11, 71, 45],
876
+ [17, 47, 21, 4, 48, 22],
877
+ [9, 39, 13, 16, 40, 14],
878
+
879
+ // 20
880
+ [3, 135, 107, 5, 136, 108],
881
+ [3, 67, 41, 13, 68, 42],
882
+ [15, 54, 24, 5, 55, 25],
883
+ [15, 43, 15, 10, 44, 16],
884
+
885
+ // 21
886
+ [4, 144, 116, 4, 145, 117],
887
+ [17, 68, 42],
888
+ [17, 50, 22, 6, 51, 23],
889
+ [19, 46, 16, 6, 47, 17],
890
+
891
+ // 22
892
+ [2, 139, 111, 7, 140, 112],
893
+ [17, 74, 46],
894
+ [7, 54, 24, 16, 55, 25],
895
+ [34, 37, 13],
896
+
897
+ // 23
898
+ [4, 151, 121, 5, 152, 122],
899
+ [4, 75, 47, 14, 76, 48],
900
+ [11, 54, 24, 14, 55, 25],
901
+ [16, 45, 15, 14, 46, 16],
902
+
903
+ // 24
904
+ [6, 147, 117, 4, 148, 118],
905
+ [6, 73, 45, 14, 74, 46],
906
+ [11, 54, 24, 16, 55, 25],
907
+ [30, 46, 16, 2, 47, 17],
908
+
909
+ // 25
910
+ [8, 132, 106, 4, 133, 107],
911
+ [8, 75, 47, 13, 76, 48],
912
+ [7, 54, 24, 22, 55, 25],
913
+ [22, 45, 15, 13, 46, 16],
914
+
915
+ // 26
916
+ [10, 142, 114, 2, 143, 115],
917
+ [19, 74, 46, 4, 75, 47],
918
+ [28, 50, 22, 6, 51, 23],
919
+ [33, 46, 16, 4, 47, 17],
920
+
921
+ // 27
922
+ [8, 152, 122, 4, 153, 123],
923
+ [22, 73, 45, 3, 74, 46],
924
+ [8, 53, 23, 26, 54, 24],
925
+ [12, 45, 15, 28, 46, 16],
926
+
927
+ // 28
928
+ [3, 147, 117, 10, 148, 118],
929
+ [3, 73, 45, 23, 74, 46],
930
+ [4, 54, 24, 31, 55, 25],
931
+ [11, 45, 15, 31, 46, 16],
932
+
933
+ // 29
934
+ [7, 146, 116, 7, 147, 117],
935
+ [21, 73, 45, 7, 74, 46],
936
+ [1, 53, 23, 37, 54, 24],
937
+ [19, 45, 15, 26, 46, 16],
938
+
939
+ // 30
940
+ [5, 145, 115, 10, 146, 116],
941
+ [19, 75, 47, 10, 76, 48],
942
+ [15, 54, 24, 25, 55, 25],
943
+ [23, 45, 15, 25, 46, 16],
944
+
945
+ // 31
946
+ [13, 145, 115, 3, 146, 116],
947
+ [2, 74, 46, 29, 75, 47],
948
+ [42, 54, 24, 1, 55, 25],
949
+ [23, 45, 15, 28, 46, 16],
950
+
951
+ // 32
952
+ [17, 145, 115],
953
+ [10, 74, 46, 23, 75, 47],
954
+ [10, 54, 24, 35, 55, 25],
955
+ [19, 45, 15, 35, 46, 16],
956
+
957
+ // 33
958
+ [17, 145, 115, 1, 146, 116],
959
+ [14, 74, 46, 21, 75, 47],
960
+ [29, 54, 24, 19, 55, 25],
961
+ [11, 45, 15, 46, 46, 16],
962
+
963
+ // 34
964
+ [13, 145, 115, 6, 146, 116],
965
+ [14, 74, 46, 23, 75, 47],
966
+ [44, 54, 24, 7, 55, 25],
967
+ [59, 46, 16, 1, 47, 17],
968
+
969
+ // 35
970
+ [12, 151, 121, 7, 152, 122],
971
+ [12, 75, 47, 26, 76, 48],
972
+ [39, 54, 24, 14, 55, 25],
973
+ [22, 45, 15, 41, 46, 16],
974
+
975
+ // 36
976
+ [6, 151, 121, 14, 152, 122],
977
+ [6, 75, 47, 34, 76, 48],
978
+ [46, 54, 24, 10, 55, 25],
979
+ [2, 45, 15, 64, 46, 16],
980
+
981
+ // 37
982
+ [17, 152, 122, 4, 153, 123],
983
+ [29, 74, 46, 14, 75, 47],
984
+ [49, 54, 24, 10, 55, 25],
985
+ [24, 45, 15, 46, 46, 16],
986
+
987
+ // 38
988
+ [4, 152, 122, 18, 153, 123],
989
+ [13, 74, 46, 32, 75, 47],
990
+ [48, 54, 24, 14, 55, 25],
991
+ [42, 45, 15, 32, 46, 16],
992
+
993
+ // 39
994
+ [20, 147, 117, 4, 148, 118],
995
+ [40, 75, 47, 7, 76, 48],
996
+ [43, 54, 24, 22, 55, 25],
997
+ [10, 45, 15, 67, 46, 16],
998
+
999
+ // 40
1000
+ [19, 148, 118, 6, 149, 119],
1001
+ [18, 75, 47, 31, 76, 48],
1002
+ [34, 54, 24, 34, 55, 25],
1003
+ [20, 45, 15, 61, 46, 16]
1004
+ ]
1005
+
1006
+ /**
1007
+ * 根据数据获取对应版本
1008
+ * @return {[type]} [description]
1009
+ */
1010
+ QRCodeAlg.prototype.getRightType = function () {
1011
+ for (var typeNumber = 1; typeNumber < 41; typeNumber++) {
1012
+ var rsBlock = RS_BLOCK_TABLE[(typeNumber - 1) * 4 + this.errorCorrectLevel]
1013
+ if (rsBlock == undefined) {
1014
+ throw new Error(
1015
+ 'bad rs block @ typeNumber:' +
1016
+ typeNumber +
1017
+ '/errorCorrectLevel:' +
1018
+ this.errorCorrectLevel
1019
+ )
1020
+ }
1021
+ var length = rsBlock.length / 3
1022
+ var totalDataCount = 0
1023
+ for (var i = 0; i < length; i++) {
1024
+ var count = rsBlock[i * 3 + 0]
1025
+ var dataCount = rsBlock[i * 3 + 2]
1026
+ totalDataCount += dataCount * count
1027
+ }
1028
+ var lengthBytes = typeNumber > 9 ? 2 : 1
1029
+ if (this.utf8bytes.length + lengthBytes < totalDataCount || typeNumber == 40) {
1030
+ this.typeNumber = typeNumber
1031
+ this.rsBlock = rsBlock
1032
+ this.totalDataCount = totalDataCount
1033
+ break
1034
+ }
1035
+ }
1036
+ }
1037
+
1038
+ //---------------------------------------------------------------------
1039
+ // QRBitBuffer
1040
+ //---------------------------------------------------------------------
1041
+ function QRBitBuffer() {
1042
+ this.buffer = new Array()
1043
+ this.length = 0
1044
+ }
1045
+ QRBitBuffer.prototype = {
1046
+ get: function (index) {
1047
+ var bufIndex = Math.floor(index / 8)
1048
+ return (this.buffer[bufIndex] >>> (7 - (index % 8))) & 1
1049
+ },
1050
+ put: function (num, length) {
1051
+ for (var i = 0; i < length; i++) {
1052
+ this.putBit((num >>> (length - i - 1)) & 1)
1053
+ }
1054
+ },
1055
+ putBit: function (bit) {
1056
+ var bufIndex = Math.floor(this.length / 8)
1057
+ if (this.buffer.length <= bufIndex) {
1058
+ this.buffer.push(0)
1059
+ }
1060
+ if (bit) {
1061
+ this.buffer[bufIndex] |= 0x80 >>> this.length % 8
1062
+ }
1063
+ this.length++
1064
+ }
1065
+ }
1066
+
1067
+ // xzedit
1068
+ let qrcodeAlgObjCache = []
1069
+ /**
1070
+ * 二维码构造函数,主要用于绘制
1071
+ * @param {参数列表} opt 传递参数
1072
+ * @return {}
1073
+ */
1074
+ QRCode = function (opt) {
1075
+ //设置默认参数
1076
+ this.options = {
1077
+ text: '',
1078
+ size: 256,
1079
+ correctLevel: 3,
1080
+ background: '#ffffff',
1081
+ foreground: '#000000',
1082
+ pdground: '#000000',
1083
+ image: '',
1084
+ imageSize: 30,
1085
+ canvasId: opt.canvasId,
1086
+ nvueContext: opt.nvueContext,
1087
+ context: opt.context,
1088
+ usingComponents: opt.usingComponents,
1089
+ showLoading: opt.showLoading,
1090
+ loadingText: opt.loadingText
1091
+ }
1092
+ if (typeof opt === 'string') {
1093
+ // 只编码ASCII字符串
1094
+ opt = {
1095
+ text: opt
1096
+ }
1097
+ }
1098
+ if (opt) {
1099
+ for (var i in opt) {
1100
+ this.options[i] = opt[i]
1101
+ }
1102
+ }
1103
+ //使用QRCodeAlg创建二维码结构
1104
+ var qrCodeAlg = null
1105
+ for (var i = 0, l = qrcodeAlgObjCache.length; i < l; i++) {
1106
+ if (
1107
+ qrcodeAlgObjCache[i].text == this.options.text &&
1108
+ qrcodeAlgObjCache[i].text.correctLevel == this.options.correctLevel
1109
+ ) {
1110
+ qrCodeAlg = qrcodeAlgObjCache[i].obj
1111
+ break
1112
+ }
1113
+ }
1114
+ if (i == l) {
1115
+ qrCodeAlg = new QRCodeAlg(this.options.text, this.options.correctLevel)
1116
+ qrcodeAlgObjCache.push({
1117
+ text: this.options.text,
1118
+ correctLevel: this.options.correctLevel,
1119
+ obj: qrCodeAlg
1120
+ })
1121
+ }
1122
+ /**
1123
+ * 计算矩阵点的前景色
1124
+ * @param {Obj} config
1125
+ * @param {Number} config.row 点x坐标
1126
+ * @param {Number} config.col 点y坐标
1127
+ * @param {Number} config.count 矩阵大小
1128
+ * @param {Number} config.options 组件的options
1129
+ * @return {String}
1130
+ */
1131
+ let getForeGround = function (config) {
1132
+ var options = config.options
1133
+ if (
1134
+ options.pdground &&
1135
+ ((config.row > 1 && config.row < 5 && config.col > 1 && config.col < 5) ||
1136
+ (config.row > config.count - 6 &&
1137
+ config.row < config.count - 2 &&
1138
+ config.col > 1 &&
1139
+ config.col < 5) ||
1140
+ (config.row > 1 &&
1141
+ config.row < 5 &&
1142
+ config.col > config.count - 6 &&
1143
+ config.col < config.count - 2))
1144
+ ) {
1145
+ return options.pdground
1146
+ }
1147
+ return options.foreground
1148
+ }
1149
+ // 创建canvas
1150
+ let createCanvas = function (options) {
1151
+ if (options.showLoading) {
1152
+ uni.showLoading({
1153
+ title: options.loadingText,
1154
+ mask: true
1155
+ })
1156
+ }
1157
+ var ctx = ''
1158
+ if (options.nvueContext) {
1159
+ ctx = options.nvueContext
1160
+ } else {
1161
+ ctx = uni.createCanvasContext(options.canvasId, options.context)
1162
+ }
1163
+ var count = qrCodeAlg.getModuleCount()
1164
+ var ratioSize = options.size
1165
+ var ratioImgSize = options.imageSize
1166
+ //计算每个点的长宽
1167
+ var tileW = (ratioSize / count).toPrecision(4)
1168
+ var tileH = (ratioSize / count).toPrecision(4)
1169
+ //绘制
1170
+ for (var row = 0; row < count; row++) {
1171
+ for (var col = 0; col < count; col++) {
1172
+ var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW)
1173
+ var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW)
1174
+ var foreground = getForeGround({
1175
+ row: row,
1176
+ col: col,
1177
+ count: count,
1178
+ options: options
1179
+ })
1180
+ ctx.setFillStyle(qrCodeAlg.modules[row][col] ? foreground : options.background)
1181
+ ctx.fillRect(Math.round(col * tileW), Math.round(row * tileH), w, h)
1182
+ }
1183
+ }
1184
+ if (options.image) {
1185
+ var x = Number(((ratioSize - ratioImgSize) / 2).toFixed(2))
1186
+ var y = Number(((ratioSize - ratioImgSize) / 2).toFixed(2))
1187
+ drawRoundedRect(ctx, x, y, ratioImgSize, ratioImgSize, 2, 6, true, true)
1188
+ ctx.drawImage(options.image, x, y, ratioImgSize, ratioImgSize)
1189
+ // 画圆角矩形
1190
+ function drawRoundedRect(ctxi, x, y, width, height, r, lineWidth, fill, stroke) {
1191
+ ctxi.setLineWidth(lineWidth)
1192
+ ctxi.setFillStyle(options.background)
1193
+ ctxi.setStrokeStyle(options.background)
1194
+ ctxi.beginPath() // draw top and top right corner
1195
+ ctxi.moveTo(x + r, y)
1196
+ ctxi.arcTo(x + width, y, x + width, y + r, r) // draw right side and bottom right corner
1197
+ ctxi.arcTo(x + width, y + height, x + width - r, y + height, r) // draw bottom and bottom left corner
1198
+ ctxi.arcTo(x, y + height, x, y + height - r, r) // draw left and top left corner
1199
+ ctxi.arcTo(x, y, x + r, y, r)
1200
+ ctxi.closePath()
1201
+ if (fill) {
1202
+ ctxi.fill()
1203
+ }
1204
+ if (stroke) {
1205
+ ctxi.stroke()
1206
+ }
1207
+ }
1208
+ }
1209
+ setTimeout(
1210
+ () => {
1211
+ ctx.draw(true, () => {
1212
+ // 保存到临时区域
1213
+ setTimeout(() => {
1214
+ if (options.nvueContext) {
1215
+ ctx.toTempFilePath(
1216
+ 0,
1217
+ 0,
1218
+ options.width,
1219
+ options.height,
1220
+ options.width,
1221
+ options.height,
1222
+ '',
1223
+ 1,
1224
+ function (res) {
1225
+ if (options.cbResult) {
1226
+ options.cbResult(res.tempFilePath)
1227
+ }
1228
+ }
1229
+ )
1230
+ } else {
1231
+ uni.canvasToTempFilePath(
1232
+ {
1233
+ width: options.width,
1234
+ height: options.height,
1235
+ destWidth: options.width,
1236
+ destHeight: options.height,
1237
+ canvasId: options.canvasId,
1238
+ quality: Number(1),
1239
+ success: function (res) {
1240
+ if (options.cbResult) {
1241
+ // 由于官方还没有统一此接口的输出字段,所以先判定下 支付宝为 res.apFilePath
1242
+ if (!empty(res.tempFilePath)) {
1243
+ options.cbResult(res.tempFilePath)
1244
+ } else if (!empty(res.apFilePath)) {
1245
+ options.cbResult(res.apFilePath)
1246
+ } else {
1247
+ options.cbResult(res.tempFilePath)
1248
+ }
1249
+ }
1250
+ },
1251
+ fail: function (res) {
1252
+ if (options.cbResult) {
1253
+ options.cbResult(res)
1254
+ }
1255
+ },
1256
+ complete: function () {
1257
+ uni.hideLoading()
1258
+ }
1259
+ },
1260
+ options.context
1261
+ )
1262
+ }
1263
+ }, options.text.length + 100)
1264
+ })
1265
+ },
1266
+ options.usingComponents ? 0 : 150
1267
+ )
1268
+ }
1269
+ createCanvas(this.options)
1270
+ // 空判定
1271
+ let empty = function (v) {
1272
+ let tp = typeof v,
1273
+ rt = false
1274
+ if (tp == 'number' && String(v) == '') {
1275
+ rt = true
1276
+ } else if (tp == 'undefined') {
1277
+ rt = true
1278
+ } else if (tp == 'object') {
1279
+ if (JSON.stringify(v) == '{}' || JSON.stringify(v) == '[]' || v == null) rt = true
1280
+ } else if (tp == 'string') {
1281
+ if (v == '' || v == 'undefined' || v == 'null' || v == '{}' || v == '[]') rt = true
1282
+ } else if (tp == 'function') {
1283
+ rt = false
1284
+ }
1285
+ return rt
1286
+ }
1287
+ }
1288
+ QRCode.prototype.clear = function (fn) {
1289
+ var ctx = ''
1290
+ if (options.nvueContext) {
1291
+ ctx = options.nvueContext
1292
+ } else {
1293
+ uni.createCanvasContext(this.options.canvasId, this.options.context)
1294
+ }
1295
+ ctx.clearRect(0, 0, this.options.size, this.options.size)
1296
+ ctx.draw(false, () => {
1297
+ if (fn) {
1298
+ fn()
1299
+ }
1300
+ })
1301
+ }
1302
+ })()
1303
+
1304
+ export default QRCode