hy-app 0.5.10 → 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 (286) 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/props.ts +186 -186
  109. package/components/hy-input/typing.d.ts +31 -31
  110. package/components/hy-line/hy-line.vue +55 -55
  111. package/components/hy-line/props.ts +43 -43
  112. package/components/hy-line-progress/hy-line-progress.vue +102 -102
  113. package/components/hy-line-progress/props.ts +33 -33
  114. package/components/hy-list/hy-list.vue +226 -226
  115. package/components/hy-list/props.ts +69 -69
  116. package/components/hy-list/typing.d.ts +6 -6
  117. package/components/hy-loading/hy-loading.vue +107 -107
  118. package/components/hy-loading/props.ts +65 -65
  119. package/components/hy-menu/hy-menu.vue +159 -159
  120. package/components/hy-menu/props.ts +44 -44
  121. package/components/hy-menu/typing.d.ts +34 -34
  122. package/components/hy-modal/hy-modal.vue +173 -173
  123. package/components/hy-modal/props.ts +90 -90
  124. package/components/hy-modal/typing.d.ts +11 -11
  125. package/components/hy-navbar/hy-navbar.vue +144 -144
  126. package/components/hy-navbar/props.ts +78 -78
  127. package/components/hy-navbar/typing.d.ts +6 -6
  128. package/components/hy-notice-bar/hy-column-notice.vue +94 -94
  129. package/components/hy-notice-bar/hy-notice-bar.vue +96 -96
  130. package/components/hy-notice-bar/hy-row-notice.vue +121 -121
  131. package/components/hy-notice-bar/props.ts +85 -85
  132. package/components/hy-notice-bar/typing.d.ts +8 -8
  133. package/components/hy-notify/hy-notify.vue +174 -174
  134. package/components/hy-notify/props.ts +51 -51
  135. package/components/hy-number-step/hy-number-step.vue +367 -367
  136. package/components/hy-number-step/props.ts +112 -112
  137. package/components/hy-number-step/typing.d.ts +16 -16
  138. package/components/hy-overlay/hy-overlay.vue +60 -60
  139. package/components/hy-overlay/props.ts +33 -33
  140. package/components/hy-overlay/typing.d.ts +4 -4
  141. package/components/hy-pagination/hy-pagination.vue +135 -135
  142. package/components/hy-pagination/props.ts +55 -55
  143. package/components/hy-pagination/typing.d.ts +10 -10
  144. package/components/hy-picker/hy-picker.vue +7 -5
  145. package/components/hy-picker/props.ts +7 -2
  146. package/components/hy-picker/typing.d.ts +9 -5
  147. package/components/hy-popover/hy-popover.vue +251 -251
  148. package/components/hy-popover/props.ts +51 -51
  149. package/components/hy-popover/typing.d.ts +39 -39
  150. package/components/hy-popup/hy-popup.vue +197 -197
  151. package/components/hy-popup/props.ts +85 -85
  152. package/components/hy-popup/typing.d.ts +10 -10
  153. package/components/hy-price/hy-price.vue +79 -79
  154. package/components/hy-price/props.ts +54 -54
  155. package/components/hy-price/typing.d.ts +4 -4
  156. package/components/hy-qrcode/hy-qrcode.vue +216 -216
  157. package/components/hy-qrcode/props.ts +70 -70
  158. package/components/hy-qrcode/qrcode.js +1304 -1304
  159. package/components/hy-qrcode/typing.d.ts +8 -8
  160. package/components/hy-radio/hy-radio.vue +226 -226
  161. package/components/hy-radio/props.ts +1 -1
  162. package/components/hy-radio/typing.d.ts +8 -8
  163. package/components/hy-rate/hy-rate.vue +239 -239
  164. package/components/hy-rate/props.ts +77 -77
  165. package/components/hy-rate/typing.d.ts +6 -6
  166. package/components/hy-read-more/hy-read-more.vue +130 -130
  167. package/components/hy-read-more/props.ts +45 -45
  168. package/components/hy-read-more/typing.d.ts +6 -6
  169. package/components/hy-rolling-num/hy-rolling-num.vue +188 -188
  170. package/components/hy-rolling-num/props.ts +68 -68
  171. package/components/hy-scroll-list/hy-scroll-list.vue +123 -123
  172. package/components/hy-scroll-list/props.ts +22 -22
  173. package/components/hy-scroll-list/typing.d.ts +6 -6
  174. package/components/hy-search/hy-search.vue +221 -221
  175. package/components/hy-search/props.ts +131 -131
  176. package/components/hy-search/typing.d.ts +22 -22
  177. package/components/hy-signature/hy-signature.vue +640 -640
  178. package/components/hy-signature/props.ts +118 -118
  179. package/components/hy-signature/typing.d.ts +93 -93
  180. package/components/hy-slider/hy-slider.vue +444 -444
  181. package/components/hy-slider/props.ts +77 -77
  182. package/components/hy-slider/typing.d.ts +10 -10
  183. package/components/hy-status-bar/hy-status-bar.vue +41 -41
  184. package/components/hy-status-bar/props.ts +8 -8
  185. package/components/hy-status-bar/typing.d.ts +12 -12
  186. package/components/hy-steps/hy-steps.vue +267 -267
  187. package/components/hy-steps/props.ts +49 -49
  188. package/components/hy-steps/typing.d.ts +21 -21
  189. package/components/hy-sticky/hy-sticky.vue +226 -226
  190. package/components/hy-sticky/props.ts +24 -24
  191. package/components/hy-sticky/typing.d.ts +4 -4
  192. package/components/hy-submit-bar/hy-submit-bar.vue +189 -189
  193. package/components/hy-submit-bar/props.ts +91 -91
  194. package/components/hy-submit-bar/typing.d.ts +24 -24
  195. package/components/hy-subsection/hy-subsection.vue +207 -207
  196. package/components/hy-subsection/props.ts +52 -52
  197. package/components/hy-subsection/typing.d.ts +13 -13
  198. package/components/hy-swipe-action/hy-swipe-action.vue +323 -323
  199. package/components/hy-swipe-action/index.ts +25 -25
  200. package/components/hy-swipe-action/props.ts +47 -47
  201. package/components/hy-swipe-action/typing.d.ts +25 -25
  202. package/components/hy-swiper/hy-swiper-indicator.vue +75 -75
  203. package/components/hy-swiper/hy-swiper.vue +224 -224
  204. package/components/hy-swiper/props.ts +128 -128
  205. package/components/hy-swiper/typing.d.ts +26 -26
  206. package/components/hy-switch/hy-switch.vue +173 -173
  207. package/components/hy-switch/props.ts +61 -61
  208. package/components/hy-switch/typing.d.ts +8 -8
  209. package/components/hy-tabbar/hy-tabbar.vue +136 -136
  210. package/components/hy-tabbar/props.ts +59 -59
  211. package/components/hy-tabbar/typing.d.ts +21 -21
  212. package/components/hy-tabbar-group/hy-tabbar-group.vue +87 -87
  213. package/components/hy-tabbar-group/props.ts +78 -78
  214. package/components/hy-tabbar-group/typing.d.ts +16 -16
  215. package/components/hy-tabbar-item/hy-tabbar-item.vue +103 -103
  216. package/components/hy-tabbar-item/typing.d.ts +10 -10
  217. package/components/hy-table/hy-table.vue +358 -358
  218. package/components/hy-table/props.ts +47 -47
  219. package/components/hy-table/typing.d.ts +34 -34
  220. package/components/hy-tabs/hy-tabs.vue +335 -335
  221. package/components/hy-tabs/props.ts +77 -77
  222. package/components/hy-tabs/typing.d.ts +33 -33
  223. package/components/hy-tag/hy-tag.vue +174 -174
  224. package/components/hy-tag/props.ts +89 -89
  225. package/components/hy-tag/typing.d.ts +13 -13
  226. package/components/hy-text/hy-text.vue +237 -237
  227. package/components/hy-text/props.ts +115 -115
  228. package/components/hy-text/typing.d.ts +6 -6
  229. package/components/hy-textarea/hy-textarea.vue +197 -197
  230. package/components/hy-textarea/props.ts +116 -116
  231. package/components/hy-textarea/typing.d.ts +22 -22
  232. package/components/hy-toast/hy-toast.vue +190 -190
  233. package/components/hy-toast/typing.d.ts +38 -38
  234. package/components/hy-tooltip/hy-tooltip.vue +277 -277
  235. package/components/hy-tooltip/props.ts +78 -78
  236. package/components/hy-tooltip/typing.d.ts +4 -4
  237. package/components/hy-transition/hy-transition.vue +157 -157
  238. package/components/hy-transition/props.ts +32 -32
  239. package/components/hy-transition/typing.d.ts +16 -16
  240. package/components/hy-upload/hy-upload.vue +385 -385
  241. package/components/hy-upload/props.ts +132 -132
  242. package/components/hy-upload/typing.d.ts +65 -65
  243. package/components/hy-warn/hy-warn.vue +115 -115
  244. package/components/hy-warn/props.ts +49 -49
  245. package/components/hy-warn/typing.d.ts +6 -6
  246. package/components/hy-waterfall/hy-waterfall.vue +191 -191
  247. package/components/hy-waterfall/props.ts +21 -21
  248. package/components/hy-watermark/hy-watermark.vue +978 -978
  249. package/components/hy-watermark/props.ts +104 -104
  250. package/components/index.ts +183 -183
  251. package/global.d.ts +91 -91
  252. package/index.ts +1 -1
  253. package/libs/api/http.ts +140 -140
  254. package/libs/api/index.ts +1 -1
  255. package/libs/common/index.ts +2 -2
  256. package/libs/common/queue.ts +28 -28
  257. package/libs/composables/index.ts +6 -6
  258. package/libs/composables/usePopover.ts +241 -241
  259. package/libs/composables/useQueue.ts +53 -53
  260. package/libs/composables/useShakeService.ts +64 -64
  261. package/libs/composables/useShare.ts +42 -42
  262. package/libs/composables/useToast.ts +45 -45
  263. package/libs/composables/useTouch.ts +51 -51
  264. package/libs/config/color.ts +7 -7
  265. package/libs/config/icon.ts +430 -430
  266. package/libs/config/index.ts +2 -2
  267. package/libs/css/iconfont.css +443 -443
  268. package/libs/global/index.ts +6 -6
  269. package/libs/global/register-properties.ts +37 -37
  270. package/libs/index.ts +7 -7
  271. package/libs/typing/index.ts +4 -4
  272. package/libs/typing/modules/common.d.ts +139 -139
  273. package/libs/typing/modules/enum.ts +67 -67
  274. package/libs/typing/modules/form.ts +5 -1
  275. package/libs/typing/modules/http.ts +17 -17
  276. package/libs/typing/modules/icon.d.ts +366 -366
  277. package/libs/typing/modules/rect.ts +10 -10
  278. package/libs/utils/base64.ts +119 -119
  279. package/libs/utils/calendar.js +1021 -1021
  280. package/libs/utils/colorGradient.ts +112 -112
  281. package/libs/utils/index.ts +5 -5
  282. package/libs/utils/inside.ts +350 -350
  283. package/libs/utils/inspect.ts +171 -171
  284. package/libs/utils/utils.ts +521 -521
  285. package/package.json +18 -18
  286. 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