基于C语言的开发板实现小区信息显示屏
【1】C语言-》字体头文件font.h
#ifndef __font_h__
#define __font_h__
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#define color u32
#define getColor(a, b, c, d) (a|b<<8|c<<16|d<<24)
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef char s8;
typedef short s16;
typedef int s32;
typedef long long s64;
typedef struct stbtt_fontinfo
{
void * userdata;
unsigned char * data; // pointer to .ttf file
int fontstart; // offset of start of font
int numGlyphs; // number of glyphs, needed for range checking
int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf
int index_map; // a cmap mapping for our chosen character encoding
int indexToLocFormat; // format needed to map from glyph index to glyph
} stbtt_fontinfo;
typedef struct{
u32 height;
u32 width;
u32 byteperpixel;
u8 *map;
}bitmap;
typedef struct{
stbtt_fontinfo *info;
u8 *buffer;
float scale;
}font;
//1.初始化字库
font *fontLoad(char *fontPath);
//2.设置字体的大小
void fontSetSize(font *f, s32 pixels);
//3.设置字体输出框的大小
bitmap *createBitmap(u32 width, u32 height, u32 byteperpixel);
//可以指定输出框的颜色
bitmap *createBitmapWithInit(u32 width, u32 height, u32 byteperpixel, color c);
//4.把字体输出到输出框中
void fontPrint(font *f, bitmap *screen, s32 x, s32 y, char *text, color c, s32 maxWidth);
//5.把输出框的所有信息显示到LCD屏幕中
// bitmap.width
// bitmap.height
// bitmap.bytepixel
// bitmap.map
// 关闭字体库
void fontUnload(font *f);
// 关闭bitmap
void destroyBitmap(bitmap *bm);
#endif
【2】C语言-》字体文件font.c
#include "font.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <pthread.h>
#define wchar s32
#define wchar_to_str(wc) ((char *)(wc))
#define color u32
#define getColor(a, b, c, d) (a|b<<8|c<<16|d<<24)
#define getA(c) ((c>> 0)&0x000000ff)
#define getR(c) ((c>> 8)&0x000000ff)
#define getG(c) ((c>>16)&0x000000ff)
#define getB(c) ((c>>24)&0x000000ff)
u32 wstrlen(wchar *ws);
wchar *utf8_to_ucs2(char *code);
extern int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset);
// Given an offset into the file that defines a font, this function builds
// the necessary cached info for the rest of the system. You must allocate
// the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't
// need to do anything special to free it, because the contents are pure
// value data with no additional data structures. Returns 0 on failure.
int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint);
float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels);
float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels);
void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap);
void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1);
void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing);
int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2);
int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1);
void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing);
int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2);
int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint);
bitmap *createBitmap(u32 width, u32 height, u32 byteperpixel){
bitmap *bm = (bitmap *)malloc(sizeof(bitmap));
bzero(bm, sizeof(bitmap));
bm->height = height;
bm->width = width;
bm->byteperpixel = byteperpixel;
bm->map = (u8 *)malloc(width*height*byteperpixel);
bzero(bm->map, width*height*byteperpixel);
return bm;
}
void destroyBitmap(bitmap *bm){
bzero(bm->map, bm->height * bm->width * bm->byteperpixel);
free(bm->map);
bzero(bm, sizeof(bitmap));
free(bm);
}
color getPixel(bitmap *bm, u32 x, u32 y){
if(bm->byteperpixel == 3){
u8 r = *(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 0);
u8 g = *(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 1);
u8 b = *(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 2);
return getColor(0, r, g, b);
}else if(bm->byteperpixel == 4){
u8 r = *(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 0);
u8 g = *(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 1);
u8 b = *(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 2);
u8 a = *(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 3);
return getColor(a, r, g, b);
}
return 0;
}
void setPixel(bitmap *bm, u32 x, u32 y, color c){
if(bm->byteperpixel == 3){
*(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 0) = getR(c);
*(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 1) = getG(c);
*(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 2) = getB(c);
}else if(bm->byteperpixel == 4){
*(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 0) = getR(c);
*(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 1) = getG(c);
*(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 2) = getB(c);
*(bm->map + y*bm->width*bm->byteperpixel + x*bm->byteperpixel + 3) = getA(c);
}
}
bitmap *createBitmapWithInit(u32 width, u32 height, u32 byteperpixel, color c){
bitmap *bm = createBitmap(width, height, byteperpixel);
u32 x, y;
for(y=0; y<height; y++){
for(x=0; x<width; x++){
setPixel(bm, x, y, c);
}
}
return bm;
}
u32 wstrlen(wchar *ws){
u32 len = 0;
while(*(ws+len)!='\0')
len++;
return len;
}
wchar *utf8_to_ucs2(char *code){
wchar *ucs2 = (wchar *)malloc((strlen(code)+2)*sizeof(wchar));
bzero(ucs2, (strlen(code)+2)*sizeof(wchar));
s16 com = 1<<7;
u32 x;
for(x=0; x<=strlen(code); x++){
char utf = code[x];
u32 size = 0;
u32 i = 0;
u32 index = (utf&com) != 0;
u16 binary[16];
if(index == 0){
///0xxxxxxx ==> 00000000 0xxxxxxxx
for(; i < 8; ++i){
binary[i] = 0;
}
for(; i < 16; ++i){
binary[i] = (utf & 1 << (15 - i)) != 0;
}
}else if(utf&(1 << 5) == 0){
// 110xxxxx 10yyyyyy ==> 00000xxx xxyyyyyy
for(; i < 5; ++i){
binary[i] = 0;
}
for(; i < 10; ++i){
binary[i] = (utf&(1 << (9 - i))) != 0;
}
x += 1;
utf = code[x];
for(; i < 16; ++i){
binary[i] = (utf&(1 << (15 - i))) != 0;
}
}else{
//1110xxxx 10yyyyyy 10zzzzzz ==> xxxxyyyy yyzzzzzz
for(; i < 4; ++i){
binary[i] = (utf & 1 << (3 - i)) != 0;
}
x += 1;
utf = code[x];
for(; i < 10; ++i){
binary[i] = (utf & 1 << (9 - i)) != 0;
}
x += 1;
utf = code[x];
for(; i < 16; ++i){
binary[i] = (utf & 1 << (15 - i)) != 0;
}
}
wchar ch = 0;
for(i=0; i <16; i++){
ch <<= 1;
ch |= binary[i];
}
u32 len = wstrlen(ucs2);
ucs2[len] = ch;
ucs2[len+1] = 0;
}
return ucs2;
}
void fontPrint(font *f, bitmap *screen, s32 x, s32 y, char *text, color c, s32 maxWidth){
wchar *wText = utf8_to_ucs2(text);
u8 *charRaster = NULL;
s32 bx, by, bw, bh;
s32 ascent, descent, lineGap;
s32 sx = 0, sy = 0;
stbtt_GetFontVMetrics(f->info, &ascent, &descent, &lineGap);
ascent *= f->scale;
descent *= f->scale;
lineGap *= f->scale;
u32 i;
for(i=0; i<wstrlen(wText); i++){
if(wText[i] == '\n'){
sy += ascent - descent + lineGap;
sx = 0;
continue;
}
stbtt_GetCodepointBitmapBox(f->info, wText[i], f->scale, f->scale, &bx, &by, &bw, &bh);
s32 charWidth = bw - bx;
s32 charHeight = bh - by;
s32 oy = ascent + by;
if(maxWidth > 0 && sx + charWidth > maxWidth) {
sy += ascent - descent + lineGap;
sx = 0;
}
charRaster = realloc(charRaster, charWidth*charHeight);
stbtt_MakeCodepointBitmap(f->info, charRaster, charWidth, charHeight, charWidth, f->scale, f->scale, wText[i]);
s32 advance;
stbtt_GetCodepointHMetrics(f->info, wText[i], &advance, 0);
s32 kerning = stbtt_GetCodepointKernAdvance(f->info, wText[i], wText[i+1]);
s32 printLength = advance * f->scale + kerning * f->scale;
s32 mx;
for(mx=0; mx<printLength; mx++){
if(charWidth+mx < printLength-mx){
continue;
}
break;
}
s32 ix, iy;
for(iy=0; iy<charHeight; iy++){
for(ix=0; ix<charWidth; ix++){
s32 xpos = x + sx + ix + mx;// + (printLength-charWidth)/2;
s32 ypos = (y + sy + oy + iy) - 1;
if(charRaster[ix+iy*charWidth]!=0 && xpos<screen->width && ypos<screen->height){
u32 alpha = charRaster[ix+iy*charWidth];
u32 invAlpha = 255 - alpha;
color bgc = getPixel(screen, xpos, ypos);
u8 bgr = getR(bgc);
u8 bgg = getG(bgc);
u8 bgb = getB(bgc);
u8 r = (alpha * getR(c) + invAlpha * bgr) >> 8;
u8 g = (alpha * getG(c) + invAlpha * bgg) >> 8;
u8 b = (alpha * getB(c) + invAlpha * bgb) >> 8;
setPixel(screen, xpos, ypos, getColor(0, r, g, b));
}
}
}
bzero(charRaster, charWidth*charHeight);
sx += printLength;
}
free(charRaster);
free(wText);
}
void fontSetSize(font *f, s32 pixels){
f->scale = stbtt_ScaleForPixelHeight(f->info, pixels);
}
font *fontLoad(char *fontPath){
// 打开字体文件并读取
s32 fd = open(fontPath, O_RDONLY);
if(fd==-1)
return NULL;
u32 bufferSize = lseek(fd, 0, SEEK_END);
u8 *buffer = (u8 *)malloc(bufferSize);
lseek(fd, 0, SEEK_SET);
read(fd, buffer, bufferSize);
close(fd);
// 从内存读取
font *f = (font *)malloc(sizeof(font));
f->info = (stbtt_fontinfo *)malloc(sizeof(stbtt_fontinfo));
if(!buffer || bufferSize==0)
return NULL;
if(stbtt_InitFont(f->info, buffer, 0) != 1)
return NULL;
f->buffer = buffer;
f->scale = stbtt_ScaleForPixelHeight(f->info, 16);
// 返回
return f;
}
void fontUnload(font *f){
free(f->info);
free(f->buffer);
free(f);
}
【3】C语言-》开发板显示main.c
注意要先将ttf文件放入开发板上
链接:https://pan.baidu.com/s/1uBK7Lp5TcLGcWp5xPNzwxw?pwd=5wf2
提取码:5wf2
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include <fcntl.h>
#include "font.h"
void showbitmap(bitmap *bm, int x, int y)
{
// 准备好LCD设备(如果多次显示,应该只做一遍)
// 字体的信息:
bm->width;
bm->height;
bm->byteperpixel;
bm->map; // 指向RGB数据,没有上下颠倒,也没有一行4字节倍数的约束,就是纯粹的RGB
}
int main(int argc, char const *argv[])
{
//1.初始化字库
// 注意要先将ttf文件放入开发板上
font *f = fontLoad("simfang.ttf"); // 指定字库文件,比如simfang.ttf
//2.设置字体的大小
fontSetSize(f, 24);
//3.设置字体输出框的大小
bitmap *bm;
bm = createBitmapWithInit(800, 28, 4, 0xFFFFFFFF);
//4.把字体输出到输出框中
fontPrint(f, bm, 80, 2, "北京天安门", 0xFF000000, 0);
//5.将bm妥善地放置到LCD上显示出来
showbitmap(bm, 0, 0);
return 0;
}