Linux基础项目开发1:量产工具——文字系统(四)

前言:

前面我们已经把显示系统,输入系统的框架搭建好了,那么有了输入和显示,显示的内容应该是什么呢?这节就要让我们一起对显示的内容,文字系统进行搭建。

目录

一、数据结构抽象

1.描述一个文字的位图:

2.描述一个字库操作:

3.font_manager.h

二、实现Freetype代码

freetype.c

 三、文字管理

font_manager.c

四、单元测试 

1.font_test.c 

2.disp_manager.c

3.disp_manager.h 

4. common.h

5.unittest下的Makefile

6.font下的Makefile

7.顶层的Makefile 

五、上板测试


 

一、数据结构抽象

 描述字符的方式:1.位置、大小   2.点阵

        点阵可以从固定大小的点阵字体文件中获得,也可以从Freetype的矢量字体文件中获得,所以我们需要抽象出一个结构体用来描述这些字符,一个结构体描述一个文字的位图,一个结构体描述一个字库操作。

1.描述一个文字的位图:

2.描述一个字库操作:

        使用点阵绘制文字时:每个文字的大小一样,前后文件互不影响 ,使用Freetype绘制文字时:大小可能不同,前面文字会影响后面文字

 

对于单个Freetype字符,格式如下 

         我们要抽象出一个结构体FontBitMap,能描述一个“字符”:位置、大小、位图,我们还要抽象出一个结构体FontOpr,能描述字体的操作,比如Freetype的操作、固定点阵字体的操作

3.font_manager.h

#ifndef _FONT_MANAGER_H
#define _FONT_MANAGER_H


#include <common.h>


typedef struct FontBitMap {
	int iLeftUpX;
	int iLeftUpY;
	int iWidth;
	int iRows;
	int iCurOriginX;
	int iCurOriginY;
	int iNextOriginX;
	int iNextOriginY;
	unsigned char *pucBuffer;
}FontBitMap, *PFontBitMap;

typedef struct FontOpr {
	char *name;
	int (*FontInit)(char *aFineName);
	int (*SetFontSize)(int iFontSize);
	int (*GetFontBitMap)(unsigned int dwCode, PFontBitMap ptFontBitMap);
	struct FontOpr *ptNext;
}FontOpr, *PFontOpr;

void RegisterFont(PFontOpr ptFontOpr);

void FontsRegister(void);

int SelectAndInitFont(char *aFontOprName, char *aFontFileName);
int SetFontSize(int iFontSize);
int GetFontBitMap(unsigned int dwCode, PFontBitMap ptFontBitMap);


#endif




第28行:链表

第30行:注册单个字符库 ,从链表里挑出想要的字库

第32行:在g_ptFonts链表里面挑出来你想要的字体文件

第33行:将找到的字体设置字体大小

第34行:将找到的字体设置位图

为了方便后续使用区域,我们进行如下操作,将区域定义到一个结构体上Region tRegion;

typedef struct FontBitMap {
	Region tRegion;
	int iCurOriginX;
	int iCurOriginY;
	int iNextOriginX;
	int iNextOriginY;
	unsigned char *pucBuffer;
}FontBitMap, *PFontBitMap;

这个 tRegiondisp manager.h中有声明

typedef struct Region {
	int iLeftUpX;
	int iLeftUpY;
	int iWidth;
	int iHeigh;
}Region, *PRegion;

二、实现Freetype代码

freetype.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 <math.h>
#include <wchar.h>
#include <sys/ioctl.h>
#include <font_manager.h>

#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H


static FT_Face g_tFace;
static int g_iDefaultFontSize = 12;

static int FreeTypeFontInit(char *aFineName)
{
    FT_Library    library;
    int error;

    error = FT_Init_FreeType( &library );                 /* initialize library */    
	if (error)
	{
		printf("FT_Init_FreeType err\n");
		return -1;
	}
	
    error = FT_New_Face(library, aFineName, 0, &g_tFace ); /* create face object */
	if (error)
	{
		printf("FT_New_Face err\n");
		return -1;
	}

    FT_Set_Pixel_Sizes(g_tFace, g_iDefaultFontSize, 0);

	return 0;
}

static int FreeTypeSetFontSize(int iFontSize)
{
    FT_Set_Pixel_Sizes(g_tFace, iFontSize, 0);
	return 0;
}

