精华内容
下载资源
问答
  • littlevGL:字体与汉字

    千次阅读 2019-01-26 22:48:51
    使用各种嵌入式GUI时,总会遇到“汉字显示”“字体”这些关卡。 阅读本文前,最好已经了解Uincode,UTF-8,UTF-16,GBK,GB2312相关知识,不懂最好网络搜索相关知识。 1.内置字体 littlevGL内置了好几种字体。在lv_...

    使用各种嵌入式GUI时,总会遇到“汉字显示”“字体”这些关卡。

    阅读本文前,最好已经了解Uincode,UTF-8,UTF-16,GBK,GB2312相关知识,不懂最好网络搜索相关知识。

    1.内置字体

    littlevGL内置了好几种字体。在lv_conf.h中开关相关字体

    /*==================
     *    FONT USAGE
     *===================*/
    
    /* More info about fonts: https://littlevgl.com/basics#fonts
     * To enable a built-in font use 1,2,4 or 8 values
     * which will determine the bit-per-pixel */
    #define USE_LV_FONT_DEJAVU_10              0
    #define USE_LV_FONT_DEJAVU_10_LATIN_SUP    0
    #define USE_LV_FONT_DEJAVU_10_CYRILLIC     0
    #define USE_LV_FONT_SYMBOL_10              0
    
    #define USE_LV_FONT_DEJAVU_20              4
    #define USE_LV_FONT_DEJAVU_20_LATIN_SUP    0
    #define USE_LV_FONT_DEJAVU_20_CYRILLIC     0
    #define USE_LV_FONT_SYMBOL_20              4
    
    #define USE_LV_FONT_DEJAVU_30              0
    #define USE_LV_FONT_DEJAVU_30_LATIN_SUP    0
    #define USE_LV_FONT_DEJAVU_30_CYRILLIC     0
    #define USE_LV_FONT_SYMBOL_30              0
    
    #define USE_LV_FONT_DEJAVU_40              0
    #define USE_LV_FONT_DEJAVU_40_LATIN_SUP    0
    #define USE_LV_FONT_DEJAVU_40_CYRILLIC     0
    #define USE_LV_FONT_SYMBOL_40              0
    
    #define USE_LV_FONT_MONOSPACE_8            0
    

    其中0代表不使用,1,2,4,8使能并设置抗锯齿值。

    字体文件在lv_fonts文件夹下。

    littlevGL支持UTF-8。在lv_conf.h中开启UTF8

    /*Text settings*/
    #define LV_TXT_UTF8             1                /*Enable UTF-8 coded Unicode character usage */

    2.自定义字体

    littlevGL支持自定义字体。

    官方字体生成网站:https://littlevgl.com/ttf-font-to-c-array

    不知为何作者没有发布离线字体生成工具。我打算过段时间有空就自己用C#写一个。

    生成的字体文件类似于lv_fonts文件夹下面的各种字体文件,使用方式也一样。

    使用之前需要把源文件转为UTF8格式。

    //myfont是自定义的字体
    void lv_tutorial_fonts(void)
    {
        static lv_style_t style1;
        char *str="我的祖国\nis 好好的!";
    
        /*Create a style and use the new font*/
        lv_style_copy(&style1, &lv_style_plain);
        style1.text.font = &myfont; 
    
        /*Create a label and set new text*/
        lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);
        lv_obj_set_pos(label, 100, 10);
        lv_label_set_style(label, &style1);
        lv_label_set_text(label, str ); 
    }

    3.外置字体

    上面的方法只适合字体文件比较小的情况,要是字体太大,放不进MCU,那就需要更进一步。

    对源文件的显示字体源码分析后,发现关键在于字体结构

    typedef struct _lv_font_struct
    {
        uint32_t unicode_first;
        uint32_t unicode_last;
        const uint8_t * glyph_bitmap;
        const lv_font_glyph_dsc_t * glyph_dsc;
        const uint32_t * unicode_list;
        const uint8_t * (*get_bitmap)(const struct _lv_font_struct *,uint32_t);     /*Get a glyph's  bitmap from a font*/
        int16_t (*get_width)(const struct _lv_font_struct *,uint32_t);        /*Get a glyph's with with a given font*/
        struct _lv_font_struct * next_page;    /*Pointer to a font extension*/
        uint32_t h_px       :8;
        uint32_t bpp        :4;                /*Bit per pixel: 1, 2 or 4*/
        uint32_t monospace  :8;                /*Fix width (0: normal width)*/
        uint16_t glyph_cnt;                    /*Number of glyphs (letters) in the font*/
    } lv_font_t;
    

    打开一个字体文件,其中字体定义

    lv_font_t lv_font_dejavu_20 = {
        .unicode_first = 32,    /*First Unicode letter in this font*/
        .unicode_last = 126,    /*Last Unicode letter in this font*/
        .h_px = 20,             /*Font height in pixels*/
        .glyph_bitmap = lv_font_dejavu_20_glyph_bitmap, /*Bitmap of glyphs*/
        .glyph_dsc = lv_font_dejavu_20_glyph_dsc,       /*Description of glyphs*/
        .glyph_cnt = 95,            /*Number of glyphs in the font*/
        .unicode_list = NULL,   /*Every character in the font from 'unicode_first' to 'unicode_last'*/
        .get_bitmap = lv_font_get_bitmap_continuous,    /*Function pointer to get glyph's bitmap*/
        .get_width = lv_font_get_width_continuous,  /*Function pointer to get glyph's width*/
    #if USE_LV_FONT_DEJAVU_20 == 1
        .bpp = 1,               /*Bit per pixel*/
    #elif USE_LV_FONT_DEJAVU_20 == 2
        .bpp = 2,               /*Bit per pixel*/
    #elif USE_LV_FONT_DEJAVU_20 == 4
        .bpp = 4,               /*Bit per pixel*/
    #elif USE_LV_FONT_DEJAVU_20 == 8
        .bpp = 8,               /*Bit per pixel*/
    #endif
        .monospace = 0,
        .next_page = NULL,      /*Pointer to a font extension*/
    };
    

    上面代码,lv_font_get_bitmap_continuous()函数为字体点阵获取函数,返回的是对应字符在点阵数组的位置。

    另外还有些字体使用的是lv_font_get_bitmap_sparse();这两个函数功能是一样的。

    由此,我们可以仿照此函数,想办法从外部存储器获得某个字符的点阵数据,并且保存在一个静态数组里,最后返回此数组首地址即可。

    要完成这些,前提是1.把字符的点阵数组转化为BIN文件(去原子的论坛搜索下载C2B 1.1版本,2.0版本有BUG);2.把此文件弄到外置存储器。

    对于第2点。有很多方法。比如通过写一个PC串口助手把文件发送烧写进SPI flash(W25QXX之类);或者直接使用专门的烧录工具写进SPI flash;或者偷懒,直接放在SD卡里让MCU调用。

    这里我使用偷懒的方法,把字体文件放到SD卡里,以文件的形式读取数据。必须要说明,此方法频繁地进行文件操作,速度不咋地(最好把堆栈调大些,否则可能溢出)。

    内置的字体点阵获取函数

    /**
     * Generic bitmap get function used in 'font->get_bitmap' when the font NOT contains all characters in the range (sparse)
     * @param font pointer to font
     * @param unicode_letter an unicode letter which bitmap should be get
     * @return pointer to the bitmap or NULL if not found
     */
    const uint8_t * lv_font_get_bitmap_sparse(const lv_font_t * font, uint32_t unicode_letter)
    {
        /*Check the range*/
        if(unicode_letter < font->unicode_first || unicode_letter > font->unicode_last) return NULL;
    
        uint32_t i;
        for(i = 0; font->unicode_list[i] != 0; i++) {
            if(font->unicode_list[i] == unicode_letter) {
                return &font->glyph_bitmap[font->glyph_dsc[i].glyph_index];
            }
        }
    
        return NULL;
    }

    仿照上面,自定义的函数

    //look above
    const uint8_t * ex_lv_font_get_bitmap_sparse(const lv_font_t * font, uint32_t unicode_letter)
    {
        uint8_t * pval=NULL; 
        uint32_t i;
        /*Check the range*/
        if(unicode_letter < font->unicode_first || unicode_letter > font->unicode_last){ return NULL;}
    
        for(i = 0; font->unicode_list[i] != 0; i++) 
        {
            if(font->unicode_list[i] == unicode_letter) 
            {
                FIL Binfile;
                FRESULT res;
                uint32_t br,fsize; 
                i=font->glyph_dsc[i].glyph_index;
                res=f_open(&Binfile, (const TCHAR*)font->glyph_bitmap ,FA_OPEN_EXISTING|FA_READ);
                if(res != FR_OK) { return NULL;}
                fsize = Binfile.fsize ;
                if(i+LetterSIZE <= fsize)
                {
                    f_lseek(&Binfile,i );  
                    res = f_read(&Binfile, letterBuff ,LetterSIZE ,&br);
                    if( res == FR_OK && ( br == LetterSIZE || br == LetterSIZE/2 ) || br==0 )
                    {
                        pval=letterBuff;
                    }
                }
                f_close(&Binfile);
                
                return pval;
            }
        }
        return NULL;
    }

    然后要把字体的点阵数组删除,在字体定义里修改.glyph_bitmap和.glyph_bitmap成员。如下

    lv_font_t myfont = 
    {
        .unicode_first = 32,    /*First Unicode letter in this font*/
        .unicode_last = 40664,    /*First Unicode letter in this font*/
        .h_px = 37,                /*Font height in pixels*/
        .glyph_bitmap = "0:/FONT/HZ1A.bin",    /*Bitmap of glyphs*/
        .glyph_dsc = glyph_dsc,        /*Description of glyphs*/
        .unicode_list = unicode_list,    /*List of unicode characters*/
        .get_bitmap = ex_lv_font_get_bitmap_sparse,    /*Function pointer to get glyph's bitmap*/
        .get_width = lv_font_get_width_sparse,    /*Function pointer to get glyph's width*/
        .bpp = 1,                /*Bit per pixel*/
        .next_page = NULL,        /*Pointer to a font extension*/
    };

    "0:/FONT/HZ1A.bin"是字体文件路径。

    再次说明,此方法不应该在实际项目中使用,效率不好。建议把字体文件按地址烧录进SPI flash,需要的时候再按照地址直接读取。上面的".glyph_bitmap"可赋值为该地址。原理都是一样的。

     

    展开全文
  • C语言 - 随机生成数字 和 汉字

    千次阅读 2020-05-04 18:30:45
    目录1 随机生成数字(整数 和 浮点数)1.1 注意 + rand()取值范围1.2 在[m, n]中随机取数(整 + 浮)1.2.1 注意:1.2.2 ...+ 浮) - 升级1.3.1 思路 ( 接 1.2.4 )1.3.2 实现代码2 随机生成汉字2.1 需了解的基础2.2 ...

    0 写在前面

    在区间 [ m, n ] 随机取值,首先应判断 n > m 是否成立!下面的代码没有判断,因为文章仅在 n > m 的情况下,从算法、技术方面实现随机取数

    1 随机生成数字(整数 和 浮点数)

    最简单的代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    int main()
    {
    	srand(time(NULL));
    	int i;
    	
    	i = rand();
    	cout << "i = " << i << endl <<endl;
    	
    	system("pause"); 
    	return 0;
    }
    

    1.1 rand() 简析

    rand()详解:https://www.cnblogs.com/cyttina/p/3162208.html

    本质

    用递推公式,得到周期很长的数列 ( 开始的数定了,那数列的数就固定下来 ),至于 rand() 内部递推公式是什么,网上没找到。

    递推开始的数就很重要了!
    srand( 数字p ); 表示递推从带入 p 开始,意味着:无论程序重复运行几次,每次得到的数列都是一模一样的(易知)
    srand(time(NULL)) ; 表示 开始的位置 是用系统的时间,而时间是每分每秒都在变化的,这样就得到了 “ 随机 ” 数列,即随机数,仔细想想依然不够随机…,这一点见 本文1.4.4(2)

    使用注意

    必须是主函数 中加上 srand(time(NULL)); 而不是在子函数的第一行! 这样 rand() 就是随机 整数
    在子函数中想随机生成 整数,同样可以用 rand()
    可参见 https://blog.csdn.net/qq_40893824/article/details/105066291

    rand()取值范围:

    rand() 整数的随机取值范围:[ 0, 32767 ],RAND_MAX = 32768的余数就是 [ 0, 32767 ]

    1.2 在 [ m, n ] 中随机取数(整 + 浮)

    适用范围m 和 n 的区间长度随机取值
    仅整数n – m < 32768 = 2^15rand()%(n – m + 1) + m
    整数、浮点数n – m >= 32768 = 2^151.0 * rand() / 32767 * (n – m) + m 或
    ( (double)rand() / 32767 ) * (n - m) + m

    1.2.1 注意:

    1 在n – m >= 32768,随机取值 1.0 * rand() / 32767 * (n – m) + m 中 1.0 不可以省略!
    或 ( (double)rand() / 32767 ) * (n - m) + m 中 double 不可省略!
    若省略,则随机值 极大概率 会是左边界值 m,极小概率是右边界值 n
    因为 rand() 是 [0, 32766] 时 rand() / 32767 = 0!
    rand() 是32767 时,rand() / 32767 = 1

    2 代码中需注意:
    生成浮点数,使用了数据类型 long double,在用 printf() 输出时,输出格式是%-3.4Lf,L是大写不是小写!

    floatdoublelong double
    输入scanf()%-3.4f%-3.4lf%-3.4Lf
    输出printf()%-3.4f%-3.4f%-3.4Lf

    1.2.2 思路:

    1 在区间 [ m, n ] 生成整数
    1.1 区间范围 < 32768,rand()%(n – m + 1) + m
    1.2 区间范围 >= 32768,1.0 * rand() / 32767 * (n – m) + m

    2 在区间 [ m, n ] 生成浮点数:1.0 * rand() / 32767 * (n – m) + m

    1.2.3 实现代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    void creat()
    {
    	long long m, n, p, i, length;
    	long double m1, n1, p1;
    	
    	cout << "1 区间取整数" << endl << endl;
    	
    	cout << "1.1 n - m < 32768" <<endl;
    	m = -2113;
    	n = 3567;
    	cout << "m = " << m << endl;
    	cout << "n = " << n << endl;
    	cout << "在[" << m << ", " << n << "]中随机取整数:" << endl;;
    	for(i = 0; i < 10; i++)
    	{	
    		p = rand()%(n - m + 1) + m;
    		cout << "第" << setw(2) << i + 1 << " 次:p = " << p << endl;
    	}
    	cout << endl << endl; 
    	
    	cout << "1.2 n - m >= 32768" <<endl;
    	m = -21133;
    	n = 35673;
    	cout << "m = " << m << endl;
    	cout << "n = " << n << endl;
    	cout << "在[" << m << ", " << n << "]中随机取整数:" << endl;
    	for(i = 0; i < 10; i++)
    	{	
    		p = (1.0*rand()/32767)*(n - m) + m;
    		cout << "第" << setw(2) << i + 1 << " 次:p = " << p << endl;
    	}
    	cout << endl << endl << endl;
    	
    	
    	cout << "2 区间取浮点数" << endl << endl;
    	
    	cout << "rand()直接取" << endl; 
    	m1 = -21131234.2123123;
    	n1 = 35671234.2121231;
    	cout << "m1 = " << m1 << endl;
    	cout << "n1 = " << n1 << endl;
    	cout << "在[" << m1 << ", " << n1 << "]中随机取浮点数:" << endl;;
    	for(i = 0; i < 10; i++)
    	{	
    		p1 = ( (double)rand()/32767 )*(n1 - m1) + m1;
    		cout << "第" << setw(2) << i + 1 << " 次:p1 = " ;
    		printf("%-7.8Lf\n", p1);
    	}
    	cout << endl << endl << endl;
    }
    
    int main()
    {
    	srand(time(NULL));
    	int i;
    	
    	i = rand();
    	cout << "随机i = " << i << endl << endl << endl;
    	
    	creat(); 
    	
    	system("pause"); 
    	return 0;
    }
    
    //

    1.2.4 不足:超大区间会失去随机的均匀性

    随机取整数 和 浮点数,当取值范围特别大时,会失去 随机的均匀性,即:区间中有些数是 不可能 被取到的!
    原因?

    再来研究随机取值的思路:
    讨论范围:在区间 [ m, n ] 中 随机取值 p,n - m >= 32768,p = 1.0 * rand() / 32767 * (n – m) + m 看成 [ m, n ] 的随机值,p 可能的取值有哪些?

    本质上,rand()随机在 [ 0, 32767 ] 中随机取数,有 32768 种情况,扩展到 [ m, n ] 其实仍然有32768种情况(易知)
    [ 0, 32767 ] 的 323768 种情况是:0, 1, 2, …, 32766, 32767
    [ 0, 32767 ] 和 [ m, n ] 的 323768 种情况比较:

    情况编号rand() 随机数p[ m, n ] 随机数p
    10m
    21m + (n - m) / 32767
    32m + 2 * (n - m) / 32767
    43m + 3*(n - m)/32767
    3276732766m + 32766(n - m)/32767
    3278832767m + 32767(n - m)/32767 = n

    绝对不会取到的数的个数 = n - m + 1 - 32767 = n - m - 32768

    当 n - m 超过 32768 不是很多时,未取到的数很少(姑且可忽略),其随机生成的数还可以看成随机数
    但是当 n - m 远超 32768 时,随机的数就不能当成随机数了!
    下面的1.3改进了这个不足!

    1.3 在 [ m, n ] 中随机取数(整 + 浮) - 初步升级

    1.3.0 目标

    均匀性:每个整数都会被取到,且概率相同

    1.3.1 思路 ( 接 1.2.4 )

    生成整数:

    在 [ m, n ] 中随机生成整数,区间长度 length = n - m
    然后在 [ 0, length ] 中随机取数 p,最后再加上 m,这样就得到 [ m, n ] 的随机整数,怎么随机取整数 又不失 均匀性?

    A length < 32768 时,返回 rand() ; 而不是返回 rand()%(length+1);
    B 否则
    r = rand() ;
    p = ( 1.0 * r / 32767 ) * length ;
    r 分 2 种情况
    (1) 当取 0 - 32766,相邻两数的间隔是 length = length / 32767 , 递归 至 A,p += 递归返回的数
    (2) 当取 32767,这个数就是边界 length,返回 p
    代码在(1) 后,不管是不是 32767 都要 return p; 因为这时可以看成 p 已经是生成好的数了,需要返回。

    这样可保证 [ 0, length ] 中每个 整数 都可能 被取到。
    即,保证了 [ m, n ] 中每个 整数 都可能 被取到

    注意:
    1 长度 比 区间包含数字的个数 小 1
    2 区间开闭
    上面两点在编程时很容易混淆,不知道该除以长度还是数字的个数
    闭区间 除以 长度,此时端点会被取到,容易思考;
    若除以包含的数字个数,每次随机取数要额外考虑最后一段的取值范围,麻烦 又 容易出错

    生成浮点数

    1 [ m, n ] 随机生成浮点数,m 和 n 本身也是浮点数,区间 length = n - m 是浮点数
    将 length 强制转为 long long 类型,再随机取整数,小数部分单独写个过程随机取
    如何取整 或 强制取整 见文章:https://blog.csdn.net/qq_40893824/article/details/105922443

    2 怎么取?在什么范围内随机取?
    因为整数部分已经随机取了,而且 每个整数都有被取到的可能,那么现在的小数,它的范围应该在 [ 0, 1) 之间,注意开闭!
    有一种情况不是 [ 0, 1) 间取值
    举例这样描述这个情况:length = 12.345,整数就在随机在 [ 0, 12 ] 中取值,当取到12 时,我的小数部分就不能在 [ 0, 1) 间取值,因为可能会超过边界,比如小数取到 0.6,则12 + 0.6 = 12.6 > 12.345,越界了,应在 [ 0, 0.345 ] 中取浮点数

    此时定义 r 是取到的整数
    当 length - r < 1时,在 [ 0, length - r ] 中取值 (1.0 * rand()) / 32767 * ( length - r )
    当 length - r >= 1时,在 [ 0, 1) 中取值 (1.0 * rand()) / 32768 ;

    注意:
    上面除的数 32767 和 32778 不一样
    因为是 2 种情况:32767 对应闭区间,32768 对应开区间!
    为什么 length - r >= 1时,在 [ 0, 1) 中取值 而不是 [ 0, 1 ] 中取值?
    原因:若 区间边界1 可能被取到,那 此时的数就不是小数了,整数平均被取到的均匀性会破坏掉

    1.3.2 实现代码

    #include<bits/stdc++.h>
    #define min 1e-4 
    using namespace std;
    
    long long LLmyrand(long long length) 
    {
    	long long r, p;
    	if(length < 32768)
    		return rand()%(length+1);
    	else
    	{
    		r = rand();
    		p = (1.0*r/32767)*length;
    		//cout << "粗略 p - m =  " << p << endl;
    		if (r < 32767)
    		{
    			length /= 32767; // length被分了32767份, length/32767 就是每一份的长度; 
    			//注意:
    			// a 长度 比 区间包含数字 的个数小 1
    			// b 区间的开闭
    			// a、b 两点在编程时很容易混淆,不知道该除以长度还是数字的个数
    			// 闭区间 除以 长度,此时端点会被取到,容易思考;若除以包含的数字个数,每次随机取数要额外考虑最后一段的取值范围,这样不好 
    			p += LLmyrand(length);
    		}
    		return p;
    	}
    }
    
    long double LDmyrand(long double length) 
    {
    	long long r;
    	long double p, leng;
    	r =  LLmyrand((long long)length); 
    	//cout << "粗略 p - m =  " << p << endl;
    	
    	p = (long double)r ;
    	leng = length - r;
    	if(leng >= 1)
    	{
    		p += (1.0*rand())/32768;	
    	}
    	else
    	{
    		p += (1.0*rand())/32767*leng;
    	}
    	return p;
    }
    
    void creat()
    {
    	long long m, n, p, i, length;
    	long double m1, n1, p1, length1;
    	
    	cout << "n - m > 32768 生成整数 - 改进" << endl << endl;
    	m = -211123234232;
    	n =  331123234234;
    	cout << "m = " << m << endl;
    	cout << "n = " << n << endl;
    	cout << "在[" << m << ", " << n << "]中随机取整数:" << endl << endl;
    	for(i = 0; i < 10; i++)
    	{	
    		length = n - m;
    		p = LLmyrand(length) + m;
    		//cout << "p - m =  " << p - m << endl;
    		cout << "第" << setw(2) << i + 1 << " 次:p = " << p << endl << endl;
    	}
    	cout << endl << endl << endl; 
    	
    	
    	cout << "n1 - m1 > 32768 生成浮点数 - 改进" << endl << endl;
    	m1 = -1231212312.123123123;
    	n1 =  1231567358.1212;
    	cout << "m1 = " << setprecision(20) << m1 << endl;
    	cout << "n1 = " << setprecision(20) << n1 << endl;
    	cout << "在[" << setprecision(20) << m1 << ", " << n1 << "]中随机取浮点数:" << endl << endl;
    	for(i = 0; i < 10; i++)
    	{	
    		length1 = n1 - m1;
    		p1 = LDmyrand(length1) + m1;
    		//cout << "p1 - m1 =  " << p1 - m1 << endl;
    		cout << "第" << setw(2) << i + 1 << " 次:p1 = " << setprecision(20) <<p1 << endl << endl;
    	}
    	cout << endl << endl << endl; 
    }
    
    int main()
    {
    	srand(time(NULL));
    	int i;
    	i = rand();
    	
    	creat(); 
    	
    	system("pause"); 
    	return 0;
    }
    

    1.4 在 [ m, n ] 中随机取数(整 + 浮) - 升级最终版

    1.3 中,在整数区间的范围内随机取整数
    在随机浮点数中,也用到了随机取整数的操作,弥补了随机的均匀性

    1.4.1 初步升级的不足(举例描述)

    1.3 中尝试 随机取数的均匀性(每个整数都会被取到,且概率相同)
    再看 1.3 的思路:

    在 [ m, n ] 中随机生成整数,区间长度 length = n - m
    直接在 [ 0, length ] 中随机取数 p,最后再加上 m,这样就得到 [ m, n ] 的随机整数

    A length < 32768 时,返回 rand()%length ;
    B 否则
    r = rand() ;
    p = ( 1.0 * r / 32767 ) * length ;
    r 共有 32768 种情况
    (1) 当取 0 - 32766,相邻两数的间隔是 length = length / 32767 , 递归 至 A,p += 递归返回的数
    (2) 当取 32767,这个数就是边界 length,返回 p

    有漏洞的地方:

    当取 0 - 32766,相邻两数的间隔是 length = length / 32767 , 递归 至 A,p += 递归返回的数

    漏洞举例

    简化模型:在 [ 3, 26 ] 中随机取整数,rand()的范围是 [ 0, 3 ],即RAND_MAX = 3,length = 26 - 3 = 23,在 [ 0, 23 ] 中随机取数
    r = rand()

    rp = ( 1.0 * r / 3 ) * 26 ;
    00
    17
    215
    323

    0, 7, 15, 23 的间隔分别是:7, 8, 8

    这说明 相邻两数的间隔不是固定的 length / 32767!

    1.4.2 修改 相邻两数的间隔

    length = (1.0*(r + 1)/32767)*length - (1.0*r/32767)*length; 
    

    1.4.3 代码

    代码太长,单独写成一篇文章:https://blog.csdn.net/qq_40893824/article/details/105928858

    1.4.4 不足

    (1) 仍未到达完全的均匀性
    (2) rand() 本身的不足限制

    (1) 不完全均匀

    每个数会被取到(√),每个数被取到的概率相同(×

    例子 - 简化模型:
    在 [ 3, 26 ] 中随机取整数,rand()的范围是 [ 0, 3 ],即RAND_MAX = 3,length = 26 - 3 = 23,在 [ 0, 23 ] 中随机取数
    第一次取值可能是:0, 7, 15, 23 (概率相同)
    第二次取值概率:

    第1次取值概率下一次取值每个数的概率
    01/41/7
    71/41/8
    151/41/8

    得:

    数字取值概率
    0-6( 1/4 ) * ( 1/7 )
    7( 1/4 ) * ( 1/8 )
    15( 1/4 ) * ( 1/8 )
    231/4

    这样看来每个数都可能被取到,但概率不唯一,即仍不均匀
    简单验证过程是否有问题,看概率和是否为 1
    ( 1/4 ) * ( 1/7 ) * 7 +
    ( 1/4 ) * ( 1/8 ) * 8 +
    ( 1/4 ) * ( 1/8 ) * 8 +
    1/4 = 1

    (2) rand() 本身的限制

    可看看:https://blog.csdn.net/czc1997/article/details/78167705
    在没有开始 rand() 时,rand 是随机的,一旦开始,其生成的数就是确定了
    因为 rand() 本质是周期很长的数列(递推),给定递推开始的数,那么后面的数都是可以用公式表示出来

    以上两点均暂时没想出解决的办法

    2 随机生成汉字

    2.1 需了解的基础

    1个汉字存进 字符数组,貌似是占 1个字节单元,其实是 2个字节单元!汉字有个区位码表
    高字节 对应 区码( = 行号)
    低字节 对应 位码( = 列号)
    区码 + 位码 = 区位码

    区位码表(94 x 94 的表格):每个汉字 对应唯一 1个位置
    内容见:https://www.doc88.com/p-9955966114086.html ( 无 04 - 15 分区内容)
    https://wenku.baidu.com/view/b5340aef11661ed9ad51f01dc281e53a580251a2.html ( 含 04 - 09 分区内容 )

    为什么不见 10 - 15分区内容?因为:
    01 - 09 区 :特殊符号
    10 - 15 区 :用户自定义符号(未编码,属于一级汉字范围)
    16 - 55 区 :一级汉字(3755 = (55 - 16 + 1 - 1)*94 + 89),按拼音排序(55时,列号范围:[ 1, 89 ] !
    56 - 87 区 :二级汉字(3008 = (87 - 56 + 1)*94),按部首/笔画排序
    88 - 94 区 :用户自定义汉字(未编码)

    所以汉字共 6763

    2.2 汉字行列号

    汉字的行号范围 [16, 87],列号范围 [1, 94]

    2.3 汉字 与 字母 的区分依据

    1 个汉字 占 2 个字节( = 16 bit),每 1 个字节 = 8 bit 位
    而且每 1 个字节的最高位(符号位) 一定 是1,代表负数!
    1 个字母 占 1 个字节,最高位 一定 是 0, 代表正数!

    2.3.1 在 [ 16, 87 ] 和 [ 1, 94 ] 随机生成整数

    	a = rand()%(87 - 16 + 1) + 16; //在[16, 87]随机生成整数
    	b = rand()%num1 + 1; //在[1, 94]随机生成整数
    	str[2*i] = 0 - a; // 别忘了是负数!
    	str[2*i + 1] = 0 - (b); // 同理
    

    2.4 注意(很重要!)

    本次注意单独列出来,很重要

    1. 单个汉字,它的区位码 在C语言 或 计算机中 是负数,这个没错,但并不是无脑直接让符号位变成1!
      而是本身的区位码减去96(网络别处 我没看到谁提到过这个)
    2. 区码为 55 的时候,位码 范围是 [ 1, 89 ] … 而不是 [ 1, 94 ] 。这是在随机生成汉字的时候,总出现 bug 空格,发现的知识点

    2.4.1 验证

    1 汉字区位码 在计算机中存储
    以汉字 ‘山’ 为例

    汉字 ‘山’ 的 区码 = 41,位码 = 29

    #include<bits/stdc++.h>
    #define num 100
    using namespace std;
    
    int main()
    {
    	char b0[num], b1[num];
    	//
    	cout << "汉字真正区位码 与 实际存储:" << endl << endl;
    	
    	char str[num] = "山";
    	
    	cout << "山: "  << endl;
    	cout << "真正的 区码 = 41, 位码 = 29" << endl;
    	
    	itoa(str[0], b0, 10);
    	itoa(str[1], b1, 10);
    	cout << "计算机中 存储的区码 = "<< b0 << ", 位码 = " << b1 << endl;
    	cout << "41 - (-55) = " << 41 + 55 << endl;
    	cout << "29 - (-67) = " << 29 + 67 << endl << endl;;
    	
    	system("pause");
    	return 0;
    }
    

    2 区码是 55 的时候,位码 范围是 [ 1, 89 ]:

    2.5 实现代码

    #include<bits/stdc++.h>
    #define num 10000
    #define num1 94
    using namespace std;
    
    void creat(char *str, FILE *fp)
    {	
    	char name[] = "./set.txt";
    	fp = fopen(name, "w+");
    
    	cout << "随机生成汉字" << endl;
    	int length = rand()%num, i, a, b; 
    	cout << "想生成 " << length << "个字" << endl;
    	
    	str = (char*)malloc((2*length + 1)*sizeof(char));
    	
    	for(i = 0; i < length; i++)
    	{
    		a = rand()%(87 - 16 + 1) + 16; //在[16, 87]随机生成整数
    		if(a == 55)
    			b = rand()%(89 - 1 + 1) + 1; //在[1, 89]随机生成整数
    		else
    			b = rand()%num1 + 1; //在[1, 94]随机生成整数
    		str[2*i] = a - 96; // 别忘了是负数!
    		str[2*i + 1] = b - 96; // 同理
    		//printf("%d %d\n",str[2*i] + 96, str[2*i + 1] + 96);
    	}
    	str[2*length] = '\0';
    	cout << "生成完毕!" << endl << endl;
    	
    	puts(str);
    	fputs(str,fp);
    	cout << endl << endl;
    	fclose(fp);
    }
    
    int main()
    {	
    	srand(time(NULL));
    	char str[] = "";
    	int i;
    	FILE *fp;
    	
    	for(i = 0; i < 1; i++)
    		creat(str, fp);
    	
    	system("pause");
    	return 0;
    }
    
    展开全文
  • 如何在matplotlib中使用中文字体是老问题了,相关文章非常多。 前几天有人问我如何知道中文字体名称和实际文件的对应关系时,才想起来原来没思考过这个问题,只能让他记住字体与文件的对应关系或者去fonts目录查看。...

    问题来源

    如何在matplotlib中使用中文字体是老问题了,相关文章非常多。
    前几天有人问我如何知道中文字体名称和实际文件的对应关系时,才想起来原来没思考过这个问题,只能让他记住字体与文件的对应关系或者去fonts目录查看。
    难道真的就没有稍微自动化、智能化的查看支持matplotlib的字体名称与文件的对应关系的方法?

    问题解决步骤

    matplotlib与字体相关的模块是font_manager,观察源码font_manager.py可知:

    1. matplotlib支持哪种类型的字体?

    def get_fontext_synonyms(fontext):
        """
        Return a list of file extensions extensions that are synonyms for
        the given file extension *fileext*.
        """
        return {
            'afm': ['afm'],
            'otf': ['otf', 'ttc', 'ttf'],
            'ttc': ['otf', 'ttc', 'ttf'],
            'ttf': ['otf', 'ttc', 'ttf'],
        }[fontext]
    

    由此可知matplotlib只支持ttfafm字体。

    • ‘ttf’: TrueType and OpenType fonts (.ttf, .ttc, .otf)
    • ‘afm’: Adobe Font Metrics (.afm)

    2. matplotlib如何查找系统字体?

    findSystemFonts模块函数的作用是查找系统字体。
    def findSystemFonts(fontpaths=None, fontext='ttf'): -->list
    参数fontext默认值为'ttf',另外还支持值'afm'
    参数fontpaths默认值是None
    对于fontpaths有两种种情况。

    fontpathsNone

    函数会判断操作系统,如果是Windows,调用函数win32InstalledFonts,如果不是Windows,调用函数get_fontconfig_fonts

    对于Windows,函数win32InstalledFonts到以下路径查找。

    
    # OS Font paths
    MSFolders = \
        r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
    MSFontDirectories = [
        r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts',
        r'SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts']
    MSUserFontDirectories = [
        str(Path.home() / 'AppData/Local/Microsoft/Windows/Fonts'),
        str(Path.home() / 'AppData/Roaming/Microsoft/Windows/Fonts'),
    ]
    

    对于非Windows操作系统,函数get_fontconfig_fonts主要依托fontconfig包(即fc-list命令)查找字体,要求fontconfig>=2.7

    fontpaths不为None

    fontpaths不为None时,通过list_fonts()函数查找字体。
    list_fonts()函数其实一个通用的按路径、扩展名递归遍历文件路径的函数。

    def list_fonts(directory, extensions):
        """
        Return a list of all fonts matching any of the extensions, found
        recursively under the directory.
        """
        extensions = ["." + ext for ext in extensions]
        return [os.path.join(dirpath, filename)
                # os.walk ignores access errors, unlike Path.glob.
                for dirpath, _, filenames in os.walk(directory)
                for filename in filenames
                if Path(filename).suffix.lower() in extensions]
    

    3.matplotlib如何查找matplotlib自带字体?

    安装matplotlib时,会在site-packages\matplotlib\mpl-data\fonts目录放置一系列字体。

    通过源码可知fonts目录下有'ttf', 'afm', 'pdfcorefonts'3个子目录。

    paths = [cbook._get_data_path('fonts', subdir)
                     for subdir in ['ttf', 'afm', 'pdfcorefonts']]
    
    In [1]: import matplotlib.cbook as cbook
    In [2]: paths = [cbook._get_data_path('fonts', subdir)   for subdir in ['ttf', 'afm', 'pdfcorefonts']]
    In [3]: paths
    Out[4]:
    [WindowsPath('c:/users/administrator/appdata/local/programs/python/python37/lib/site-packages/matplotlib/mpl-data/fonts/ttf'),
     WindowsPath('c:/users/administrator/appdata/local/programs/python/python37/lib/site-packages/matplotlib/mpl-data/fonts/afm'),
     WindowsPath('c:/users/administrator/appdata/local/programs/python/python37/lib/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts')]
    

    4.matplotlib如何生成字体列表?

    FontManager类是matplotlib管理字体的重要类,是一个单例类。FontManager实例在构造后会创建一个ttf字体列表和一个afm字体列表,并会缓存他们的字体属性。
    下面简单看看ttflistafmlist列表的元素的属性。

    In [1]: import matplotlib.font_manager as mf
    In [2]: ttflist=mf.FontManager().ttflist
    In [3]: vars(ttflist[0])
    Out[3]:
    {'fname': 'c:\\users\\administrator\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\matplotlib\\mpl-data\\fonts\\ttf\\DejaVuSansMono-BoldOblique.ttf',
     'name': 'DejaVu Sans Mono',
     'style': 'oblique',
     'variant': 'normal',
     'weight': 700,
     'stretch': 'normal',
     'size': 'scalable'}
    In [4]: len(ttflist)
    Out[4]: 252
    In [5]: afmlist=mf.FontManager().afmlist
    In [6]: vars(afmlist[0])
    Out[6]:
    {'fname': 'c:\\users\\administrator\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\matplotlib\\mpl-data\\fonts\\afm\\pagko8a.afm',
     'name': 'ITC Avant Garde Gothic',
     'style': 'italic',
     'variant': 'normal',
     'weight': 'book',
     'stretch': 'normal',
     'size': 'scalable'}
    In [7]: len(afmlist)
    Out[7]: 60
    

    5.matplotlib的字体属性缓存在哪里?

    前面了解到matplotlib会缓存字体属性那在什么位置呢?
    根据源码可知,字体缓存的所在目录是.matplotlib,缓存文件是fontlist-v330.json(文件名与版本有关)。在某些老版本的matplotlib中字体缓存文件名是fontList.cache

    _fmcache = os.path.join(
        mpl.get_cachedir(), 'fontlist-v{}.json'.format(FontManager.__version__))
    
    In [1]: import matplotlib
    In [2]: matplotlib.get_cachedir()
    Out[2]: 'C:\\Users\\Administrator\\.matplotlib'
    

    6. 怎么知道哪些字体是中文字体?

    虽然在前面已经知道matplotlib会把系统字体和自带字体信息存放在ttflistafmlist中,但是在这些字体信息中也不容易确定哪些是中文字体。
    通过资料查找有3种方法:

    • 查看Windows的fonts系统目录中显示的字体名称和文件名属性。这种方法效率太低!

    • 通过注册表项[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts]查看字体名和字体文件名称映射。这种方法一些系统字体仍然看不到汉字名称。
      在这里插入图片描述

    • 根据第1种方法想到了去查字体文件的元数据,Python相关的库有两个:fonttools,作者是老爹Guido的弟弟Just van RossumTTFQuery,基于fonttools的TTF包,只能查看TTF文件而且最后更新日期是2012年。

    TTFQery项目地址https://pypi.org/project/TTFQuery/
    源码中有些小问题,源码不算复杂,直接修改。

    import sys
    from fontTools.ttLib import TTFont
    from fontTools.ttLib.ttCollection import TTCollection
    
    UNICODE_ENCODINGS = {0: 'Unicode 1.0 semantics',
                         1: 'Unicode 1.1 semantics',
                         2: 'Unicode 1.1 semantics',
                         3: 'Unicode 2.0 and onwards semantics, Unicode BMP only (cmap subtable formats 0, 4, 6).',
                         4: 'Unicode 2.0 and onwards semantics, Unicode full repertoire (cmap subtable formats 0, 4, 6, 10, 12).',
                         5: 'Unicode Variation Sequences (cmap subtable format 14).',
                         6: 'Unicode Variation Sequences (cmap subtable format 14).'}
    
    
    WINDOWS_ENCODINGS = {0: 'Symbol',
                         1: 'Unicode BMP(UCS-2)',
                         2: 'ShiftJIS',
                         3: 'PRC',
                         4: 'Big5',
                         5: 'Wansung',
                         6: 'Johab',
                         7: 'Reserved',
                         8: 'Reserved',
                         9: 'Reserved',
                         10: 'Unicode UCS-4'}
    
    
    WINDOWS_LANGUAGES = {1025: 'Arabic/Saudi Arabia',
                         1026: 'Bulgarian/Bulgaria',
                         1027: 'Catalan/Catalan',
                         1028: 'Chinese/Taiwan',
                         1029: 'Czech/Czech Republic',
                         1030: 'Danish/Denmark',
                         1031: 'German/Germany',
                         1032: 'Greek/Greece',
                         1033: 'English/United States',
                         1034: 'Spanish (Traditional Sort)/Spain',
                         1035: 'Finnish/Finland',
                         1036: 'French/France',
                         1037: 'Hebrew/Israel',
                         1038: 'Hungarian/Hungary',
                         1039: 'Icelandic/Iceland',
                         1040: 'Italian/Italy',
                         1041: 'Japanese/Japan',
                         1042: 'Korean/Korea',
                         1043: 'Dutch/Netherlands',
                         1044: 'Norwegian (Bokmal)/Norway',
                         1045: 'Polish/Poland',
                         1046: 'Portuguese/Brazil',
                         1047: 'Romansh/Switzerland',
                         1048: 'Romanian/Romania',
                         1049: 'Russian/Russia',
                         1050: 'Croatian/Croatia',
                         1051: 'Slovak/Slovakia',
                         1052: 'Albanian/Albania',
                         1053: 'Swedish/Sweden',
                         1054: 'Thai/Thailand',
                         1055: 'Turkish/Turkey',
                         1056: 'Urdu/Islamic Republic of Pakistan',
                         1057: 'Indonesian/Indonesia',
                         1058: 'Ukrainian/Ukraine',
                         1059: 'Belarusian/Belarus',
                         1060: 'Slovenian/Slovenia',
                         1061: 'Estonian/Estonia',
                         1062: 'Latvian/Latvia',
                         1063: 'Lithuanian/Lithuania',
                         1064: 'Tajik (Cyrillic)/Tajikistan',
                         1066: 'Vietnamese/Vietnam',
                         1067: 'Armenian/Armenia',
                         1068: 'Azeri (Latin)/Azerbaijan',
                         1069: 'Basque/Basque',
                         1070: 'Upper Sorbian/Germany',
                         1071: 'Macedonian (FYROM)/Former Yugoslav Republic of Macedonia',
                         1074: 'Setswana/South Africa',
                         1076: 'isiXhosa/South Africa',
                         1077: 'isiZulu/South Africa',
                         1078: 'Afrikaans/South Africa',
                         1079: 'Georgian/Georgia',
                         1080: 'Faroese/Faroe Islands',
                         1081: 'Hindi/India',
                         1082: 'Maltese/Malta',
                         1083: 'Sami (Northern)/Norway',
                         1086: 'Malay/Malaysia',
                         1087: 'Kazakh/Kazakhstan',
                         1088: 'Kyrgyz/Kyrgyzstan',
                         1089: 'Kiswahili/Kenya',
                         1090: 'Turkmen/Turkmenistan',
                         1091: 'Uzbek (Latin)/Uzbekistan',
                         1092: 'Tatar/Russia',
                         1093: 'Bengali/India',
                         1094: 'Punjabi/India',
                         1095: 'Gujarati/India',
                         1096: 'Odia (formerly Oriya)/India',
                         1097: 'Tamil/India',
                         1098: 'Telugu/India',
                         1099: 'Kannada/India',
                         1100: 'Malayalam/India',
                         1101: 'Assamese/India',
                         1102: 'Marathi/India',
                         1103: 'Sanskrit/India',
                         1104: 'Mongolian (Cyrillic)/Mongolia',
                         1105: 'Tibetan/PRC',
                         1106: 'Welsh/United Kingdom',
                         1107: 'Khmer/Cambodia',
                         1108: 'Lao/Lao P.D.R.',
                         1110: 'Galician/Galician',
                         1111: 'Konkani/India',
                         1114: 'Syriac/Syria',
                         1115: 'Sinhala/Sri Lanka',
                         1117: 'Inuktitut/Canada',
                         1118: 'Amharic/Ethiopia',
                         1121: 'Nepali/Nepal',
                         1122: 'Frisian/Netherlands',
                         1123: 'Pashto/Afghanistan',
                         1124: 'Filipino/Philippines',
                         1125: 'Divehi/Maldives',
                         1128: 'Hausa (Latin)/Nigeria',
                         1130: 'Yoruba/Nigeria',
                         1131: 'Quechua/Bolivia',
                         1132: 'Sesotho sa Leboa/South Africa',
                         1133: 'Bashkir/Russia',
                         1134: 'Luxembourgish/Luxembourg',
                         1135: 'Greenlandic/Greenland',
                         1136: 'Igbo/Nigeria',
                         1144: 'Yi/PRC',
                         1146: 'Mapudungun/Chile',
                         1148: 'Mohawk/Mohawk',
                         1150: 'Breton/France',
                         1152: 'Uighur/PRC',
                         1153: 'Maori/New Zealand',
                         1154: 'Occitan/France',
                         1155: 'Corsican/France',
                         1156: 'Alsatian/France',
                         1157: 'Yakut/Russia',
                         1158: "K'iche/Guatemala",
                         1159: 'Kinyarwanda/Rwanda',
                         1160: 'Wolof/Senegal',
                         1164: 'Dari/Afghanistan',
                         2049: 'Arabic/Iraq',
                         2052: "Chinese/People's Republic of China",
                         2055: 'German/Switzerland',
                         2057: 'English/United Kingdom',
                         2058: 'Spanish/Mexico',
                         2060: 'French/Belgium',
                         2064: 'Italian/Switzerland',
                         2067: 'Dutch/Belgium',
                         2068: 'Norwegian (Nynorsk)/Norway',
                         2070: 'Portuguese/Portugal',
                         2074: 'Serbian (Latin)/Serbia',
                         2077: 'Sweden/Finland',
                         2092: 'Azeri (Cyrillic)/Azerbaijan',
                         2094: 'Lower Sorbian/Germany',
                         2107: 'Sami (Northern)/Sweden',
                         2108: 'Irish/Ireland',
                         2110: 'Malay/Brunei Darussalam',
                         2115: 'Uzbek (Cyrillic)/Uzbekistan',
                         2117: 'Bengali/Bangladesh',
                         2128: "Mongolian (Traditional)/People's Republic of China",
                         2141: 'Inuktitut (Latin)/Canada',
                         2143: 'Tamazight (Latin)/Algeria',
                         2155: 'Quechua/Ecuador',
                         3073: 'Arabic/Egypt',
                         3076: 'Chinese/Hong Kong S.A.R.',
                         3079: 'German/Austria',
                         3081: 'English/Australia',
                         3082: 'Spanish (Modern Sort)/Spain',
                         3084: 'French/Canada',
                         3098: 'Serbian (Cyrillic)/Serbia',
                         3131: 'Sami (Northern)/Finland',
                         3179: 'Quechua/Peru',
                         4097: 'Arabic/Libya',
                         4100: 'Chinese/Singapore',
                         4103: 'German/Luxembourg',
                         4105: 'English/Canada',
                         4106: 'Spanish/Guatemala',
                         4108: 'French/Switzerland',
                         4122: 'Croatian (Latin)/Bosnia and Herzegovina',
                         4155: 'Sami (Lule)/Norway',
                         5121: 'Arabic/Algeria',
                         5124: 'Chinese/Macao S.A.R.',
                         5127: 'German/Liechtenstein',
                         5129: 'English/New Zealand',
                         5130: 'Spanish/Costa Rica',
                         5132: 'French/Luxembourg',
                         5146: 'Bosnian (Latin)/Bosnia and Herzegovina',
                         5179: 'Sami (Lule)/Sweden',
                         6145: 'Arabic/Morocco',
                         6153: 'English/Ireland',
                         6154: 'Spanish/Panama',
                         6156: 'French/Principality of Monaco',
                         6170: 'Serbian (Latin)/Bosnia and Herzegovina',
                         6203: 'Sami (Southern)/Norway',
                         7169: 'Arabic/Tunisia',
                         7177: 'English/South Africa',
                         7178: 'Spanish/Dominican Republic',
                         7194: 'Serbian (Cyrillic)/Bosnia and Herzegovina',
                         7227: 'Sami (Southern)/Sweden',
                         8193: 'Arabic/Oman',
                         8201: 'English/Jamaica',
                         8202: 'Spanish/Venezuela',
                         8218: 'Bosnian (Cyrillic)/Bosnia and Herzegovina',
                         8251: 'Sami (Skolt)/Finland',
                         9217: 'Arabic/Yemen',
                         9225: 'English/Caribbean',
                         9226: 'Spanish/Colombia',
                         9275: 'Sami (Inari)/Finland',
                         10241: 'Arabic/Syria',
                         10249: 'English/Belize',
                         10250: 'Spanish/Peru',
                         11265: 'Arabic/Jordan',
                         11273: 'English/Trinidad and Tobago',
                         11274: 'Spanish/Argentina',
                         12289: 'Arabic/Lebanon',
                         12297: 'English/Zimbabwe',
                         12298: 'Spanish/Ecuador',
                         13313: 'Arabic/Kuwait',
                         13321: 'English/Republic of the Philippines',
                         13322: 'Spanish/Chile',
                         14337: 'Arabic/U.A.E.',
                         14346: 'Spanish/Uruguay',
                         15361: 'Arabic/Bahrain',
                         15370: 'Spanish/Paraguay',
                         16385: 'Arabic/Qatar',
                         16393: 'English/India',
                         16394: 'Spanish/Bolivia',
                         17417: 'English/Malaysia',
                         17418: 'Spanish/El Salvador',
                         18441: 'English/Singapore',
                         18442: 'Spanish/Honduras',
                         19466: 'Spanish/Nicaragua',
                         20490: 'Spanish/Puerto Rico',
                         21514: 'Spanish/United States'}
    
    MACINTOSH_ENCODINGS = {0: 'Roman',
                           1: 'Japanese',
                           2: 'Chinese',
                           3: 'Korean',
                           4: 'Arabic',
                           5: 'Hebrew',
                           6: 'Greek',
                           7: 'Russian',
                           8: 'RSymbol',
                           9: 'Devanagari',
                           10: 'Gurmukhi',
                           11: 'Gujarati',
                           12: 'Oriya',
                           13: 'Bengali',
                           14: 'Tamil',
                           15: 'Telugu',
                           16: 'Kannada',
                           17: 'Malayalam',
                           18: 'Sinhalese',
                           19: 'Burmese',
                           20: 'Khmer',
                           21: 'Thai',
                           22: 'Laotian',
                           23: 'Georgian',
                           24: 'Armenian',
                           25: 'Chinese',
                           26: 'Tibetan',
                           27: 'Mongolian',
                           28: 'Geez',
                           29: 'Slavic',
                           30: 'Vietnamese',
                           31: 'Sindhi',
                           32: 'Uninterpreted'}
    
    MACINTOSH_LANGUAGES = {0: 'English',
                           1: 'French',
                           2: 'German',
                           3: 'Italian',
                           4: 'Dutch',
                           5: 'Swedish',
                           6: 'Spanish',
                           7: 'Danish',
                           8: 'Portuguese',
                           9: 'Norwegian',
                           10: 'Hebrew',
                           11: 'Japanese',
                           12: 'Arabic',
                           13: 'Finnish',
                           14: 'Inuktitut',
                           15: 'Icelandic',
                           16: 'Maltese',
                           17: 'Turkish',
                           18: 'Croatian',
                           19: 'Chinese (Traditional)',
                           20: 'Urdu',
                           21: 'Hindi',
                           22: 'Thai',
                           23: 'Korean',
                           24: 'Lithuanian',
                           25: 'Polish',
                           26: 'Hungarian',
                           27: 'Estonian',
                           28: 'Latvian',
                           29: 'Sami',
                           30: 'Faroese',
                           31: 'Farsi/Persian',
                           32: 'Russian',
                           33: 'Chinese (Simplified)',
                           34: 'Flemish',
                           35: 'Irish Gaelic',
                           36: 'Albanian',
                           37: 'Romanian',
                           38: 'Czech',
                           39: 'Slovak',
                           40: 'Slovenian',
                           41: 'Yiddish',
                           42: 'Serbian',
                           43: 'Macedonian',
                           44: 'Bulgarian',
                           45: 'Ukrainian',
                           46: 'Byelorussian',
                           47: 'Uzbek',
                           48: 'Kazakh',
                           49: 'Azerbaijani (Cyrillic script)',
                           50: 'Azerbaijani (Arabic script)',
                           51: 'Armenian',
                           52: 'Georgian',
                           53: 'Moldavian',
                           54: 'Kirghiz',
                           55: 'Tajiki',
                           56: 'Turkmen',
                           57: 'Mongolian (Mongolian script)',
                           58: 'Mongolian (Cyrillic script)',
                           59: 'Pashto',
                           60: 'Kurdish',
                           61: 'Kashmiri',
                           62: 'Sindhi',
                           63: 'Tibetan',
                           64: 'Nepali',
                           65: 'Sanskrit',
                           66: 'Marathi',
                           67: 'Bengali',
                           68: 'Assamese',
                           69: 'Gujarati',
                           70: 'Punjabi',
                           71: 'Oriya',
                           72: 'Malayalam',
                           73: 'Kannada',
                           74: 'Tamil',
                           75: 'Telugu',
                           76: 'Sinhalese',
                           77: 'Burmese',
                           78: 'Khmer',
                           79: 'Lao',
                           80: 'Vietnamese',
                           81: 'Indonesian',
                           82: 'Tagalong',
                           83: 'Malay (Roman script)',
                           84: 'Malay (Arabic script)',
                           85: 'Amharic',
                           86: 'Tigrinya',
                           87: 'Galla',
                           88: 'Somali',
                           89: 'Swahili',
                           90: 'Kinyarwanda/Ruanda',
                           91: 'Rundi',
                           92: 'Nyanja/Chewa',
                           93: 'Malagasy',
                           94: 'Esperanto',
                           128: 'Welsh',
                           129: 'Basque',
                           130: 'Catalan',
                           131: 'Latin',
                           132: 'Quenchua',
                           133: 'Guarani',
                           134: 'Aymara',
                           135: 'Tatar',
                           136: 'Uighur',
                           137: 'Dzongkha',
                           138: 'Javanese (Roman script)',
                           139: 'Sundanese (Roman script)',
                           140: 'Galician',
                           141: 'Afrikaans',
                           142: 'Breton',
                           144: 'Scottish Gaelic',
                           145: 'Manx Gaelic',
                           146: 'Irish Gaelic (with dot above)',
                           147: 'Tongan',
                           148: 'Greek (polytonic)',
                           149: 'Greenlandic',
                           150: 'Azerbaijani (Roman script)'}
    
    ISO_IDS = {
        0: '7-bit ASCII',
        1: 'ISO 10646',
        2: 'ISO 8859-1'
    }
    
    CUSTOMS = {}
    
    
    PLATFORMS = {0: {'name': 'Unicode',
                     'encodings': UNICODE_ENCODINGS,
                     'languages': UNICODE_ENCODINGS},
                 1: {'name': 'Macintosh',
                     'encodings': MACINTOSH_ENCODINGS,
                     'languages': MACINTOSH_LANGUAGES},
                 2: {'name': 'ISO [deprecated]',
                     'encodings': ISO_IDS,
                     'languages': ISO_IDS},
                 3: {'name': 'Windows',
                     'encodings': WINDOWS_ENCODINGS,
                     'languages': WINDOWS_LANGUAGES},
                 4: {'name': 'Custom',
                     'encodings': CUSTOMS,
                     'languages': CUSTOMS}}
    
    
    NAME_TABLE = {0: 'Copyright Notice',
                  1: 'Font Family',
                  2: 'SubFamily',
                  3: 'Unique Font Identifier',
                  4: 'Full Font Name',
                  5: 'Version',
                  6: 'PostScript Name',
                  7: 'Trademark',
                  8: 'Manufacturer Name',
                  9: 'Designer',
                  10: 'Description',
                  11: 'Vendor URL',
                  12: 'Designer URL',
                  13: 'License Description',
                  14: 'License Info URL',
                  15: 'Reserved',
                  16: 'Typographic Family',
                  17: 'Typographic SubFamily',
                  18: 'Compatible Full',
                  19: 'Sample Text',
                  20: 'PostScript CID findfont name',
                  21: 'WWS Family Name',
                  22: 'WWS SubFamily Name',
                  23: 'Light Background Pallete',
                  24: 'Dark Background Pallete',
                  25: 'Variations PostScript Name Prefix'}
    
    
    ENCODINGS = {
        "Roman": 'latin_1'
    }
    
    def parse_meta(font):
        """The main meta parsing function. Thanks to Fonttools library."""
        data = {}
        for nti in font['name'].names:
            key = nti.nameID
            platform_data = PLATFORMS[nti.platformID]
            if platform_data['name'] == 'Custom':
                encoding = {'id': 0, 'value': 'Custom'}
                language = {'id': 0, 'value': 'Custom'}
            else:
                encoding = {'id': nti.platEncID,
                            'value': platform_data['encodings'].get(nti.platEncID, "Unknown")}
                language = {'id': nti.langID,
                            'value': platform_data['languages'].get(nti.langID, "Unknown")}
            name_str = nti.toStr()
            field = NAME_TABLE.get(nti.nameID, False)
            if not field:
                if 26 <= nti.nameID <= 255:
                    field = 'Reserved [{}]'.format(nti.nameID)
                elif 256 <= nti.nameID:
                    field = 'Font Specific[{}]'.format(nti.nameID)
    
            data[key] = {"field": field,
                        "value": name_str,
                        "encoding": encoding,
                        "language": language
            }
        return data
    
    def get_font_name(data, language=None):
        language_name = data.get(4).get('language').get('value')
        font_full_name = data.get(4).get('value')
    
        if language is None:
            return font_full_name
        else:
            if language in language_name:
                return font_full_name
            
    
    if __name__ == '__main__':
        from pathlib import Path
        import matplotlib.font_manager as fm
        
        ttflist=fm.FontManager().ttflist
        
        for f in ttflist:
            if Path(f.fname).suffix.lower()=='.ttf':
                # 输出字体元数据中语言包含有中文的TTF字体
                data = parse_meta(TTFont(f.fname))
                out_ttf = get_font_name(data,'Chinese')
                if out_ttf:
                    print(f.fname,f.name,out_ttf)
            elif Path(f.fname).suffix.lower()=='.ttc':
                # 输出所有TTC字体中包含的字体名称信息
                ttc = TTCollection(f.fname)
                for ttf in ttc:
                    ttc_data = parse_meta(ttf)
                    out_ttc = get_font_name(ttc_data,'Chinese')
                    if out_ttc:
                        print(f.fname,f.name,out_ttc)
    

    ttc文件很特殊,它是多个ttf文件集合,常用字体宋体微软雅黑等在Windows10中都是ttc文件,而且奇怪的是很多语言信息不是中文的ttc字体也可以显示中文。

    C:\Windows\Fonts\STHUPO.TTF STHupo 华文琥珀
    C:\Windows\Fonts\mingliub.ttc MingLiU-ExtB 細明體-ExtB
    C:\Windows\Fonts\mingliub.ttc MingLiU-ExtB 新細明體-ExtB
    C:\Windows\Fonts\mingliub.ttc MingLiU-ExtB 細明體_HKSCS-ExtB
    C:\Windows\Fonts\simkai.ttf KaiTi 楷体
    C:\Windows\Fonts\STXIHEI.TTF STXihei 华文细黑
    C:\Users\Administrator\AppData\Local\Microsoft\Windows\Fonts\仿宋_GB2312.ttf FangSong_GB2312 仿宋_GB2312
    C:\Users\Administrator\AppData\Local\Microsoft\Windows\Fonts\楷体_GB2312.ttf KaiTi_GB2312 楷体_GB2312
    C:\Windows\Fonts\STXINGKA.TTF STXingkai 华文行楷
    C:\Windows\Fonts\STCAIYUN.TTF STCaiyun 华文彩云
    C:\Windows\Fonts\simsun.ttc SimSun 宋体
    C:\Windows\Fonts\simsun.ttc SimSun 新宋体
    C:\Windows\Fonts\STKAITI.TTF STKaiti 华文楷体
    C:\Windows\Fonts\msjhl.ttc Microsoft JhengHei 微軟正黑體 Light
    C:\Windows\Fonts\msjhl.ttc Microsoft JhengHei Microsoft JhengHei UI Light
    C:\Users\Administrator\AppData\Local\Microsoft\Windows\Fonts\华文中宋.ttf STZhongsong 华文中宋
    C:\Windows\Fonts\FZYTK.TTF FZYaoTi 方正姚体
    C:\Users\Administrator\AppData\Local\Microsoft\Windows\Fonts\方正卡通简体.ttf FZKaTong-M19S 方正卡通简体
    C:\Windows\Fonts\simhei.ttf SimHei 黑体
    C:\Windows\Fonts\方正粗黑宋简体.ttf FZCuHeiSongS-B-GB 方正粗黑宋简体
    C:\Windows\Fonts\Deng.ttf DengXian 等线
    C:\Users\Administrator\AppData\Local\Microsoft\Windows\Fonts\FZXBSJW.TTF FZXiaoBiaoSong-B05S 方正小标宋简体
    C:\Windows\Fonts\Dengl.ttf DengXian 等线 Light
    C:\Windows\Fonts\msjh.ttc Microsoft JhengHei 微軟正黑體
    C:\Windows\Fonts\msjh.ttc Microsoft JhengHei Microsoft JhengHei UI
    C:\Windows\Fonts\msyh.ttc Microsoft YaHei 微软雅黑
    C:\Windows\Fonts\msyh.ttc Microsoft YaHei Microsoft Yahei UI
    C:\Windows\Fonts\STFANGSO.TTF STFangsong 华文仿宋
    C:\Windows\Fonts\simfang.ttf FangSong 仿宋
    C:\Windows\Fonts\SIMLI.TTF LiSu 隶书
    C:\Windows\Fonts\SIMYOU.TTF YouYuan 幼圆
    C:\Windows\Fonts\STLITI.TTF STLiti 华文隶书
    C:\Windows\Fonts\Dengb.ttf DengXian 等线 Bold
    C:\Windows\Fonts\msyhl.ttc Microsoft YaHei 微软雅黑 Light
    C:\Windows\Fonts\msyhl.ttc Microsoft YaHei Microsoft YaHei UI Light
    C:\Windows\Fonts\STSONG.TTF STSong 华文宋体
    C:\Windows\Fonts\STXINWEI.TTF STXinwei 华文新魏
    C:\Windows\Fonts\FZSTK.TTF FZShuTi 方正舒体
    

    参考

    https://matplotlib.org/api/font_manager_api.html
    http://ttfquery.sourceforge.net/
    https://fonttools.readthedocs.io/en/latest/ttLib/index.html

    展开全文
  • 要知道,这些英文字体对中文文字的表现是没有影响的(这里仅指单纯的文字表现,对齐、下划线等问题不予考虑),英文字体仅英文字体及一些字符有影响,中文字体依旧勃起,处于真空的裸露的状态,这种裸露直接裸给了...

    一、浏览器默认字体

    众所周知,浏览器字体默认的设置为“宋体/simsun字体 16像素”,例如Chrome浏览器下:
    Chrome浏览器下默认字体 张鑫旭-鑫空间-鑫生活

    二、CSS中设置的字体

    考虑到兼容性,我们总会在CSS中队字体进行一些设置,这类设置往往设置在body标签上,无论是人人网,腾讯网,淘宝网,开心,新浪,网易等都是如此。以下为各个大型网站的body的字体设置:

    人人网:

    body{font-family:Tahoma,Verdana,STHeiTi,simsun,sans-serif;}

    其中simsun为中文字体。

    腾讯网:

    body{font-family:"宋体","Arial Narrow";}

    淘宝网:

    body{font:12px/1.5 tahoma,arial,sans-serif;}

    开心网:

    body{font-family:'lucida grande',tahoma,helvetica,arial,'bitstream vera sans',sans-serif;}

    新浪微博:

    html{font-family:Arial,Helvetica,sans-serif,"宋体"}

    白社会:

    body{font:12px/20px Tahoma,Verdana,Arial,sans-serif;}

    三、浏览器默认字体与CSS字体间的关系

    要说关系,很简单,就是CSS字体的级别大于浏览器默认字体的级别。但是,在中国,作为中文网站,中文用户,中英文之间的差异使得故事的发展变得生动有趣了,这也是本文的所讨论的关键所在。

    咱们不急,今天荷兰和日本对的比赛反正耗得很,听我娓娓道来~~

    应该都知道,浏览器的默认字体是可以更改的,例如IE浏览器,见下图:
    IE浏览器下修改浏览器默认字体 张鑫旭-鑫空间-鑫生活

    或者是Firefox浏览器,工具 -> 选项 -> 内容,见下图:
    Firefox浏览器下默认字体 张鑫旭-鑫空间-鑫生活

    我们现在将默认字体由“宋体”改成“微软雅黑”,再看看第二部分提到了这些网站页面的字体表现:
    浏览器默认字体改为“微软雅黑”  张鑫旭-鑫空间-鑫生活

    下图全部截自Firefox3.6浏览器下,在IE浏览器下修改默认字体也会得到类似的结果,您可以自己试一试,下图顺序与第二部分出现的网站列表是一一对应的,图上已标明了浏览器默认字体“微软雅黑”是否起作用的情况。

    人人网浏览器微软雅黑字体下的表现 张鑫旭-鑫空间-鑫生活

    腾讯网浏览器微软雅黑字体下的表现 张鑫旭-鑫空间-鑫生活

    淘宝网浏览器微软雅黑下表现 张鑫旭-鑫空间-鑫生活

    开心网浏览器微软雅黑下表现 张鑫旭-鑫空间-鑫生活

    新浪微博在浏览器微软雅黑字体下的表现 张鑫旭-鑫空间-鑫生活

    白社会浏览器字体改为微软雅黑后 张鑫旭-鑫空间-鑫生活

    可以看到,人人网,淘宝网以及腾讯网下,页面上的字体依然长得就像是“宋体”一样,也就是说,修改浏览器的默认字体对其一点效果都没有;但是在开心网,新浪微博,白社会(以及我的博客)这些页面上,字体的表现就是微软雅黑效果。为什么会有这些差异呢?

    究其原因,不难理解。在本文的第二段落,将上述网站最顶级标签的font属性都罗列了出来,这是有原因的。仔细观察相应网站的body/html设置的font/font-family属性,相信您会找出表现差异的原因了——凡是浏览器默认字体不起作用的页面都是在CSS中设置了中文字体的页面。例如,人人网的simsun字体,腾讯网的“宋体”,淘宝网的“宋体”,只要在font/font-family属性中出现了对中文字体的设置,那么浏览器的自定义的默认字体就会失效,不起作用。OK,这里还有个看似“例外”的情况,就是新浪微博的页面,其html标签的CSS字体样式是:html{font-family:Arial,Helvetica,sans-serif,"宋体";},其也设置了含“宋体”的字体属性啊,为何页面上的表现依然是“微软雅黑”的效果而与腾讯网、淘宝网不一样呢?我之前就提过新浪微博的页面重构的水准与其新浪网的地位不匹,从这个font-family属性的设置可见一斑。我们在设置font-family属性是会在最后带有sans-serif或是serif,其分别表示“无衬线字体”和“衬线字体”,这个东东不是厕所里的屁屁——随便放的,我个人认为,其作用为终结,终结font-family属性,也即是说跟在sans-serif/serif后面的字体都是聋子的耳朵——摆设。所以新浪微博页面字体设置html{font-family:Arial,Helvetica,sans-serif,"宋体";}中的“宋体”压根就是多余的,永远也不会起作用,只会加大CSS文件尺寸的冗余代码。如果将“宋体”调至”sans-serif”的前面,那么情况就会大不一样。

    ( sans-serif和serif事实上对应的是某个字母体系,也就是无衬线体系和衬线体系,我们的机器里,无论如何,一定会有属于这两种体系中的英文或中文字体,比如宋体就属于serif衬线体系,所以大篇幅正文采用了宋体,而黑体则属于sans-serif无衬线体系,因为会放在例如标题中使用,如果将某种字体放在这两种字体体系之后,那基本就是没有意义的,因为在应用它之前,前面一定找到了对应的字体,所以sina才会犯了这样一个错误,应该是前端人员的“粗心”导致的吧。 )

    四、与用户体验与页面可用性之间的关联

    我们为什么要在body中设置font-family属性,其一就是在于统一,也就是所谓的兼容性,其二就是让英文字符更好看,“宋体”下的英文字符看多了会让人觉得蹩脚的……所以我们会设置font-family:arial; 或是font-family:Tahoma;这是需要的。对于中文站点,这类英文字体的设置依旧留下了中文的突破口。要知道,这些英文字体对中文文字的表现是没有影响的(这里仅指单纯的文字表现,对齐、下划线等问题不予考虑),英文字体仅对英文字体及一些字符有影响,中文字体依旧勃起,处于真空的裸露的状态,这种裸露直接裸给了浏览器,也就是说英文字体下的中文字体仅受浏览器的默认字体影响,于是这就牵涉到了一个页面可用性的问题。

    有一部分用户,虽然是一小部分,但是他们喜欢使用自定义的中文字体,拿我身边的事情举例吧。我有几个同事就喜欢“微软雅黑”字体,他就是把浏览器的默认字体设成了“微软雅黑”。根据他的口述,在他看来,访问一个网站,发现这个网站的字体不是他自定义的字体,他会有些许的挫败感,如果一个网站可以接受他修改的字体,以“微软雅黑”的形式显示,其对这个网站的认同感也会提升。由于“英文字体下的中文字体仅受浏览器的默认字体影响”,这类仅仅设置了英文字体的网站在我的这几个同事心中的分值无形中就提高了,而强制了中文字体的网站分值会下降。

    我们可能仅仅是忽略而已,仅仅是不知道而已!对于中文网站,我们的用户绝大多数是中文用户,在页面上设置中文字体属性(宋体/simsun)会降低页面的可用性和潜在的用户体验。如今的web,好的产品往往是可以满足用户的个性需求和自主能动性。页面上中文字体的设置会扼杀浏览器的默认中文字体,无法让用户以自己喜欢的中文字体显示。所以,我个人的倾向是,不要再CSS中,至少在body/html这类标签上设置中文字体。

    我本想把本文的题目定为“不要再CSS中定义中文字体”,这样的题目更有噱头,但是……(我要转折)。因为我突然想到,有些网站就是不让你使用您自己定义的字体,比如网站可能会使用“微软雅黑”与“宋体”来区分中文与标题,如果网站中文字体可以提过浏览器自定义,例如“微软雅黑”,则标题与正文字体一致,反而增加了阅读浏览负担,降低了用户体验。

    所以,到底哪种做法更好,要看实际的情况,合适的往往是最好的。但是,您需要知道:在CSS中设置中文字体会让中文用户无法通过修改浏览器默认字体来按照自己的需要浏览网页。至于具体您会怎么做,那就看您自己了。

    //zxx:日本队挂了~~

    原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
    本文地址:http://www.zhangxinxu.com/wordpress/?p=874

    (本篇完)// 想要打赏?点击这里。有话要说?点击这里

    想找个师兄入门前端?不妨 ×
    分享到: 3
    document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000)



    标签: css相关, font, font-family, simsun, 中文字体, 可用性, 字体, 宋体, 浏览器, 用户体验

    展开全文
  • 点阵字体显示系列之二:汉字显示

    千次阅读 2016-10-03 21:49:32
    ...本文是作者在研究过程中的一篇文章,本着...作者才疏学浅,孤陋寡闻,能力有限,文中出现的术语及概念的描述多有不当之处,由于本文并非学术报告及论文,不对这些概念性东西进行深入调研,如需权威性解释
  • 前段时间因为换工作的缘故又恰巧碰到国庆节,所以有段时间自己没有更新博客了,过完国庆到新公司报道,感觉还不错,就是现在住的地方离新公司有点远,地铁20站,伤不起啊,我每天早上7点多就要起床,然后屁颠屁颠的...
  • 然后,当中的文字加入其LOGO的部分图形元素,用LOGO当中的图形替代字体的某个笔画,将文字的局部替换,使文字的内涵外露,在形象和感官上都增加了一定的艺术感染力。字形结构重构进行图形化设计的基础毕竟是文字,...
  • Java 汉字转拼音(完美支持解决多音)

    万次阅读 热门讨论 2014-09-28 15:07:59
    上一篇文章Java 汉字转拼音
  • 今天在做一个输入框的内容,要求只能输入英文及英文符号,这才去查了资料了解了一下正则表达式的匹配规则,发现还是有点难度的,这才常用的正则表达式来进行总结一下: 1.匹配英文和数字及英文状态下的符号: 2....
  • 实现AHT20温湿度采集(1)电路连接二、OLED显示温湿度信息三、OLED滚动显示中文信息总结参考文章 一、基于I2C接口的温湿度采集(AHT20) 1.I2C (1)什么是I2C I2C总线是由Philips公司开发的一种简单、双向二线制...
  • 使用Windows中的字体生成点阵字库

    万次阅读 2018-07-09 09:55:05
    所有的汉字或者英文都是下面的原理,由左至右,每8个点占用一个字节,最后不足8个字节的占用一个字节,而且从最高位向最低位排列。生成的字库说明:(以12×12例子)一个汉字占用字节数:12÷8=1····4也就是占用...
  • VBA提取汉字字母混在字符串

    千次阅读 2013-12-23 15:28:23
    问题在于汉字并不止这两个或三个,我的文本文件里汉字数量有很大变化的,想了好多办法都不能很好解决。  解决案:  用StrConv进行Unicode 和 Ansi 格式的切换。  ...
  • 教材分析 本节内容主要是了解文字处理技术的发展变化及其意义,并从中领悟传播民族文化的必要性和紧迫性:了解文字在计算机中的编码方式:介绍了处理软件的基本特征,并会利用处理软件进行信息的加工与表达,并学会...
  • 汉字识别原理、方法与实现

    千次阅读 2019-10-30 14:16:37
    汉字识别问题,是将各种打字、印刷或书写的汉字文本中每一个汉字的图形或图像用计算机将其辨认出来,并标注其汉字类别代码的问题。因此,汉字识别是一个图像识别问题。 汉字识别数量极大,一般在4000个以上,是...
  • 这样大家C语言中汉字的存储是不是很清晰的了解了呢? 下面看C语言中汉字的输入。 在头文件#include 中的gets()可以实现汉字的输入。同样是gb2312码的输入。gb2312兼容了ASCII编码。 好了,就写这些了。我的QQ号 ...
  • 阿拉伯数字转换成中文读法的C语言程序

    千次阅读 多人点赞 2020-05-13 00:09:53
    记一道评论区的题目 ​ 导语 : 作为一个西电的菜鸡 , ...​ 分析一下 , 是想实现一个小写数字到中文大写数字的转化. 那么 , 如果我们想要实现这个功能 , 首先我们要重新回顾一下中文数字的读法和英文读法的区别. 2.
  • LVGL Font 字体

    千次阅读 多人点赞 2020-09-17 09:57:15
    MCU_Font 自动字模提取工具 1.做这个软件的初衷 ...软件先从我们的代码中取出需要显示的字符,然后将字符转为字模数据,再将字幕数据按照预定的格式存储为字体的.c文件,最后由单片机程序字模数据解析并
  • Linux内核如何输出中文字符

    千次阅读 多人点赞 2019-05-18 08:29:19
    你在Windows/MacOS的登录Linux的SSH终端上很容易输入中文并且获得中文输出,比如下面这样: 但是却几乎不可能将中文显示在Linux自身的 虚拟终端 上: [root@localhost font]# echo 皮鞋 >/dev/tty2 显示...
  • 17个角度,看汉字繁体和简体之争  作者:裴钰  近期,部分学者、文化人士陆续提出要废除简体,全面恢复繁体,同时,还有一部分学者主张要继续汉字的简化,不必恢复 繁体,“繁简汉字...
  • 之前在用java时特别是用户名或密码使用正则非常爽,写 脚本上用正则也非常爽,可是到了OC这却把我虐了一把,可能是OC掌握的不够。这里就罗列了从网上找的很有用的资料,感谢大神们的贡献。 首先举一个例子:...
  • 汉字库,字模的了解

    千次阅读 2013-11-09 11:33:36
    汉字库,字模的了解 标签: 技术类  2007-09-04 21:50阅读(726)评论(0)  由于Turbo C应用于DOS操作系统下,在使用Turbo C进行程序设计时,一般情况下只好使用英文进行人机交互。要是想直接用中文界面...
  • 上面已经了解到要让1602显示就需要将特地的地址输入特地的值,如果你刚接触1602,此时一定特别想了解怎么将上面的思路转换为verilog代码。但是一定需要注意时序问题,1602的读写时序为:  这里特别注意了...
  • LCD1602显示中文汉字

    万次阅读 多人点赞 2016-05-03 09:47:17
    小子在西藏 2011-11-25编写 ...LCD1602显示中文汉字     LCD1602相比大家都比较了解,但是我们一般只用来显示字符,数字。 最近在网上看许多人用LCD1602来显示汉字,觉得有趣 于是拜读了一些资料,教程
  • 那么怎么显示文字,才能更加的美观,那么大家需要了解以下文字属性。   字体属性 属性 用途 语法(一些写法) font-family 设置字体类型 1)该属性主要用来...
  • 而神经网络模型,解决Non-linear Hypotheses非常有效。 对于该模型,以下几点值得关注: 神经网络能够构造复杂的Non-linear Hypotheses的原因(层数越多,函数构造越复杂); Adding all these ...
  • 统计汉字使用频率

    千次阅读 2019-05-01 18:05:08
    4、利用数组,所有汉字按使用次数进行排序。 二、要到的基础库 本练习要到Glib库,Glib是在C语言标准库的基础上实现的一套跨平台的功能强大的通用函数库。 三、编程环境 编程环境为Cygwi...
  • [Ubuntu]明明白白安装中文字体

    千次阅读 2007-07-05 08:54:00
    [Ubuntu]明明白白安装中文字体授权方式:署名,非...Ubuntu 6.06 dapper对中文的支持应该说是一向不错的,包括现在默认安装就包含了scim输入法。然而,一般安装的ubuntu虽然能够显示、输入中文了,但总觉得所显示的中
  • 通过CSS实现 文字渐变色 的两种方式

    万次阅读 多人点赞 2019-01-17 17:49:09
    这里就不很详细的介绍了,想详细了解的朋友可以看看上面这篇文章,一定会你有所帮助的。 mask属性简单说,就是能让元素的某一部分显示或隐藏。 我们看张图就能明白,第二种方式实现的原理了 总结 ...
  • 之前泰文的了解只听过“萨瓦迪卡”-_-!!,所以前两天在学习泰文的排版规范及unicode编码,了解之后开始学习文字点阵打印的原理及代码编写。今天学习了汉字16*16点阵字库的使用。 这里首先感谢陪她去流浪大佬的文章...
  • C++里中文转拼音那点事

    千次阅读 2016-12-17 20:54:35
    C++里中文转拼音那点事C里中文转拼音那点事 效果图 插叙 结尾效果图 在讲解前,让我们先来看下效果图,给你想继续看的心情O(∩_∩)O 插叙 这上代码前,让我们一起先了解下什么是UNICODE编码? Unicode(统一码、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 98,852
精华内容 39,540
关键字:

对汉字的了解20字