⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 freetype.c

📁 ARM9-2410教学实验系统下Linux下minigui程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** $Id: freetype.c,v 1.26 2003/09/25 04:08:54 snig Exp $** ** freetype.c: TrueType font support based on FreeType 1.3.1.** ** Copyright (C) 2003 Feynman Software.** Copyright (C) 2000 ~ 2002 Wei Yongming.**** Current maintainer: WEI Yongming.**** Create date: 2000/08/21*//***  This library is free software; you can redistribute it and/or**  modify it under the terms of the GNU Library General Public**  License as published by the Free Software Foundation; either**  version 2 of the License, or (at your option) any later version.****  This library is distributed in the hope that it will be useful,**  but WITHOUT ANY WARRANTY; without even the implied warranty of**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU**  Library General Public License for more details.****  You should have received a copy of the GNU Library General Public**  License along with this library; if not, write to the Free**  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,**  MA 02111-1307, USA*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <math.h>#include "common.h"#include "minigui.h"#include "gdi.h"#include "devfont.h"#include "charset.h"#include "fontname.h"#include "misc.h"#if defined(_TTF_SUPPORT) && !defined(_HAS_FREETYPE2)#include <freetype1/freetype/freetype.h>#include <freetype1/freetype/ftxkern.h>#include <freetype1/freetype/ftnameid.h>#include <freetype1/freetype/ftxcmap.h>#include <freetype1/freetype/ftxwidth.h>#include "freetype.h"#if TT_FREETYPE_MAJOR != 1 | TT_FREETYPE_MINOR < 3    #error "You must link with freetype lib version 1.3.x +, and not freetype 2. \        You can download it at http://www.freetype.org"#endif/******************************* Global data ********************************/static TT_Engine ttf_engine;        /* The ONLY freetype engine */static BYTE virtual_palette [] = {0, 32, 64, 128, 255};/************************ Create/Destroy FreeType font ***********************/static BOOL CreateFreeTypeFont (const char *name, TTFGLYPHINFO* ttf_glyph_info){    unsigned short      i, n;    unsigned short      platform, encoding;    TT_Face_Properties  properties;    /* Load face */    if (TT_Open_Face (ttf_engine, name, &ttf_glyph_info->face) != TT_Err_Ok)        return FALSE;    /* Load first kerning table */    ttf_glyph_info->can_kern = TRUE;    if (TT_Load_Kerning_Table (ttf_glyph_info->face, 0) != TT_Err_Ok)        ttf_glyph_info->can_kern = FALSE;    else {        if (TT_Get_Kerning_Directory (ttf_glyph_info->face, &ttf_glyph_info->directory)            != TT_Err_Ok)            ttf_glyph_info->can_kern = FALSE;        else {            /* Support only version 0 kerning table ... */            if ((ttf_glyph_info->directory.version != 0) ||                (ttf_glyph_info->directory.nTables <= 0) ||                (ttf_glyph_info->directory.tables->loaded != 1) ||                (ttf_glyph_info->directory.tables->version != 0) ||                (ttf_glyph_info->directory.tables->t.kern0.nPairs <= 0))                    ttf_glyph_info->can_kern = FALSE;        }    }#if 0    fprintf (stderr, "Font %s: can kern? %c\n", name, ttf_glyph_info->can_kern ? 'y' : 'n');#endif    /* Get face properties and allocate preload arrays */    TT_Get_Face_Properties (ttf_glyph_info->face, &properties);    /* Create a glyph container */    if (TT_New_Glyph (ttf_glyph_info->face, &ttf_glyph_info->glyph) != TT_Err_Ok)        return FALSE;    /* Look for a Unicode charmap: Windows flavor of Apple flavor only */    n = properties.num_CharMaps;    for (i = 0; i < n; i++) {        TT_Get_CharMap_ID (ttf_glyph_info->face, i, &platform, &encoding);        if (((platform == TT_PLATFORM_MICROSOFT) &&            (encoding == TT_MS_ID_UNICODE_CS)) ||                ((platform == TT_PLATFORM_APPLE_UNICODE) &&                     (encoding == TT_APPLE_ID_DEFAULT)))        {            TT_Get_CharMap (ttf_glyph_info->face, i, &ttf_glyph_info->char_map);            i = n + 1;        }    }    if (i == n) {        fprintf (stderr, "GDI (When Create TTF Font): no unicode map table\n");        return FALSE;    }        ttf_glyph_info->first_char = TT_CharMap_First (ttf_glyph_info->char_map, NULL);    ttf_glyph_info->last_char = TT_CharMap_Last (ttf_glyph_info->char_map, NULL);    ttf_glyph_info->last_glyph_index            = (properties.num_Glyphs > 255) ? 255 : properties.num_Glyphs - 1;    return TRUE;}static void DestroyFreeTypeFont (TTFGLYPHINFO* ttf_glyph_info){    if (ttf_glyph_info->valid) {        TT_Done_Glyph (ttf_glyph_info->glyph);        TT_Close_Face (ttf_glyph_info->face);        ttf_glyph_info->valid = FALSE;    }}/************************ Alloc/Free raster bitmap buffer ********************/static BYTE* rb_buffer;static size_t rb_buf_size;static BYTE* get_raster_bitmap_buffer (size_t size){    if (size <= rb_buf_size) return rb_buffer;    rb_buf_size = ((size + 31) >> 5) << 5;#if 0    fprintf (stderr, "buf_size: %d.\n", buf_size);#endif    rb_buffer = realloc (rb_buffer, rb_buf_size);    return rb_buffer;}static void free_raster_bitmap_buffer (void){    free (rb_buffer);    rb_buffer = NULL;    rb_buf_size = 0;}/************************ Init/Term of FreeType fonts ************************/static int nr_fonts;static TTFGLYPHINFO* ttf_glyph_infos;static DEVFONT* ttf_dev_fonts;#define SECTION_NAME    "truetypefonts"BOOL InitFreeTypeFonts (void){    int i;    char font_name [LEN_UNIDEVFONT_NAME + 1];    /* Does load TrueType fonts? */    if (GetMgEtcIntValue (SECTION_NAME, "font_number",                &nr_fonts) < 0 )        return FALSE;    if ( nr_fonts < 1) return TRUE;    /* Alloc space for devfont and ttfinfo. */    ttf_glyph_infos = calloc (nr_fonts, sizeof (TTFGLYPHINFO));    ttf_dev_fonts = calloc (nr_fonts, sizeof (DEVFONT));    if (ttf_glyph_infos == NULL || ttf_dev_fonts == NULL) {        goto error_alloc;    }    for (i = 0; i < nr_fonts; i++)        ttf_glyph_infos [i].valid = FALSE;    /* Init freetype library */    if (TT_Init_FreeType (&ttf_engine) != TT_Err_Ok) {        goto error_alloc;    }    TT_Set_Raster_Gray_Palette (ttf_engine, virtual_palette);    /* Init kerning extension */    if (TT_Init_Kerning_Extension (ttf_engine) != TT_Err_Ok) {        TT_Done_FreeType (ttf_engine);        goto error_alloc;    }    for (i = 0; i < nr_fonts; i++) {        char key [11];        char charset [LEN_FONT_NAME + 1];        char file [MAX_PATH + 1];        CHARSETOPS* charset_ops;        sprintf (key, "name%d", i);        if (GetMgEtcValue (SECTION_NAME, key,                           font_name, LEN_UNIDEVFONT_NAME) < 0 )            goto error_load;        if (!fontGetCharsetFromName (font_name, charset)) {            fprintf (stderr, "GDI: Invalid font name (charset): %s.\n",                    font_name);            goto error_load;        }        if ((charset_ops = GetCharsetOps (charset)) == NULL) {            fprintf (stderr, "GDI: Not supported charset: %s.\n", charset);            goto error_load;        }        sprintf (key, "fontfile%d", i);        if (GetMgEtcValue (SECTION_NAME, key, file, MAX_PATH) < 0)            goto error_load;        if (!CreateFreeTypeFont (file, ttf_glyph_infos + i))            goto error_load;        strncpy (ttf_dev_fonts[i].name, font_name, LEN_UNIDEVFONT_NAME);        ttf_dev_fonts[i].name [LEN_UNIDEVFONT_NAME] = '\0';        ttf_dev_fonts[i].font_ops = &freetype_font_ops;        ttf_dev_fonts[i].charset_ops = charset_ops;        ttf_dev_fonts[i].data = ttf_glyph_infos + i;#if 0        fprintf (stderr, "GDI: TTFDevFont %i: %s.\n", i, ttf_dev_fonts[i].name);#endif        ttf_glyph_infos [i].valid = TRUE;    }    for (i = 0; i < nr_fonts; i++) {        int nr_charsets;        char charsets [LEN_UNIDEVFONT_NAME + 1];        if (ttf_dev_fonts [i].charset_ops->bytes_maxlen_char > 1) {            AddMBDevFont (ttf_dev_fonts + i);        }        else            AddSBDevFont (ttf_dev_fonts + i);        fontGetCharsetPartFromName (ttf_dev_fonts[i].name, charsets);        if ((nr_charsets = charsetGetCharsetsNumber (charsets)) > 1) {            int j;            for (j = 1; j < nr_charsets; j++) {                char charset [LEN_FONT_NAME + 1];                CHARSETOPS* charset_ops;                DEVFONT* new_devfont;                charsetGetSpecificCharset (charsets, j, charset);                if ((charset_ops = GetCharsetOps (charset)) == NULL)                    continue;                new_devfont = calloc (1, sizeof (DEVFONT));                memcpy (new_devfont, ttf_dev_fonts + i, sizeof (DEVFONT));                new_devfont->charset_ops = charset_ops;                if (new_devfont->charset_ops->bytes_maxlen_char > 1)                    AddMBDevFont (new_devfont);                else                    AddSBDevFont (new_devfont);            }        }    }    return TRUE;error_load:    fprintf (stderr, "GDI: Error in loading TrueType fonts\n");    for (i = 0; i < nr_fonts; i++)        DestroyFreeTypeFont (ttf_glyph_infos + i);error_alloc:    free (ttf_glyph_infos);    free (ttf_dev_fonts);    ttf_glyph_infos = NULL;    ttf_dev_fonts = NULL;    TT_Done_FreeType (ttf_engine);    return FALSE;}void TermFreeTypeFonts (void){    if (ttf_glyph_infos) {        TT_Done_FreeType (ttf_engine);        ttf_glyph_infos = NULL;    }        free_raster_bitmap_buffer ();}/*************** TrueType on FreeType font operations ************************/static TT_UShort Get_Glyph_Width (TTFINSTANCEINFO* ttf_inst_info, TT_UShort glyph_index){    TT_F26Dot6  xmin, xmax;    TT_Outline  outline;    TT_BBox     bbox;    TTFGLYPHINFO* ttf_glyph_info = ttf_inst_info->ttf_glyph_info;    if (TT_Load_Glyph (ttf_inst_info->instance, ttf_glyph_info->glyph, glyph_index,                TTLOAD_DEFAULT) != TT_Err_Ok)    {        /* Try to load default glyph: index 0 */        if (TT_Load_Glyph (ttf_inst_info->instance, ttf_glyph_info->glyph, 0,                    TTLOAD_DEFAULT) != TT_Err_Ok)        {            return 0;        }    }    TT_Get_Glyph_Outline (ttf_glyph_info->glyph, &outline);    TT_Get_Outline_BBox (&outline, &bbox);    xmin = (bbox.xMin & -64) >> 6;    xmax = ((bbox.xMax + 63) & -64) >> 6;    return (xmax - xmin);}static int get_char_width (LOGFONT* logfont, DEVFONT* devfont,                 const unsigned char* mchar, int len){    TT_UShort       index;    TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont);    index = TT_Char_Index (ttf_inst_info->ttf_glyph_info->char_map,             (*devfont->charset_ops->conv_to_uc16) (mchar, len));    if (index < 256)        return ttf_inst_info->widths [index];    return ttf_inst_info->ave_width;}static int get_max_width (LOGFONT* logfont, DEVFONT* devfont){    TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont);    return ttf_inst_info->max_width;}static intcompute_kernval (TTFINSTANCEINFO* ttf_inst_info){    int i = 0;    int kernval;    TTFGLYPHINFO* ttf_glyph_info = ttf_inst_info->ttf_glyph_info;    int nPairs = ttf_glyph_info->directory.tables->t.kern0.nPairs;    TT_Kern_0_Pair *pair = ttf_glyph_info->directory.tables->t.kern0.pairs;    if (ttf_inst_info->last_glyph_code != -1) {        while ((pair->left != ttf_inst_info->last_glyph_code)            && (pair->right != ttf_inst_info->cur_glyph_code))        {            pair++;            i++;            if (i == nPairs)                break;        }        if (i == nPairs)            kernval = 0;        else            /* We round the value (hence the +32) */            kernval = (pair->value + 32) & -64;    } else        kernval = 0;    return kernval;}static int get_str_width (LOGFONT* logfont, DEVFONT* devfont,                 const unsigned char* mstr, int n, int cExtra){    unsigned short uni_char;    TT_F26Dot6  x = 0;    TT_UShort   index;    TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont);    TTFGLYPHINFO* ttf_glyph_info = ttf_inst_info->ttf_glyph_info;#if 1    TT_Glyph_Metrics metrics;#endif    ttf_inst_info->last_glyph_code = -1;       /* reset kerning*/    ttf_inst_info->last_pen_pos = -1;    while (n > 0) {        int char_len = (*devfont->charset_ops->len_first_char) (mstr, n);        uni_char = (*devfont->charset_ops->conv_to_uc16) (mstr, char_len);        n -= char_len;        mstr += char_len;        index = TT_Char_Index (ttf_glyph_info->char_map, uni_char);        if (index < 256)            x += ttf_inst_info->widths [index];        else {#if 1            if (TT_Load_Glyph (ttf_inst_info->instance, ttf_glyph_info->glyph, index,                    TTLOAD_DEFAULT) != TT_Err_Ok)                continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -