示例#1
0
static XftFont *
GetFont(
    UnixFtFont *fontPtr,
    FcChar32 ucs4)
{
    int i;

    if (ucs4) {
	for (i = 0; i < fontPtr->nfaces; i++) {
	    FcCharSet *charset = fontPtr->faces[i].charset;
	    if (charset && FcCharSetHasChar(charset, ucs4)) {
		break;
	    }
	}
	if (i == fontPtr->nfaces) {
	    i = 0;
	}
    } else {
	i = 0;
    }
    if (!fontPtr->faces[i].ftFont) {
	FcPattern *pat = FcFontRenderPrepare(0, fontPtr->pattern,
		fontPtr->faces[i].source);

	fontPtr->faces[i].ftFont = XftFontOpenPattern(fontPtr->display, pat);
    }
    return fontPtr->faces[i].ftFont;
}
示例#2
0
//=========================================
// setText
//-----------------------------------------
XImage* setText (Display* dpy,int screen,char* text, int* x, int* y) {
	Window root = RootWindow    ( dpy,screen );
	int DWidth  = DisplayWidth  ( dpy,screen );
	int DHeight = DisplayHeight ( dpy,screen );

	XftPattern *pattern = NULL;
	XftFont*  FTfont    = NULL;
	XftDraw*  FTdraw    = NULL;
	XftColor* FTcolor   = NULL;
	XImage*   Image     = NULL;

	XGlyphInfo FTinfo;
	XColor color;
	XGCValues values;
	int XTwidth;
	int XTheight;
	int x1,y1;

	pattern = XftNameParse (XFTFONT);
	pattern = XftFontMatch (dpy,screen,pattern,NULL);
	FTfont  = XftFontOpenPattern (dpy, pattern);
	XftTextExtentsUtf8 (
		dpy,FTfont,text,strlen(text),&FTinfo
	);
	XTwidth = FTinfo.xOff;
	XTheight= FTfont->height + 20;
	FTdraw  = XftDrawCreate (
		dpy, root, DefaultVisual(dpy,screen),DefaultColormap(dpy,screen)
	);
	FTcolor = (XftColor*)malloc(sizeof(XftColor));
	color.red   = 255 << 8;
	color.green = 255 << 8;
	color.blue  = 255 << 8;
	XAllocColor (dpy,DefaultColormap(dpy,screen),&color);
	XSetForeground(dpy,DefaultGC (dpy,screen),color.pixel);
	XGetGCValues (
		dpy, DefaultGC (dpy,screen),
		GCForeground | GCBackground, &values
	);
	FTcolor->color.red   = color.red;
	FTcolor->color.green = color.green;
	FTcolor->color.blue  = color.blue;
	FTcolor->color.alpha = 0xffff;

	x1 = (int)((DWidth  / 2) - (XTwidth  / 2));
	y1 = (int)((DHeight / 2) - (XTheight / 2));

	XftDrawStringUtf8 (
		FTdraw, FTcolor,FTfont,x1,y1,text,strlen(text)
	);
	XFlush (dpy);
	y1 = (int)((DHeight / 2) - XTheight);
	Image = XGetImage(
		dpy,root,x1,y1,XTwidth,XTheight,AllPlanes,XYPixmap
	);
	*x = x1;
	*y = y1;
	return (Image);
}
示例#3
0
文件: drw.c 项目: Dean4Devil/dwm
/* This function is an implementation detail. Library users should use
 * drw_font_create instead.
 */
static Fnt * drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern)
{
	Fnt *font;

	if (!(fontname || fontpattern))
		die("No font specified.\n");

	if (!(font = (Fnt *)calloc(1, sizeof(Fnt))))
		return NULL;

	if (fontname)
	{
		/* Using the pattern found at font->xfont->pattern does not yield same
		 * the same substitution results as using the pattern returned by
		 * FcNameParse; using the latter results in the desired fallback
		 * behaviour whereas the former just results in
		 * missing-character-rectangles being drawn, at least with some fonts.
		 */
		if (!(font->xfont = XftFontOpenName(drw->dpy, drw->screen, fontname)) ||
		    !(font->pattern = FcNameParse((FcChar8 *) fontname)))
		{
			if (font->xfont)
			{
				XftFontClose(drw->dpy, font->xfont);
				font->xfont = NULL;
			}
			fprintf(stderr, "error, cannot load font: '%s'\n", fontname);
		}
	}
	else if (fontpattern)
	{
		if (!(font->xfont = XftFontOpenPattern(drw->dpy, fontpattern)))
		{
			fprintf(stderr, "error, cannot load font pattern.\n");
		} else {
			font->pattern = NULL;
		}
	}

	if (!font->xfont)
	{
		free(font);
		return NULL;
	}

	font->ascent = font->xfont->ascent;
	font->descent = font->xfont->descent;
	font->h = font->ascent + font->descent;
	font->dpy = drw->dpy;
	return font;
}
示例#4
0
static XftFont *
GetFont(
    UnixFtFont *fontPtr,
    FcChar32 ucs4)
{
    int i;

    if (ucs4) {
	for (i = 0; i < fontPtr->nfaces; i++) {
	    FcCharSet *charset = fontPtr->faces[i].charset;
	    if (charset && FcCharSetHasChar(charset, ucs4)) {
		break;
	    }
	}
	if (i == fontPtr->nfaces) {
	    i = 0;
	}
    } else {
	i = 0;
    }
    if (!fontPtr->faces[i].ftFont) {
	FcPattern *pat = FcFontRenderPrepare(0,
	    fontPtr->pattern, fontPtr->faces[i].source);
	XftFont *ftFont = XftFontOpenPattern(fontPtr->display, pat);

	if (!ftFont) {
	    /*
	     * The previous call to XftFontOpenPattern() should not fail,
	     * but sometimes does anyway.  Usual cause appears to be
	     * a misconfigured fontconfig installation; see [Bug 1090382].
	     * Try a fallback:
	     */
	    ftFont = XftFontOpen(fontPtr->display, fontPtr->screen,
			FC_FAMILY, FcTypeString, "sans",
			FC_SIZE, FcTypeDouble, 12.0,
			NULL);
	}
	if (!ftFont) {
	    /*
	     * The previous call should definitely not fail.
	     * Impossible to proceed at this point.
	     */
	    Tcl_Panic("Cannot find a usable font.");
	}

	fontPtr->faces[i].ftFont = ftFont;
    }
    return fontPtr->faces[i].ftFont;
}
static XftFont* open_pattern(FcPattern* pattern, Antialiasing antialiasing, Hinting hinting)
{
	#ifdef FC_HINT_STYLE
		static const int hintstyles[] = {
			FC_HINT_NONE, FC_HINT_SLIGHT, FC_HINT_MEDIUM, FC_HINT_FULL
		};
	#endif /* FC_HINT_STYLE */

	FcPattern* res_pattern;
	FcResult result;
	XftFont* font;

	Display* xdisplay = gdk_x11_get_default_xdisplay();
	int screen = gdk_x11_get_default_screen();

	res_pattern = XftFontMatch(xdisplay, screen, pattern, &result);
	
	if (res_pattern == NULL)
	{
		return NULL;
	}

	FcPatternDel(res_pattern, FC_HINTING);
	FcPatternAddBool(res_pattern, FC_HINTING, hinting != HINT_NONE);

	#ifdef FC_HINT_STYLE
		FcPatternDel(res_pattern, FC_HINT_STYLE);
		FcPatternAddInteger(res_pattern, FC_HINT_STYLE, hintstyles[hinting]);
	#endif /* FC_HINT_STYLE */

	FcPatternDel(res_pattern, FC_ANTIALIAS);
	FcPatternAddBool(res_pattern, FC_ANTIALIAS, antialiasing != ANTIALIAS_NONE);

	FcPatternDel(res_pattern, FC_RGBA);
	FcPatternAddInteger(res_pattern, FC_RGBA, antialiasing == ANTIALIAS_RGBA ? FC_RGBA_RGB : FC_RGBA_NONE);

	FcPatternDel(res_pattern, FC_DPI);
	FcPatternAddInteger(res_pattern, FC_DPI, 96);

	font = XftFontOpenPattern(xdisplay, res_pattern);
	
	if (!font)
	{
		FcPatternDestroy(res_pattern);
	}

	return font;
}
示例#6
0
//=========================================
// XFontSetup
//-----------------------------------------
XTFont XFontSetup (XInit xi,char *text) {
	// ...
	// Open the defined XFTFONT and calculate the
	// pixel width and height needed for text with the
	// given font
	// ---
	XftPattern *pattern;
	XGlyphInfo FTinfo;
	XTFont xt;

	pattern = XftNameParse (XFTFONT);
	pattern = XftFontMatch (xi.dpy,xi.DScreen,pattern,NULL);
	xt.FTfont = XftFontOpenPattern (xi.dpy, pattern);
	XftTextExtentsUtf8 (
		xi.dpy,xt.FTfont,text,strlen(text),&FTinfo
	);
	xt.XTheight = xt.FTfont->height;
	xt.XTwidth  = FTinfo.xOff;
	return(xt);
}
示例#7
0
static inline XftFont *
get_font(Display *xdisplay, FT_Face face, gint size, FcCharSet *charset)
{
    FcPattern *pattern;
    XftFont *font;
    int screen = DefaultScreen (xdisplay);

    pattern = FcPatternBuild(NULL,
			     FC_FT_FACE, FcTypeFTFace, face,
			     FC_PIXEL_SIZE, FcTypeDouble, (double)size,
			     NULL);

    if (charset)
	FcPatternAddCharSet (pattern, "charset", charset);

    FcConfigSubstitute (NULL, pattern, FcMatchPattern);
    XftDefaultSubstitute (xdisplay, screen, pattern);

    font = XftFontOpenPattern(xdisplay, pattern);

    return font;
}
示例#8
0
文件: main.c 项目: notadecent/uTox
static XftFont* getfont(XftFont **font, uint32_t ch)
{
    XftFont *first = font[0];
    if(!FcCharSetHasChar(charset, ch)) {
        return first;
    }

    while(*font) {
        if(XftGlyphExists(display, *font, ch)) {
            return *font;
        }
        font++;
    }

    FcResult result;
    int i;
    for(i = 0; i != fs->nfont; i++) {
        FcCharSet *cs;
        result = FcPatternGetCharSet(fs->fonts[i], FC_CHARSET, 0, &cs);
        if(FcCharSetHasChar(cs, ch)) {
            FcPattern *p = FcPatternDuplicate(fs->fonts[i]), *pp;

            double size;
            if(!FcPatternGetDouble(first->pattern, FC_PIXEL_SIZE, 0, &size)) {
                FcPatternAddDouble(p, FC_PIXEL_SIZE, size);
            }

            pp = XftFontMatch(display, screen, p, &result);
            *font = XftFontOpenPattern(display, pp);
            FcPatternDestroy(p);
            return *font;
        }
    }

    //should never happen
    return first;
}
示例#9
0
文件: nenu.c 项目: mytchel/nenu
void load_font(FcChar8 *font_str) {
	FcPattern *pattern, *match;
	FcResult result;

	if (font_str[0] == '-') 
		pattern = XftXlfdParse(font_str, False, False);
	else
		pattern = FcNameParse((FcChar8 *) font_str);

	if (!pattern)
		die("Failed to get font pattern");

	match = FcFontMatch(NULL, pattern, &result);
	if (!match)
		die("Failed to get font match");

	if (!(font = XftFontOpenPattern(display, match))) {
		FcPatternDestroy(match);
		die("Failed to open font");
	}

	ascent = font->ascent;
	descent = font->descent;
}
示例#10
0
static Lisp_Object
xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
{
  FcResult result;
  Display *display = FRAME_X_DISPLAY (f);
  Lisp_Object val, filename, idx, font_object;
  FcPattern *pat = NULL, *match;
  struct xftfont_info *xftfont_info = NULL;
  struct font *font;
  double size = 0;
  XftFont *xftfont = NULL;
  int spacing;
  char name[256];
  int len, i;
  XGlyphInfo extents;
  FT_Face ft_face;
  FcMatrix *matrix;

  val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
  if (! CONSP (val))
    return Qnil;
  val = XCDR (val);
  filename = XCAR (val);
  idx = XCDR (val);
  size = XINT (AREF (entity, FONT_SIZE_INDEX));
  if (size == 0)
    size = pixel_size;
  pat = FcPatternCreate ();
  FcPatternAddInteger (pat, FC_WEIGHT, FONT_WEIGHT_NUMERIC (entity));
  i = FONT_SLANT_NUMERIC (entity) - 100;
  if (i < 0) i = 0;
  FcPatternAddInteger (pat, FC_SLANT, i);
  FcPatternAddInteger (pat, FC_WIDTH, FONT_WIDTH_NUMERIC (entity));
  FcPatternAddDouble (pat, FC_PIXEL_SIZE, pixel_size);
  val = AREF (entity, FONT_FAMILY_INDEX);
  if (! NILP (val))
    FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) SDATA (SYMBOL_NAME (val)));
  val = AREF (entity, FONT_FOUNDRY_INDEX);
  if (! NILP (val))
    FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) SDATA (SYMBOL_NAME (val)));
  val = AREF (entity, FONT_SPACING_INDEX);
  if (! NILP (val))
    FcPatternAddInteger (pat, FC_SPACING, XINT (val));
  val = AREF (entity, FONT_DPI_INDEX);
  if (! NILP (val))
    {
      double dbl = XINT (val);

      FcPatternAddDouble (pat, FC_DPI, dbl);
    }
  val = AREF (entity, FONT_AVGWIDTH_INDEX);
  if (INTEGERP (val) && XINT (val) == 0)
    FcPatternAddBool (pat, FC_SCALABLE, FcTrue);
  /* This is necessary to identify the exact font (e.g. 10x20.pcf.gz
     over 10x20-ISO8859-1.pcf.gz).  */
  FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity));

  xftfont_add_rendering_parameters (pat, entity);

  FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename));
  FcPatternAddInteger (pat, FC_INDEX, XINT (idx));


  block_input ();
  /* Make sure that the Xrender extension is added before the Xft one.
     Otherwise, the close-display hook set by Xft is called after the
     one for Xrender, and the former tries to re-add the latter.  This
     results in inconsistency of internal states and leads to X
     protocol error when one reconnects to the same X server.
     (Bug#1696)  */
  {
    int event_base, error_base;
    XRenderQueryExtension (display, &event_base, &error_base);
  }

  /* Substitute in values from X resources and XftDefaultSet.  */
  XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat);
  match = XftFontMatch (display, FRAME_X_SCREEN_NUMBER (f), pat, &result);
  xftfont_fix_match (pat, match);

  FcPatternDestroy (pat);
  xftfont = XftFontOpenPattern (display, match);
  if (!xftfont)
    {
      unblock_input ();
      XftPatternDestroy (match);
      return Qnil;
    }
  ft_face = XftLockFace (xftfont);
  unblock_input ();

  /* We should not destroy PAT here because it is kept in XFTFONT and
     destroyed automatically when XFTFONT is closed.  */
  font_object = font_make_object (VECSIZE (struct xftfont_info), entity, size);
  ASET (font_object, FONT_TYPE_INDEX, Qxft);
  len = font_unparse_xlfd (entity, size, name, 256);
  if (len > 0)
    ASET (font_object, FONT_NAME_INDEX, make_string (name, len));
  len = font_unparse_fcname (entity, size, name, 256);
  if (len > 0)
    ASET (font_object, FONT_FULLNAME_INDEX, make_string (name, len));
  else
    ASET (font_object, FONT_FULLNAME_INDEX,
	  AREF (font_object, FONT_NAME_INDEX));
  ASET (font_object, FONT_FILE_INDEX, filename);
  ASET (font_object, FONT_FORMAT_INDEX,
	ftfont_font_format (xftfont->pattern, filename));
  font = XFONT_OBJECT (font_object);
  font->pixel_size = size;
  font->driver = &xftfont_driver;
  font->encoding_charset = font->repertory_charset = -1;

  xftfont_info = (struct xftfont_info *) font;
  xftfont_info->display = display;
  xftfont_info->xftfont = xftfont;
  /* This means that there's no need of transformation.  */
  xftfont_info->matrix.xx = 0;
  if (FcPatternGetMatrix (xftfont->pattern, FC_MATRIX, 0, &matrix)
      == FcResultMatch)
    {
      xftfont_info->matrix.xx = 0x10000L * matrix->xx;
      xftfont_info->matrix.yy = 0x10000L * matrix->yy;
      xftfont_info->matrix.xy = 0x10000L * matrix->xy;
      xftfont_info->matrix.yx = 0x10000L * matrix->yx;
    }
  if (INTEGERP (AREF (entity, FONT_SPACING_INDEX)))
    spacing = XINT (AREF (entity, FONT_SPACING_INDEX));
  else
    spacing = FC_PROPORTIONAL;
  if (! ascii_printable[0])
    {
      int ch;
      for (ch = 0; ch < 95; ch++)
	ascii_printable[ch] = ' ' + ch;
    }
  block_input ();

  /* Unfortunately Xft doesn't provide a way to get minimum char
     width.  So, we set min_width to space_width.  */

  if (spacing != FC_PROPORTIONAL
#ifdef FC_DUAL
      && spacing != FC_DUAL
#endif	/* FC_DUAL */
      )
    {
      font->min_width = font->max_width = font->average_width
	= font->space_width = xftfont->max_advance_width;
      XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents);
    }
  else
    {
      XftTextExtents8 (display, xftfont, ascii_printable, 1, &extents);
      font->min_width = font->max_width = font->space_width
	= extents.xOff;
      if (font->space_width <= 0)
	/* dirty workaround */
	font->space_width = pixel_size;
      XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents);
      font->average_width = (font->space_width + extents.xOff) / 95;
    }
  unblock_input ();

  font->ascent = xftfont->ascent;
  font->descent = xftfont->descent;
  if (pixel_size >= 5)
    {
      /* The above condition is a dirty workaround because
	 XftTextExtents8 behaves strangely for some fonts
	 (e.g. "Dejavu Sans Mono") when pixel_size is less than 5. */
      if (font->ascent < extents.y)
	font->ascent = extents.y;
      if (font->descent < extents.height - extents.y)
	font->descent = extents.height - extents.y;
    }
  font->height = font->ascent + font->descent;

  if (XINT (AREF (entity, FONT_SIZE_INDEX)) == 0)
    {
      int upEM = ft_face->units_per_EM;

      font->underline_position = -ft_face->underline_position * size / upEM;
      font->underline_thickness = ft_face->underline_thickness * size / upEM;
      if (font->underline_thickness > 2)
	font->underline_position -= font->underline_thickness / 2;
    }
  else
    {
      font->underline_position = -1;
      font->underline_thickness = 0;
    }
