1/*
2
3Copyright 1990, 1994, 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
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27*/
28
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32
33#include <X11/fonts/fntfilst.h>
34#include <X11/fonts/bitmap.h>
35#include <X11/fonts/bdfint.h>
36
37#ifndef MAXSHORT
38#define MAXSHORT    32767
39#endif
40
41#ifndef MINSHORT
42#define MINSHORT    -32768
43#endif
44
45static xCharInfo initMinMetrics = {
46MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, 0xFFFF};
47static xCharInfo initMaxMetrics = {
48MINSHORT, MINSHORT, MINSHORT, MINSHORT, MINSHORT, 0x0000};
49
50#define MINMAX(field,ci) \
51	if (minbounds->field > (ci)->field) \
52	     minbounds->field = (ci)->field; \
53	if (maxbounds->field < (ci)->field) \
54	     maxbounds->field = (ci)->field;
55
56#define COMPUTE_MINMAX(ci) \
57    if ((ci)->ascent || (ci)->descent || \
58	(ci)->leftSideBearing || (ci)->rightSideBearing || \
59	(ci)->characterWidth) \
60    { \
61	MINMAX(ascent, (ci)); \
62	MINMAX(descent, (ci)); \
63	MINMAX(leftSideBearing, (ci)); \
64	MINMAX(rightSideBearing, (ci)); \
65	MINMAX(characterWidth, (ci)); \
66    }
67
68void
69bitmapComputeFontBounds(FontPtr pFont)
70{
71    BitmapFontPtr  bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
72    int         nchars;
73    int         r,
74                c;
75    CharInfoPtr ci;
76    int         maxOverlap;
77    int         overlap;
78    xCharInfo  *minbounds,
79               *maxbounds;
80    int         i;
81    int		numneg = 0, numpos = 0;
82
83    if (bitmapFont->bitmapExtra) {
84	minbounds = &bitmapFont->bitmapExtra->info.minbounds;
85	maxbounds = &bitmapFont->bitmapExtra->info.maxbounds;
86    } else {
87	minbounds = &pFont->info.minbounds;
88	maxbounds = &pFont->info.maxbounds;
89    }
90    *minbounds = initMinMetrics;
91    *maxbounds = initMaxMetrics;
92    maxOverlap = MINSHORT;
93    nchars = bitmapFont->num_chars;
94    for (i = 0, ci = bitmapFont->metrics; i < nchars; i++, ci++) {
95	COMPUTE_MINMAX(&ci->metrics);
96	if (ci->metrics.characterWidth < 0)
97	    numneg++;
98	else
99	    numpos++;
100	minbounds->attributes &= ci->metrics.attributes;
101	maxbounds->attributes |= ci->metrics.attributes;
102	overlap = ci->metrics.rightSideBearing - ci->metrics.characterWidth;
103	if (maxOverlap < overlap)
104	    maxOverlap = overlap;
105    }
106    if (bitmapFont->bitmapExtra) {
107	if (numneg > numpos)
108	    bitmapFont->bitmapExtra->info.drawDirection = RightToLeft;
109	else
110	    bitmapFont->bitmapExtra->info.drawDirection = LeftToRight;
111	bitmapFont->bitmapExtra->info.maxOverlap = maxOverlap;
112	minbounds = &pFont->info.minbounds;
113	maxbounds = &pFont->info.maxbounds;
114	*minbounds = initMinMetrics;
115	*maxbounds = initMaxMetrics;
116        i = 0;
117	maxOverlap = MINSHORT;
118	for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
119	    for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) {
120		ci = ACCESSENCODING(bitmapFont->encoding, i);
121		if (ci) {
122		    COMPUTE_MINMAX(&ci->metrics);
123		    if (ci->metrics.characterWidth < 0)
124			numneg++;
125		    else
126			numpos++;
127		    minbounds->attributes &= ci->metrics.attributes;
128		    maxbounds->attributes |= ci->metrics.attributes;
129		    overlap = ci->metrics.rightSideBearing -
130			ci->metrics.characterWidth;
131		    if (maxOverlap < overlap)
132			maxOverlap = overlap;
133		}
134                i++;
135	    }
136	}
137    }
138    if (numneg > numpos)
139	pFont->info.drawDirection = RightToLeft;
140    else
141	pFont->info.drawDirection = LeftToRight;
142    pFont->info.maxOverlap = maxOverlap;
143}
144
145void
146bitmapComputeFontInkBounds(FontPtr pFont)
147{
148    BitmapFontPtr  bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
149    int         nchars;
150    int         r,
151                c;
152    CharInfoPtr cit;
153    xCharInfo  *ci;
154    int         offset;
155    xCharInfo  *minbounds,
156               *maxbounds;
157    int         i;
158
159    if (!bitmapFont->ink_metrics) {
160	if (bitmapFont->bitmapExtra) {
161	    bitmapFont->bitmapExtra->info.ink_minbounds = bitmapFont->bitmapExtra->info.minbounds;
162	    bitmapFont->bitmapExtra->info.ink_maxbounds = bitmapFont->bitmapExtra->info.maxbounds;
163	}
164	pFont->info.ink_minbounds = pFont->info.minbounds;
165	pFont->info.ink_maxbounds = pFont->info.maxbounds;
166    } else {
167	if (bitmapFont->bitmapExtra) {
168	    minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds;
169	    maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds;
170	} else {
171	    minbounds = &pFont->info.ink_minbounds;
172	    maxbounds = &pFont->info.ink_maxbounds;
173	}
174	*minbounds = initMinMetrics;
175	*maxbounds = initMaxMetrics;
176	nchars = bitmapFont->num_chars;
177	for (i = 0, ci = bitmapFont->ink_metrics; i < nchars; i++, ci++) {
178	    COMPUTE_MINMAX(ci);
179	    minbounds->attributes &= ci->attributes;
180	    maxbounds->attributes |= ci->attributes;
181	}
182	if (bitmapFont->bitmapExtra) {
183	    minbounds = &pFont->info.ink_minbounds;
184	    maxbounds = &pFont->info.ink_maxbounds;
185	    *minbounds = initMinMetrics;
186	    *maxbounds = initMaxMetrics;
187            i=0;
188	    for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
189		for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) {
190		    cit = ACCESSENCODING(bitmapFont->encoding, i);
191		    if (cit) {
192			offset = cit - bitmapFont->metrics;
193			ci = &bitmapFont->ink_metrics[offset];
194			COMPUTE_MINMAX(ci);
195			minbounds->attributes &= ci->attributes;
196			maxbounds->attributes |= ci->attributes;
197		    }
198                    i++;
199		}
200	    }
201	}
202    }
203}
204
205Bool
206bitmapAddInkMetrics(FontPtr pFont)
207{
208    BitmapFontPtr  bitmapFont;
209    int         i;
210
211    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
212    bitmapFont->ink_metrics = malloc(bitmapFont->num_chars * sizeof(xCharInfo));
213    if (!bitmapFont->ink_metrics) {
214      fprintf(stderr, "Error: Couldn't allocate ink_metrics (%d*%ld)\n",
215	      bitmapFont->num_chars, (unsigned long)sizeof(xCharInfo));
216	return FALSE;
217    }
218    for (i = 0; i < bitmapFont->num_chars; i++)
219	FontCharInkMetrics(pFont, &bitmapFont->metrics[i], &bitmapFont->ink_metrics[i]);
220    pFont->info.inkMetrics = TRUE;
221    return TRUE;
222}
223
224/* ARGSUSED */
225int
226bitmapComputeWeight(FontPtr pFont)
227{
228    return 10;
229}
230