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 "fntfilst.h"
34#include "bitmap.h"
35#include "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 = {
46    MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, 0xFFFF
47};
48
49static xCharInfo initMaxMetrics = {
50    MINSHORT, MINSHORT, MINSHORT, MINSHORT, MINSHORT, 0x0000
51};
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    CharInfoPtr ci;
77    int         maxOverlap;
78    int         overlap;
79    xCharInfo  *minbounds, *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    }
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 (int r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
120            for (int 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
151    if (!bitmapFont->ink_metrics) {
152        if (bitmapFont->bitmapExtra) {
153            bitmapFont->bitmapExtra->info.ink_minbounds =
154                bitmapFont->bitmapExtra->info.minbounds;
155            bitmapFont->bitmapExtra->info.ink_maxbounds =
156                bitmapFont->bitmapExtra->info.maxbounds;
157        }
158        pFont->info.ink_minbounds = pFont->info.minbounds;
159        pFont->info.ink_maxbounds = pFont->info.maxbounds;
160    }
161    else {
162        xCharInfo  *minbounds, *maxbounds, *ci;
163        int         nchars, i;
164
165        if (bitmapFont->bitmapExtra) {
166            minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds;
167            maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds;
168        }
169        else {
170            minbounds = &pFont->info.ink_minbounds;
171            maxbounds = &pFont->info.ink_maxbounds;
172        }
173        *minbounds = initMinMetrics;
174        *maxbounds = initMaxMetrics;
175        nchars = bitmapFont->num_chars;
176        for (i = 0, ci = bitmapFont->ink_metrics; i < nchars; i++, ci++) {
177            COMPUTE_MINMAX(ci);
178            minbounds->attributes &= ci->attributes;
179            maxbounds->attributes |= ci->attributes;
180        }
181        if (bitmapFont->bitmapExtra) {
182            minbounds = &pFont->info.ink_minbounds;
183            maxbounds = &pFont->info.ink_maxbounds;
184            *minbounds = initMinMetrics;
185            *maxbounds = initMaxMetrics;
186            i = 0;
187            for (int r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
188                for (int c = pFont->info.firstCol; c <= pFont->info.lastCol; c++)
189                {
190                    CharInfoPtr cit = ACCESSENCODING(bitmapFont->encoding, i);
191                    if (cit) {
192                        int     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
210    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
211    bitmapFont->ink_metrics = malloc(bitmapFont->num_chars * sizeof(xCharInfo));
212    if (!bitmapFont->ink_metrics) {
213        fprintf(stderr, "Error: Couldn't allocate ink_metrics (%d*%ld)\n",
214                bitmapFont->num_chars, (unsigned long) sizeof(xCharInfo));
215        return FALSE;
216    }
217    for (int i = 0; i < bitmapFont->num_chars; i++)
218        FontCharInkMetrics(pFont, &bitmapFont->metrics[i],
219                           &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