自己设计一种运行在单片机的嵌入式gui图形库—控件设计之二维码

1、控件结构体

typedef struct 
{
    fv_widget_t  widget;
    fv_color_t   dark_color;   //暗的颜色,默认值为 黑色                      
    fv_color_t   light_color;  //亮的颜色,默认值为 白色      
    uint8_t    * map_buf;      //二维码解码后的 位图数据缓存(一个方块点 占一个bit)
    uint32_t     map_width;    //二维码解码后的 位图宽度(宽度和高度相等)
    uint32_t     scale;
} fv_qrcode_t;

2、控件绘制

static int32_t on_paint_self(fv_widget_t* widget, fv_canvas_t* canvas)
{
    fv_qrcode_t * qrcode = (fv_qrcode_t*)widget;
    uint32_t      row_byte_cnt;
    int32_t       qr_size;
    uint8_t     * buf_u8;
    uint8_t       n;

    if (qrcode->map_buf == FV_NULL)
    {
        return 0;
    }

    if (qrcode->scale == 0)
    {
        return 0;
    }

    qr_size = qrcode->map_width;
    row_byte_cnt = (qr_size + 7) / 8;

    for (int32_t y = 0; y < qr_size; y++)
    {
        n = 0;
        buf_u8 = ((uint8_t*)qrcode->map_buf) + row_byte_cnt * y;

        for (int32_t x = 0; x < qr_size; x++)
        {
            if ((*buf_u8 & (1 << (7 - n))) != 0)
            {
                canvas->draw_ctx.draw_ctx_brush.brush_fill_color = qrcode->light_color;
            }
            else
            {
                canvas->draw_ctx.draw_ctx_brush.brush_fill_color = qrcode->dark_color;
            }

            fv_rectangle_t rect;
            rect.rectangle_left = x * qrcode->scale + (widget->w - qrcode->scale * qr_size) / 2;
            rect.rectangle_top = y * qrcode->scale + (widget->h - qrcode->scale * qr_size) / 2;
            rect.rectangle_right = rect.rectangle_left + qrcode->scale - 1;
            rect.rectangle_bottom = rect.rectangle_top + qrcode->scale - 1;
            fv_canvas_rectangle_draw(canvas, &rect);

            n++;
            if (n == 8)
            {
                buf_u8++;
                n = 0;
            }
        }
    }

    return 0;
}

3、更新二维码

int32_t fv_qrcode_update(fv_widget_t* widget, const char* str)
{
    fv_qrcode_t * qrcode = (fv_qrcode_t*)widget;
    uint32_t      data_len;
    int32_t       width;

    width = FV_MIN(widget->w, widget->h);

    data_len = strlen(str);
    if (data_len > qrcodegen_BUFFER_LEN_MAX)
    {
        return -1;
    }

    int32_t qr_version = qrcodegen_getMinFitVersion(qrcodegen_Ecc_MEDIUM, data_len);
    if (qr_version <= 0)
    {
        return -1;
    }

    int32_t qr_size = qrcodegen_version2size(qr_version);
    if (qr_size <= 0) 
    {
        return -1;
    }

    int32_t scale = width / qr_size;
    if (scale <= 0) 
    {
        return -1;
    }

    int32_t remain = width % qr_size;
    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 = fv_mem_alloc(qrcodegen_BUFFER_LEN_FOR_VERSION(qr_version));

    uint8_t* data_tmp = fv_mem_alloc(qrcodegen_BUFFER_LEN_FOR_VERSION(qr_version));

    memcpy(data_tmp, str, data_len);

    fv_bool_t ok = qrcodegen_encodeBinary(data_tmp, data_len,
        qr0, qrcodegen_Ecc_MEDIUM,
        qr_version, qr_version,
        qrcodegen_Mask_AUTO, true);

    if (!ok)
    {
        fv_mem_free(qr0);
        fv_mem_free(data_tmp);
        return -1;
    }

    qr_size = qrcodegen_getSize(qr0);

    uint32_t row_byte_cnt = (qr_size + 7) / 8;

    if (qrcode->map_buf != FV_NULL)
    {
        fv_mem_free(qrcode->map_buf);
        qrcode->map_buf = FV_NULL;
    }

    qrcode->map_buf = fv_mem_alloc(row_byte_cnt * qr_size);
    fv_mem_zero(qrcode->map_buf, row_byte_cnt * qr_size);
    qrcode->map_width = qr_size;
    qrcode->scale = scale;

    uint8_t * buf_u8; 
    uint8_t n;
    for (int32_t y = 0; y < qr_size; y++)
    {
        n = 0;
        buf_u8 = ((uint8_t*)qrcode->map_buf) + row_byte_cnt * y;

        for (int32_t x = 0; x < qr_size; x++)
        {
            fv_bool_t a = qrcodegen_getModule(qr0, x, y);

            if (!a)
            {
                *buf_u8 |= (1 << (7 - n));
            }

            n++;
            if (n == 8)
            {
                buf_u8++;
                n = 0;
            }
        }
    }

    fv_mem_free(qr0);
    fv_mem_free(data_tmp);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值