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#include "libxfontint.h"
33#include "src/util/replace.h"
34
35#include <X11/fonts/fntfilst.h>
36#include <X11/fonts/bitmap.h>
37#include <X11/fonts/bdfint.h>
38
39#ifndef MAXSHORT
40#define MAXSHORT    32767
41#endif
42
43#ifndef MINSHORT
44#define MINSHORT    -32768
45#endif
46
47static xCharInfo initMinMetrics = {
48MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, 0xFFFF};
49static xCharInfo initMaxMetrics = {
50MINSHORT, MINSHORT, MINSHORT, MINSHORT, MINSHORT, 0x0000};
51
52#define MINMAX(field,ci) \
53	if (minbounds->field > (ci)->field) \
54	     minbounds->field = (ci)->field; \
55	if (maxbounds->field < (ci)->field) \
56	     maxbounds->field = (ci)->field;
57
58#define COMPUTE_MINMAX(ci) \
59    if ((ci)->ascent || (ci)->descent || \
60	(ci)->leftSideBearing || (ci)->rightSideBearing || \
61	(ci)->characterWidth) \
62    { \
63	MINMAX(ascent, (ci)); \
64	MINMAX(descent, (ci)); \
65	MINMAX(leftSideBearing, (ci)); \
66	MINMAX(rightSideBearing, (ci)); \
67	MINMAX(characterWidth, (ci)); \
68    }
69
70void
71bitmapComputeFontBounds(FontPtr pFont)
72{
73    BitmapFontPtr  bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
74    int         nchars;
75    int         r,
76                c;
77    CharInfoPtr ci;
78    int         maxOverlap;
79    int         overlap;
80    xCharInfo  *minbounds,
81               *maxbounds;
82    int         i;
83    int		numneg = 0, numpos = 0;
84
85    if (bitmapFont->bitmapExtra) {
86	minbounds = &bitmapFont->bitmapExtra->info.minbounds;
87	maxbounds = &bitmapFont->bitmapExtra->info.maxbounds;
88    } else {
89	minbounds = &pFont->info.minbounds;
90	maxbounds = &pFont->info.maxbounds;
91    }
92    *minbounds = initMinMetrics;
93    *maxbounds = initMaxMetrics;
94    maxOverlap = MINSHORT;
95    nchars = bitmapFont->num_chars;
96    for (i = 0, ci = bitmapFont->metrics; i < nchars; i++, ci++) {
97	COMPUTE_MINMAX(&ci->metrics);
98	if (ci->metrics.characterWidth < 0)
99	    numneg++;
100	else
101	    numpos++;
102	minbounds->attributes &= ci->metrics.attributes;
103	maxbounds->attributes |= ci->metrics.attributes;
104	overlap = ci->metrics.rightSideBearing - ci->metrics.characterWidth;
105	if (maxOverlap < overlap)
106	    maxOverlap = overlap;
107    }
108    if (bitmapFont->bitmapExtra) {
109	if (numneg > numpos)
110	    bitmapFont->bitmapExtra->info.drawDirection = RightToLeft;
111	else
112	    bitmapFont->bitmapExtra->info.drawDirection = LeftToRight;
113	bitmapFont->bitmapExtra->info.maxOverlap = maxOverlap;
114	minbounds = &pFont->info.minbounds;
115	maxbounds = &pFont->info.maxbounds;
116	*minbounds = initMinMetrics;
117	*maxbounds = initMaxMetrics;
118        i = 0;
119	maxOverlap = MINSHORT;
120	for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
121	    for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) {
122		ci = ACCESSENCODING(bitmapFont->encoding, i);
123		if (ci) {
124		    COMPUTE_MINMAX(&ci->metrics);
125		    if (ci->metrics.characterWidth < 0)
126			numneg++;
127		    else
128			numpos++;
129		    minbounds->attributes &= ci->metrics.attributes;
130		    maxbounds->attributes |= ci->metrics.attributes;
131		    overlap = ci->metrics.rightSideBearing -
132			ci->metrics.characterWidth;
133		    if (maxOverlap < overlap)
134			maxOverlap = overlap;
135		}
136                i++;
137	    }
138	}
139    }
140    if (numneg > numpos)
141	pFont->info.drawDirection = RightToLeft;
142    else
143	pFont->info.drawDirection = LeftToRight;
144    pFont->info.maxOverlap = maxOverlap;
145}
146
147void
148bitmapComputeFontInkBounds(FontPtr pFont)
149{
150    BitmapFontPtr  bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
151    int         nchars;
152    int         r,
153                c;
154    CharInfoPtr cit;
155    xCharInfo  *ci;
156    int         offset;
157    xCharInfo  *minbounds,
158               *maxbounds;
159    int         i;
160
161    if (!bitmapFont->ink_metrics) {
162	if (bitmapFont->bitmapExtra) {
163	    bitmapFont->bitmapExtra->info.ink_minbounds = bitmapFont->bitmapExtra->info.minbounds;
164	    bitmapFont->bitmapExtra->info.ink_maxbounds = bitmapFont->bitmapExtra->info.maxbounds;
165	}
166	pFont->info.ink_minbounds = pFont->info.minbounds;
167	pFont->info.ink_maxbounds = pFont->info.maxbounds;
168    } else {
169	if (bitmapFont->bitmapExtra) {
170	    minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds;
171	    maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds;
172	} else {
173	    minbounds = &pFont->info.ink_minbounds;
174	    maxbounds = &pFont->info.ink_maxbounds;
175	}
176	*minbounds = initMinMetrics;
177	*maxbounds = initMaxMetrics;
178	nchars = bitmapFont->num_chars;
179	for (i = 0, ci = bitmapFont->ink_metrics; i < nchars; i++, ci++) {
180	    COMPUTE_MINMAX(ci);
181	    minbounds->attributes &= ci->attributes;
182	    maxbounds->attributes |= ci->attributes;
183	}
184	if (bitmapFont->bitmapExtra) {
185	    minbounds = &pFont->info.ink_minbounds;
186	    maxbounds = &pFont->info.ink_maxbounds;
187	    *minbounds = initMinMetrics;
188	    *maxbounds = initMaxMetrics;
189            i=0;
190	    for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
191		for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) {
192		    cit = ACCESSENCODING(bitmapFont->encoding, i);
193		    if (cit) {
194			offset = cit - bitmapFont->metrics;
195			ci = &bitmapFont->ink_metrics[offset];
196			COMPUTE_MINMAX(ci);
197			minbounds->attributes &= ci->attributes;
198			maxbounds->attributes |= ci->attributes;
199		    }
200                    i++;
201		}
202	    }
203	}
204    }
205}
206
207Bool
208bitmapAddInkMetrics(FontPtr pFont)
209{
210    BitmapFontPtr  bitmapFont;
211    int         i;
212
213    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
214    bitmapFont->ink_metrics = mallocarray(bitmapFont->num_chars, sizeof(xCharInfo));
215    if (!bitmapFont->ink_metrics) {
216      fprintf(stderr, "Error: Couldn't allocate ink_metrics (%d*%ld)\n",
217	      bitmapFont->num_chars, (unsigned long)sizeof(xCharInfo));
218	return FALSE;
219    }
220    for (i = 0; i < bitmapFont->num_chars; i++)
221	FontCharInkMetrics(pFont, &bitmapFont->metrics[i], &bitmapFont->ink_metrics[i]);
222    pFont->info.inkMetrics = TRUE;
223    return TRUE;
224}
225
226/* ARGSUSED */
227int
228bitmapComputeWeight(FontPtr pFont)
229{
230    return 10;
231}
232