Edit

IABSD.fr/xenocara/lib/libXft/src/xftextent.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2012-03-10 14:09:34
    Hash : b9bf44cc
    Message : update to libXft 2.3.0

  • lib/libXft/src/xftextent.c
  • /*
     * Copyright © 2000 Keith Packard
     *
     * Permission to use, copy, modify, distribute, and sell this software and its
     * documentation for any purpose is hereby granted without fee, provided that
     * the above copyright notice appear in all copies and that both that
     * copyright notice and this permission notice appear in supporting
     * documentation, and that the name of Keith Packard not be used in
     * advertising or publicity pertaining to distribution of the software without
     * specific, written prior permission.  Keith Packard makes no
     * representations about the suitability of this software for any purpose.  It
     * is provided "as is" without express or implied warranty.
     *
     * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     * PERFORMANCE OF THIS SOFTWARE.
     */
    
    #include "xftint.h"
    
    _X_EXPORT void
    XftGlyphExtents (Display	    *dpy,
    		 XftFont	    *pub,
    		 _Xconst FT_UInt    *glyphs,
    		 int		    nglyphs,
    		 XGlyphInfo	    *extents)
    {
        XftFontInt		*font = (XftFontInt *) pub;
        FT_UInt		missing[XFT_NMISSING];
        int			nmissing;
        int			n;
        _Xconst FT_UInt	*g;
        FT_UInt		glyph;
        XftGlyph		*xftg;
        FcBool		glyphs_loaded;
        int			x, y;
        int			left, right, top, bottom;
        int			overall_left, overall_right;
        int			overall_top, overall_bottom;
    
        g = glyphs;
        n = nglyphs;
        nmissing = 0;
        glyphs_loaded = FcFalse;
        while (n--)
    	if (XftFontCheckGlyph (dpy, pub, FcFalse, *g++, missing, &nmissing))
    	    glyphs_loaded = FcTrue;
        if (nmissing)
    	XftFontLoadGlyphs (dpy, pub, FcFalse, missing, nmissing);
        g = glyphs;
        n = nglyphs;
        xftg = NULL;
        while (n)
        {
    	glyph = *g++;
    	n--;
    	if (glyph < font->num_glyphs &&
    	    (xftg = font->glyphs[glyph]))
    	    break;
        }
        if (n == 0)
        {
    	if (xftg)
    	    *extents = xftg->metrics;
    	else
    	    memset (extents, '\0', sizeof (*extents));
        }
        else
        {
    	x = 0;
    	y = 0;
    	overall_left = x - xftg->metrics.x;
    	overall_top = y - xftg->metrics.y;
    	overall_right = overall_left + (int) xftg->metrics.width;
    	overall_bottom = overall_top + (int) xftg->metrics.height;
    	x += xftg->metrics.xOff;
    	y += xftg->metrics.yOff;
    	while (n--)
    	{
    	    glyph = *g++;
    	    if (glyph < font->num_glyphs && (xftg = font->glyphs[glyph]))
    	    {
    		left = x - xftg->metrics.x;
    		top = y - xftg->metrics.y;
    		right = left + (int) xftg->metrics.width;
    		bottom = top + (int) xftg->metrics.height;
    		if (left < overall_left)
    		    overall_left = left;
    		if (top < overall_top)
    		    overall_top = top;
    		if (right > overall_right)
    		    overall_right = right;
    		if (bottom > overall_bottom)
    		    overall_bottom = bottom;
    		x += xftg->metrics.xOff;
    		y += xftg->metrics.yOff;
    	    }
    	}
    	extents->x = -overall_left;
    	extents->y = -overall_top;
    	extents->width = overall_right - overall_left;
    	extents->height = overall_bottom - overall_top;
    	extents->xOff = x;
    	extents->yOff = y;
        }
        if (glyphs_loaded)
    	_XftFontManageMemory (dpy, pub);
    }
    
    #define NUM_LOCAL   1024
    
    _X_EXPORT void
    XftTextExtents8 (Display	    *dpy,
    		 XftFont	    *pub,
    		 _Xconst FcChar8    *string,
    		 int		    len,
    		 XGlyphInfo	    *extents)
    {
        FT_UInt	    *glyphs, glyphs_local[NUM_LOCAL];
        int		    i;
    
        if (len <= NUM_LOCAL)
    	glyphs = glyphs_local;
        else
        {
    	glyphs = malloc (len * sizeof (FT_UInt));
    	if (!glyphs)
    	{
    	    memset (extents, '\0', sizeof (XGlyphInfo));
    	    return;
    	}
        }
        for (i = 0; i < len; i++)
    	glyphs[i] = XftCharIndex (dpy, pub, string[i]);
        XftGlyphExtents (dpy, pub, glyphs, len, extents);
        if (glyphs != glyphs_local)
    	free (glyphs);
    }
    
    _X_EXPORT void
    XftTextExtents16 (Display	    *dpy,
    		  XftFont	    *pub,
    		  _Xconst FcChar16  *string,
    		  int		    len,
    		  XGlyphInfo	    *extents)
    {
        FT_UInt	    *glyphs, glyphs_local[NUM_LOCAL];
        int		    i;
    
        if (len <= NUM_LOCAL)
    	glyphs = glyphs_local;
        else
        {
    	glyphs = malloc (len * sizeof (FT_UInt));
    	if (!glyphs)
    	{
    	    memset (extents, '\0', sizeof (XGlyphInfo));
    	    return;
    	}
        }
        for (i = 0; i < len; i++)
    	glyphs[i] = XftCharIndex (dpy, pub, string[i]);
        XftGlyphExtents (dpy, pub, glyphs, len, extents);
        if (glyphs != glyphs_local)
    	free (glyphs);
    }
    
    _X_EXPORT void
    XftTextExtents32 (Display	    *dpy,
    		  XftFont	    *pub,
    		  _Xconst FcChar32  *string,
    		  int		    len,
    		  XGlyphInfo	    *extents)
    {
        FT_UInt	    *glyphs, glyphs_local[NUM_LOCAL];
        int		    i;
    
        if (len <= NUM_LOCAL)
    	glyphs = glyphs_local;
        else
        {
    	glyphs = malloc (len * sizeof (FT_UInt));
    	if (!glyphs)
    	{
    	    memset (extents, '\0', sizeof (XGlyphInfo));
    	    return;
    	}
        }
        for (i = 0; i < len; i++)
    	glyphs[i] = XftCharIndex (dpy, pub, string[i]);
        XftGlyphExtents (dpy, pub, glyphs, len, extents);
        if (glyphs != glyphs_local)
    	free (glyphs);
    }
    
    _X_EXPORT void
    XftTextExtentsUtf8 (Display	    *dpy,
    		    XftFont	    *pub,
    		    _Xconst FcChar8 *string,
    		    int		    len,
    		    XGlyphInfo	    *extents)
    {
        FT_UInt	    *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL];
        FcChar32	    ucs4;
        int		    i;
        int		    l;
        int		    size;
    
        i = 0;
        glyphs = glyphs_local;
        size = NUM_LOCAL;
        while (len && (l = FcUtf8ToUcs4 (string, &ucs4, len)) > 0)
        {
    	if (i == size)
    	{
    	    glyphs_new = malloc (size * 2 * sizeof (FT_UInt));
    	    if (!glyphs_new)
    	    {
    		if (glyphs != glyphs_local)
    		    free (glyphs);
    		memset (extents, '\0', sizeof (XGlyphInfo));
    		return;
    	    }
    	    memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt));
    	    size *= 2;
    	    if (glyphs != glyphs_local)
    		free (glyphs);
    	    glyphs = glyphs_new;
    	}
    	glyphs[i++] = XftCharIndex (dpy, pub, ucs4);
    	string += l;
    	len -= l;
        }
        XftGlyphExtents (dpy, pub, glyphs, i, extents);
        if (glyphs != glyphs_local)
    	free (glyphs);
    }
    
    _X_EXPORT void
    XftTextExtentsUtf16 (Display		*dpy,
    		     XftFont		*pub,
    		     _Xconst FcChar8	*string,
    		     FcEndian		endian,
    		     int		len,
    		     XGlyphInfo		*extents)
    {
        FT_UInt	    *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL];
        FcChar32	    ucs4;
        int		    i;
        int		    l;
        int		    size;
    
        i = 0;
        glyphs = glyphs_local;
        size = NUM_LOCAL;
        while (len && (l = FcUtf16ToUcs4 (string, endian, &ucs4, len)) > 0)
        {
    	if (i == size)
    	{
    	    glyphs_new = malloc (size * 2 * sizeof (FT_UInt));
    	    if (!glyphs_new)
    	    {
    		if (glyphs != glyphs_local)
    		    free (glyphs);
    		memset (extents, '\0', sizeof (XGlyphInfo));
    		return;
    	    }
    	    memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt));
    	    size *= 2;
    	    if (glyphs != glyphs_local)
    		free (glyphs);
    	    glyphs = glyphs_new;
    	}
    	glyphs[i++] = XftCharIndex (dpy, pub, ucs4);
    	string += l;
    	len -= l;
        }
        XftGlyphExtents (dpy, pub, glyphs, i, extents);
        if (glyphs != glyphs_local)
    	free (glyphs);
    }