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