#ifdef HAVE_LIBOTF
  xftfont_info->maybe_otf = (ft_face->face_flags & FT_FACE_FLAG_SFNT) != 0;
  xftfont_info->otf = NULL;
#endif	/* HAVE_LIBOTF */
  xftfont_info->ft_size = ft_face->size;

  font->baseline_offset = 0;
  font->relative_compose = 0;
  font->default_ascent = 0;
  font->vertical_centering = 0;
#ifdef FT_BDF_H
  if (! (ft_face->face_flags & FT_FACE_FLAG_SFNT))
    {
      BDF_PropertyRec rec;

      if (FT_Get_BDF_Property (ft_face, "_MULE_BASELINE_OFFSET", &rec) == 0
	  && rec.type == BDF_PROPERTY_TYPE_INTEGER)
	font->baseline_offset = rec.u.integer;
      if (FT_Get_BDF_Property (ft_face, "_MULE_RELATIVE_COMPOSE", &rec) == 0
	  && rec.type == BDF_PROPERTY_TYPE_INTEGER)
	font->relative_compose = rec.u.integer;
      if (FT_Get_BDF_Property (ft_face, "_MULE_DEFAULT_ASCENT", &rec) == 0
	  && rec.type == BDF_PROPERTY_TYPE_INTEGER)
	font->default_ascent = rec.u.integer;
    }
