1c76ae52dSmrg/*
2de3c0529Smrg * Copyright © 2022 Thomas E. Dickey
3c76ae52dSmrg * Copyright © 2000 Keith Packard
4c76ae52dSmrg *
5c76ae52dSmrg * Permission to use, copy, modify, distribute, and sell this software and its
6c76ae52dSmrg * documentation for any purpose is hereby granted without fee, provided that
7de3c0529Smrg * the above copyright notice appear in all copies and that both that copyright
8de3c0529Smrg * notice and this permission notice appear in supporting documentation, and
9de3c0529Smrg * that the name of the above copyright holders not be used in advertising or
10de3c0529Smrg * publicity pertaining to distribution of the software without specific,
11de3c0529Smrg * written prior permission.  The above copyright holders make no
12c76ae52dSmrg * representations about the suitability of this software for any purpose.  It
13c76ae52dSmrg * is provided "as is" without express or implied warranty.
14c76ae52dSmrg *
15de3c0529Smrg * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD TO
16de3c0529Smrg * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17de3c0529Smrg * FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE
18de3c0529Smrg * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19de3c0529Smrg * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20de3c0529Smrg * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21de3c0529Smrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22c76ae52dSmrg */
23c76ae52dSmrg
24c76ae52dSmrg/*
25c76ae52dSmrg * These definitions are solely for use by the implementation of Xft
26c76ae52dSmrg * and constitute no kind of standard.  If you need any of these functions,
27c76ae52dSmrg * please drop me a note.  Either the library needs new functionality,
28c76ae52dSmrg * or there's a way to do what you need using the existing published
29c76ae52dSmrg * interfaces. keithp@freedesktop.org
30c76ae52dSmrg */
31c76ae52dSmrg
32c76ae52dSmrg#ifndef _XFTINT_H_
33c76ae52dSmrg#define _XFTINT_H_
34c76ae52dSmrg
35c76ae52dSmrg#ifdef HAVE_CONFIG_H
36c76ae52dSmrg#include "config.h"
37c76ae52dSmrg#endif
38c76ae52dSmrg
39c76ae52dSmrg#include <stdio.h>
40c76ae52dSmrg#include <stdlib.h>
41c76ae52dSmrg#include <string.h>
42c76ae52dSmrg#include <ctype.h>
43de3c0529Smrg#include <assert.h>
44c76ae52dSmrg
45c76ae52dSmrg#include <X11/Xlib.h>
46c76ae52dSmrg#include <X11/Xutil.h>
47c76ae52dSmrg#include <X11/Xmd.h>
48c76ae52dSmrg#include <X11/Xlibint.h>
49c76ae52dSmrg#define _XFT_NO_COMPAT_
50c76ae52dSmrg#include "Xft.h"
51c76ae52dSmrg#include <fontconfig/fcprivate.h>
52c76ae52dSmrg#include <fontconfig/fcfreetype.h>
53c76ae52dSmrg
54c76ae52dSmrgtypedef struct _XftMatcher {
55c76ae52dSmrg    char    *object;
56c76ae52dSmrg    double  (*compare) (char *object, FcValue value1, FcValue value2);
57c76ae52dSmrg} XftMatcher;
58c76ae52dSmrg
59c76ae52dSmrgtypedef struct _XftSymbolic {
60c76ae52dSmrg    const char	*name;
61c76ae52dSmrg    int		value;
62c76ae52dSmrg} XftSymbolic;
63c76ae52dSmrg
64c76ae52dSmrg/*
65c76ae52dSmrg * Glyphs are stored in this structure
66c76ae52dSmrg */
67c76ae52dSmrgtypedef struct _XftGlyph {
68c76ae52dSmrg    XGlyphInfo	    metrics;
69c76ae52dSmrg    void	    *bitmap;
70c76ae52dSmrg    unsigned long   glyph_memory;
71de3c0529Smrg    Picture         picture;
72c76ae52dSmrg} XftGlyph;
73c76ae52dSmrg
74c76ae52dSmrg/*
75de3c0529Smrg * If the "trackmemusage" option is set, glyphs are managed via a doubly-linked
76de3c0529Smrg * list.  To save space, the links are just array indices.
77de3c0529Smrg */
78de3c0529Smrgtypedef struct _XftGlyphUsage {
79de3c0529Smrg    XftGlyph        contents;
80de3c0529Smrg    FT_UInt	    newer;
81de3c0529Smrg    FT_UInt	    older;
82de3c0529Smrg} XftGlyphUsage;
83de3c0529Smrg
84de3c0529Smrg/*
85de3c0529Smrg * A hash table translates Unicode values into glyph indices
86c76ae52dSmrg */
87c76ae52dSmrgtypedef struct _XftUcsHash {
88c76ae52dSmrg    FcChar32	    ucs4;
89c76ae52dSmrg    FT_UInt	    glyph;
90c76ae52dSmrg} XftUcsHash;
91c76ae52dSmrg
92c76ae52dSmrg/*
93c76ae52dSmrg * Many fonts can share the same underlying face data; this
94c76ae52dSmrg * structure references that.  Note that many faces may in fact
95c76ae52dSmrg * live in the same font file; that is irrelevant to this structure
96c76ae52dSmrg * which is concerned only with the individual faces themselves
97c76ae52dSmrg */
98c76ae52dSmrg
99c76ae52dSmrgtypedef struct _XftFtFile {
100c76ae52dSmrg    struct _XftFtFile	*next;
101c76ae52dSmrg    int			ref;	    /* number of font infos using this file */
1022836776bSmrg
103c76ae52dSmrg    char		*file;	    /* file name */
104c76ae52dSmrg    int			id;	    /* font index within that file */
105c76ae52dSmrg
106c76ae52dSmrg    FT_F26Dot6		xsize;	    /* current xsize setting */
107c76ae52dSmrg    FT_F26Dot6		ysize;	    /* current ysize setting */
108c76ae52dSmrg    FT_Matrix		matrix;	    /* current matrix setting */
1092836776bSmrg
110c76ae52dSmrg    int			lock;	    /* lock count; can't unload unless 0 */
111c76ae52dSmrg    FT_Face		face;	    /* pointer to face; only valid when lock */
112c76ae52dSmrg} XftFtFile;
113c76ae52dSmrg
114c76ae52dSmrg/*
115c76ae52dSmrg * This structure holds the data extracted from a pattern
116c76ae52dSmrg * needed to create a unique font object.
117c76ae52dSmrg */
118c76ae52dSmrg
119c76ae52dSmrgstruct _XftFontInfo {
120c76ae52dSmrg    /*
121c76ae52dSmrg     * Hash value (not include in hash value computation)
122c76ae52dSmrg     */
123c76ae52dSmrg    FcChar32		hash;
124c76ae52dSmrg    XftFtFile		*file;		/* face source */
125c76ae52dSmrg    /*
126c76ae52dSmrg     * Rendering options
127c76ae52dSmrg     */
128c76ae52dSmrg    FT_F26Dot6		xsize, ysize;	/* pixel size */
129c76ae52dSmrg    FcBool		antialias;	/* doing antialiasing */
130c76ae52dSmrg    FcBool		embolden;	/* force emboldening */
131de3c0529Smrg    FcBool		color;		/* contains color glyphs */
132c76ae52dSmrg    int			rgba;		/* subpixel order */
1332836776bSmrg    int			lcd_filter;	/* lcd filter */
134c76ae52dSmrg    FT_Matrix		matrix;		/* glyph transformation matrix */
135c76ae52dSmrg    FcBool		transform;	/* non-identify matrix? */
136c76ae52dSmrg    FT_Int		load_flags;	/* glyph load flags */
137c76ae52dSmrg    FcBool		render;		/* whether to use the Render extension */
138c76ae52dSmrg    /*
139c76ae52dSmrg     * Internal fields
140c76ae52dSmrg     */
141c76ae52dSmrg    int			spacing;
142c76ae52dSmrg    FcBool		minspace;
143c76ae52dSmrg    int			char_width;
144c76ae52dSmrg};
145c76ae52dSmrg
146c76ae52dSmrg/*
147c76ae52dSmrg * Internal version of the font with private data
148c76ae52dSmrg */
149c76ae52dSmrg
150c76ae52dSmrgtypedef struct _XftFontInt {
151c76ae52dSmrg    XftFont		public;		/* public fields */
152c76ae52dSmrg    XftFont		*next;		/* all fonts on display */
153c76ae52dSmrg    XftFont		*hash_next;	/* fonts in this hash chain */
154c76ae52dSmrg    XftFontInfo		info;		/* Data from pattern */
155c76ae52dSmrg    int			ref;		/* reference count */
156c76ae52dSmrg    /*
157c76ae52dSmrg     * Per-glyph information, indexed by glyph ID
158c76ae52dSmrg     * This array follows the font in memory
159c76ae52dSmrg     */
160c76ae52dSmrg    XftGlyph		**glyphs;
161de3c0529Smrg    FT_UInt		num_glyphs;	/* size of glyphs/bitmaps arrays */
162c76ae52dSmrg    /*
163c76ae52dSmrg     * Hash table to get from Unicode value to glyph ID
164c76ae52dSmrg     * This array follows the glyphs in memory
165c76ae52dSmrg     */
166c76ae52dSmrg    XftUcsHash		*hash_table;
167c76ae52dSmrg    int			hash_value;
168c76ae52dSmrg    int			rehash_value;
169c76ae52dSmrg    /*
170c76ae52dSmrg     * X specific fields
171c76ae52dSmrg     */
172c76ae52dSmrg    GlyphSet		glyphset;	/* Render glyphset */
173c76ae52dSmrg    XRenderPictFormat	*format;	/* Render format for glyphs */
174c76ae52dSmrg    /*
175c76ae52dSmrg     * Glyph memory management fields
176c76ae52dSmrg     */
177c76ae52dSmrg    unsigned long	glyph_memory;
178c76ae52dSmrg    unsigned long	max_glyph_memory;
179de3c0529Smrg    unsigned            sizeof_glyph;	/* sizeof(XftGlyph) or XftGlyphUsage */
180de3c0529Smrg    FT_UInt		newest;		/* index, for tracking usage */
181de3c0529Smrg    FT_UInt		total_inuse;	/* total, for verifying usage */
182de3c0529Smrg    FcBool		track_mem_usage;   /* Use XftGlyphUsage */
183c76ae52dSmrg    FcBool		use_free_glyphs;   /* Use XRenderFreeGlyphs */
184c76ae52dSmrg} XftFontInt;
185c76ae52dSmrg
186c76ae52dSmrgtypedef enum _XftClipType {
187c76ae52dSmrg    XftClipTypeNone, XftClipTypeRegion, XftClipTypeRectangles
188c76ae52dSmrg} XftClipType;
189c76ae52dSmrg
190c76ae52dSmrgtypedef struct _XftClipRect {
191c76ae52dSmrg    int			xOrigin;
192c76ae52dSmrg    int			yOrigin;
193c76ae52dSmrg    int			n;
194c76ae52dSmrg} XftClipRect;
195c76ae52dSmrg
196c76ae52dSmrg#define XftClipRects(cr)    ((XRectangle *) ((cr) + 1))
197c76ae52dSmrg
198c76ae52dSmrgtypedef union _XftClip {
199c76ae52dSmrg    XftClipRect	    *rect;
200c76ae52dSmrg    Region	    region;
201c76ae52dSmrg} XftClip;
202c76ae52dSmrg
203c76ae52dSmrgstruct _XftDraw {
204c76ae52dSmrg    Display	    *dpy;
205c76ae52dSmrg    int		    screen;
206c76ae52dSmrg    unsigned int    bits_per_pixel;
207c76ae52dSmrg    unsigned int    depth;
208c76ae52dSmrg    Drawable	    drawable;
209c76ae52dSmrg    Visual	    *visual;	/* NULL for bitmaps */
210c76ae52dSmrg    Colormap	    colormap;
211c76ae52dSmrg    XftClipType	    clip_type;
212c76ae52dSmrg    XftClip	    clip;
213c76ae52dSmrg    int		    subwindow_mode;
214c76ae52dSmrg    struct {
215c76ae52dSmrg	Picture		pict;
216c76ae52dSmrg    } render;
217c76ae52dSmrg    struct {
218c76ae52dSmrg	GC		gc;
219c76ae52dSmrg	int		use_pixmap;
220c76ae52dSmrg    } core;
221c76ae52dSmrg};
222c76ae52dSmrg
223c76ae52dSmrg/*
224c76ae52dSmrg * Instead of taking two round trips for each blending request,
225c76ae52dSmrg * assume that if a particular drawable fails GetImage that it will
226c76ae52dSmrg * fail for a "while"; use temporary pixmaps to avoid the errors
227c76ae52dSmrg */
228c76ae52dSmrg
229c76ae52dSmrg#define XFT_ASSUME_PIXMAP	20
230c76ae52dSmrg
231c76ae52dSmrgtypedef struct _XftSolidColor {
232c76ae52dSmrg    XRenderColor    color;
233c76ae52dSmrg    int		    screen;
234c76ae52dSmrg    Picture	    pict;
235c76ae52dSmrg} XftSolidColor;
236c76ae52dSmrg
237c76ae52dSmrg#define XFT_NUM_SOLID_COLOR	16
238c76ae52dSmrg
239c76ae52dSmrg#define XFT_NUM_FONT_HASH	127
240c76ae52dSmrg
241c76ae52dSmrgtypedef struct _XftDisplayInfo {
242c76ae52dSmrg    struct _XftDisplayInfo  *next;
243c76ae52dSmrg    Display		    *display;
244c76ae52dSmrg    XExtCodes		    *codes;
245c76ae52dSmrg    FcPattern		    *defaults;
246c76ae52dSmrg    FcBool		    hasRender;
2478292847cSmrg    FcBool		    hasSolid;
248c76ae52dSmrg    XftFont		    *fonts;
249c76ae52dSmrg    XRenderPictFormat	    *solidFormat;
250c76ae52dSmrg    unsigned long	    glyph_memory;
251c76ae52dSmrg    unsigned long	    max_glyph_memory;
252de3c0529Smrg    FcBool		    track_mem_usage;
253c76ae52dSmrg    FcBool		    use_free_glyphs;
254c76ae52dSmrg    int			    num_unref_fonts;
255c76ae52dSmrg    int			    max_unref_fonts;
256c76ae52dSmrg    XftSolidColor	    colors[XFT_NUM_SOLID_COLOR];
257c76ae52dSmrg    XftFont		    *fontHash[XFT_NUM_FONT_HASH];
258c76ae52dSmrg} XftDisplayInfo;
259c76ae52dSmrg
260c76ae52dSmrg/*
261c76ae52dSmrg * By default, use no more than 4 meg of server memory total, and no
262c76ae52dSmrg * more than 1 meg for any one font
263c76ae52dSmrg */
264c76ae52dSmrg#define XFT_DPY_MAX_GLYPH_MEMORY    (4 * 1024 * 1024)
265c76ae52dSmrg#define XFT_FONT_MAX_GLYPH_MEMORY   (1024 * 1024)
266c76ae52dSmrg
267c76ae52dSmrg/*
268c76ae52dSmrg * By default, keep the last 16 unreferenced fonts around to
269c76ae52dSmrg * speed reopening them.  Note that the glyph caching code
270c76ae52dSmrg * will keep the global memory usage reasonably limited
271c76ae52dSmrg */
272c76ae52dSmrg#define XFT_DPY_MAX_UNREF_FONTS	    16
273c76ae52dSmrg
274c76ae52dSmrgextern XftDisplayInfo	*_XftDisplayInfo;
275c76ae52dSmrg
276de3c0529Smrg/*
277de3c0529Smrg * Bits in $XFT_DEBUG, which can be combined.
278de3c0529Smrg */
279c76ae52dSmrg#define XFT_DBG_OPEN	1
280c76ae52dSmrg#define XFT_DBG_OPENV	2
281c76ae52dSmrg#define XFT_DBG_RENDER	4
282c76ae52dSmrg#define XFT_DBG_DRAW	8
283c76ae52dSmrg#define XFT_DBG_REF	16
284c76ae52dSmrg#define XFT_DBG_GLYPH	32
285c76ae52dSmrg#define XFT_DBG_GLYPHV	64
286c76ae52dSmrg#define XFT_DBG_CACHE	128
287c76ae52dSmrg#define XFT_DBG_CACHEV	256
288c76ae52dSmrg#define XFT_DBG_MEMORY	512
289de3c0529Smrg#define XFT_DBG_USAGE	1024
290c76ae52dSmrg
291de3c0529Smrg/*
292de3c0529Smrg * Categories for memory allocation.
293de3c0529Smrg */
294de3c0529Smrgtypedef enum {
295de3c0529Smrg    XFT_MEM_DRAW
296de3c0529Smrg    , XFT_MEM_FONT
297de3c0529Smrg    , XFT_MEM_FILE
298de3c0529Smrg    , XFT_MEM_GLYPH
299de3c0529Smrg    , XFT_MEM_NUM
300de3c0529Smrg} XFT_MEM_KIND;
301de3c0529Smrg
302de3c0529Smrg#define AllocTypedArray(n,type)         malloc ((size_t)(n) * sizeof (type))
303de3c0529Smrg#define AllocUIntArray(n)               AllocTypedArray(n, FT_UInt)
304de3c0529Smrg#define AllocGlyphElt8Array(n)          AllocTypedArray(n, XGlyphElt8)
305de3c0529Smrg#define AllocGlyphSpecArray(n)          AllocTypedArray(n, XftGlyphSpec)
306de3c0529Smrg#define AllocGlyphFontSpecArray(n)      AllocTypedArray(n, XftGlyphFontSpec)
307c76ae52dSmrg
308c76ae52dSmrg/* xftcore.c */
309c76ae52dSmrgvoid
310c76ae52dSmrgXftRectCore (XftDraw		*draw,
311c76ae52dSmrg	     _Xconst XftColor	*color,
3122836776bSmrg	     int		x,
313c76ae52dSmrg	     int		y,
314c76ae52dSmrg	     unsigned int	width,
315c76ae52dSmrg	     unsigned int	height);
316c76ae52dSmrg
317c76ae52dSmrgvoid
318c76ae52dSmrgXftGlyphCore (XftDraw		*draw,
319c76ae52dSmrg	      _Xconst XftColor	*color,
320c76ae52dSmrg	      XftFont		*public,
321c76ae52dSmrg	      int		x,
322c76ae52dSmrg	      int		y,
323c76ae52dSmrg	      _Xconst FT_UInt	*glyphs,
324c76ae52dSmrg	      int		nglyphs);
325c76ae52dSmrg
326c76ae52dSmrgvoid
327c76ae52dSmrgXftGlyphSpecCore (XftDraw		*draw,
328c76ae52dSmrg		  _Xconst XftColor	*color,
329c76ae52dSmrg		  XftFont		*public,
330c76ae52dSmrg		  _Xconst XftGlyphSpec	*glyphs,
331c76ae52dSmrg		  int			nglyphs);
332c76ae52dSmrg
333c76ae52dSmrgvoid
334c76ae52dSmrgXftGlyphFontSpecCore (XftDraw			*draw,
335c76ae52dSmrg		      _Xconst XftColor		*color,
336c76ae52dSmrg		      _Xconst XftGlyphFontSpec	*glyphs,
337c76ae52dSmrg		      int			nglyphs);
338c76ae52dSmrg
339c76ae52dSmrg/* xftdbg.c */
340c76ae52dSmrgint
341c76ae52dSmrgXftDebug (void);
342c76ae52dSmrg
343c76ae52dSmrg/* xftdpy.c */
344c76ae52dSmrgXftDisplayInfo *
345c76ae52dSmrg_XftDisplayInfoGet (Display *dpy, FcBool createIfNecessary);
346c76ae52dSmrg
347c76ae52dSmrgvoid
348c76ae52dSmrg_XftDisplayManageMemory (Display *dpy);
349c76ae52dSmrg
350c76ae52dSmrgint
3512836776bSmrgXftDefaultParseBool (const char *v);
352c76ae52dSmrg
353c76ae52dSmrgFcBool
354c76ae52dSmrgXftDefaultGetBool (Display *dpy, const char *object, int screen, FcBool def);
355c76ae52dSmrg
356c76ae52dSmrgint
357c76ae52dSmrgXftDefaultGetInteger (Display *dpy, const char *object, int screen, int def);
358c76ae52dSmrg
359c76ae52dSmrgdouble
360c76ae52dSmrgXftDefaultGetDouble (Display *dpy, const char *object, int screen, double def);
361c76ae52dSmrg
362c76ae52dSmrgFcFontSet *
363c76ae52dSmrgXftDisplayGetFontSet (Display *dpy);
364c76ae52dSmrg
365c76ae52dSmrg/* xftdraw.c */
366c76ae52dSmrgunsigned int
367c76ae52dSmrgXftDrawDepth (XftDraw *draw);
368c76ae52dSmrg
369c76ae52dSmrgunsigned int
370c76ae52dSmrgXftDrawBitsPerPixel (XftDraw *draw);
371c76ae52dSmrg
372c76ae52dSmrgFcBool
373c76ae52dSmrgXftDrawRenderPrepare (XftDraw	*draw);
374c76ae52dSmrg
375c76ae52dSmrg/* xftextent.c */
3762836776bSmrg
377c76ae52dSmrg/* xftfont.c */
378c76ae52dSmrg
379c76ae52dSmrg/* xftfreetype.c */
380c76ae52dSmrgFcBool
381c76ae52dSmrg_XftSetFace (XftFtFile *f, FT_F26Dot6 xsize, FT_F26Dot6 ysize, FT_Matrix *matrix);
382c76ae52dSmrg
383c76ae52dSmrgvoid
384c76ae52dSmrgXftFontManageMemory (Display *dpy);
385c76ae52dSmrg
386c76ae52dSmrg/* xftglyph.c */
387c76ae52dSmrgvoid
388c76ae52dSmrg_XftFontUncacheGlyph (Display *dpy, XftFont *public);
389c76ae52dSmrg
390c76ae52dSmrgvoid
391c76ae52dSmrg_XftFontManageMemory (Display *dpy, XftFont *public);
392c76ae52dSmrg
393c76ae52dSmrg/* xftinit.c */
394c76ae52dSmrgvoid
395c76ae52dSmrgXftMemReport (void);
396c76ae52dSmrg
397c76ae52dSmrgvoid
398de3c0529SmrgXftMemAlloc (int kind, size_t size);
399c76ae52dSmrg
400c76ae52dSmrgvoid
401de3c0529SmrgXftMemFree (int kind, size_t size);
402c76ae52dSmrg
403c76ae52dSmrg/* xftlist.c */
404c76ae52dSmrgFcFontSet *
405c76ae52dSmrgXftListFontsPatternObjects (Display	    *dpy,
406c76ae52dSmrg			    int		    screen,
407c76ae52dSmrg			    FcPattern	    *pattern,
408c76ae52dSmrg			    FcObjectSet    *os);
409c76ae52dSmrg
410c76ae52dSmrg/* xftname.c */
411c76ae52dSmrg
412c76ae52dSmrg/* xftrender.c */
413c76ae52dSmrg
414c76ae52dSmrg/* xftstr.c */
415c76ae52dSmrgint
416c76ae52dSmrg_XftMatchSymbolic (XftSymbolic *s, int n, const char *name, int def);
417c76ae52dSmrg
418c76ae52dSmrg/* xftswap.c */
419c76ae52dSmrgint
420c76ae52dSmrgXftNativeByteOrder (void);
421c76ae52dSmrg
422c76ae52dSmrgvoid
423c76ae52dSmrgXftSwapCARD32 (CARD32 *data, int n);
424c76ae52dSmrg
425c76ae52dSmrgvoid
426c76ae52dSmrgXftSwapCARD24 (CARD8 *data, int width, int height);
427c76ae52dSmrg
428c76ae52dSmrgvoid
429c76ae52dSmrgXftSwapCARD16 (CARD16 *data, int n);
430c76ae52dSmrg
431c76ae52dSmrgvoid
432c76ae52dSmrgXftSwapImage (XImage *image);
433c76ae52dSmrg
434c76ae52dSmrg/* xftxlfd.c */
435c76ae52dSmrg#endif /* _XFT_INT_H_ */
436