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

📄 gdft.c

📁 Linux/Unix下的绘图函数库(Graphic Drawing Library)
💻 C
📖 第 1 页 / 共 3 页
字号:
/********************************************//* gd interface to freetype library         *//*                                          *//* John Ellson   ellson@graphviz.org        *//********************************************/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "gd.h"#include "gdhelpers.h"#include "entities.h"/* 2.0.10: WIN32, not MSWIN32 */#ifndef WIN32#include <unistd.h>#else#include <io.h>#define R_OK 04			/* Needed in Windows */#endif/* number of antialised colors for indexed bitmaps */#define NUMCOLORS 8static int fontConfigFlag = 0;static char *font_path(char **fontpath, char *name_list);/* translate a fontconfig fontpattern into a fontpath. 	return NULL if OK, else return error string */static char *font_pattern(char **fontpath, char *fontpattern);/* 2.0.30: move these up here so we can build correctly without freetype	but with fontconfig *//* * The character (space) used to separate alternate fonts in the * fontlist parameter to gdImageStringFT. 2.0.18: space was a * poor 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#define MAX(a,b) ((a)>(b)?(a):(b))#define MIN(a,b) ((a)<(b)?(a):(b))BGD_DECLARE(char *) 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_LIBFREETYPEBGD_DECLARE(char *) 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";}BGD_DECLARE(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#ifndef HAVE_LIBFONTCONFIGstatic char * font_pattern(char **fontpath, char *fontpattern){  return "libgd was not built with FontConfig support\n";}#endif /* HAVE_LIBFONTCONFIG */#include "gdcache.h"/* 2.0.16 Christophe Thomas: starting with FreeType 2.1.6, this is  mandatory, and it has been supported for a long while. */#ifdef HAVE_FT2BUILD_H#include <ft2build.h>#include FT_FREETYPE_H#include FT_GLYPH_H#include FT_SIZES_H#else#include <freetype/freetype.h>#include <freetype/ftglyph.h>#include <freetype/ftsizes.h>#endif/* 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.05typedef struct{  char *fontlist;		/* key */  int flags;			/* key */  char *fontpath;  FT_Library *library;  FT_Face face;}font_t;typedef struct{  char *fontlist;		/* key */  int flags;			/* 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"#endifstatic int comp_entities(const void *e1, const void *e2) {  struct entities_s *en1 = (struct entities_s *) e1;  struct entities_s *en2 = (struct entities_s *) e2;  return strcmp(en1->name, en2->name);}#define Tcl_UniChar int#define TCL_UTF_MAX 3static intgdTcl_UtfToUniChar (char *str, Tcl_UniChar * chPtr)/* str is the UTF8 next character pointer *//* chPtr is the int for the result */{  int byte;  char entity_name_buf[ENTITY_NAME_LENGTH_MAX+1];  char *p;  struct entities_s key, *res;  /* HTML4.0 entities in decimal form, e.g. &#197; */  /*           or in hexadecimal form, e.g. &#x6C34; */  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;	    }	}      else        {          key.name = p = entity_name_buf;          for (i = 1; i < 1 + ENTITY_NAME_LENGTH_MAX; i++)            {              byte = *((unsigned char *) (str + i));              if (byte == '\0')                break;              if (byte == ';')                {                  *p++ = '\0';                  res = bsearch(&key, entities, NR_OF_ENTITIES,                       sizeof(entities[0]), *comp_entities);                  if (res)                    {                      *chPtr = (Tcl_UniChar) res->value;                      return ++i;                    }                  break;               }              *p++ = byte;            }        }    }  /*   * 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 intfontTest (void *element, void *key){  font_t *a = (font_t *) element;  fontkey_t *b = (fontkey_t *) key;  return (strcmp (a->fontlist, b->fontlist) == 0 && a->flags == b->flags);}static int useFontConfig(int flag){	if (fontConfigFlag) {		return (!(flag & gdFTEX_FONTPATHNAME));	} else {		return flag & gdFTEX_FONTCONFIG;	}}static void *fontFetch (char **error, void *key){  font_t *a;  fontkey_t *b = (fontkey_t *) key;  char *suffix;  FT_Error err;  *error = NULL;  a = (font_t *) gdMalloc (sizeof (font_t));  a->fontlist = strdup (b->fontlist);  a->flags = b->flags;  a->library = b->library;  a->fontpath = NULL;#ifdef HAVE_LIBFONTCONFIG  if (!useFontConfig(b->flags))   	*error = font_path(&(a->fontpath), a->fontlist);              else  	*error = font_pattern(&(a->fontpath), a->fontlist);#else  *error = font_path(&(a->fontpath), a->fontlist);#endif /* HAVE_LIBFONTCONFIG */  if (*error || !a->fontpath || !a->fontpath[0])                {      /* 2.0.12: TBB: free these. Thanks to Frank Faubert. */      free (a->fontlist);      if (a->fontpath)	free (a->fontpath);      gdFree (a);      if (! *error)	*error = "font_path() returned an empty font pathname";      return NULL;    }#if 0fprintf(stderr,"fontpathname=%s\n",fullname);#endif  err = FT_New_Face(*b->library, a->fontpath, 0, &a->face);  /* Read kerning metrics for Postscript fonts. */  if (!err      && ((suffix = strstr(a->fontpath, ".pfa"))	  || (suffix = strstr(a->fontpath, ".pfb")))      && ((strcpy(suffix, ".afm") && (access(a->fontpath, R_OK) == 0))	  || (strcpy(suffix, ".pfm") && (access(a->fontpath, R_OK) == 0))))  {    err = FT_Attach_File(a->face, a->fontpath);  }  if (err)    {      /* 2.0.12: TBB: free these. Thanks to Frank Faubert. */      free (a->fontlist);      free (a->fontpath);      gdFree (a);      *error = "Could not read font";      return NULL;    }  return (void *) a;}static voidfontRelease (void *element){  font_t *a = (font_t *) element;  FT_Done_Face (a->face);  gdFree (a->fontlist);  gdFree (a->fontpath);  gdFree ((char *) element);}/********************************************************************//* tweencolor cache functions                                            */static inttweenColorTest (void *element, void *key){  tweencolor_t *a = (tweencolor_t *) element;  tweencolorkey_t *b = (tweencolorkey_t *) key;  return (a->pixel == b->pixel	  && a->bgcolor == b->bgcolor	  && a->fgcolor == b->fgcolor && a->im == b->im);}/* * Computes a color in im's color table that is part way between * the background and foreground colors proportional to the gray * pixel value in the range 0-NUMCOLORS. The fg and bg colors must already * be in the color table for palette images. For truecolor images the * returned value simply has an alpha component and gdImageAlphaBlend * does the work so that text can be alpha blended across a complex * background (TBB; and for real in 2.0.2). */static void *tweenColorFetch (char **error, void *key){  tweencolor_t *a;  tweencolorkey_t *b = (tweencolorkey_t *) key;  int pixel, npixel, bg, fg;  gdImagePtr im;  a = (tweencolor_t *) gdMalloc (sizeof (tweencolor_t));  pixel = a->pixel = b->pixel;  bg = a->bgcolor = b->bgcolor;  fg = a->fgcolor = b->fgcolor;

⌨️ 快捷键说明

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