电子产品量产工具(完结篇)

 所学均来自百问网

目录

1. 按钮改进

2. 函数名改进

3. 支持配置文件的command

4. 项目效果


1. 按钮改进

freetype.c

static int FreetypeGetStringRegionCar(char *str, PRegionCartesian  ptRegionCar)
{
    int i;
    int error;
    FT_BBox bbox;
    FT_BBox glyph_bbox;
    FT_Vector pen;
    FT_Glyph  glyph;
    FT_GlyphSlot slot = g_tface->glyph;
​
    /* 初始化 */
    bbox.xMin = bbox.yMin = 32000;
    bbox.xMax = bbox.yMax = -32000;
​
    /* 指定原点为(0, 0) */
    pen.x = 0;
    pen.y = 0;
​
    /* 计算每个字符的bounding box */
    /* 先translate, 再load char, 就可以得到它的外框了 */
    for (i = 0; i < strlen(str); i++)
    {
        /* 转换:transformation */
        FT_Set_Transform(g_tface, 0, &pen);
​
        /* 加载位图: load glyph image into the slot (erase previous one) */
        error = FT_Load_Char(g_tface, str[i], FT_LOAD_RENDER);
        if (error)
        {
            printf("FT_Load_Char error\n");
            return -1;
        }
​
        /* 取出glyph */
        error = FT_Get_Glyph(g_tface->glyph, &glyph);
        if (error)
        {
            printf("FT_Get_Glyph error!\n");
            return -1;
        }
        
        /* 从glyph得到外框: bbox */
        FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &glyph_bbox);
​
        /* 更新外框 */
        if ( glyph_bbox.xMin < bbox.xMin )
            bbox.xMin = glyph_bbox.xMin;
​
        if ( glyph_bbox.yMin < bbox.yMin )
            bbox.yMin = glyph_bbox.yMin;
​
        if ( glyph_bbox.xMax > bbox.xMax )
            bbox.xMax = glyph_bbox.xMax;
​
        if ( glyph_bbox.yMax > bbox.yMax )
            bbox.yMax = glyph_bbox.yMax;
        
        /* 计算下一个字符的原点: increment pen position */
        pen.x += slot->advance.x;
        pen.y += slot->advance.y;
    }
​
    /* return string bbox */
    //*abbox = bbox;
    ptRegionCar->iLeftUpX = bbox.xMin;
    ptRegionCar->iLeftUpY = bbox.yMax;
    ptRegionCar->iWidth = bbox.xMax - bbox.xMin + 1;
    ptRegionCar->iHeigh = bbox.yMax - bbox.yMin + 1;
​
    return 0;
}

main_page.c

static int GetFontSizeForAllButton(void)
{
    int i;
    int max_len = -1;
    int max_index = 0;
    int len;
    RegionCartesian tRegionCar;
    float k,kx,ky;
    // 找出name最长的Button
    for(i = 0; i < g_tButtonCnt; i++)
    {
        len = strlen(g_tButtons[i].name);
        if(len > max_len)
        {
            max_len = len;
            max_index = i;
        }       
    }
    // 以font_size = 100 为例 算出它的外框
    SetFontSize(100);
    GetStringRegionCar(g_tButtons[max_index].name,&tRegionCar);
    // 把文字的外框缩放为Button的外框
    kx = (float)g_tButtons[max_index].tRegion.iWidth / tRegionCar.iWidth;
    ky = (float)g_tButtons[max_index].tRegion.iHeigh / tRegionCar.iHeigh;
    if(kx < ky)
        k = kx;
    else
        k = ky;
​
    // 反算出font_size 只取80% 避免文字太靠近边界
    return k * 100 * 0.8;
}

disp_manager.c

