Beispiel #1
0
static void
GetTkFontAttributes(
    XftFont *ftFont,
    TkFontAttributes *faPtr)
{
    const char *family = "Unknown";
    const char *const *familyPtr = &family;
    int weight, slant, size, pxsize;
    double ptsize;

    (void) XftPatternGetString(ftFont->pattern, XFT_FAMILY, 0, familyPtr);
    if (XftPatternGetDouble(ftFont->pattern, XFT_SIZE, 0,
	    &ptsize) == XftResultMatch) {
	size = (int) ptsize;
    } else if (XftPatternGetInteger(ftFont->pattern, XFT_PIXEL_SIZE, 0,
	    &pxsize) == XftResultMatch) {
	size = -pxsize;
    } else {
	size = 12;
    }
    if (XftPatternGetInteger(ftFont->pattern, XFT_WEIGHT, 0,
	    &weight) != XftResultMatch) {
	weight = XFT_WEIGHT_MEDIUM;
    }
    if (XftPatternGetInteger(ftFont->pattern, XFT_SLANT, 0,
	    &slant) != XftResultMatch) {
	slant = XFT_SLANT_ROMAN;
    }

#if DEBUG_FONTSEL
    printf("family %s size %d weight %d slant %d\n",
	    family, size, weight, slant);
#endif /* DEBUG_FONTSEL */

    faPtr->family = Tk_GetUid(family);
    faPtr->size = size;
    faPtr->weight = (weight > XFT_WEIGHT_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
    faPtr->slant = (slant > XFT_SLANT_ROMAN) ? TK_FS_ITALIC : TK_FS_ROMAN;
    faPtr->underline = 0;
    faPtr->overstrike = 0;
}
JBoolean
JXFontManager::GetFontSizes
	(
	const JCharacter*	name,
	JSize*				minSize,
	JSize*				maxSize,
	JArray<JSize>*		sizeList
	)
	const
{
	*minSize = *maxSize = 0;
	sizeList->RemoveAll();
	sizeList->SetCompareFunction(JCompareSizes);
	sizeList->SetSortOrder(JOrderedSetT::kSortAscending);

#ifdef _J_USE_XFT
	XftFontSet* fs = XftListFonts(*itsDisplay, DefaultScreen((Display*)*itsDisplay), XFT_FAMILY, XftTypeString, name, 0, XFT_SIZE, 0);

	if (fs->nfont == 0)
	{
		*minSize = 8;
		*maxSize = 24;
		XftFontSetDestroy(fs);		
		return kJTrue;
	}

	for (int i=0; i<fs->nfont; i++)
	{
		double raw_size;
		if (XftPatternGetDouble(fs->fonts[i], XFT_SIZE, 0, &raw_size) == XftResultMatch)
		{
			JSize fontSize = static_cast<JSize>(raw_size);
			if (sizeList->IsEmpty())
			{
				*minSize = *maxSize = fontSize;
			}

			JBoolean isDuplicate;
			const JIndex index =
				sizeList->GetInsertionSortIndex(fontSize, &isDuplicate);
			if (!isDuplicate)
			{
				sizeList->InsertElementAtIndex(index, fontSize);

				if (fontSize < *minSize)
				{
					*minSize = fontSize;
				}
				else if (fontSize > *maxSize)
				{
					*maxSize = fontSize;
				}
			}
		}
	}
	
	// Look for scalable
	if ((*minSize == 0) && (*maxSize == 0))
	{
		*minSize = 8;
		*maxSize = 24;
		XftFontSetDestroy(fs);		
		return kJTrue;
	}
	
	XftFontSetDestroy(fs);		
#else
	JString xFontName, charSet;
	if (!ConvertToXFontName(name, &xFontName, &charSet))
		{
		charSet = "*-*";
		}

	// check for rescalable font

	JString regexStr = "-*-" + xFontName + "-*-*-*-*-*-0-75-75-*-*-" + charSet;

	int nameCount;
	char** nameList = XListFonts(*itsDisplay, regexStr, INT_MAX, &nameCount);
	if (nameList != NULL)
		{
		*minSize = 8;
		*maxSize = 24;
		XFreeFontNames(nameList);
		return kJTrue;
		}

	// get list of available sizes

	regexStr = "-*-" + xFontName + "-*-*-*-*-*-*-75-75-*-*-" + charSet;

	nameList = XListFonts(*itsDisplay, regexStr, INT_MAX, &nameCount);
	if (nameList == NULL)
		{
		return kJFalse;
		}

	JSize fontSize;
	for (int i=0; i<nameCount; i++)
		{
		const std::string s(nameList[i], strlen(nameList[i]));
		std::istringstream input(s);
		input.ignore();							// initial dash
		JIgnoreUntil(input, '-');				// foundry name
		JIgnoreUntil(input, '-');				// font name
		JIgnoreUntil(input, '-');				// medium/bold
		JIgnoreUntil(input, '-');				// roman/oblique/italic
		JIgnoreUntil(input, '-');				// character spacing
		input.ignore();							// extra dash
		JIgnoreUntil(input, '-');				// pixel height
		input >> fontSize;						// 10*(point size)

		if (fontSize < 10)
			{
			continue;		// we already checked for rescalable version
			}

		fontSize /= 10;
		if (sizeList->IsEmpty())
			{
			*minSize = *maxSize = fontSize;
			}

		JBoolean isDuplicate;
		const JIndex index =
			sizeList->GetInsertionSortIndex(fontSize, &isDuplicate);
		if (!isDuplicate)
			{
			sizeList->InsertElementAtIndex(index, fontSize);

			if (fontSize < *minSize)
				{
				*minSize = fontSize;
				}
			else if (fontSize > *maxSize)
				{
				*maxSize = fontSize;
				}
			}
		}

	XFreeFontNames(nameList);
#endif

	return JNegate( sizeList->IsEmpty() );
}
Beispiel #3
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;
}
Beispiel #4
0
XFontStruct*
XftCoreOpen (Display *dpy, XftPattern *pattern)
{
    XftCoreFont	*cf;
    char	*xlfd;
    char	*xlfd_pixel = 0;
    char	*i, *o;
    int		d;
    Bool	scalable;
    double	pixel_size;
    int		pixel_int;
    XFontStruct	*ret;

#if 0
    printf ("Core ");
    XftPatternPrint (pattern);
#endif
    if (XftPatternGetString (pattern, XFT_XLFD, 0, &xlfd) != XftResultMatch)
	return 0;
    if (XftPatternGetBool (pattern, XFT_SCALABLE, 0, &scalable) != XftResultMatch)
	return 0;
    if (scalable)
    {
	if (XftPatternGetDouble (pattern, XFT_PIXEL_SIZE, 0, &pixel_size) != XftResultMatch)
	    return 0;
	pixel_int = (int) (pixel_size + 0.5);
	if (pixel_int)
	{
	    xlfd_pixel = (char *) malloc (strlen (xlfd) + 32);
	    i = xlfd;
	    o = xlfd_pixel;
	    d = 0;
	    while (d != 7 && *i)
	    {
		if ((*o++ = *i++) == '-')
		    d++;
	    }
	    if (*i)
	    {
		sprintf (o, "%d", pixel_int);
		o += strlen (o);
		while (*i != '-')
		    ++i;
	    }
	    while ((*o++ = *i++));
#if 0
	    printf ("original %s sized %s\n", xlfd, xlfd_pixel);
#endif
	    xlfd = xlfd_pixel;
	}
    }
    for (cf = _XftCoreFonts; cf; cf = cf->next)
    {
	if (cf->display == dpy &&
	    !_XftStrCmpIgnoreCase (cf->xlfd, xlfd))
	{
	    cf->ref++;
	    if (_XftFontDebug () & XFT_DBG_REF)
	    {
		printf ("Xlfd \"%s\" matches existing font (%d)\n",
			xlfd, cf->ref);
	    }
	    break;
	}
    }
    if (!cf)
    {
	ret = XLoadQueryFont (dpy, xlfd);
	if (!ret)
	    return 0;

	cf = (XftCoreFont *) malloc (sizeof (XftCoreFont) +
				     strlen (xlfd) + 1);
	if (!cf)
	{
	    XFreeFont (dpy, ret);
	    return 0;
	}
	
        if (_XftFontDebug () & XFT_DBG_REF)
	    printf ("Xlfd \"%s\" matches new font\n", xlfd);
	
	cf->next = _XftCoreFonts;
	_XftCoreFonts = cf;
	cf->ref = 1;
	
	cf->font = ret;
	cf->xlfd = (char *) (cf + 1);
	strcpy (cf->xlfd, xlfd);
    }
    if (xlfd_pixel)
	free (xlfd_pixel);
    return cf->font;
}