static int FreeTypeGetFontBitMap(unsigned int dwCode, PFontBitMap ptFontBitMap)
{
	int error;
    FT_Vector pen;
    FT_Glyph  glyph;
    

    pen.x = ptFontBitMap->iCurOriginX * 64; /* 单位: 1/64像素 */
    pen.y = ptFontBitMap->iCurOriginY * 64; /* 单位: 1/64像素 */

	/* 转换:transformation */
	FT_Set_Transform(g_tFace, 0, &pen);

	/* 加载位图: load glyph image into the slot (erase previous one) */
	error = FT_Load_Char(g_tFace, dwCode, FT_LOAD_RENDER);
	if (error)
	{
		printf("FT_Load_Char error\n");
		return -1;
	}

	ptFontBitMap->pucBuffer = slot->bitmap.buffer;
	
	ptFontBitMap->tRegion.iLeftUpX = slot->bitmap_left;
	ptFontBitMap->tRegion.iLeftUpY = ptFontBitMap->iCurOriginY*2 - slot->bitmap_top;
	ptFontBitMap->tRegion.iWidth   = slot->bitmap.width;
	ptFontBitMap->tRegion.iHeigh   = slot->bitmap.rows;
	ptFontBitMap->iNextOriginX = ptFontBitMap->iCurOriginX + slot->advance.x / 64;
	ptFontBitMap->iNextOriginY = ptFontBitMap->iCurOriginY;

	return 0;
}


static FontOpr g_tFreetypeOpr = {
	.name          = "freetype",
	.FontInit      = FreeTypeFontInit,
	.SetFontSize   = FreeTypeSetFontSize,
	.GetFontBitMap = FreeTypeGetFontBitMap,
};

void FreetypeRegister(void)
{
	RegisterFont(&g_tFreetypeOpr);
}

static FontOpr g_tFreetypeOpr

第86~91行:实现FontOpr这个结构体里面的函数

        第87行:之后可以通过freetype这个名字找到FontOpr这个结构体

        第88行:初始化函数

        第89行:自定义设置字符大小

        第90行:得到位图并且设置坐标值

第19行:对应字体文件 

第20行:对应字体大小

static int FreeTypeFontInit(char *aFineName)

第22~44行:进行初始化 

        第27行:初始化freetype库

        第34行:加载字体文件

        第41行:设置默认的字体大小

static int FreeTypeSetFontSize(int iFontSize)

第 46~50行:自定义设置字符大小

给一个字符的编码值如何得到它的位图呢? 

static int FreeTypeGetFontBitMap(unsigned int dwCode, PFontBitMap ptFontBitMap)

第52~83行:得到位图并且设置坐标值

        第55行:pen用来反推原点

        第57行:记录点阵

        第59、60行:根据位图原点的X和Y坐标反推原点

        第63行:转换

        第66行:加载位图

        第73行:存放点阵

        第75~80行:描述一个文字的位图

void FreetypeRegister(void)

第93~96行: 进行注册,上层font_manager.c提供

 三、文字管理

        我们可能要用到的字体有多种,那么怎么选择用哪个字符呢,所以我们要编写一个程序管理多种字符。

font_manager.c


#include <font_manager.h>
#include <string.h>


static PFontOpr g_ptFonts = NULL;
static PFontOpr g_ptDefaulFontOpr = NULL;


void RegisterFont(PFontOpr ptFontOpr)
{
	ptFontOpr->ptNext = g_ptFonts;
	g_ptFonts = ptFontOpr;
}

void FontsRegister(void)
{
	extern void FreetypeRegister(void);
	FreetypeRegister();
}

int SelectAndInitFont(char *aFontOprName, char *aFontFileName)
{
	PFontOpr ptTmp = g_ptFonts;
	while (ptTmp)
	{
		if (strcmp(ptTmp->name, aFontOprName) == 0)
			break;
		ptTmp = ptTmp->ptNext;
	}

	if (!ptTmp)
		return -1;

	g_ptDefaulFontOpr = ptTmp;
	return ptTmp->FontInit(aFontFileName);
}

int SetFontSize(int iFontSize)
{
	return g_ptDefaulFontOpr->SetFontSize(iFontSize);
}

int GetFontBitMap(unsigned int dwCode, PFontBitMap ptFontBitMap)
{
	return g_ptDefaulFontOpr->GetFontBitMap(dwCode, ptFontBitMap);
}


实现这四个函数

第6行: 注册的单个字库链表头放到g_ptFonts

