📄 gdft.c
字号:
/********************************************//* gd interface to freetype library *//* *//* John Ellson ellson@graphviz.org *//********************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "gd.h"#include "gdhelpers.h"#ifndef MSWIN32#include <unistd.h>#else#include <io.h>#ifndef R_OK# define R_OK 04 /* Needed in Windows */#endif#endif#ifdef WIN32#define access _access#ifndef R_OK#define R_OK 2#endif#endif/* number of antialised colors for indexed bitmaps *//* overwrite Windows GDI define in case of windows build */#ifdef NUMCOLORS#undef NUMCOLORS#endif#define NUMCOLORS 8char *gdImageStringTTF (gdImage * im, int *brect, int fg, char *fontlist, double ptsize, double angle, int x, int y, char *string){ /* 2.0.6: valid return */ return gdImageStringFT (im, brect, fg, fontlist, ptsize, angle, x, y, string);}#ifndef HAVE_LIBFREETYPEchar *gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsize, double angle, int x, int y, char *string, gdFTStringExtraPtr strex){ return "libgd was not built with FreeType font support\n";}char *gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist, double ptsize, double angle, int x, int y, char *string){ return "libgd was not built with FreeType font support\n";}#else#include "gdcache.h"#include <ft2build.h>#include FT_FREETYPE_H#include FT_GLYPH_H/* number of fonts cached before least recently used is replaced */#define FONTCACHESIZE 6/* number of antialias color lookups cached */#define TWEENCOLORCACHESIZE 32/* * Line separation as a factor of font height. * No space between if LINESPACE = 1.00 * Line separation will be rounded up to next pixel row. */#define LINESPACE 1.05/* * The character (space) used to separate alternate fonts in the * fontlist parameter to gdImageStringFT. 2.0.18: space was a oor choice for this. */#define LISTSEPARATOR ";"/* * DEFAULT_FONTPATH and PATHSEPARATOR are host type dependent and * are normally set by configure in config.h. These are just * some last resort values that might match some Un*x system * if building this version of gd separate from graphviz. */#ifndef DEFAULT_FONTPATH#if defined(__APPLE__) || (defined(__MWERKS__) && defined(macintosh))#define DEFAULT_FONTPATH "/usr/share/fonts/truetype:/System/Library/Fonts:/Library/Fonts"#else#define DEFAULT_FONTPATH "/usr/share/fonts/truetype"#endif#endif#ifndef PATHSEPARATOR#define PATHSEPARATOR ":"#endif#ifndef TRUE#define FALSE 0#define TRUE !FALSE#endif#ifndef MAX#define MAX(a,b) ((a)>(b)?(a):(b))#endif#ifndef MIN#define MIN(a,b) ((a)<(b)?(a):(b))#endiftypedef struct{ char *fontlist; /* key */ FT_Library *library; FT_Face face; FT_Bool have_char_map_unicode, have_char_map_big5, have_char_map_sjis, have_char_map_apple_roman; gdCache_head_t *glyphCache;} font_t;typedef struct{ char *fontlist; /* key */ FT_Library *library;} fontkey_t;typedef struct{ int pixel; /* key */ int bgcolor; /* key */ int fgcolor; /* key *//* -ve means no antialias */ gdImagePtr im; /* key */ int tweencolor;} tweencolor_t;typedef struct{ int pixel; /* key */ int bgcolor; /* key */ int fgcolor; /* key *//* -ve means no antialias */ gdImagePtr im; /* key */} tweencolorkey_t;/******************************************************************** * gdTcl_UtfToUniChar is borrowed from Tcl ... *//* * tclUtf.c -- * * Routines for manipulating UTF-8 strings. * * Copyright (c) 1997-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tclUtf.c 1.25 98/01/28 18:02:43 *//* *--------------------------------------------------------------------------- * * gdTcl_UtfToUniChar -- * * Extract the Tcl_UniChar represented by the UTF-8 string. Bad * UTF-8 sequences are converted to valid Tcl_UniChars and processing * continues. Equivalent to Plan 9 chartorune(). * * The caller must ensure that the source buffer is long enough that * this routine does not run off the end and dereference non-existent * memory looking for trail bytes. If the source buffer is known to * be '\0' terminated, this cannot happen. Otherwise, the caller * should call Tcl_UtfCharComplete() before calling this routine to * ensure that enough bytes remain in the string. * * Results: * *chPtr is filled with the Tcl_UniChar, and the return value is the * number of bytes from the UTF-8 string that were consumed. * * Side effects: * None. * *--------------------------------------------------------------------------- */#ifdef JISX0208#include "jisx0208.h"#endif#define Tcl_UniChar int#define TCL_UTF_MAX 3static int gdTcl_UtfToUniChar (char *str, Tcl_UniChar * chPtr)/* str is the UTF8 next character pointer *//* chPtr is the int for the result */{ int byte; /* HTML4.0 entities in decimal form, e.g. Å */ byte = *((unsigned char *) str); if (byte == '&') { int i, n = 0; byte = *((unsigned char *) (str + 1)); if (byte == '#') { byte = *((unsigned char *) (str + 2)); if (byte == 'x' || byte == 'X') { for (i = 3; i < 8; i++) { byte = *((unsigned char *) (str + i)); if (byte >= 'A' && byte <= 'F') byte = byte - 'A' + 10; else if (byte >= 'a' && byte <= 'f') byte = byte - 'a' + 10; else if (byte >= '0' && byte <= '9') byte = byte - '0'; else break; n = (n * 16) + byte; } } else { for (i = 2; i < 8; i++) { byte = *((unsigned char *) (str + i)); if (byte >= '0' && byte <= '9') { n = (n * 10) + (byte - '0'); } else { break; } } } if (byte == ';') { *chPtr = (Tcl_UniChar) n; return ++i; } } } /* Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones. */ byte = *((unsigned char *) str);#ifdef JISX0208 if (0xA1 <= byte && byte <= 0xFE) { int ku, ten; ku = (byte & 0x7F) - 0x20; ten = (str[1] & 0x7F) - 0x20; if ((ku < 1 || ku > 92) || (ten < 1 || ten > 94)) { *chPtr = (Tcl_UniChar) byte; return 1; } *chPtr = (Tcl_UniChar) UnicodeTbl[ku - 1][ten - 1]; return 2; } else#endif /* JISX0208 */ if (byte < 0xC0) { /* Handles properly formed UTF-8 characters between * 0x01 and 0x7F. Also treats \0 and naked trail * bytes 0x80 to 0xBF as valid characters representing * themselves. */ *chPtr = (Tcl_UniChar) byte; return 1; } else if (byte < 0xE0) { if ((str[1] & 0xC0) == 0x80) { /* Two-byte-character lead-byte followed by a trail-byte. */ *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (str[1] & 0x3F)); return 2; } /* * A two-byte-character lead-byte not followed by trail-byte * represents itself. */ *chPtr = (Tcl_UniChar) byte; return 1; } else if (byte < 0xF0) { if (((str[1] & 0xC0) == 0x80) && ((str[2] & 0xC0) == 0x80)) { /* Three-byte-character lead byte followed by two trail bytes. */ *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) | ((str[1] & 0x3F) << 6) | (str[2] & 0x3F)); return 3; } /* A three-byte-character lead-byte not followed by two trail-bytes represents itself. */ *chPtr = (Tcl_UniChar) byte; return 1; }#if TCL_UTF_MAX > 3 else { int ch, total, trail; total = totalBytes[byte]; trail = total - 1; if (trail > 0) { ch = byte & (0x3F >> trail); do { str++; if ((*str & 0xC0) != 0x80) { *chPtr = byte; return 1; } ch <<= 6; ch |= (*str & 0x3F); trail--; } while (trail > 0); *chPtr = ch; return total; } }#endif *chPtr = (Tcl_UniChar) byte; return 1;}/********************************************************************//* font cache functions */static int fontTest (void *element, void *key){ font_t *a = (font_t *) element; fontkey_t *b = (fontkey_t *) key; return (strcmp (a->fontlist, b->fontlist) == 0);}static void *fontFetch (char **error, void *key){ font_t *a; fontkey_t *b = (fontkey_t *) key; int n; int font_found = 0; unsigned short platform, encoding; char *fontsearchpath, *fontlist; char fullname[MAXPATHLEN], cur_dir[MAXPATHLEN]; char *name, *path=NULL, *dir; char *strtok_ptr; FT_Error err; FT_CharMap found = 0; FT_CharMap charmap; a = (font_t *) gdPMalloc(sizeof(font_t)); a->fontlist = gdPEstrdup(b->fontlist); a->library = b->library; /* * Search the pathlist for any of a list of font names. */ fontsearchpath = getenv ("GDFONTPATH"); if (!fontsearchpath) { fontsearchpath = DEFAULT_FONTPATH; } fontlist = gdEstrdup(a->fontlist); /* * Must use gd_strtok_r else pointer corrupted by strtok in nested loop. */ for (name = gd_strtok_r (fontlist, LISTSEPARATOR, &strtok_ptr); name; name = gd_strtok_r (0, LISTSEPARATOR, &strtok_ptr)) { /* make a fresh copy each time - strtok corrupts it. */ path = gdEstrdup (fontsearchpath); /* if name is an absolute filename then test directly */ if (*name == '/' || (name[0] != 0 && name[1] == ':' && (name[2] == '/' || name[2] == '\\'))) { snprintf(fullname, sizeof(fullname) - 1, "%s", name); if (access(fullname, R_OK) == 0) { font_found++; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -