minigui字体管理

minigui字体管理

仅针对内建字体资源,即定义了_INCORE_RES之后的字体管理

minigui配置为使用NEWGAL

minigui-1.6.8

 

1、  逻辑字体、设备字体及字符集的关系

minigui中,每个逻辑字体至少由一个单字节的设备字体组成。设备字体是直接与底层字体相关的数据结构。

 

/** The logical font structure. */

typedef struct _LOGFONT {

    /** The type of the logical font. */

    char type [LEN_FONT_NAME + 1];

    /** The family name of the logical font. */

    char family [LEN_FONT_NAME + 1];

    /** The charset of the logical font. */

    char charset [LEN_FONT_NAME + 1];

    /** The styles of the logical font. */

    DWORD style;

    /** The size of the logical font. */

    int size;

    /** The rotation angle of the logical font. */

    int rotation;

    /** The scale factor of sbc device font. */

    unsigned short sbc_scale;

    /** The scale factor of mbc device font. */

    unsigned short mbc_scale;

    DEVFONT* sbc_devfont;

    DEVFONT* mbc_devfont;

} LOGFONT;

 

struct _DEVFONT

{

    char             name [LEN_UNIDEVFONT_NAME + 1];

    DWORD            style;

    FONTOPS*         font_ops;

    CHARSETOPS*      charset_ops;

    struct _DEVFONT* sbc_next;

    struct _DEVFONT* mbc_next;

    void*            data;

};

 

每一个设备字体有一个操作集。通过这个字体操作集,我们可以从相应的字体文件中获得某个字符的点阵(对光栅字体而言,包括等宽光栅字体RBF和变宽光栅字体VBF),或轮廓(对矢量字体而言,包括TrueTypeAdobe Type1字体等)。之后,MINIGUI上层函数就可以将这些点阵输出到屏幕上,最终就可以看到显示在屏幕上的文字。

 

在设备字体中,还有一个字符集操作集,通过这个字符集操作集,可以对多种字符集混合的字符串进行文本分析。

 

显示文本的过程中,首先要分析文本字符串的组成,然后从设备字体中获取相关的尺寸信息、字型位图等信息,然后再显示在屏幕上。

 

2、  字体初始化

minigui中,在初始化GDI时,会对字体进行初始化,我们现在关注InitGDI函数中调用的如下几个函数:

 

1)  BOOL InitIncoreRBFonts (void)  src/rawbitmap.c line 188-255

 

BOOL InitIncoreRBFonts (void)

{

    int i;

 

    incore_rbf_dev_fonts = calloc (NR_RBFONTS, sizeof (DEVFONT));

    incore_rbf_infos = calloc (NR_RBFONTS, sizeof (RBFINFO));

 

    if (!incore_rbf_dev_fonts || !incore_rbf_infos)

        return TRUE;

 

    for (i = 0; i < NR_RBFONTS; i++) {

        char charset [LEN_FONT_NAME + 1];

 

        if (!fontGetCharsetFromName (incore_rbfonts [i]->name, charset)) {

            fprintf (stderr, "GDI: Invalid font name (charset): %s./n",

                    incore_rbfonts [i]->name);

            goto error_load;

        }

 

        if ((incore_rbf_infos [i].charset_ops

               = GetCharsetOpsEx (charset)) == NULL) {

            fprintf (stderr, "GDI: Not supported charset: %s./n", charset);

            goto error_load;

        }

 

        if ((incore_rbf_infos [i].width = fontGetWidthFromName (incore_rbfonts [i]->name)) == -1) {

            fprintf (stderr, "GDI: Invalid font name (width): %s./n",

                    incore_rbfonts [i]->name);

            goto error_load;

        }

       

        if ((incore_rbf_infos [i].height = fontGetHeightFromName (incore_rbfonts [i]->name)) == -1) {

            fprintf (stderr, "GDI: Invalid font name (height): %s./n",

                    incore_rbfonts [i]->name);

            goto error_load;

        }

       

        incore_rbf_infos [i].nr_chars = incore_rbf_infos [i].charset_ops->nr_chars;

 

        incore_rbf_infos [i].font_size = ((incore_rbf_infos [i].width + 7) >> 3) *

                incore_rbf_infos [i].height * incore_rbf_infos [i].nr_chars;

        incore_rbf_infos [i].font = (unsigned char*) incore_rbfonts [i]->data;

 

        strncpy (incore_rbf_dev_fonts[i].name, incore_rbfonts [i]->name, LEN_DEVFONT_NAME);

        incore_rbf_dev_fonts[i].name [LEN_DEVFONT_NAME] = '/0';

        incore_rbf_dev_fonts[i].font_ops = &raw_bitmap_font_ops;

        incore_rbf_dev_fonts[i].charset_ops = incore_rbf_infos [i].charset_ops;

        incore_rbf_dev_fonts[i].data = incore_rbf_infos + i;

#if 0

        fprintf (stderr, "GDI: RBFDevFont %i: %s./n", i, incore_rbf_dev_fonts[i].name);

#endif

    }

 

    for (i = 0; i < NR_RBFONTS; i++) {

        if (incore_rbf_infos [i].charset_ops->bytes_maxlen_char > 1)

            AddMBDevFont (incore_rbf_dev_fonts + i);

        else

            AddSBDevFont (incore_rbf_dev_fonts + i);

    }

 

    return TRUE;

 

error_load:

    fprintf (stderr, "GDI: Error in initializing incore raw bitmap fonts!/n");

 

    TermIncoreRBFonts ();

    return FALSE;

}

 

该函数中,首先根据配置时选择的RBF设备字体, 初始化了设备字体数据结构,然后根据这些RBF设备字体是多字节还是单字节,分别将它们添加到多字节设备字体链和单字节设备字体链的链尾。这样所有在配置时选中的RBF设备字体将根据其是单字节的还是多字节的,被保存到了全局的设备字体链中。

 

2BOOL InitIncoreVBFonts (void)  src/font/varbitmap.c        line 356-386

 

BOOL InitIncoreVBFonts (void)

{

    int i;

 

    if (NR_VBFONTS == 0)

        return TRUE;

 

    if ((incore_vbf_dev_font = malloc (NR_VBFONTS * sizeof (DEVFONT))) == NULL)

        return FALSE;

 

    for (i = 0; i < NR_VBFONTS; i++) {

        if ((incore_vbf_dev_font [i].charset_ops

                = vbfGetCharsetOps (incore_vbfonts [i])) == NULL) {

            fprintf (stderr,

                "GDI: Not supported charset for var-bitmap font %s./n",

                incore_vbfonts[i]->name);

            free (incore_vbf_dev_font);

            return FALSE;

        }

 

        strncpy (incore_vbf_dev_font [i].name, incore_vbfonts [i]->name, LEN_DEVFONT_NAME);

        incore_vbf_dev_font [i].name [LEN_DEVFONT_NAME] = '/0';

        incore_vbf_dev_font [i].font_ops = &var_bitmap_font_ops;

        incore_vbf_dev_font [i].data     = incore_vbfonts [i];

    }

 

    for (i = 0; i < NR_VBFONTS; i++)

        AddSBDevFont (incore_vbf_dev_font + i);

 

    return TRUE;

}

 

同样,该函数根据配置时选择的VBF设备字体,初始化了设备字体数据结构。然后把他们添加到单字节设备字体链的尾部。这样,配置时选择的所有VBF设备字体,也被保存到了全局设备字体链中。

 

3BOOL InitSysFont (void) src/font/sysfont.c

 

 

BOOL InitSysFont (void)