第7行:将22~37行找到的字库名字保存在g_ptDefaulFontOpr

void RegisterFont(PFontOpr ptFontOpr)

第10~14行:实现与freetype.c链接的链表

void FontsRegister(void)

第16~20行:实现多个字体的注册

        第18行:调用底层代码提供一个注册函数,注册单个字库,从链表里挑出想要的字库

假设你有多个字库,你要选择某一个,要提供一个SelectAndInitFont字体文件

int SelectAndInitFont(char *aFontOprName, char *aFontFileName)

 第22~37行:首先在g_ptFonts链表里面挑出来你想要的字体文件

        aFontOprName表示字库操作的名字,aFontFileName表示字体文件的名字

        第24行:在链表里面挑出来

        第27行:表示已经找到了

        第29行:没有找到,继续在链表里的下一个位置找

        第32行:表示不存在

        第35行:如果存在则调用初始化函数

int SetFontSize(int iFontSize)

第39~42行:将找到的字体设置字体大小

int GetFontBitMap(unsigned int dwCode, PFontBitMap ptFontBitMap)

 第44~47行:将找到的字体设置位图

四、单元测试 

1.font_test.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 <font_manager.h>
#include <disp_manager.h>

#define FONTDATAMAX 4096

static const unsigned char fontdata_8x16[FONTDATAMAX] = {
	//此处点阵省略
    .........

};

/**********************************************************************
 * 函数名称: lcd_put_ascii
 * 功能描述: 在LCD指定位置上显示一个8*16的字符
 * 输入参数: x坐标,y坐标,ascii码
 * 输出参数: 无
 * 返 回 值: 无
 ***********************************************************************/ 
void lcd_put_ascii(int x, int y, unsigned char c)
{
	unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];
	int i, b;
	unsigned char byte;

	for (i = 0; i < 16; i++)
	{
		byte = dots[i];
		for (b = 7; b >= 0; b--)
		{
			if (byte & (1<<b))
			{
				/* show */
				PutPixel(x+7-b, y+i, 0xffffff); /* 白 */
			}
			else
			{
				/* hide */
				PutPixel(x+7-b, y+i, 0); /* 黑 */
			}
		}
	}
}

int main(int argc, char **argv)
{

	PDispBuff ptBuffer;
	int error;

	FontBitMap tFontBitMap;
	char *str= "Hello Linux";
	int i = 0;
	int lcd_x;
	int lcd_y;
	int font_size;
		

	if (argc != 5)
	{
		printf("Usage: %s <font_file> <lcd_x> <lcd_y> <font_size>\n", argv[0]);
		return -1;
	}

	lcd_x = strtol(argv[2], NULL, 0);
	lcd_y = strtol(argv[3], NULL, 0);
	
	font_size  = strtol(argv[4], NULL, 0);
	
		
	DisplayInit();

	SelectDefaultDisplay("fb");

	InitDefaultDisplay();

	ptBuffer = GetDisplayBuffer();

	FontsRegister();
	
	error = SelectAndInitFont("freetype", argv[1]);
	if (error)
	{
		printf("SelectAndInitFont err\n");
		return -1;
	}
	
	SetFontSize(font_size);

	while (str[i])
	{
		/* get bitmap */
		tFontBitMap.iCurOriginX = lcd_x;
		tFontBitMap.iCurOriginY = lcd_y;
		error = GetFontBitMap(str[i], &tFontBitMap);
		if (error)
		{
			printf("SelectAndInitFont err\n");
			return -1;
		}

		/* draw on buffer */		
		DrawFontBitMap(&tFontBitMap,0xff0000);//0xff0000为红色

		/* flush to lcd/web */		
		FlushDisplayRegion(&tFontBitMap.tRegion, ptBuffer);
		

		lcd_x = tFontBitMap.iNextOriginX;
		lcd_y = tFontBitMap.iNextOriginY;	
		i++;
	}
	
	return 0;	
}


第60行:保存字符位图

第61行:想要显示的字符串

第68~72行:打印出具体用法    

                     <font_file>                字体文件

                     <lcd_x> <lcd_y>      显示的位置  

                     <font_size>              字体的大小

第74、75行:将字符串转化成整数传入到lcd_xlcd_y

第77行:将字符串转化成整数传入到 font_size

第86行:获得显示的设备

第88行:FontsRegister()注册单个字符库 ,从链表里挑出想要的字库

第90行:SelectAndInitFont("freetype", argv[1])去选择freetype字库操作,传入argv[1]字体文件

第97行:SetFontSize设置字体大小

第102、103行:绘制图像的原点 

第104行:GetFontBitMap得到字符位图

第112行:把位图绘制出来,绘制到默认设备中

第115行:绘制的内容刷到LCD或者web上

第118、119行:绘制完后取下一个位图的坐标

2.disp_manager.c

disp_manager.c中实现位图绘制

void DrawFontBitMap(PFontBitMap ptFontBitMap, unsigned int dwColor)

void DrawFontBitMap(PFontBitMap ptFontBitMap, unsigned int dwColor)
{
    int i, j, p, q;
	int x = ptFontBitMap->tRegion.iLeftUpX;
	int y = ptFontBitMap->tRegion.iLeftUpY;
    int x_max = x + ptFontBitMap->tRegion.iWidth;
    int y_max = y + ptFontBitMap->tRegion.iHeigh;
	int width = ptFontBitMap->tRegion.iWidth;
	unsigned char *buffer = ptFontBitMap->pucBuffer;

    //printf("x = %d, y = %d\n", x, y);

    for ( j = y, q = 0; j < y_max; j++, q++ )
    {
        for ( i = x, p = 0; i < x_max; i++, p++ )
        {
            if ( i < 0      || j < 0       ||
                i >= g_tDispBuff.iXres || j >= g_tDispBuff.iYres )
            continue;

            //image[j][i] |= bitmap->buffer[q * bitmap->width + p];
            if (buffer[q * width + p])
	            PutPixel(i, j, dwColor);
        }
    }
	
}

3.disp_manager.h 

声明函数DrawFontBitMap

void DrawFontBitMap(PFontBitMap ptFontBitMap, unsigned int dwColor);

头文件包含#include <font_manager.h>

#ifndef _DISP_MANAGER_H
#define _DISP_MANAGER_H

#include <common.h>
#include <font_manager.h>


typedef struct DispBuff {
	int iXres;
	int iYres;
	int iBpp;
	char *buff;
}DispBuff, *PDispBuff;



typedef struct DispOpr {
	char *name;
	int (*DeviceInit)(void);
	int (*DeviceExit)(void);
	int (*GetBuffer)(PDispBuff ptDispBuff);
	int (*FlushRegion)(PRegion ptRegion, PDispBuff ptDispBuff);
	struct DispOpr *ptNext;
}DispOpr, *PDispOpr;

void RegisterDisplay(PDispOpr ptDispOpr);

void DisplayInit(void);
int SelectDefaultDisplay(char *name);
int InitDefaultDisplay(void);
int PutPixel(int x, int y, unsigned int dwColor);
int FlushDisplayRegion(PRegion ptRegion, PDispBuff ptDispBuff);
PDispBuff GetDisplayBuffer(void);
void DrawFontBitMap(PFontBitMap ptFontBitMap, unsigned int dwColor);


#endif

4. common.h

        因为显示系统和文字系统都需要用到这个区域结构体,所以我们直接把它拿出来定义成一个公共的头文件

#ifndef _COMMON_H
#define _COMMON_H

#ifndef NULL
#define NULL (void *)0
#endif

typedef struct Region {
	int iLeftUpX;
	int iLeftUpY;
	int iWidth;
	int iHeigh;
}Region, *PRegion;

#endif

5.unittest下的Makefile

EXTRA_CFLAGS  := 
CFLAGS_file.o := 

#obj-y += disp_test.o
#obj-y += input_test.o
obj-y += font_test.o

6.font下的Makefile

EXTRA_CFLAGS  := 
CFLAGS_file.o := 

obj-y += font_manager.o
obj-y += freetype.o

7.顶层的Makefile 


CROSS_COMPILE ?= 
AS		= $(CROSS_COMPILE)as
LD		= $(CROSS_COMPILE)ld
CC		= $(CROSS_COMPILE)gcc
CPP		= $(CC) -E
AR		= $(CROSS_COMPILE)ar
NM		= $(CROSS_COMPILE)nm

STRIP		= $(CROSS_COMPILE)strip
OBJCOPY		= $(CROSS_COMPILE)objcopy
OBJDUMP		= $(CROSS_COMPILE)objdump

export AS LD CC CPP AR NM
export STRIP OBJCOPY OBJDUMP

CFLAGS := -Wall -O2 -g
CFLAGS += -I $(shell pwd)/include