#endif

  return font_object;
}
示例#11
0
TGlyphInfo *glyph_cache_get_info(TGlyphCache *cache, gunichar glyph) {
	TGlyphInfo *gfi;
	XftFont *xftfont;
	PangoFont *font;
	PangoGlyph pglyph;
	PangoRectangle ink, logical;
	gint ascent, descent;
	gint x_offset;
	gint nominal_width;
	double scale_y, scale_x;

	if (!cache->hash)
		return NULL;

	gfi = g_hash_table_lookup(cache->hash, GINT_TO_POINTER(glyph));
	if (gfi)
		return gfi;

	font = pango_fontset_get_font(cache->font_set, glyph);

	pglyph = pango_fc_font_get_glyph(PANGO_FC_FONT(font), glyph);
	if (!pglyph) {
		fprintf (stderr, "Error: Unable to find glyph %d.\n", glyph);
		if (!pglyph)
			pglyph = pango_fc_font_get_glyph(PANGO_FC_FONT(font), glyph);
		if (!pglyph)
			pglyph = PANGO_GET_UNKNOWN_GLYPH (glyph);
		if (!pglyph)
			return NULL;
	}
	pango_font_get_glyph_extents(font, pglyph, &ink, &logical);

	ascent = PANGO_ASCENT(logical);
	descent = PANGO_DESCENT(logical);

	xftfont = pango_xft_font_get_font(font);

	x_offset = 0;

	nominal_width = cache->width;
	if (g_unichar_iswide(glyph))
		nominal_width *= 2;

	scale_x = scale_y = 1.0;

	if (logical.width > nominal_width) {
		if (logical.width)
			scale_x = (double)nominal_width / (double)logical.width;
		else
			scale_x = 1.0;
	}

	if (logical.height != cache->height) {
		double scale;

		if (ascent) {
			scale_y = (double)cache->ascent / (double)ascent;
		} else {
			scale_y = 1.0;
		}
		if (descent) {
			scale = (double)cache->descent / (double)descent;
			if (scale < scale_y)
				scale_y = scale;
		}
	}

	if (scale_x >= 1.0) {
		scale_x = 1.0;
		x_offset += (nominal_width - logical.width) / 2;
	}

	if (scale_x < 1.0 || scale_y != 1.0) {
		FcBool scalable;

		FcPatternGetBool(xftfont->pattern, FC_SCALABLE, 0, &scalable);
		if (!scalable) {
			/* Bah. Need better handling of non-scalable fonts */
			if (scale_x < 1.0) scale_x = 1.0;
			scale_y = 1.0;
		} else if (scale_x < 1.0 || scale_y != 1.0) {
			FcPattern *pattern;
			FcMatrix mat;

			pattern = FcPatternDuplicate(xftfont->pattern);

			FcMatrixInit (&mat);

			FcMatrixScale(&mat, scale_x, scale_y);

			FcPatternDel (pattern, FC_MATRIX);
			FcPatternAddMatrix(pattern, FC_MATRIX, &mat);

			xftfont = XftFontOpenPattern(
				GDK_DISPLAY_XDISPLAY(cache->display),
				pattern
			);
		}

		ascent = ascent * scale_y;
	}

	g_object_unref(font);

//	gfi = calloc(sizeof(TGlyphInfo), 1);
	gfi = g_slice_new(TGlyphInfo);
	gfi->font = xftfont;

	gfi->x_offset = PANGO_PIXELS(x_offset);

	gfi->y_offset = cache->ascent + (cache->ascent - ascent);
	gfi->y_offset = PANGO_PIXELS(gfi->y_offset);

	g_hash_table_insert(cache->hash, GINT_TO_POINTER(glyph), gfi);

	return gfi;
}
示例#12
0
static XftFont *gui_find_font(winlist_t *win, FcChar32 ucs4)
{
    unsigned int i;
    int weight, slant, scalable;
    double font_size;
    FcFontSet *fontset;
    XftFont *font = NULL;

    /* 缺字列表有這個字,那就不用再找啦 */
    if (FcCharSetHasChar(gui->missing_chars, ucs4))
    {
	return NULL;
    }

    /* 找出 Cache 相符的字型 */
    for (i=0 ; i < gui->num_fonts ; i++)
    {
	XftPatternGetDouble(gui->xftfonts[i]->pattern, XFT_PIXEL_SIZE, 0, &font_size);
	if ((int)font_size == win->font_size &&
	    FcCharSetHasChar(gui->xftfonts[i]->charset, ucs4))
	{
	    return gui->xftfonts[i];
	}
    }

    /* 列出所有可能的字型 */
    FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_CHARSET, NULL);
    /* 只要標準、非斜體、可縮放字型即可 */
    FcPattern *listpat = FcPatternBuild(NULL,
				FC_SLANT, FcTypeInteger, FC_SLANT_ROMAN,
				FC_SCALABLE, FcTypeBool, FcTrue,
				NULL);
    fontset = FcFontList(NULL, listpat, os);
    FcPatternDestroy(listpat);
    FcObjectSetDestroy(os);

    for (i=0; i< fontset->nfont; i++)
    {
	FcPattern *pat = fontset->fonts[i];
	FcCharSet *fcs = NULL;

	if (FcPatternGetCharSet(pat, FC_CHARSET, 0, &fcs) != FcResultMatch)
	    continue;

	if (!FcCharSetHasChar(fcs, ucs4))
	    continue;

	FcResult res;
	FcPattern *mpat = FcFontMatch(0, pat, &res);
	if (!mpat)
	    continue;

	XftPatternAddDouble(mpat, XFT_PIXEL_SIZE, (double)win->font_size);
	XftFont *chkfont = XftFontOpenPattern(gui->display, mpat);

        if (chkfont)
	{
	    gui->num_fonts ++;
	    gui->xftfonts = (XftFont **)oxim_realloc(gui->xftfonts, gui->num_fonts * sizeof(XftFont *));
	    if (!gui->xftfonts)
	    {
		FcPatternDestroy(mpat);
		continue;
	    }
	    gui->xftfonts[gui->num_fonts - 1] = chkfont;
	    font = chkfont;
	    break;
	}
	else
	{
	    FcPatternDestroy(mpat);
	}
    }

    FcFontSetDestroy(fontset);

    if (!font)
	FcCharSetAddChar(gui->missing_chars, ucs4);

    return font;
}
示例#13
0
static XftFont *
GetFont(
    UnixFtFont *fontPtr,
    FcChar32 ucs4,
    double angle)
{
    int i;

    if (ucs4) {
	for (i = 0; i < fontPtr->nfaces; i++) {
	    FcCharSet *charset = fontPtr->faces[i].charset;

	    if (charset && FcCharSetHasChar(charset, ucs4)) {
		break;
	    }
	}
	if (i == fontPtr->nfaces) {
	    i = 0;
	}
    } else {
	i = 0;
    }
    if ((angle == 0.0 && !fontPtr->faces[i].ft0Font) || (angle != 0.0 &&
	    (!fontPtr->faces[i].ftFont || fontPtr->faces[i].angle != angle))){
	FcPattern *pat = FcFontRenderPrepare(0, fontPtr->pattern,
		fontPtr->faces[i].source);
	double s = sin(angle*PI/180.0), c = cos(angle*PI/180.0);
	FcMatrix mat;
	XftFont *ftFont;

	/*
	 * Initialize the matrix manually so this can compile with HP-UX cc
	 * (which does not allow non-constant structure initializers). [Bug
	 * 2978410]
	 */

	mat.xx = mat.yy = c;
	mat.xy = -(mat.yx = s);

	if (angle != 0.0) {
	    FcPatternAddMatrix(pat, FC_MATRIX, &mat);
	}
	ftFont = XftFontOpenPattern(fontPtr->display, pat);
	if (!ftFont) {
	    /*
	     * The previous call to XftFontOpenPattern() should not fail, but
	     * sometimes does anyway. Usual cause appears to be a
	     * misconfigured fontconfig installation; see [Bug 1090382]. Try a
	     * fallback:
	     */

	    ftFont = XftFontOpen(fontPtr->display, fontPtr->screen,
		    FC_FAMILY, FcTypeString, "sans",
		    FC_SIZE, FcTypeDouble, 12.0,
		    FC_MATRIX, FcTypeMatrix, &mat,
		    NULL);
	}
	if (!ftFont) {
	    /*
	     * The previous call should definitely not fail. Impossible to
	     * proceed at this point.
	     */

	    Tcl_Panic("Cannot find a usable font");
	}

	if (angle == 0.0) {
	    fontPtr->faces[i].ft0Font = ftFont;
	} else {
	    if (fontPtr->faces[i].ftFont) {
		XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);
	    }
	    fontPtr->faces[i].ftFont = ftFont;
	    fontPtr->faces[i].angle = angle;
	}
    }
    return (angle==0.0? fontPtr->faces[i].ft0Font : fontPtr->faces[i].ftFont);
}
示例#14
0
文件: Menu.C 项目: bbidulock/wmx
Menu::Menu(WindowManager *manager, XEvent *e)
    : m_items(0), m_nItems(0), m_nHidden(0),
      m_hasSubmenus(False),
      m_windowManager(manager),
      m_event(e)
{
    if (!m_initialised)
    {
	XGCValues *values;
	XSetWindowAttributes *attr;

        m_menuGC = (GC *) malloc(m_windowManager->screensTotal() * sizeof(GC));
        m_window = (Window *) malloc(m_windowManager->screensTotal() *
				     sizeof(Window));
#ifdef CONFIG_USE_XFT
	char *fi = strdup(CONFIG_MENU_FONT);
	char *ffi = fi, *tokstr = fi;
	while ((fi = strtok(tokstr, ","))) {
		
	    fprintf(stderr, "fi = \"%s\"\n", fi);
	    tokstr = 0;
	    
	    FcPattern *pattern = FcPatternCreate();
	    FcPatternAddString(pattern, FC_FAMILY, (FcChar8 *)fi);
	    FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);

#ifndef FC_WEIGHT_REGULAR
#define FC_WEIGHT_REGULAR FC_WEIGHT_MEDIUM
#endif
	    FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR);
	    FcPatternAddInteger(pattern, FC_PIXEL_SIZE, CONFIG_MENU_FONT_SIZE);
	    FcConfigSubstitute(FcConfigGetCurrent(), pattern, FcMatchPattern);

	    FcResult result = FcResultMatch;
	    FcPattern *match = FcFontMatch(FcConfigGetCurrent(), pattern, &result);
	    FcPatternDestroy(pattern);

	    if (!match || result != FcResultMatch) {
		if (match) FcPatternDestroy(match);
		continue;
	    }

	    m_font = XftFontOpenPattern(display(), match);
	    if (m_font) break;
	    FcPatternDestroy(match);
	}
	free(ffi);
	if (!m_font) {
	    m_windowManager->fatal("couldn't load menu Xft font");
	}
	m_xftColour = (XftColor *) malloc(m_windowManager->screensTotal() *
					  sizeof(XftColor));
	m_xftDraw = (XftDraw **) malloc(m_windowManager->screensTotal() *
					sizeof(XftDraw *));
