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

📄 ttfont.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   unsigned char      *ptr;
   unsigned char       cr, cg, cb, a, r, g, b, nr, ng, nb;
   unsigned long       pixel;

   cr = (col >> 16) & 0xff;
   cg = (col >> 8) & 0xff;
   cb = col & 0xff;
   for (y = 0; y < xim->height; y++)
     {
	ptr = (unsigned char *)rmap->bitmap + offset_x + ((y + offset_y) * rmap->cols);
	for (x = 0; x < xim->width; x++)
	  {
	     if ((a = alpha_lut[*ptr]) > 0)
	       {
		  if (a < 255)
		    {
		       pixel = gdk_image_get_pixel(xim, x, y);
		       r = (pixel >> 16) & 0xff;
		       g = (pixel >> 8) & 0xff;
		       b = pixel & 0xff;

		       tmp = (cr - r) * a;
		       nr = r + ((tmp + (tmp >> 8) + 0x80) >> 8);
		       tmp = (cg - g) * a;
		       ng = g + ((tmp + (tmp >> 8) + 0x80) >> 8);
		       tmp = (cb - b) * a;
		       nb = b + ((tmp + (tmp >> 8) + 0x80) >> 8);
		       pixel = ((nr << 16) | (ng << 8) | (nb));
		       gdk_image_put_pixel(xim, x, y, pixel);
		    }
		  else
		     gdk_image_put_pixel(xim, x, y, col);
	       }
	     ptr++;
	  }
     }
}

static void
merge_text_1(GdkImage * xim, TT_Raster_Map * rmap, int offset_x, int offset_y,
	     unsigned long col)
{
   int                 x, y;
   unsigned char      *ptr;

   for (y = 0; y < xim->height; y++)
     {
	ptr = (unsigned char *)rmap->bitmap + offset_x + ((y + offset_y) * rmap->cols);
	for (x = 0; x < xim->width; x++)
	  {
	     if (alpha_lut[*ptr] > 2)
		gdk_image_put_pixel(xim, x, y, col);
	     ptr++;
	  }
     }
}

void
EFont_draw_string(GdkPixmap *win, GdkGC *gc, int x, int y, char *text,
		  Efont * font)
{
   GdkImage             *xim = NULL;
   int                  width, height, w, h, inx, iny, clipx, clipy, rx;
   int                  depth;
   TT_Raster_Map       *rmap, *rtmp;
   unsigned long        col = 0;
   GdkGCValues          gcv;
   char                 is_pixmap = 0;

   inx = 0;
   iny = 0;

   if (strlen(text) < 1)
       return;

   ttfLock.Acquire();

   rtmp = calc_size(font, &w, &h, text);
   if (w <= 0 || h <= 0)
   {
       destroy_font_raster(rtmp);
       ttfLock.Release();
       return;
   }
   rmap = create_font_raster(w, h);

   render_text(rmap, rtmp, font, text, &inx, &iny);

   is_pixmap = 1;
   gdk_window_get_geometry((GdkWindow *)win, &rx, &rx,
	     &width, &height,
	     &depth);
   gdk_flush();
   gdk_gc_get_values(gc, &gcv);
   col = gcv.foreground.pixel;

   clipx = 0;
   clipy = 0;

   x = x - inx;
   y = y - iny;

   width = width - x;
   height = height - y;
   if (width > w)
      width = w;
   if (height > h)
      height = h;

   if (x < 0)
     {
	clipx = -x;
	width += x;
	x = 0;
     }
   if (y < 0)
     {
	clipy = -y;
	height += y;
	y = 0;
     }
   if ((width <= 0) || (height <= 0))
     {
	destroy_font_raster(rmap);
	destroy_font_raster(rtmp);
        ttfLock.Release();
	return;
     }

   xim = gdk_image_get((GdkWindow *)win, x, y, width, height);

   if (depth == 16)
     {
/*	if (id->x.render_depth == 15)
	   merge_text_15(xim, rmap, clipx, clipy, col);
	else */
	   merge_text_16(xim, rmap, clipx, clipy, col);
     }
   else if ((depth == 24) || (depth == 32))
      merge_text_24(xim, rmap, clipx, clipy, col);
   else if (depth == 15)
      merge_text_15(xim, rmap, clipx, clipy, col);
   else if (depth <= 8)
      merge_text_1(xim, rmap, clipx, clipy, col);

   gdk_draw_image((GdkWindow *)win, gc, xim, 0, 0, x, y, width, height);

   destroy_font_raster(rmap);
   destroy_font_raster(rtmp);
   gdk_image_destroy(xim);

   ttfLock.Release();
}

void
Efont_free(Efont * f)
{
   int                 i;

   if (!f)
      return;
   ttfLock.Acquire();

   TT_Done_Instance(f->instance);
   TT_Close_Face(f->face);
   for (i = 0; i < f->num_glyph; i++)
     {
	if (f->glyphs_cached[i])
	   destroy_font_raster(f->glyphs_cached[i]);
	if (!TT_VALID(f->glyphs[i]))
	   TT_Done_Glyph(f->glyphs[i]);
     }
   if (f->glyphs)
      free(f->glyphs);
   if (f->glyphs_cached)
      free(f->glyphs_cached);
   free(f);

   have_engine--;

   if (!have_engine)
       TT_Done_FreeType(engine);

   ttfLock.Release();
}

