Ejemplo n.º 1
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);
}
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;
}
Ejemplo n.º 3
0
status
ws_create_font(FontObj f, DisplayObj d)
{ XpceFontInfo xref;
  DisplayWsXref r = d->ws_ref;
  XftFont *xft = NULL;

  if ( !instanceOfObject(f->x_name, ClassCharArray) ||
       !isstrA(&f->x_name->data) )			/* HACK */
  { XftPattern *p = XftPatternCreate();
    XftPattern *match;
    FcResult fcrc;
    int i;
    char *fam;
    int mono = FALSE;
    Real  scale  = getClassVariableValueObject(f, NAME_scale);
    double fscale = (scale ? valReal(scale) : 1.0);

    if ( f->family == NAME_screen )
    { fam = "monospace";
      mono = TRUE;
    } else
      fam = strName(f->family);

    XftPatternAddString(p, XFT_FAMILY, fam);
    XftPatternAddDouble(p, XFT_PIXEL_SIZE, (double)valInt(f->points)*fscale);
    if ( f->style == NAME_italic )
      XftPatternAddInteger(p, XFT_SLANT, XFT_SLANT_ITALIC);
    else if ( f->style == NAME_roman )
      XftPatternAddInteger(p, XFT_SLANT, XFT_SLANT_ROMAN);
    else if ( f->style == NAME_bold )
      XftPatternAddInteger(p, XFT_WEIGHT, XFT_WEIGHT_BOLD);

    if ( mono )
    { DEBUG(NAME_font, Cprintf("Asking for fixed\n"));
      XftPatternAddInteger(p, XFT_SPACING, XFT_MONO);
    }

    if ( !(match = XftFontMatch(r->display_xref, r->screen, p, &fcrc)) )
    { DEBUG(NAME_font, Cprintf("XftFontMatch() failed. Calling replaceFont()\n"));
      return replaceFont(f, d);
    }

#ifdef HAVE_XFTNAMEUNPARSE
    DEBUG(NAME_font,
	  { char buf[1024];
	    XftNameUnparse(match, buf, sizeof(buf));
	    Cprintf("Match = '%s'\n", buf);
	  });
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
Archivo: drw.c Proyecto: ffflorian/dwm
int
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text)
{
	char buf[1024];
	int tx, ty, th;
	Extnts tex;
	XftDraw *d = NULL;
	Fnt *curfont, *nextfont;
	size_t i, len;
	int utf8strlen, utf8charlen, render;
	long utf8codepoint = 0;
	const char *utf8str;
	FcCharSet *fccharset;
	FcPattern *fcpattern;
	FcPattern *match;
	XftResult result;
	int charexists = 0;

	if (!drw->scheme || !drw->fontcount)
		return 0;

	if (!(render = x || y || w || h)) {
		w = ~w;
	} else {
		XSetForeground(drw->dpy, drw->gc, drw->scheme->bg->pix);
		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
		d = XftDrawCreate(drw->dpy, drw->drawable,
		                  DefaultVisual(drw->dpy, drw->screen),
		                  DefaultColormap(drw->dpy, drw->screen));
	}

	curfont = drw->fonts[0];
	while (1) {
		utf8strlen = 0;
		utf8str = text;
		nextfont = NULL;
		while (*text) {
			utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
			for (i = 0; i < drw->fontcount; i++) {
				charexists = charexists || XftCharExists(drw->dpy, drw->fonts[i]->xfont, utf8codepoint);
				if (charexists) {
					if (drw->fonts[i] == curfont) {
						utf8strlen += utf8charlen;
						text += utf8charlen;
					} else {
						nextfont = drw->fonts[i];
					}
					break;
				}
			}

			if (!charexists || (nextfont && nextfont != curfont))
				break;
			else
				charexists = 0;
		}

		if (utf8strlen) {
			drw_font_getexts(curfont, utf8str, utf8strlen, &tex);
			/* shorten text if necessary */
			for (len = MIN(utf8strlen, (sizeof buf) - 1); len && (tex.w > w - drw->fonts[0]->h || w < drw->fonts[0]->h); len--)
				drw_font_getexts(curfont, utf8str, len, &tex);

			if (len) {
				memcpy(buf, utf8str, len);
				buf[len] = '\0';
				if (len < utf8strlen)
					for (i = len; i && i > len - 3; buf[--i] = '.');

				if (render) {
					th = curfont->ascent + curfont->descent;
					ty = y + (h / 2) - (th / 2) + curfont->ascent;
					tx = x + (h / 2);
					XftDrawStringUtf8(d, &drw->scheme->fg->rgb, curfont->xfont, tx, ty, (XftChar8 *)buf, len);
				}
				x += tex.w;
				w -= tex.w;
			}
		}

		if (!*text) {
			break;
		} else if (nextfont) {
			charexists = 0;
			curfont = nextfont;
		} else {
			/* Regardless of whether or not a fallback font is found, the
			 * character must be drawn.
			 */
			charexists = 1;

			if (drw->fontcount >= DRW_FONT_CACHE_SIZE)
				continue;

			fccharset = FcCharSetCreate();
			FcCharSetAddChar(fccharset, utf8codepoint);

			if (!drw->fonts[0]->pattern) {
				/* Refer to the comment in drw_font_xcreate for more
				 * information. */
				die("the first font in the cache must be loaded from a font string.\n");
			}

			fcpattern = FcPatternDuplicate(drw->fonts[0]->pattern);
			FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
			FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);

			FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
			FcDefaultSubstitute(fcpattern);
			match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);

			FcCharSetDestroy(fccharset);
			FcPatternDestroy(fcpattern);

			if (match) {
				curfont = drw_font_xcreate(drw, NULL, match);
				if (curfont && XftCharExists(drw->dpy, curfont->xfont, utf8codepoint)) {
					drw->fonts[drw->fontcount++] = curfont;
				} else {
					drw_font_free(curfont);
					curfont = drw->fonts[0];
				}
			}
		}
	}
	if (d)
		XftDrawDestroy(d);

	return x;
}