#else
	m_font = (XFontStruct **) malloc(m_windowManager->screensTotal() *
					 sizeof(XFontStruct *));
#endif
	values = (XGCValues *) malloc(m_windowManager->screensTotal() *
				      sizeof(XGCValues));
	attr = (XSetWindowAttributes *) malloc(m_windowManager->screensTotal() *
				      sizeof(XSetWindowAttributes));
	
        for (int i = 0; i < m_windowManager->screensTotal(); i++)
	{
	    m_foreground = m_windowManager->allocateColour
	      (i, CONFIG_MENU_FOREGROUND, "menu foreground");
	    m_background = m_windowManager->allocateColour
	      (i, CONFIG_MENU_BACKGROUND, "menu background");
	    m_border = m_windowManager->allocateColour
	      (i, CONFIG_MENU_BORDERS, "menu border");

#ifndef CONFIG_USE_XFT
	    char **ml;
	    int mc;
	    char *ds;
	    
	    m_fontset = XCreateFontSet(display(), CONFIG_NICE_MENU_FONT,
				       &ml, &mc, &ds);
	    if (!m_fontset)
	      m_fontset = XCreateFontSet(display(), CONFIG_NASTY_FONT,
					 &ml, &mc, &ds);
	    if (m_fontset) {
		XFontStruct **fs_list;
		XFontsOfFontSet(m_fontset, &fs_list, &ml);
		m_font[i] = fs_list[0];
	    } else {
		m_font[i] = NULL;
	    }
#define XDrawString(t,u,v,w,x,y,z) XmbDrawString(t,u,m_fontset,v,w,x,y,z)
	    if (!m_font[i]) m_windowManager->fatal("couldn't load menu font\n");
#endif
	    
	    values[i].background = m_background;
	    values[i].foreground = m_foreground ^ m_background;
	    values[i].function = GXxor;
	    values[i].line_width = 0;
	    values[i].subwindow_mode = IncludeInferiors;
#ifndef CONFIG_USE_XFT
	    values[i].font = m_font[i]->fid;
#endif
	    m_menuGC[i] = XCreateGC
	      (display(), m_windowManager->mroot(i),
	       GCForeground | GCBackground | GCFunction |
	       GCLineWidth | GCSubwindowMode, &values[i]);

#ifndef CONFIG_USE_XFT
	    XChangeGC(display(), Border::drawGC(m_windowManager, i),
		      GCFont, &values[i]);
#endif

	    m_window[i] = XCreateSimpleWindow
	      (display(), m_windowManager->mroot(i), 0, 0, 1, 1, 1,
	       m_border, m_background);

	    
#if ( CONFIG_USE_PIXMAPS != False ) && ( CONFIG_USE_PIXMAP_MENUS != False )
	    attr[i].background_pixmap = Border::backgroundPixmap(manager);
#endif
	    attr[i].save_under =
	      (DoesSaveUnders(ScreenOfDisplay(display(), i)) ?
	     True : False);

#if ( CONFIG_USE_PIXMAPS != False ) && ( CONFIG_USE_PIXMAP_MENUS != False )
	    XChangeWindowAttributes
	      (display(), m_window[i], CWBackPixmap, &attr[i]);
#endif
	    XChangeWindowAttributes
	      (display(), m_window[i], CWSaveUnder, &attr[i]);

#ifdef CONFIG_USE_XFT
	    XftColorAllocName
		(display(),
		 XDefaultVisual(display(), i),
		 XDefaultColormap(display(), i),
		 CONFIG_MENU_FOREGROUND,
		 &m_xftColour[i]);

	    m_xftDraw[i] = XftDrawCreate(display(), m_window[i],
					 XDefaultVisual(display(), i),
					 XDefaultColormap(display(), i));
#endif
	}
	m_initialised = True;
    }
}