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