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

📄 gdft.c

📁 Linux/Unix下的绘图函数库(Graphic Drawing Library)
💻 C
📖 第 1 页 / 共 3 页
字号:
      ch = *next;      /* carriage returns */      if (ch == '\r')	{	  penf.x = 0;	  previous = 0;		/* clear kerning flag */	  next++;	  continue;	}      /* newlines */      if (ch == '\n')	{	  /* 2.0.13: reset penf.x. Christopher J. Grayce */	  penf.x = 0;	  penf.y += linespace * ptsize * 64 * METRIC_RES / 72;	  penf.y &= ~63;	/* round down to 1/METRIC_RES */	  previous = 0;		/* clear kerning flag */	  next++;	  continue;	}        switch (encoding)	  {	  case gdFTEX_Unicode:	    {	      /* use UTF-8 mapping from ASCII */	      len = gdTcl_UtfToUniChar (next, &ch);/* EAM DEBUG *//* TBB: get this exactly right: 2.1.3 *or better*, all possible cases. *//* 2.0.24: David R. Morrison: use the more complete ifdef here. */#if ((defined(FREETYPE_MAJOR)) && (((FREETYPE_MAJOR == 2) && (((FREETYPE_MINOR == 1) && (FREETYPE_PATCH >= 3)) || (FREETYPE_MINOR > 1))) || (FREETYPE_MAJOR > 2)))      	      if (charmap->encoding == FT_ENCODING_MS_SYMBOL)#else	      if (charmap->platform_id == 3 && charmap->encoding_id == 0)#endif /* Freetype 2.1 or better */		{		  /* I do not know the significance of the constant 0xf000. */		  /* It was determined by inspection of the character codes */		  /* stored in Microsoft font symbol.ttf                    */		  ch |= 0xf000;		}/* EAM DEBUG */	      next += len;	    }	    break;	  case gdFTEX_Shift_JIS:	    {	      unsigned char c;	      int jiscode;	      c = *next;	      if (0xA1 <= c && c <= 0xFE)	        {	          next++;	          jiscode = 0x100 * (c & 0x7F) + ((*next) & 0x7F);      		  ch = (jiscode >> 8) & 0xFF;		  jiscode &= 0xFF;		  if (ch & 1)		    jiscode += 0x40 - 0x21;		  else		    jiscode += 0x9E - 0x21;		  if (jiscode >= 0x7F)		    jiscode++;		  ch = (ch - 0x21) / 2 + 0x81;		  if (ch >= 0xA0)		    ch += 0x40;		  ch = (ch << 8) + jiscode;		}	      else		{		  ch = c & 0xFF;	/* don't extend sign */		}	      next++;	    }	    break;	  case gdFTEX_Big5:	    {	      /*	       * Big 5 mapping:	       * use "JIS-8 half-width katakana" coding from 8-bit characters. Ref:	       * ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/japan.inf-032092.sjs	       */	      ch = (*next) & 0xFF;	/* don't extend sign */	      next++;	      if (ch >= 161	/* first code of JIS-8 pair */		  && *next)		{		/* don't advance past '\0' */		  /* TBB: Fix from Kwok Wah On: & 255 needed */		  ch = (ch * 256) + ((*next) & 255);		  next++;		}	    }	    break;	  }      /* Convert character code to glyph index */      glyph_index = FT_Get_Char_Index (face, ch);      /* retrieve kerning distance */      if ( ! (strex && (strex->flags & gdFTEX_DISABLE_KERNING))		&& ! FT_IS_FIXED_WIDTH(face)		&& FT_HAS_KERNING(face)		&& previous		&& glyph_index)        FT_Get_Kerning (face, previous, glyph_index, ft_kerning_default, &delta);      else	delta.x = delta.y = 0;	  penf.x += delta.x;      /* When we know the position of the second or subsequent character,	save the (kerned) advance from the preceeding character in the	xshow vector */      if (i && strex && (strex->flags & gdFTEX_XSHOW))        {	  /* make sure we have enough allocation for two numbers		so we don't have to recheck for the terminating number */	  if (! xshow_alloc) {		xshow_alloc = 100;		strex->xshow = malloc(xshow_alloc);		xshow_pos = 0;	  } 	  else if (xshow_pos + 20 > xshow_alloc) {		xshow_alloc += 100;		strex->xshow = realloc(strex->xshow, xshow_alloc);	}	  xshow_pos += sprintf(strex->xshow + xshow_pos, "%g ",		(double)(penf.x - oldpenf.x) * hdpi / (64 * METRIC_RES));        }      oldpenf.x = penf.x;      /* load glyph image into the slot (erase previous one) */      err = FT_Load_Glyph (face, glyph_index, render_mode);      if (err)	{	  gdCacheDelete (tc_cache);	  gdMutexUnlock (gdFontCacheMutex);	  return "Problem loading glyph";	}      horiAdvance = slot->metrics.horiAdvance;      if (brect)	{			/* only if need brect */	  glyph_min.x = penf.x + slot->metrics.horiBearingX;	  glyph_min.y = penf.y - slot->metrics.horiBearingY;#if 0	  if (ch == ' ')        /* special case for trailing space */            {              glyph_max.x = penf.x + horiAdvance;            }          else            {	      glyph_max.x = glyph_min.x + slot->metrics.width;            }#else          glyph_max.x = penf.x + horiAdvance;#endif	  glyph_max.y = glyph_min.y + slot->metrics.height;	  if (i==0)	    {	      total_min = glyph_min;	      total_max = glyph_max;	    }	  else	    {              if (glyph_min.x < total_min.x)                  total_min.x = glyph_min.x;              if (glyph_min.y < total_min.y)                  total_min.y = glyph_min.y;              if (glyph_max.x > total_max.x)                  total_max.x = glyph_max.x;              if (glyph_max.y > total_max.y)                  total_max.y = glyph_max.y;	    }	}      if (render)	{          FT_Activate_Size (platform_specific);          /* load glyph again into the slot (erase previous one)  - this time with scaling */          err = FT_Load_Glyph (face, glyph_index, render_mode);          if (err)	    {	      gdCacheDelete (tc_cache);	      gdMutexUnlock (gdFontCacheMutex);	      return "Problem loading glyph";	    }          /* load and transform glyph image */          FT_Get_Glyph (slot, &image);	  if (image->format != ft_glyph_format_bitmap)	    {	      err = FT_Glyph_To_Bitmap (&image, ft_render_mode_normal, 0, 1);	      if (err)		{		  gdCacheDelete (tc_cache);		  gdMutexUnlock (gdFontCacheMutex);		  return "Problem rendering glyph";		}	    }	  /* now, draw to our target surface */	  bm = (FT_BitmapGlyph) image;          /* position rounded down to nearest pixel at current dpi		 (the estimate was rounded up to next 1/METRIC_RES, so this should fit) */	  gdft_draw_bitmap (tc_cache, im, fg, bm->bitmap,                    x + (penf.x * cos_a + penf.y * sin_a)*hdpi/(METRIC_RES*64) + bm->left,                    y - (penf.x * sin_a - penf.y * cos_a)*vdpi/(METRIC_RES*64) - bm->top);          FT_Done_Glyph (image);	}      /* record current glyph index for kerning */      previous = glyph_index;      penf.x += horiAdvance;    }  /* Save the (unkerned) advance from the last character in the xshow vector */  if (strex && (strex->flags & gdFTEX_XSHOW) && strex->xshow)    {	sprintf(strex->xshow + xshow_pos, "%g",                (double)(penf.x - oldpenf.x) * hdpi / (64 * METRIC_RES) );    }  if (brect)    {				/* only if need brect */      double dpix, dpiy;            dpix = 64 * METRIC_RES / hdpi;      dpiy = 64 * METRIC_RES / vdpi;      /* increase by 1 pixel to allow for rounding */      total_min.x -= METRIC_RES;      total_min.y -= METRIC_RES;      total_max.x += METRIC_RES;      total_max.y += METRIC_RES;       /* rotate bounding rectangle, scale and round to int pixels, and translate */      brect[0] = x + (total_min.x * cos_a + total_max.y * sin_a)/dpix;      brect[1] = y - (total_min.x * sin_a - total_max.y * cos_a)/dpiy;      brect[2] = x + (total_max.x * cos_a + total_max.y * sin_a)/dpix;      brect[3] = y - (total_max.x * sin_a - total_max.y * cos_a)/dpiy;      brect[4] = x + (total_max.x * cos_a + total_min.y * sin_a)/dpix;      brect[5] = y - (total_max.x * sin_a - total_min.y * cos_a)/dpiy;      brect[6] = x + (total_min.x * cos_a + total_min.y * sin_a)/dpix;      brect[7] = y - (total_min.x * sin_a - total_min.y * cos_a)/dpiy;    }  FT_Done_Size (platform_independent);  if (render)    FT_Done_Size (platform_specific);  if (tmpstr)    gdFree (tmpstr);  gdCacheDelete (tc_cache);  gdMutexUnlock (gdFontCacheMutex);  return (char *) NULL;}#endif /* HAVE_LIBFREETYPE */#ifdef HAVE_LIBFONTCONFIG/* Code to find font path, with special mapping for Postscript font names. * * Dag Lem <dag@nimrod.no> */#include <fontconfig/fontconfig.h>/* #define NO_POSTSCRIPT_ALIAS 1 */#ifndef NO_POSTSCRIPT_ALIAStypedef struct _PostscriptAlias {  char* name;  char* family;  char* style;} PostscriptAlias;/* This table maps standard Postscript font names to URW Type 1 fonts.   The mapping is converted from Ghostscript (Fontmap.GS)   for use with fontconfig. */static PostscriptAlias postscript_alias[] = {  { "AvantGarde-Book", "URW Gothic L", "Book" },  { "AvantGarde-BookOblique", "URW Gothic L", "Book Oblique" },  { "AvantGarde-Demi", "URW Gothic L", "Demi" },  { "AvantGarde-DemiOblique", "URW Gothic L", "Demi Oblique" },  { "Bookman-Demi", "URW Bookman L", "Demi Bold" },  { "Bookman-DemiItalic", "URW Bookman L", "Demi Bold Italic" },  { "Bookman-Light", "URW Bookman L", "Light" },  { "Bookman-LightItalic", "URW Bookman L", "Light Italic" },  { "Courier", "Nimbus Mono L", "Regular" },  { "Courier-Oblique", "Nimbus Mono L", "Regular Oblique" },  { "Courier-Bold", "Nimbus Mono L", "Bold" },  { "Courier-BoldOblique", "Nimbus Mono L", "Bold Oblique" },    { "Helvetica", "Nimbus Sans L", "Regular" },  { "Helvetica-Oblique", "Nimbus Sans L", "Regular Italic" },  { "Helvetica-Bold", "Nimbus Sans L", "Bold" },  { "Helvetica-BoldOblique", "Nimbus Sans L", "Bold Italic" },  { "Helvetica-Narrow", "Nimbus Sans L", "Regular Condensed" },  { "Helvetica-Narrow-Oblique", "Nimbus Sans L", "Regular Condensed Italic" },  { "Helvetica-Narrow-Bold", "Nimbus Sans L", "Bold Condensed" },  { "Helvetica-Narrow-BoldOblique", "Nimbus Sans L", "Bold Condensed Italic" },  { "NewCenturySchlbk-Roman", "Century Schoolbook L", "Roman" },  { "NewCenturySchlbk-Italic", "Century Schoolbook L", "Italic" },  { "NewCenturySchlbk-Bold", "Century Schoolbook L", "Bold" },  { "NewCenturySchlbk-BoldItalic", "Century Schoolbook L", "Bold Italic" },  { "Palatino-Roman", "URW Palladio L", "Roman" },  { "Palatino-Italic", "URW Palladio L", "Italic" },  { "Palatino-Bold", "URW Palladio L", "Bold" },  { "Palatino-BoldItalic", "URW Palladio L", "Bold Italic" },  { "Symbol", "Standard Symbols L", "Regular" },  { "Times-Roman", "Nimbus Roman No9 L", "Regular" },  { "Times-Italic", "Nimbus Roman No9 L", "Regular Italic" },  { "Times-Bold", "Nimbus Roman No9 L", "Medium" },  { "Times-BoldItalic", "Nimbus Roman No9 L", "Medium Italic" },  { "ZapfChancery-MediumItalic", "URW Chancery L", "Medium Italic" },  { "ZapfDingbats", "Dingbats", "" },};#endifstatic FcPattern* find_font(FcPattern* pattern){  FcResult result;  FcConfigSubstitute(0, pattern, FcMatchPattern);  FcConfigSubstitute(0, pattern, FcMatchFont);  FcDefaultSubstitute(pattern);  return FcFontMatch(0, pattern, &result);}#ifndef NO_POSTSCRIPT_ALIASstatic char* find_postscript_font(FcPattern **fontpattern, char* fontname){  FcPattern* font = NULL;  int i;  *fontpattern = NULL;  for (i = 0; i < sizeof(postscript_alias)/sizeof(*postscript_alias); i++) {    if (strcmp(fontname, postscript_alias[i].name) == 0) {      FcChar8* family;      FcPattern* pattern =	FcPatternBuild(0,		       FC_FAMILY, FcTypeString, postscript_alias[i].family,		       FC_STYLE, FcTypeString, postscript_alias[i].style,		       (char*)0);      font = find_font(pattern);      FcPatternDestroy(pattern);      if (!font || FcPatternGetString(font, FC_FAMILY, 0, &family) != FcResultMatch)	return "fontconfig: Couldn't retrieve font family name.";            /* Check whether we got the font family we wanted. */      if (strcmp((const char *)family, postscript_alias[i].family) != 0) {	FcPatternDestroy(font);	return "fontconfig: Didn't find expected font family. Perhaps URW Type 1 fonts need installing?";      }      break;    }  }  *fontpattern = font;  return NULL;}#endifstatic char * font_pattern(char **fontpath, char *fontpattern){  FcPattern* font = NULL;  FcChar8* file;  FcPattern* pattern;#ifndef NO_POSTSCRIPT_ALIAS  char *error;#endif  *fontpath = NULL;#ifndef NO_POSTSCRIPT_ALIAS  error = find_postscript_font(&font, fontpattern);  if (!font) {    if (error)      return error;#endif    pattern = FcNameParse((const FcChar8 *)fontpattern);    font = find_font(pattern);    FcPatternDestroy(pattern);#ifndef NO_POSTSCRIPT_ALIAS  }#endif  if (!font || FcPatternGetString(font, FC_FILE, 0, &file) != FcResultMatch)    return "fontconfig: Couldn't retrieve font file name.";  *fontpath = strdup((const char *)file);  FcPatternDestroy(font);  return NULL;}#endif /* HAVE_LIBFONTCONFIG *//* Look up font using font names as file names. */static char * font_path(char **fontpath, char *name_list){  int font_found = 0;  char *fontsearchpath, *fontlist;  char *fullname = NULL;  char *name, *path, *dir;  char *strtok_ptr;  /*   * Search the pathlist for any of a list of font names.   */  *fontpath = NULL;  fontsearchpath = getenv ("GDFONTPATH");  if (!fontsearchpath)    fontsearchpath = DEFAULT_FONTPATH;  fontlist = strdup (name_list);  /*   * 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 = strdup (fontsearchpath);      /*       * Allocate an oversized buffer that is guaranteed to be       * big enough for all paths to be tested.       */      /* 2.0.22: Thorben Kundinger: +8 is needed, not +6. */      fullname = gdRealloc (fullname,                          strlen (fontsearchpath) + strlen (name) + 8);      /* if name is an absolute or relative pathname then test directly */      if (strchr (name, '/')	  || (name[0] != 0 && name[1] == ':'	      && (name[2] == '/' || name[2] == '\\')))	{	  sprintf (fullname, "%s", name);	  if (access (fullname, R_OK) == 0)	    {	      font_found++;              /* 2.0.16: memory leak fixed, Gustavo Scotti */              gdFree (path);	      break;	    }	}      for (dir = strtok (path, PATHSEPARATOR); dir;	   dir = strtok (0, PATHSEPARATOR))	{          if (strchr (name, '.'))	    {	      sprintf (fullname, "%s/%s", dir, name);	      if (access (fullname, R_OK) == 0)	        {	          font_found++;	          break;	        }	      else		{		  continue;		}            }	  sprintf (fullname, "%s/%s.ttf", dir, name);	  if (access (fullname, R_OK) == 0)	    {	      font_found++;	      break;	    }	  sprintf (fullname, "%s/%s.pfa", dir, name);	  if (access (fullname, R_OK) == 0)	    {	      font_found++;	      break;	    }	  sprintf (fullname, "%s/%s.pfb", dir, name);	  if (access (fullname, R_OK) == 0)	    {	      font_found++;	      break;	    }	  sprintf (fullname, "%s/%s.dfont", dir, name);	  if (access (fullname, R_OK) == 0)	    {	      font_found++;	      break;	    }	}      gdFree (path);      if (font_found)	break;    }  gdFree (fontlist);  if (!font_found)    {      free (fullname);      return "Could not find/open font";    }  *fontpath = fullname;  return NULL;}BGD_DECLARE(int) gdFTUseFontConfig(int flag){#ifdef HAVE_LIBFONTCONFIG	fontConfigFlag = 1;	return 1;#else	return 0;#endif /* HAVE_LIBFONTCONFIG */}

⌨️ 快捷键说明

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