LDFLAGS := -lts -lpthread -lfreetype

export CFLAGS LDFLAGS

TOPDIR := $(shell pwd)
export TOPDIR

TARGET := test


obj-y += display/
obj-y += input/
obj-y += font/
obj-y += unittest/

all : start_recursive_build $(TARGET)
	@echo $(TARGET) has been built!

start_recursive_build:
	make -C ./ -f $(TOPDIR)/Makefile.build

$(TARGET) : built-in.o
	$(CC) -o $(TARGET) built-in.o $(LDFLAGS)

clean:
	rm -f $(shell find -name "*.o")
	rm -f $(TARGET)

distclean:
	rm -f $(shell find -name "*.o")
	rm -f $(shell find -name "*.d")
	rm -f $(TARGET)

 第20行:链接库

LDFLAGS := -lts -lpthread -lfreetype

 第30~33行:打开这四个文件夹进行make

obj-y += display/
obj-y += input/
obj-y += font/
obj-y += unittest/

五、上板测试

book@100ask:17_font_unittest_ok$ make
book@100ask:17_font_unittest_ok$ cp -r 17_font_unittest_ok/ ~/nfs_rootfs/
[root@100ask:~]#  mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt
[root@100ask:~]# cd /mnt/
[root@100ask:/mnt/17_font_unittest_ok]# ./test ./simsun.ttc 100 400 100

注意:编译时候要将字库文件一起上传上去

运行效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/208737.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

西南科技大学(数据结构A)期末自测练习三

一、填空题&#xff08;每空1分&#xff0c;共10分&#xff09; 1、为解决计算机主机与打印机之间速度不匹配的问题&#xff0c;通常设置一个打印数据缓冲区。主机将要输出的数据依次写入缓冲区&#xff0c;打印机则依次从缓冲区中取出数据&#xff0c;则该换缓冲区的逻辑结构…

JIRA 基本使用

该页面可以&#xff1a; 查看个人基本信息以及归属的邮件组修改常用参数配置查看指给自己的 Open 问题查看自己最近的活动记录等 权限管理 Project 权限管理 JIRA 项目有三种通用权限方案&#xff1a; 公开权限方案&#xff08;默认禁止使用此方案&#xff09;&#xff1a…

FlowJo软件的简单介绍 掌控流式细胞分析的科技巨匠 FlowJo10

FlowJo 10 for Mac是一款强大的流式细胞数据分析软件&#xff0c;具有以下功能&#xff1a; 数据导入与预处理&#xff1a;FlowJo 10可以轻松导入各种类型的流式细胞数据&#xff0c;并对数据进行预处理&#xff0c;包括去噪、背景校正等&#xff0c;以确保数据的准确性和可靠…

视频怎么去水印?如何下载保存无水印视频?

你是否曾经在观看鬼畜素材视频时&#xff0c;被烦人的水印挡住了视线&#xff0c;让你感到十分郁闷&#xff1f;不要担心&#xff0c;今天我将为你介绍几种经典的方法&#xff0c;让你轻松下载无水印视频&#xff0c;让观看体验更加清爽不留痕迹。让我们一起来试试吧&#xff0…

vue实现数字千分位格式化 如6,383,993,037,937.463

1.封装文件&#xff1a;numberToCurrency.js /**实现数字千分位格式化 如6,383,993,037,937.463 */ export function numberToCurrencyNo(value) {if (!value) return 0// 获取整数部分const intPart Math.trunc(value)// 整数部分处理&#xff0c;增加,const intPartFormat …

牛客算法题 【HJ97 记负均正】 golang实现

题目 HJ97 记负均正 描述 首先输入要输入的整数个数n&#xff0c;然后输入n个整数。输出为n个整数中负数的个数&#xff0c;和所有正整数的平均值&#xff0c;结果保留一位小数。 0即不是正整数&#xff0c;也不是负数&#xff0c;不计入计算。如果没有正数&#xff0c;则平均…

如何访问电脑的组策略编辑器?

如何打开组策略 如果我们使用的是 Win 10 系统&#xff0c;如何打开组策略&#xff1f;下面为大家总结了四种打开组策略编辑器的方法。 从搜索框打开 Win 10 策略组怎么打开&#xff1f;一个简单快速的方法就是使用 Windows 自带的搜索栏。我们可以向搜索框中输入“编辑组策…

netty源码:(1)NioEventLoopGroup

