~ubuntu-branches/ubuntu/trusty/libxfont/trusty-proposed

« back to all changes in this revision

Viewing changes to src/Speedo/spglyph.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Potyra
  • Date: 2009-05-09 12:11:53 UTC
  • mfrom: (1.1.10 upstream) (10.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090509121153-nwte290k1e9gew62
Tags: 1:1.4.0-1ubuntu1
* Rebase to unstable, remaining change:
  + debian/rules: unset LDFLAGS to not be hit by -Bsymbolic-functions,
    as libxfont contains weak symbols which are meant to be overriden
    (cf. LP #226156).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Xorg: spglyph.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */
2
 
/*
3
 
 * Copyright 1990, 1991 Network Computing Devices;
4
 
 * Portions Copyright 1987 by Digital Equipment Corporation
5
 
 *
6
 
 * Permission to use, copy, modify, distribute, and sell this software and
7
 
 * its documentation for any purpose is hereby granted without fee, provided
8
 
 * that the above copyright notice appear in all copies and that both that
9
 
 * copyright notice and this permission notice appear in supporting
10
 
 * documentation, and that the names of Network Computing Devices or Digital
11
 
 * not be used in advertising or publicity pertaining to distribution of
12
 
 * the software without specific, written prior permission.
13
 
 *
14
 
 * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
15
 
 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
16
 
 * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
17
 
 * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18
 
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19
 
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20
 
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
 
 *
22
 
 * Author: Dave Lemke, Network Computing Devices Inc
23
 
 */
24
 
 
25
 
/*
26
 
 
27
 
Copyright 1987, 1998  The Open Group
28
 
 
29
 
Permission to use, copy, modify, distribute, and sell this software and its
30
 
documentation for any purpose is hereby granted without fee, provided that
31
 
the above copyright notice appear in all copies and that both that
32
 
copyright notice and this permission notice appear in supporting
33
 
documentation.
34
 
 
35
 
The above copyright notice and this permission notice shall be included
36
 
in all copies or substantial portions of the Software.
37
 
 
38
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
39
 
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
40
 
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
41
 
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
42
 
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
43
 
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
44
 
OTHER DEALINGS IN THE SOFTWARE.
45
 
 
46
 
Except as contained in this notice, the name of The Open Group shall
47
 
not be used in advertising or otherwise to promote the sale, use or
48
 
other dealings in this Software without prior written authorization
49
 
from The Open Group.
50
 
 
51
 
*/
52
 
/* $XFree86: xc/lib/font/Speedo/spglyph.c,v 1.6 2001/01/17 19:43:20 dawes Exp $ */
53
 
 
54
 
#ifdef HAVE_CONFIG_H
55
 
#include <config.h>
56
 
#endif
57
 
#include        <X11/X.h>       /* for bit order #defines */
58
 
#include        "spint.h"
59
 
#include        <X11/fonts/fontutil.h>
60
 
 
61
 
#undef  CLIP_BBOX_NOISE
62
 
 
63
 
static CurrentFontValuesRec current_font_values;
64
 
static CurrentFontValuesPtr cfv = &current_font_values;
65
 
static int  bit_order,
66
 
            byte_order,
67
 
            scan;
68
 
 
69
 
static unsigned long
70
 
sp_compute_data_size(
71
 
    FontPtr     pfont,
72
 
    int         mappad,
73
 
    int         scanlinepad,
74
 
    unsigned long start,
75
 
    unsigned long end)
76
 
{
77
 
    unsigned long ch;
78
 
    unsigned long size = 0;
79
 
    int         bpr;
80
 
    SpeedoFontPtr spf = (SpeedoFontPtr) pfont->fontPrivate;
81
 
    FontInfoPtr pinfo = &pfont->info;
82
 
    int         firstChar;
83
 
 
84
 
    firstChar = spf->master->first_char_id;
85
 
 
86
 
    /* allocate the space */
87
 
    switch (mappad) {
88
 
        int         charsize;
89
 
        CharInfoPtr ci;
90
 
        xCharInfo  *cim;
91
 
 
92
 
    case BitmapFormatImageRectMin:
93
 
        cfv->bpr = 0;
94
 
        for (ch = start; ch <= end; ch++) {
95
 
            ci = &spf->encoding[ch - firstChar];
96
 
            if (!ci)
97
 
                ci = spf->pDefault;
98
 
            cim = &ci->metrics;
99
 
            charsize = GLYPH_SIZE(ci, scanlinepad);
100
 
            charsize *= cim->ascent + cim->descent;
101
 
            size += charsize;
102
 
        }
103
 
        break;
104
 
    case BitmapFormatImageRectMaxWidth:
105
 
        bpr = GLWIDTHBYTESPADDED(FONT_MAX_WIDTH(pinfo), scanlinepad);
106
 
        cfv->bpr = bpr;
107
 
        for (ch = start; ch <= end; ch++) {
108
 
            ci = &spf->encoding[ch - firstChar];
109
 
            if (!ci)
110
 
                ci = spf->pDefault;
111
 
            cim = &ci->metrics;
112
 
            charsize = bpr * (cim->ascent + cim->descent);
113
 
            size += charsize;
114
 
        }
115
 
        break;
116
 
    case BitmapFormatImageRectMax:
117
 
        bpr = GLWIDTHBYTESPADDED(FONT_MAX_WIDTH(pinfo), scanlinepad);
118
 
        cfv->bpr = bpr;
119
 
        size = (end - start + 1) * bpr * FONT_MAX_HEIGHT(pinfo);
120
 
        break;
121
 
    default:
122
 
        assert(0);
123
 
    }
124
 
 
125
 
    return size;
126
 
}
127
 
 
128
 
static void
129
 
finish_line(SpeedoFontPtr spf)
130
 
{
131
 
    int         bpr = cfv->bpr;
132
 
    CharInfoPtr ci = &spf->encoding[cfv->char_id - spf->master->first_char_id];
133
 
 
134
 
    if (bpr == 0) {
135
 
        bpr = GLYPH_SIZE(ci, cfv->scanpad);
136
 
    }
137
 
    if (bpr) {                  /* char may not have any metrics... */
138
 
        cfv->bp = (char *)cfv->bp + bpr;
139
 
    }
140
 
    assert(cfv->bp - sp_fp_cur->bitmaps <= sp_fp_cur->bitmap_size);
141
 
}
142
 
 
143
 
 
144
 
void
145
 
sp_set_bitmap_bits(fix15 y, fix15 xbit1, fix15 xbit2)
146
 
{
147
 
    int         nmiddle;
148
 
    CARD8       startmask,
149
 
                endmask;
150
 
    CARD8       *dst;
151
 
 
152
 
    if (xbit1 > cfv->bit_width) {
153
 
 
154
 
#ifdef CLIP_BBOX_NOISE
155
 
        SpeedoErr("Run wider than bitmap width -- truncated\n");
156
 
#endif
157
 
 
158
 
        xbit1 = cfv->bit_width;
159
 
    }
160
 
    if (xbit2 > cfv->bit_width) {
161
 
 
162
 
#ifdef CLIP_BBOX_NOISE
163
 
        SpeedoErr("Run wider than bitmap width -- truncated\n");
164
 
#endif
165
 
 
166
 
        xbit2 = cfv->bit_width;
167
 
    }
168
 
 
169
 
    if (xbit2 < xbit1) {
170
 
        xbit2 = xbit1;
171
 
    }
172
 
 
173
 
    while (cfv->cur_y != y) {
174
 
        finish_line(sp_fp_cur);
175
 
        cfv->cur_y++;
176
 
    }
177
 
 
178
 
    cfv->last_y = y;
179
 
    if (y >= cfv->bit_height) {
180
 
 
181
 
#ifdef CLIP_BBOX_NOISE
182
 
        SpeedoErr("Y larger than bitmap height -- truncated\n");
183
 
#endif
184
 
 
185
 
        cfv->trunc = 1;
186
 
        return;
187
 
    }
188
 
    if (xbit1 < 0)              /* XXX this is more than a little bit rude... */
189
 
        xbit1 = 0;
190
 
 
191
 
    nmiddle = (xbit1 >> 3);
192
 
    dst = (CARD8 *)cfv->bp + nmiddle;
193
 
    xbit2 -= (xbit1 & ~7);
194
 
    nmiddle = (xbit2 >> 3);
195
 
    xbit1 &= 7;
196
 
    xbit2 &= 7;
197
 
    if (bit_order == MSBFirst) {
198
 
        startmask = ((CARD8) ~0) >> xbit1;
199
 
        endmask = ~(((CARD8) ~0) >> xbit2);
200
 
    } else {
201
 
        startmask = ((CARD8) ~0) << xbit1;
202
 
        endmask = ~(((CARD8) ~0) << xbit2);
203
 
    }
204
 
    if (nmiddle == 0)
205
 
        *dst |= endmask & startmask;
206
 
    else {
207
 
        *dst++ |= startmask;
208
 
        while (--nmiddle)
209
 
            *dst++ = (CARD8)~0;
210
 
        *dst |= endmask;
211
 
    }
212
 
}
213
 
 
214
 
/* ARGSUSED */
215
 
void
216
 
sp_open_bitmap(fix31 x_set_width, fix31 y_set_width, fix31 xorg, fix31 yorg,
217
 
                fix15 xsize, fix15 ysize)
218
 
{
219
 
    CharInfoPtr ci = &sp_fp_cur->encoding[cfv->char_id - sp_fp_cur->master->first_char_id];
220
 
 
221
 
/*-
222
 
 * this is set to provide better quality bitmaps.  since the Speedo
223
 
 * sp_get_bbox() function returns an approximate (but guarenteed to contain)
224
 
 * set of metrics, some of the bitmaps can be place poorly inside and
225
 
 * look bad.
226
 
 *
227
 
 * with this set, the actual bitmap values are used instead of the bboxes.
228
 
 * it makes things look better, but causes two possible problems:
229
 
 *
230
 
 * 1 - the reported min & max bounds may not correspond to the extents
231
 
 *      reported
232
 
 * 2 - if the extents are reported before the character is generated,
233
 
 *      a client could see them change.  this currently never happens,
234
 
 *      but will when a desired enhancement (don't reneder till needed)
235
 
 *      is made.
236
 
 */
237
 
 
238
 
#define BBOX_FIXUP 1
239
 
 
240
 
#ifdef BBOX_FIXUP
241
 
    int         off_horz;
242
 
    int         off_vert;
243
 
 
244
 
    if (xorg < 0)
245
 
        off_horz = (fix15) ((xorg - 32768L) / 65536);
246
 
    else
247
 
        off_horz = (fix15) ((xorg + 32768L) / 65536);
248
 
    if (yorg < 0)
249
 
        off_vert = (fix15) ((yorg - 32768L) / 65536);
250
 
    else
251
 
        off_vert = (fix15) ((yorg + 32768L) / 65536);
252
 
    if (xsize != 0 || ysize != 0 || ci->metrics.characterWidth)
253
 
    {
254
 
        ci->metrics.leftSideBearing = off_horz;
255
 
        ci->metrics.descent = -off_vert;
256
 
        ci->metrics.rightSideBearing = xsize + off_horz;
257
 
        ci->metrics.ascent = ysize + off_vert;
258
 
    }
259
 
    else
260
 
    {
261
 
    /* If setting the proper size would cause the character to appear to
262
 
       be non-existent, fudge things by giving it a pixel to occupy.  */
263
 
        xsize = ysize = 1;
264
 
        ci->metrics.leftSideBearing = ci->metrics.descent = 0;
265
 
        ci->metrics.rightSideBearing = ci->metrics.ascent = 1;
266
 
    }
267
 
 
268
 
    cfv->bit_width = xsize;
269
 
    cfv->bit_height = ysize;
270
 
#else
271
 
    cfv->bit_width = ci->metrics.rightSideBearing -
272
 
        ci->metrics.leftSideBearing;
273
 
    cfv->bit_height = ci->metrics.ascent + ci->metrics.descent;
274
 
#endif
275
 
 
276
 
    assert(cfv->bp - sp_fp_cur->bitmaps <= sp_fp_cur->bitmap_size);
277
 
    ci->bits = (char *) cfv->bp;
278
 
 
279
 
    cfv->cur_y = 0;
280
 
}
281
 
 
282
 
void
283
 
sp_close_bitmap()
284
 
{
285
 
    CharInfoPtr ci = &sp_fp_cur->encoding[cfv->char_id - sp_fp_cur->master->first_char_id];
286
 
    int         bpr = cfv->bpr;
287
 
 
288
 
    if (bpr == 0)
289
 
        bpr = GLYPH_SIZE(ci, cfv->scanpad);
290
 
    if (!cfv->trunc)
291
 
        finish_line(sp_fp_cur);
292
 
    cfv->trunc = 0;
293
 
    cfv->last_y++;
294
 
    while (cfv->last_y < cfv->bit_height) {
295
 
        finish_line(sp_fp_cur);
296
 
        cfv->last_y++;
297
 
    }
298
 
    if (byte_order != bit_order) {
299
 
        switch (scan) {
300
 
        case 1:
301
 
            break;
302
 
        case 2:
303
 
            TwoByteSwap(cfv->bp, bpr * cfv->bit_height);
304
 
            break;
305
 
        case 4:
306
 
            FourByteSwap(cfv->bp, bpr * cfv->bit_height);
307
 
            break;
308
 
        }
309
 
    }
310
 
}
311
 
 
312
 
int
313
 
sp_build_all_bitmaps(
314
 
    FontPtr     pfont,
315
 
    fsBitmapFormat format,
316
 
    fsBitmapFormatMask fmask)
317
 
{
318
 
    int         ret,
319
 
                glyph = 1,
320
 
                image = BitmapFormatImageRectMin;
321
 
    unsigned long glyph_size;
322
 
    SpeedoFontPtr spf = (SpeedoFontPtr) pfont->fontPrivate;
323
 
    SpeedoMasterFontPtr spmf = spf->master;
324
 
    pointer     bitmaps;
325
 
    int         start,
326
 
                end,
327
 
                i;
328
 
 
329
 
    scan = 1;
330
 
    ret = CheckFSFormat(format, fmask,
331
 
                        &bit_order, &byte_order, &scan, &glyph, &image);
332
 
 
333
 
    pfont->bit = bit_order;
334
 
    pfont->byte = byte_order;
335
 
    pfont->glyph = glyph;
336
 
    pfont->scan = scan;
337
 
    if (ret != Successful)
338
 
        return BadFontFormat;
339
 
 
340
 
    start = spmf->first_char_id;
341
 
    end = spmf->max_id;
342
 
    glyph_size = sp_compute_data_size(pfont, image, glyph, start, end);
343
 
 
344
 
    /* XXX -- MONDO KLUDGE -- add some slop */
345
 
    /*
346
 
     * not sure why this is wanted, but it keeps the packer from going off the
347
 
     * end and toasting us down the line
348
 
     */
349
 
    glyph_size += 20;
350
 
 
351
 
#ifdef DEBUG
352
 
    spf->bitmap_size = glyph_size;
353
 
#endif
354
 
 
355
 
    bitmaps = (pointer) xalloc(glyph_size);
356
 
    if (!bitmaps)
357
 
        return AllocError;
358
 
    bzero((char *) bitmaps, glyph_size);
359
 
 
360
 
    /* set up some state */
361
 
    sp_fp_cur = spf;
362
 
    spf->bitmaps = bitmaps;
363
 
    cfv->format = format;
364
 
    cfv->scanpad = glyph;
365
 
    cfv->bp = bitmaps;
366
 
 
367
 
    for (i = 0; i < spmf->num_chars; i++) {
368
 
        int j;
369
 
        cfv->char_index = spmf->enc[i * 2 + 1];
370
 
        cfv->char_id = spmf->enc[i * 2];
371
 
#ifdef DEBUG
372
 
fprintf(stderr, "build_all_sp_bitmaps:i = %d, Char ID = %d\n", i, cfv->char_id);
373
 
#endif
374
 
        if (!cfv->char_id)
375
 
            continue;
376
 
 
377
 
        /*
378
 
         * See if this character is in the list of ranges specified in the
379
 
         * XLFD name
380
 
         */
381
 
        for (j = 0; j < spf->vals.nranges; j++)
382
 
            if (cfv->char_id >= mincharno(spf->vals.ranges[j]) &&
383
 
                    cfv->char_id <= maxcharno(spf->vals.ranges[j]))
384
 
                break;
385
 
 
386
 
          /* If not, don't realize it. */
387
 
        if (spf->vals.nranges && j == spf->vals.nranges)
388
 
            continue;
389
 
 
390
 
        if (!sp_make_char(cfv->char_index)) {
391
 
 
392
 
#ifdef DEBUG                    /* can be very common with some encodings */
393
 
            SpeedoErr("Can't make char %d\n", cfv->char_index);
394
 
#endif
395
 
        }
396
 
    }
397
 
 
398
 
    return Successful;
399
 
}