void DrawTextInRegionCentral(char *name,PRegion ptRegion,unsigned int dwColor)
{
    FontBitMap tFontBitMap;
    int iOriginX,iOriginY;
    int i = 0;
    int error;
    RegionCartesian tRegionCar;
    // 计算字符的外框
    GetStringRegionCar(name, &tRegionCar);
​
    // 算出第一个字符的origin
    iOriginX = ptRegion->iLeftUpX + (ptRegion->iWidth - tRegionCar.iWidth) / 2 - tRegionCar.iLeftUpX;
    iOriginY = ptRegion->iLeftUpY + (ptRegion->iHeigh - tRegionCar.iHeigh) / 2 + tRegionCar.iLeftUpY;
​
    // 逐个绘制
    while(name[i])
    {
        // 获得位图
        tFontBitMap.iCurOriginX = iOriginX;
        tFontBitMap.iCurOriginY = iOriginY;
        error = GetFontBitMap(name[i], &tFontBitMap);
        if(error)
        {
            printf("GetFontBitMap err\n");
            return;
        }
        // 绘制
        DrawFontBitMap(&tFontBitMap,dwColor);
    
        iOriginX = tFontBitMap.iNextOriginX;
        iOriginY = tFontBitMap.iNextOriginY;
        i++;
​
    }
}

common.h

#ifndef __COMMON_H
#define __COMMON_H
typedef struct Region{
    int iLeftUpX;
    int iLeftUpY;
    int iWidth;
    int iHeigh;
}Region,*PRegion;
​
// 笛卡尔坐标系
typedef struct RegionCartesian{
    int iLeftUpX;
    int iLeftUpY;
    int iWidth;
    int iHeigh;
}RegionCartesian,*PRegionCartesian;
​
#ifndef NULL
#define NULL (void *)0
#endif
#endif

效果

2. 函数名改进

main.c的函数名修改如下,相关设置以下函数的文件均也改名

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <stdlib.h>
​
#include <disp_manager.h>
#include <font_manager.h>
#include <input_manager.h>
#include <page_manager.h>
​
​
int main(int argc, char **argv)
{
    int error;
​
    if (argc != 2)
    {
        printf("Usage: %s <font_file>\n", argv[0]);
        return -1;
    }
    
    /* 初始化显示系统 */       
    DisplaySystemRegister();  /* 以前是: DisplayInit(); */
​
    SelectDefaultDisplay("fb");
​
    InitDefaultDisplay();
​
    /* 初始化输入系统 */       
    InputSystemRegister(); /* 以前是: InputInit(); */
    IntpuDeviceInit();
​
​
    /* 初始化文字系统 */       
    FontSystemRegister(); /* 以前是: FontsRegister(); */
    
    error = SelectAndInitFont("freetype", argv[1]);
    if (error)
    {
        printf("SelectAndInitFont err\n");
        return -1;
    }
​
    /* 初始化页面系统 */       
    PageSystemRegister(); /* 以前是: PagesRegister(); */
​
    /* 运行业务系统的主页面 */
    Page("main")->Run(NULL);
    
    return 0;   
}

3. 支持配置文件的command

main_page.c

#include <page_manager.h>
#include <stdio.h>
#include <config.h>
#include <math.h>
#include <string.h>
#include <ui.h>
#include <stdlib.h>
static Button g_tButtons[ITEMCFG_MAX_NUM];
static int g_tButtonCnt;
#define X_GAP 5 // 每个按钮间隔距离
#define Y_GAP 5
​
static int MainPageOnPressed(struct Button *ptButton,PDispBuff ptDispBuff,PInputEvent ptInputEvent)
{
    unsigned int dwColor = BUTTON_DEFAULT_COLOR; // 默认颜色
    char name[100];
    char status[100];
    char *strButton;
    char *command_status[3] = {"err","ok","percent"};
    int command_status_index = 0;
    char command[1000];
    PItemCfg ptItemCfg;
    strButton = ptButton->name;
    // 对于触摸屏
    if(ptInputEvent->iType == INPUT_TYPE_TOUCH)
    {
        // 能否被点击
        if(GetItemCfgByName(ptButton->name)->bCanBeTouched == 0)
            return -1;
        // 修改颜色
        ptButton->status = !ptButton->status;
        if(ptButton->status) 
        {
            dwColor = BUTTON_PRESSEN_COLOR;
            command_status_index = 1;
        }
    }
    else if(ptInputEvent->iType == INPUT_TYPE_NET)
    {
        // 对于网络类事件
        // 根据传入的字符串修改颜色:wifi ok, wifi err,wifi 78
        sscanf(ptInputEvent->str,"%s %s",name,status);
        if(strcmp(status,"ok") == 0)
        {
            command_status_index = 1;
            dwColor = BUTTON_PRESSEN_COLOR; 
        }
        else if(strcmp(status,"err") == 0)
        {
            command_status_index = 0;
            dwColor = BUTTON_DEFAULT_COLOR;
        }
        else if(status[0] >= '0' && status[0] <= '9')
        {
            command_status_index = 2;
            dwColor = BUTTON_PERCENT_COLOR;
            strButton = status;
        }else
            return -1;
    }else
    {
        return -1;
    }
    // 绘制底色
    DrawRegion(&ptButton->tRegion, dwColor);
​
    // 居中显示文字
    DrawTextInRegionCentral(strButton,&ptButton->tRegion,BUTTON_TEXT_COLOR);
​
    // 刷新
    FlushDisplayRegion(&ptButton->tRegion,ptDispBuff);
​
    // 执行command
    ptItemCfg = GetItemCfgByName(ptButton->name);
    if(ptItemCfg->command[0] != '\0')
    {
        sprintf(command,"%s %s",ptItemCfg->command,command_status[command_status_index]);
        system(command);
    }
    return 0;
​
}
​
static int GetFontSizeForAllButton(void)
{
    int i;
    int max_len = -1;
    int max_index = 0;
    int len;
    RegionCartesian tRegionCar;
    float k,kx,ky;
    // 找出name最长的Button
    for(i = 0; i < g_tButtonCnt; i++)
    {
        len = strlen(g_tButtons[i].name);
        if(len > max_len)
        {
            max_len = len;
            max_index = i;
        }       
    }
    // 以font_size = 100 为例 算出它的外框
    SetFontSize(100);
    GetStringRegionCar(g_tButtons[max_index].name,&tRegionCar);
    // 把文字的外框缩放为Button的外框
    kx = (float)g_tButtons[max_index].tRegion.iWidth / tRegionCar.iWidth;
    ky = (float)g_tButtons[max_index].tRegion.iHeigh / tRegionCar.iHeigh;
    if(kx < ky)
        k = kx;
    else
        k = ky;
​
    // 反算出font_size 只取80% 避免文字太靠近边界
    return k * 100 * 0.8;
}
​
static void GenerateButtons(void)
{
    int width,height;
    int n_per_line;
    int row,rows;
    int col;
    int n;
    PDispBuff pDispBuff;
    int xres,yres;
    int start_x,start_y;
    PButton pButton;
    int i = 0;
    int pre_start_x,pre_start_y;
    int iFontSize;
    // 多少个按钮
    g_tButtonCnt = n = GetItemCfgCount();
​
    // 获得x y的分辨率
    pDispBuff =  GetDisplayBuffer();
    xres = pDispBuff->iXres;
    yres = pDispBuff->iYres;
    width = sqrt(1.0 / 0.618 * xres * yres / n);//算出理想宽度 但可能会使按钮越界
    n_per_line = xres / width + 1;//算出每一行能显示的按钮个数
    // 算出单个按钮的高度和宽度
    width = xres / n_per_line;
    height = 0.618 * width;
​
    // 按钮显示的起始x坐标
    start_x = (xres - width * n_per_line) / 2;
    // 算出一列有多少个按钮
    rows = n / n_per_line;
    if(rows * n_per_line < n) 
        rows++; //算出小数则加1
    // 按钮显示的起始y坐标
    start_y = (yres - rows * height) / 2;
​
    // 居中显示:计算每个按钮的region
    for(row = 0; (row < rows) && (i < n); row++)
    {
        pre_start_y = start_y + row * height;
        pre_start_x = start_x - width;
        for(col = 0; (col < n_per_line) && (i < n); col++)
        {
​
            pButton = &g_tButtons[i];
            // 下一个按钮的位置
            pButton->tRegion.iLeftUpX = pre_start_x + width;
            pButton->tRegion.iLeftUpY = pre_start_y;
            pButton->tRegion.iWidth = width - X_GAP;
            pButton->tRegion.iHeigh = height - Y_GAP;
            pre_start_x = pButton->tRegion.iLeftUpX;
​
            // 初始化按钮
            InitButton(pButton, GetItemCfgByIndex(i)->name, NULL, NULL, MainPageOnPressed);
            i++;
        }
    }
​
    iFontSize =  GetFontSizeForAllButton();
    //SetFontSize(iFontSize);
    // 显示
    for(i = 0; i < n;i++)
    {
        g_tButtons[i].iFoneSize = iFontSize;
        g_tButtons[i].OnDraw(&g_tButtons[i],pDispBuff);
        
    }
}
​
​
static int isTouchPointInRegion(int iX,int iY,PRegion ptRegion)
{
    if(iX < ptRegion->iLeftUpX || iX >= ptRegion->iLeftUpX + ptRegion->iWidth)
        return 0;
    if(iY < ptRegion->iLeftUpY || iY >= ptRegion->iLeftUpY + ptRegion->iHeigh)
        return 0;
​
    return 1;
}
​
static PButton GetButtonByName(char *name)
{
    int i;
​
    for(i = 0; i < g_tButtonCnt;i++)
    {
        if(strcmp(name,g_tButtons[i].name) == 0)
            return &g_tButtons[i];
    }
​
    return NULL;
​
​
}
static PButton GetButtonByInputEvent(PInputEvent ptInputEvent)
{
    int i;
    char name[100];
    if(ptInputEvent->iType == INPUT_TYPE_TOUCH)
    {
        for(i = 0; i < g_tButtonCnt;i++)
        {
            if(isTouchPointInRegion(ptInputEvent->iX,ptInputEvent->iY,&g_tButtons[i].tRegion))
                return &g_tButtons[i];
        }
    }else if(ptInputEvent->iType == INPUT_TYPE_NET)
    {
        sscanf(ptInputEvent->str,"%s",name);
        return GetButtonByName(name);
    }else
    {
        return NULL;
    }
    
    return NULL;
}
​
static void MainPageRun(void *pParams)
{
    int error;
    InputEvent tInputEvent;
    PButton ptButton;
    PDispBuff ptDispBuff = GetDisplayBuffer();
    // 读取配置文件
    error = ParseConfigFile();
    if(error)
        return;
    // 根据配置文件生成按钮、界面
    GenerateButtons();
    while(1)
    {
        // 读取输入事件
        error = GetInputEvent(&tInputEvent);
        if(error)
            continue;
        // 根据输入事件找到按钮
        ptButton =  GetButtonByInputEvent(&tInputEvent);
        if(!ptButton)
            continue;
        // 调用按钮的OnPressed函数
        ptButton->OnPressed(ptButton,ptDispBuff,&tInputEvent);
​
    }
}
​
​
static PageAction g_tMainPage = {
    .name = "main",
    .Run = MainPageRun,
};
​
void MainPageRegister(void)
{
    PageRegister(&g_tMainPage);
}

len.sh

#!/bin/sh
status=$1
if [ "$status" = "ok" ]
then
echo "led has been tested, it is ok"
fi
​
if [ "$status" = "err" ]
then
echo "led has been tested, it is fail"
fi

4. 项目效果

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值