Efont              *
Efont_load(char *file, int size)
{
   TT_Error            error;
   TT_CharMap          char_map;
   TT_Glyph_Metrics    metrics;
   int                 dpi = 96;
   Efont              *f;
   unsigned short      i, n, code, load_flags;
   unsigned short      num_glyphs = 0, no_cmap = 0;
   unsigned short      platform, encoding;

   ttfLock.Acquire();

   if (!have_engine)
     {
	error = TT_Init_FreeType(&engine);
	if (error) {
           ttfLock.Release();
	   return NULL;
        }
     }
   have_engine++;
   f = (Efont *)malloc(sizeof(Efont));
   f->engine = engine;
   error = TT_Open_Face(f->engine, file, &f->face);
   if (error)
     {
	free(f);
        have_engine--;
 
        if (!have_engine)
            TT_Done_FreeType(engine);

        ttfLock.Release();
	return NULL;
     }
   error = TT_Get_Face_Properties(f->face, &f->properties);
   if (error)
     {
	TT_Close_Face(f->face);
	free(f);
        have_engine--;

        if (!have_engine)
            TT_Done_FreeType(engine);

        ttfLock.Release();
/*      fprintf(stderr, "Unable to get face properties\n"); */
	return NULL;
     }
   error = TT_New_Instance(f->face, &f->instance);
   if (error)
     {
	TT_Close_Face(f->face);
	free(f);
        have_engine--;

        if (!have_engine)
            TT_Done_FreeType(engine);

        ttfLock.Release();
/*      fprintf(stderr, "Unable to create instance\n"); */
	return NULL;
     }
   TT_Set_Instance_Resolutions(f->instance, dpi, dpi);
   TT_Set_Instance_CharSize(f->instance, size * 64);

   n = f->properties.num_CharMaps;

   for (i = 0; i < n; i++)
     {
	TT_Get_CharMap_ID(f->face, i, &platform, &encoding);
	if ((platform == 3 && encoding == 1) ||
	    (platform == 0 && encoding == 0))
	  {
	     TT_Get_CharMap(f->face, i, &char_map);
	     break;
	  }
     }
   if (i == n)
      TT_Get_CharMap(f->face, 0, &char_map);
   f->num_glyph = f->properties.num_Glyphs;
   //f->num_glyph = 256;
   f->glyphs = (TT_Glyph *) malloc((f->num_glyph + 1) * sizeof(TT_Glyph));
   memset(f->glyphs, 0, f->num_glyph * sizeof(TT_Glyph));
   f->glyphs_cached = 
              (TT_Raster_Map **) malloc(f->num_glyph * sizeof(TT_Raster_Map *));
   memset(f->glyphs_cached, 0, f->num_glyph * sizeof(TT_Raster_Map *));

   load_flags = TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH;

   f->max_descent = 0;
   f->max_ascent = 0;

   for (i = 0; i < f->num_glyph; ++i)
     {
	if (TT_VALID(f->glyphs[i]))
	   continue;

	if (no_cmap)
	  {
	     code = (i - ' ' + 1) < 0 ? 0 : (i - ' ' + 1);
	     if (code >= num_glyphs)
		code = 0;
	  }
	else
	   code = TT_Char_Index(char_map, i);

	TT_New_Glyph(f->face, &f->glyphs[i]);
	TT_Load_Glyph(f->instance, f->glyphs[i], code, load_flags);
	TT_Get_Glyph_Metrics(f->glyphs[i], &metrics);

	if ((metrics.bbox.yMin & -64) < f->max_descent)
	   f->max_descent = (metrics.bbox.yMin & -64);
	if (((metrics.bbox.yMax + 63) & -64) > f->max_ascent)
	   f->max_ascent = ((metrics.bbox.yMax + 63) & -64);
     }

   TT_Instance_Metrics imetrics;
   int upm;

   TT_Get_Instance_Metrics(f->instance, &imetrics);
   upm = f->properties.header->Units_Per_EM;
   f->ascent = (f->properties.horizontal->Ascender * imetrics.y_ppem) / upm;
   f->descent = (f->properties.horizontal->Descender * imetrics.y_ppem) / upm;
   if (f->ascent < 0)
      f->ascent = -f->ascent;
   if (f->descent < 0)
      f->descent = -f->descent;

   if (((f->ascent == 0) && (f->descent == 0)) || (f->ascent == 0))
   {
       f->ascent = f->max_ascent / 64; 
       f->descent = -f->max_descent / 64;
   }

   TT_Flush_Face(f->face);

   ttfLock.Release();

   return f;
}

void
Efont_extents(Efont * f, char *text, int *font_ascent_return,
	      int *font_descent_return, int *width_return,
	      int *max_ascent_return, int *max_descent_return,
	      int *lbearing_return, int *rbearing_return)
{
   int                 i, ascent, descent, pw;
   TT_Glyph_Metrics    gmetrics;

   if (!f)
      return;

   ttfLock.Acquire();
   ascent = f->ascent;
   descent = f->descent;
   pw = 0;

   for (i = 0; text[i]; i++)
     {
	unsigned char       j = text[i];

	if (!TT_VALID(f->glyphs[j]))
	   continue;
	TT_Get_Glyph_Metrics(f->glyphs[j], &gmetrics);
	if (i == 0)
	  {
	     if (lbearing_return)
		*lbearing_return = ((-gmetrics.bearingX) / 64);
	  }
	if (text[i + 1] == 0)
	  {
	     if (rbearing_return)
		*rbearing_return = ((gmetrics.bbox.xMax - gmetrics.advance) / 64);
	  }
	pw += gmetrics.advance / 64;
     }
   if (font_ascent_return)
      *font_ascent_return = ascent;
   if (font_descent_return)
      *font_descent_return = descent;
   if (width_return)
      *width_return = pw;
   if (max_ascent_return)
      *max_ascent_return = f->max_ascent;
   if (max_descent_return)
      *max_descent_return = f->max_descent;

   ttfLock.Release();
}

#endif

⌨️ 快捷键说明

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