1/*
2
3Copyright 1991, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27/*
28 * Author:  Keith Packard, MIT X Consortium
29 */
30
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34#include "libxfontint.h"
35#include "src/util/replace.h"
36#include <X11/fonts/fntfilst.h>
37
38BitmapSourcesRec	FontFileBitmapSources;
39
40Bool
41FontFileRegisterBitmapSource (FontPathElementPtr fpe)
42{
43    FontPathElementPtr	*new;
44    int			i;
45    int			newsize;
46
47    for (i = 0; i < FontFileBitmapSources.count; i++)
48	if (FontFileBitmapSources.fpe[i] == fpe)
49	    return TRUE;
50    if (FontFileBitmapSources.count == FontFileBitmapSources.size)
51    {
52	newsize = FontFileBitmapSources.size + 4;
53	new = reallocarray (FontFileBitmapSources.fpe, newsize, sizeof *new);
54	if (!new)
55	    return FALSE;
56	FontFileBitmapSources.size = newsize;
57	FontFileBitmapSources.fpe = new;
58    }
59    FontFileBitmapSources.fpe[FontFileBitmapSources.count++] = fpe;
60    return TRUE;
61}
62
63void
64FontFileUnregisterBitmapSource (FontPathElementPtr fpe)
65{
66    int	    i;
67
68    for (i = 0; i < FontFileBitmapSources.count; i++)
69	if (FontFileBitmapSources.fpe[i] == fpe)
70	{
71	    FontFileBitmapSources.count--;
72	    if (FontFileBitmapSources.count == 0)
73	    {
74		FontFileBitmapSources.size = 0;
75		free (FontFileBitmapSources.fpe);
76		FontFileBitmapSources.fpe = 0;
77	    }
78	    else
79	    {
80	    	for (; i < FontFileBitmapSources.count; i++)
81		    FontFileBitmapSources.fpe[i] = FontFileBitmapSources.fpe[i+1];
82	    }
83	    break;
84	}
85}
86
87/*
88 * Our set_path_hook: unregister all bitmap sources.
89 * This is necessary because already open fonts will keep their FPEs
90 * allocated, but they may not be on the new font path.
91 * The bitmap sources in the new path will be registered by the init_func.
92 */
93void
94FontFileEmptyBitmapSource(void)
95{
96    if (FontFileBitmapSources.count == 0)
97	return;
98
99    FontFileBitmapSources.count = 0;
100    FontFileBitmapSources.size = 0;
101    free (FontFileBitmapSources.fpe);
102    FontFileBitmapSources.fpe = 0;
103}
104
105int
106FontFileMatchBitmapSource (FontPathElementPtr fpe,
107			   FontPtr *pFont,
108			   int flags,
109			   FontEntryPtr entry,
110			   FontNamePtr zeroPat,
111			   FontScalablePtr vals,
112			   fsBitmapFormat format,
113			   fsBitmapFormatMask fmask,
114			   Bool noSpecificSize)
115{
116    int			source;
117    FontEntryPtr	zero;
118    FontBitmapEntryPtr	bitmap;
119    int			ret;
120    FontDirectoryPtr	dir;
121    FontScaledPtr	scaled;
122
123    /*
124     * Look through all the registered bitmap sources for
125     * the same zero name as ours; entries along that one
126     * can be scaled as desired.
127     */
128    ret = BadFontName;
129    for (source = 0; source < FontFileBitmapSources.count; source++)
130    {
131    	if (FontFileBitmapSources.fpe[source] == fpe)
132	    continue;
133	dir = (FontDirectoryPtr) FontFileBitmapSources.fpe[source]->private;
134	zero = FontFileFindNameInDir (&dir->scalable, zeroPat);
135	if (!zero)
136	    continue;
137    	scaled = FontFileFindScaledInstance (zero, vals, noSpecificSize);
138    	if (scaled)
139    	{
140	    if (scaled->pFont)
141	    {
142		*pFont = scaled->pFont;
143		(*pFont)->fpe = FontFileBitmapSources.fpe[source];
144		ret = Successful;
145	    }
146	    else if (scaled->bitmap)
147	    {
148		entry = scaled->bitmap;
149		bitmap = &entry->u.bitmap;
150		if (bitmap->pFont)
151		{
152		    *pFont = bitmap->pFont;
153		    (*pFont)->fpe = FontFileBitmapSources.fpe[source];
154		    ret = Successful;
155		}
156		else
157		{
158		    ret = FontFileOpenBitmap (
159				FontFileBitmapSources.fpe[source],
160				pFont, flags, entry, format, fmask);
161		    if (ret == Successful && *pFont)
162			(*pFont)->fpe = FontFileBitmapSources.fpe[source];
163		}
164	    }
165	    else /* "cannot" happen */
166	    {
167		ret = BadFontName;
168	    }
169	    break;
170    	}
171    }
172    return ret;
173}
174