EventLoopGroup bossGroup new NioEventLoopGroup(); 不加参数创建NioEventLoopGroup的话&#xff0c;会使用cpu核数*2作为bossGroup的线程数。

2023年阅读类APP如何发展?怎么做好商业化? | TopOn观察

前言 阅读类APP作为泛娱乐应用的重要板块&#xff0c;近年来在全球都发展火热。本文将主要从阅读类应用的市场规模、头部产品及地区特点、商业化模式及提升商业变现几个方面入手&#xff0c;解析2023年阅读类APP的发展趋势&#xff0c;希望为阅读类应用开发者带来参考价值。 一…

使用visual Studio MFC 平台实现对灰度图添加椒盐噪声,并进行均值滤波与中值滤波

平滑处理–滤波 本文使用visual Studio MFC 平台实现对灰度图添加椒盐噪声&#xff0c;并进行均值滤波与中值滤波 关于其他MFC单文档工程可参考 01-Visual Studio 使用MFC 单文档工程绘制单一颜色直线和绘制渐变颜色的直线 02-visual Studio MFC 绘制单一颜色三角形、渐变颜色边…

利用python连接MySQL数据库并执行相关sql操作

一、新建MySQL数据库 1.启动MySQL服务 打开phpstudy&#xff0c;开启MySQL服务。如果开启失败的话&#xff0c;可以打开任务管理器&#xff0c;把正在运行的mysqld服务的进程进行关闭&#xff0c;再次打开MySQL服务即可启动。 2.新建MySQL数据库 选择数据库&#xff0c;点击…

ORACLE同义词说明及使用

同义词概念 Oracle的同义词&#xff08;synonyms&#xff09;从字面上理解就是别名的意思&#xff0c;和视图的功能类似&#xff0c;就是一种映射关系。它可以节省大量的数据库空间&#xff0c;对不同用户的操作同一张表没有多少差别;它扩展了数据库的使用范围&#xff0c;能够…

基于SSM的经典电影推荐网站设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

Python 流程控制

目录 程序流程 顺序结构 分支结构 单分支 双分支 多分支 if 嵌套 循环结构 while循环 for 循环 退出循环 循环与分支嵌套 附录 程序流程 程序是由语句构成&#xff0c;而流程控制语句 是用来控制程序中每条语句执行顺序的语句。可以通过控制语句实现更丰富的逻辑…

中国版的 GPTs:InsCode AI 生成应用

前言 在上一篇文章 《InsCode&#xff1a;这可能是下一代应用开发平台&#xff1f;》中&#xff0c;我们介绍了一个新的应用开发平台 InsCode&#xff0c;它是基于云原生开发环境 云 IDE AI 辅助编程的一站式在线开发平台。 最近&#xff0c;InsCode 又推出了另一种全新的开…

ASP.NET Core 使用IIS调试出现505.24错误

最近一直再学习asp.net 相关的东西&#xff0c;主要是为前端app提供一个webapi接口。在使用iis调试程序时出现HTTP Error 500.24 - Internal Server Error错误&#xff0c;搞了好久才最终解决。 1.在项目中增加web.config配置文件 2.将配置文件改为如下内容 <?xml version…

Unity | 渡鸦避难所-0 | 创建 URP 项目并导入商店资源

0 前言 知识点零零碎碎&#xff0c;没有目标&#xff0c;所以&#xff0c;一起做游戏吧 各位老师如果有什么指点、批评、漫骂、想法、建议、疑惑等&#xff0c;欢迎留言&#xff0c;一起学习 1 创建 3D&#xff08;URP&#xff09;项目 在 Unity Hub 中点击新项目&#xff…

Hive jar包冲突问题排查解决

1、报错情况 hiveserver2启动失败&#xff0c;查看日志报错&#xff1a; 2022-07-04T20:14:53,315 WARN [main]: server.HiveServer2 (HiveServer2.java:startHiveServer2(1100)) - Error starting HiveServer2 on attempt 1, will retry in 60000ms java.lang.NoSuchMethod…

Vue3中的组合式API的详细教程和介绍

文章目录 前言介绍组合式 API 基础setup 组件选项 带 ref 的响应式变量生命周期钩子注册内部 setupwatch 响应式更改独立的 computed 属性后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;vue.js &#x1f431;‍&#x1f453;博主在前端…

基于YOLOv8深度学习的120种犬类检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战、狗类检测、犬种识别

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…