mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
fix(qrcode):minimize margins as much as possible (#2804)
This commit is contained in:
parent
3035d27d4a
commit
477abcf27a
@ -85,15 +85,32 @@ lv_res_t lv_qrcode_update(lv_obj_t * qrcode, const void * data, uint32_t data_le
|
||||
|
||||
if(data_len > qrcodegen_BUFFER_LEN_MAX) return LV_RES_INV;
|
||||
|
||||
uint8_t * qr0 = lv_mem_alloc(qrcodegen_BUFFER_LEN_MAX);
|
||||
lv_img_dsc_t * imgdsc = lv_canvas_get_img(qrcode);
|
||||
|
||||
int32_t qr_version = qrcodegen_getMinFitVersion(qrcodegen_Ecc_MEDIUM, data_len);
|
||||
if (qr_version <= 0) return LV_RES_INV;
|
||||
int32_t qr_size = qrcodegen_version2size(qr_version);
|
||||
if (qr_size <= 0) return LV_RES_INV;
|
||||
int32_t scale = imgdsc->header.w / qr_size;
|
||||
if (scale <= 0) return LV_RES_INV;
|
||||
int32_t remain = imgdsc->header.w % qr_size;
|
||||
|
||||
/* The qr version is incremented by four point */
|
||||
uint32_t version_extend = remain / (scale << 2);
|
||||
if (version_extend && qr_version < qrcodegen_VERSION_MAX) {
|
||||
qr_version = qr_version + version_extend > qrcodegen_VERSION_MAX ?
|
||||
qrcodegen_VERSION_MAX : qr_version + version_extend;
|
||||
}
|
||||
|
||||
uint8_t * qr0 = lv_mem_alloc(qrcodegen_BUFFER_LEN_FOR_VERSION(qr_version));
|
||||
LV_ASSERT_MALLOC(qr0);
|
||||
uint8_t * data_tmp = lv_mem_alloc(qrcodegen_BUFFER_LEN_MAX);
|
||||
uint8_t * data_tmp = lv_mem_alloc(qrcodegen_BUFFER_LEN_FOR_VERSION(qr_version));
|
||||
LV_ASSERT_MALLOC(data_tmp);
|
||||
memcpy(data_tmp, data, data_len);
|
||||
|
||||
bool ok = qrcodegen_encodeBinary(data_tmp, data_len,
|
||||
qr0, qrcodegen_Ecc_MEDIUM,
|
||||
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX,
|
||||
qr_version, qr_version,
|
||||
qrcodegen_Mask_AUTO, true);
|
||||
|
||||
if (!ok) {
|
||||
@ -102,11 +119,9 @@ lv_res_t lv_qrcode_update(lv_obj_t * qrcode, const void * data, uint32_t data_le
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
|
||||
lv_img_dsc_t * imgdsc = lv_canvas_get_img(qrcode);
|
||||
lv_coord_t obj_w = imgdsc->header.w;
|
||||
int qr_size = qrcodegen_getSize(qr0);
|
||||
int scale = obj_w / qr_size;
|
||||
qr_size = qrcodegen_getSize(qr0);
|
||||
scale = obj_w / qr_size;
|
||||
int scaled = qr_size * scale;
|
||||
int margin = (obj_w - scaled) / 2;
|
||||
uint8_t * buf_u8 = (uint8_t *)imgdsc->data + 8; /*+8 skip the palette*/
|
||||
|
@ -1007,3 +1007,28 @@ static int numCharCountBits(enum qrcodegen_Mode mode, int version) {
|
||||
default: assert(false); return -1; // Dummy value
|
||||
}
|
||||
}
|
||||
|
||||
int qrcodegen_getMinFitVersion(enum qrcodegen_Ecc ecl, size_t dataLen)
|
||||
{
|
||||
struct qrcodegen_Segment seg;
|
||||
seg.mode = qrcodegen_Mode_BYTE;
|
||||
seg.bitLength = calcSegmentBitLength(seg.mode, dataLen);
|
||||
seg.numChars = (int)dataLen;
|
||||
|
||||
for (int version = qrcodegen_VERSION_MIN; version <= qrcodegen_VERSION_MAX; version++) {
|
||||
int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available
|
||||
int dataUsedBits = getTotalBits(&seg, 1, version);
|
||||
if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits)
|
||||
return version;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int qrcodegen_version2size(int version)
|
||||
{
|
||||
if (version < qrcodegen_VERSION_MIN || version > qrcodegen_VERSION_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ((version - 1)*4 + 21);
|
||||
}
|
@ -305,6 +305,14 @@ int qrcodegen_getSize(const uint8_t qrcode[]);
|
||||
*/
|
||||
bool qrcodegen_getModule(const uint8_t qrcode[], int x, int y);
|
||||
|
||||
/*
|
||||
* Returns the qrcode size of the specified version. Returns -1 on failure
|
||||
*/
|
||||
int qrcodegen_version2size(int version);
|
||||
/*
|
||||
* Returns the min version of the data that can be stored. Returns -1 on failure
|
||||
*/
|
||||
int qrcodegen_getMinFitVersion(enum qrcodegen_Ecc ecl, size_t dataLen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user