{

    int i;

    PLOGFONT* sys_fonts;

    int nr_fonts;

 

    if (GetMgEtcIntValue ("systemfont", "font_number", &nr_fonts) < 0 )

        return FALSE;

 

    if (nr_fonts < 1) return TRUE;

    if (nr_fonts > NR_SYSLOGFONTS) nr_fonts = NR_SYSLOGFONTS;

 

#ifdef HAVE_ALLOCA

    if ((sys_fonts = alloca (nr_fonts * sizeof (PLOGFONT))) == NULL)

#else

    if ((sys_fonts = malloc (nr_fonts * sizeof (PLOGFONT))) == NULL)

#endif

        return FALSE;

 

    memset (sys_fonts, 0, nr_fonts * sizeof (PLOGFONT));

 

    for (i = 0; i < nr_fonts; i++) {

        char key [11];

        char type[LEN_FONT_NAME + 1];

        char family[LEN_FONT_NAME + 1];

        char style[LEN_FONT_NAME + 1];

        char charset[LEN_FONT_NAME + 1];

        int height;

        char font_name [LEN_DEVFONT_NAME + 1];

 

        sprintf (key, "font%d", i);

        if (GetMgEtcValue ("systemfont", key, font_name, LEN_DEVFONT_NAME) < 0)

            goto error_load;

 

        if (!fontGetTypeNameFromName (font_name, type) ||

                !fontGetFamilyFromName (font_name, family) ||

                !fontCopyStyleFromName (font_name, style) ||

                !fontGetCharsetFromName (font_name, charset) ||

                ((height = fontGetHeightFromName (font_name)) == -1)) {

 

            fprintf (stderr, "GDI: Invalid system logical font name: %s./n",

                            font_name);

            goto error_load;

        }

 

#ifdef _DEBUG

        fprintf (stderr, "system font %d: %s-%s-%d-%s/n", i, type, family, height, charset);

#endif

 

        if (i == 0 && GetCharsetOps (charset)->bytes_maxlen_char > 1) {

            fprintf (stderr, "GDI: First system font should be a single-byte charset. font_name: %s/n",

                            font_name);

            goto error_load;

        }

 

        if ((sys_fonts[i] = CreateLogFont (type, family, charset,

                style [0], style [1], style [2],

                style [3], style [4], style [5],

                height, 0)) == NULL) {

            fprintf (stderr, "GDI: Error when creating system logical font./n");

            goto error_load;

        }

 

        if (i == 0)

            g_SysLogFont [0] = sys_fonts [0];

    }

 

    for (i = 0; i < NR_SYSLOGFONTS; i++) {

        int font_id;

 

        if (GetMgEtcIntValue ("systemfont", sys_font_name [i], &font_id) < 0

                    || font_id < 0 || font_id >= nr_fonts) {

            fprintf (stderr, "GDI: Error system logical font identifier: %s./n", sys_font_name [i]);

            goto error_load;

        }

 

        g_SysLogFont [i] = sys_fonts[font_id];

    }

 

#ifndef HAVE_ALLOCA

    free (sys_fonts);

#endif

    return TRUE;

 

error_load:

    fprintf (stderr, "GDI: Error in creating system logical fonts!/n");

    for (i = 0; i < nr_fonts; i++) {

        if (sys_fonts [i])

            DestroyLogFont (sys_fonts[i]);

    }

 

#ifndef HAVE_ALLOCA

    free (sys_fonts);

#endif

    return FALSE;

}

 

这个函数根据src/sysres/mgetc-pc.c文件中对字体的配置,创建出逻辑字体。然后再根据其配置为系统中的各组件设置逻辑字体。组件名定义在:src/font/sysfont.c line 54-62

 

static char* sys_font_name [] =

{

    "default",

    "wchar_def",

    "fixed",

    "caption",

    "menu",

    "control"

};

 

设置后逻辑字体保存于全局数组PLOGFONT g_SysLogFont [NR_SYSLOGFONTS]中,这样系统在显示时所用的字体就确定好了。

 

3、  自定义逻辑字体

当我们创建主窗口或控件时,系统会为其选择不同的逻辑字体以显示文本。当然我们也可以自定义一个逻辑字体来显示文本。可通过如下三个函数创建逻辑字体:

 

PLOGFONT GUIAPI CreateLogFontIndirect (LOGFONT *logfont);

PLOGFONT GUIAPI CreateLogFont (const char* type, const char* family,

    const char* charset, char weight, char slant, char set_width,

char spacing, char underline, char struckout, int size, int rotation);

       PLOGFONT GUIAPI CreateLogFontByName (const char* font_name);

      

创建完逻辑字体后,再通过函数

      

PLOGFONT GUIAPI SelectFont (HDC hdc, PLOGFONT log_font);

      

将所创建的逻辑字体设为要显示文本的设备上下文的逻辑字体。这样在对应的设备上下

       文中就会以自定义的逻辑字体显示文本。

你可能感兴趣的:(minigui,fonts,system,数据结构,null,struct,styles)