~ubuntu-branches/ubuntu/jaunty/texlive-bin/jaunty

« back to all changes in this revision

Viewing changes to build/TeX/libs/t1lib/t1set.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2008-06-26 23:14:59 UTC
  • mfrom: (2.1.30 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080626231459-y02rjsrgtafu83yr
Tags: 2007.dfsg.2-3
add missing source roadmap.fig of roadmap.eps in fontinst documentation
(Closes: #482915) (urgency medium due to RC bug)
(new patch add-missing-fontinst-source)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*--------------------------------------------------------------------------
2
 
  ----- File:        t1set.c 
3
 
  ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
4
 
  ----- Date:        2003-01-02
5
 
  ----- Description: This file is part of the t1-library. It contains
6
 
                     functions for setting characters and strings of
7
 
                     characters.
8
 
  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2003.
9
 
                     As of version 0.5, t1lib is distributed under the
10
 
                     GNU General Public Library Lincense. The
11
 
                     conditions can be found in the files LICENSE and
12
 
                     LGPL, which should reside in the toplevel
13
 
                     directory of the distribution.  Please note that 
14
 
                     there are parts of t1lib that are subject to
15
 
                     other licenses:
16
 
                     The parseAFM-package is copyrighted by Adobe Systems
17
 
                     Inc.
18
 
                     The type1 rasterizer is copyrighted by IBM and the
19
 
                     X11-consortium.
20
 
  ----- Warranties:  Of course, there's NO WARRANTY OF ANY KIND :-)
21
 
  ----- Credits:     I want to thank IBM and the X11-consortium for making
22
 
                     their rasterizer freely available.
23
 
                     Also thanks to Piet Tutelaers for his ps2pk, from
24
 
                     which I took the rasterizer sources in a format
25
 
                     independent from X11.
26
 
                     Thanks to all people who make free software living!
27
 
--------------------------------------------------------------------------*/
28
 
  
29
 
#define T1SET_C
30
 
 
31
 
 
32
 
#include <stdio.h>
33
 
#include <sys/types.h>
34
 
#include <sys/stat.h>
35
 
#include <fcntl.h>
36
 
#if defined(_MSC_VER)
37
 
# include <io.h>
38
 
# include <sys/types.h>
39
 
# include <sys/stat.h>
40
 
#else
41
 
# include <unistd.h>
42
 
#endif
43
 
#include <stdlib.h>
44
 
#include <math.h>
45
 
#include <string.h>
46
 
#include <setjmp.h>
47
 
 
48
 
#include "../type1/ffilest.h" 
49
 
#include "../type1/types.h"
50
 
#include "parseAFM.h" 
51
 
#include "../type1/objects.h"
52
 
#include "../type1/spaces.h"
53
 
#include "../type1/util.h"
54
 
#include "../type1/fontfcn.h"
55
 
#include "../type1/regions.h"
56
 
 
57
 
 
58
 
#include "t1types.h"
59
 
#include "t1extern.h"
60
 
#include "t1set.h"
61
 
#include "t1load.h"
62
 
#include "t1finfo.h"
63
 
#include "t1misc.h"
64
 
#include "t1base.h"
65
 
 
66
 
 
67
 
/* As a fall back */
68
 
#ifndef T1_AA_TYPE16 
69
 
#define T1_AA_TYPE16    short
70
 
#endif
71
 
#ifndef T1_AA_TYPE32 
72
 
#define T1_AA_TYPE32    int
73
 
#endif
74
 
 
75
 
 
76
 
extern char *t1_get_abort_message( int number);
77
 
extern struct region *Interior(struct segment *path, int fillrule);
78
 
extern unsigned T1_AA_TYPE32 T1aa_bg;          /* white value */
79
 
 
80
 
 
81
 
static void T1_ComputeLineParameters( int FontID, int width,
82
 
                                      int mode, float size,
83
 
                                      int *startx, int *endx,
84
 
                                      int *starty, int *endy);
85
 
  
86
 
  
87
 
 
88
 
static int T1_bit=T1GLYPH_BIT;
89
 
static int T1_byte;
90
 
static int T1_pad;
91
 
static int T1_wordsize;
92
 
 
93
 
static int c_shift=8;
94
 
static int s_shift=16;
95
 
static int l_shift=32;
96
 
 
97
 
 
98
 
 
99
 
/* bin_dump(): Print a binary dump of a byte, short and
100
 
   long variable (used for debug purposes only): */
101
 
static void bin_dump_c(unsigned char value, char space_flag)
102
 
{
103
 
  int i,j;
104
 
  
105
 
  for (i=0;i<=7;i++){
106
 
    if ((j=((value)>>i)&0x01))
107
 
      printf("X");
108
 
    else
109
 
      printf(".");
110
 
  }
111
 
  if (space_flag)
112
 
    printf(" ");
113
 
 
114
 
}
115
 
 
116
 
static void bin_dump_s(unsigned short value, char space_flag)
117
 
{
118
 
  int i,j;
119
 
 
120
 
  if (T1_CheckEndian()){
121
 
    for (i=8;i<=15;i++){
122
 
      if ((j=((value)>>i)&0x01))
123
 
        printf("X");
124
 
      else
125
 
        printf(".");
126
 
    }
127
 
    for (i=0;i<=7;i++){
128
 
      if ((j=((value)>>i)&0x01))
129
 
        printf("X");
130
 
      else
131
 
        printf(".");
132
 
    }
133
 
  }
134
 
  else{
135
 
    for (i=0;i<=15;i++){
136
 
      if ((j=((value)>>i)&0x01))
137
 
        printf("X");
138
 
      else
139
 
        printf(".");
140
 
    }
141
 
  }
142
 
  if (space_flag)
143
 
    printf(" ");
144
 
  
145
 
}
146
 
 
147
 
static void bin_dump_l(unsigned long value, char space_flag)
148
 
{
149
 
  int i,j;
150
 
  
151
 
  if (T1_CheckEndian()){
152
 
    for (i=24;i<=31;i++){
153
 
      if ((j=((value)>>i)&0x01))
154
 
        printf("X");
155
 
      else
156
 
        printf(".");
157
 
    }
158
 
    for (i=16;i<=23;i++){
159
 
      if ((j=((value)>>i)&0x01))
160
 
        printf("X");
161
 
      else
162
 
        printf(".");
163
 
    }
164
 
    for (i=8;i<=15;i++){
165
 
      if ((j=((value)>>i)&0x01))
166
 
        printf("X");
167
 
      else
168
 
        printf(".");
169
 
    }
170
 
    for (i=0;i<=7;i++){
171
 
      if ((j=((value)>>i)&0x01))
172
 
        printf("X");
173
 
      else
174
 
        printf(".");
175
 
    }
176
 
  }
177
 
  else{
178
 
    for (i=0;i<=31;i++){
179
 
      if ((j=((value)>>i)&0x01))
180
 
        printf("X");
181
 
      else
182
 
        printf(".");
183
 
    }
184
 
  }
185
 
  if (space_flag)
186
 
    printf(" ");
187
 
 
188
 
}
189
 
 
190
 
 
191
 
 
192
 
/* T1_SetChar(...): Generate the bitmap for a character */
193
 
GLYPH *T1_SetChar( int FontID, char charcode, float size,
194
 
                   T1_TMATRIX *transform)
195
 
{
196
 
  int i;
197
 
  int mode;
198
 
  struct region *area;
199
 
  struct XYspace *Current_S;
200
 
  int cache_flag    = 1;
201
 
  int rot_flag      = 0;
202
 
  unsigned char ucharcode;
203
 
  float strokewidth = 0.0f;
204
 
  volatile int strokeextraflag = 0;
205
 
  
206
 
  
207
 
  FONTSIZEDEPS *font_ptr;
208
 
  FONTPRIVATE  *fontarrayP;
209
 
  
210
 
  volatile int memsize=0;
211
 
  LONG h,w;
212
 
  LONG paddedW;
213
 
 
214
 
  /* We don't implement underlining for characters, but the rasterer
215
 
     implements it. Thus, we use a modflag of constant 0 */
216
 
  int modflag=0;
217
 
 
218
 
  static GLYPH glyph={NULL,{0,0,0,0,0,0},NULL,1};
219
 
 
220
 
 
221
 
  /* We return to this if something goes wrong deep in the rasterizer */
222
 
  if ((i=setjmp( stck_state))!=0) {
223
 
    T1_errno=T1ERR_TYPE1_ABORT;
224
 
    sprintf( err_warn_msg_buf, "t1_abort: Reason: %s",
225
 
             t1_get_abort_message( i));
226
 
    T1_PrintLog( "T1_SetChar()", err_warn_msg_buf,
227
 
               T1LOG_ERROR);
228
 
    return( NULL);
229
 
  }
230
 
 
231
 
  ucharcode=(unsigned char)charcode;
232
 
 
233
 
  
234
 
  /* Reset character glyph, if necessary */
235
 
  if (glyph.bits!=NULL){
236
 
    free(glyph.bits);
237
 
    glyph.bits=NULL;
238
 
  }
239
 
  glyph.metrics.leftSideBearing=0;
240
 
  glyph.metrics.rightSideBearing=0;
241
 
  glyph.metrics.advanceX=0;
242
 
  glyph.metrics.advanceY=0;
243
 
  glyph.metrics.ascent=0;
244
 
  glyph.metrics.descent=0;
245
 
  glyph.pFontCacheInfo=NULL;
246
 
  glyph.bpp=1;  
247
 
  
248
 
  /* First, check for a correct ID */
249
 
  i=T1_CheckForFontID(FontID);
250
 
  if (i==-1){
251
 
    T1_errno=T1ERR_INVALID_FONTID;
252
 
    return(NULL);
253
 
  }
254
 
  /* if necessary load font into memory */
255
 
  if (i==0)
256
 
    if (T1_LoadFont(FontID))
257
 
      return(NULL);
258
 
 
259
 
  /* Check for valid size */
260
 
  if (size<=0.0){
261
 
    T1_errno=T1ERR_INVALID_PARAMETER;
262
 
    return(NULL);
263
 
  }
264
 
 
265
 
  /* Assign padding value */
266
 
  T1_pad=pFontBase->bitmap_pad;
267
 
  if (pFontBase->endian)
268
 
    T1_byte=1;
269
 
  else
270
 
    T1_byte=0;
271
 
  T1_wordsize=T1_pad;
272
 
 
273
 
  fontarrayP=&(pFontBase->pFontArray[FontID]);
274
 
  
275
 
  /* Check if rotation is requested */
276
 
  if (transform!=NULL){
277
 
    /* there's rotation requested => do not cache the resulting bitmap */
278
 
    rot_flag=1;
279
 
    cache_flag=0;
280
 
  }
281
 
  else {
282
 
    rot_flag=0;
283
 
    cache_flag=1;
284
 
  }
285
 
  
286
 
  /* handle stroking stuff */
287
 
  if ( pFontBase->pFontArray[FontID].info_flags & RASTER_STROKED) {
288
 
    /* Stroking requested. If caching is not desired, clear cache_flag.
289
 
       Otherwise, leave it unaffected. */
290
 
    if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) == 0 ) {
291
 
      /* filled glyphs are cached, indicate that character is to be rendered
292
 
         on the fly and not to be cached */
293
 
      strokeextraflag = 1;
294
 
      cache_flag = 0;
295
 
    }
296
 
    strokewidth = pFontBase->pFontArray[FontID].StrokeWidth;
297
 
  }
298
 
  else {
299
 
    /* filling requested. */
300
 
    if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) != 0 ) {
301
 
      /* stroked glyphs are cached, indicate that character is to be rendered
302
 
         on the fly and not to be cached */
303
 
      strokeextraflag = 1;
304
 
      cache_flag = 0;
305
 
    }
306
 
    strokewidth = 0.0f;
307
 
  }
308
 
  
309
 
  /* font is now loaded into memory =>
310
 
     Check for size: */
311
 
  if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
312
 
    font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS);
313
 
    if (font_ptr==NULL){
314
 
      T1_errno=T1ERR_ALLOC_MEM;
315
 
      return(NULL);
316
 
    }
317
 
  }
318
 
  else {/* size is already existent in cache */
319
 
    /* If no rotation and no noncached stroking , try to get character from cache */
320
 
    if ( (rot_flag==0) && (strokeextraflag==0) ) {
321
 
      /* we don't use the .bits entry to check because in newer releases
322
 
         also white glyphs (bits=NULL) are allowed. Rather, we check
323
 
         whether bpp > 0! */
324
 
      if (font_ptr->pFontCache[ucharcode].bpp > 0){
325
 
        /* Character is already in Chache -> create a copy of cache
326
 
           and return a pointer to the result: */
327
 
        memcpy( &glyph, &(font_ptr->pFontCache[ucharcode]), sizeof(GLYPH));
328
 
        paddedW = PAD((glyph.metrics.rightSideBearing-glyph.metrics.leftSideBearing),
329
 
                      T1_pad);
330
 
        if (font_ptr->pFontCache[ucharcode].bits!=NULL) {
331
 
          memsize = (glyph.metrics.ascent-glyph.metrics.descent)*paddedW / 8;
332
 
          glyph.bits = (char *)malloc(memsize*sizeof( char));
333
 
          if (glyph.bits == NULL){
334
 
            T1_errno=T1ERR_ALLOC_MEM;
335
 
            return(NULL);
336
 
          }
337
 
          memcpy( glyph.bits, font_ptr->pFontCache[ucharcode].bits, memsize);
338
 
        }
339
 
        return(&(glyph));
340
 
      }
341
 
    }
342
 
  }
343
 
  /* Setup an appropriate charspace matrix. Note that the rasterizer
344
 
     assumes vertical values with inverted sign! Transformation should
345
 
     create a copy of the local charspace matrix which then still has
346
 
     to be made permanent. */
347
 
  if (rot_flag){
348
 
    Current_S=(struct XYspace *) 
349
 
      Permanent(Scale(Transform (font_ptr->pCharSpaceLocal,
350
 
                                 transform->cxx, - transform->cxy,
351
 
                                 transform->cyx, - transform->cyy),
352
 
                      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
353
 
  }
354
 
  else{
355
 
    Current_S=(struct XYspace *)
356
 
      Permanent(Scale(Transform(font_ptr->pCharSpaceLocal,
357
 
                                1.0, 0.0, 0.0, -1.0),
358
 
                      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
359
 
  }
360
 
  
361
 
  /* fnt_ptr now points to the correct FontSizeDeps-struct =>
362
 
     lets now raster the character */
363
 
  mode=0;
364
 
  area=fontfcnB( FontID, modflag, Current_S,
365
 
                 fontarrayP->pFontEnc,
366
 
                 ucharcode, &mode,
367
 
                 fontarrayP->pType1Data,
368
 
                 DO_RASTER,
369
 
                 strokewidth);
370
 
  KillSpace (Current_S);
371
 
 
372
 
  /* fill the glyph-structure */
373
 
  if (mode > 0) {
374
 
    sprintf( err_warn_msg_buf, "fontfcnB() set mode=%d", mode);
375
 
    T1_PrintLog( "T1_SetChar()", err_warn_msg_buf, T1LOG_WARNING);
376
 
    T1_errno=mode;
377
 
    return(NULL);
378
 
  }
379
 
  if (area == NULL){
380
 
    T1_PrintLog( "T1_SetChar()", "area=NULL returned by fontfcnB()", T1LOG_WARNING);
381
 
    T1_errno=mode;
382
 
    return(NULL);
383
 
  }
384
 
  h = area->ymax - area->ymin;
385
 
  w = area->xmax - area->xmin;
386
 
 
387
 
  if (mode == FF_NOTDEF_SUBST) {
388
 
    sprintf( err_warn_msg_buf,
389
 
             "\".notdef\" substituted for character %d from font %d",
390
 
             ucharcode, FontID);
391
 
    T1_PrintLog( "T1_SetChar()", err_warn_msg_buf, T1LOG_WARNING);
392
 
    mode=0;
393
 
  }
394
 
  
395
 
  paddedW = PAD(w, T1_pad);
396
 
  
397
 
  if (h > 0 && w > 0) {
398
 
    memsize = h * paddedW / 8 + 1;
399
 
    /* This is for the users copy of the character, for security-reasons
400
 
       the original pointer to the cache area is not used. The entry glyph.bits
401
 
       is free'ed every time this function is called: */
402
 
    glyph.bits = (char *)malloc(memsize*sizeof( char));
403
 
    if (glyph.bits == NULL){
404
 
      T1_errno=T1ERR_ALLOC_MEM;
405
 
      /* make sure to get rid of 'area' before leaving! */
406
 
      KillRegion (area);
407
 
      return(NULL);
408
 
    }
409
 
  }
410
 
  else {
411
 
    h = w = 0;
412
 
    area->xmin = area->xmax = 0;
413
 
    area->ymin = area->ymax = 0;
414
 
  }
415
 
 
416
 
  /* Assign metrics */
417
 
  glyph.metrics.leftSideBearing  = area->xmin;
418
 
  glyph.metrics.advanceX   = NEARESTPEL(area->ending.x - area->origin.x);
419
 
  glyph.metrics.advanceY   = - NEARESTPEL(area->ending.y - area->origin.y);
420
 
  glyph.metrics.rightSideBearing = area->xmax;
421
 
  glyph.metrics.descent          = - area->ymax;
422
 
  glyph.metrics.ascent           = - area->ymin;
423
 
 
424
 
  
425
 
  if (h > 0 && w > 0) {
426
 
    (void) memset(glyph.bits, 0, memsize);
427
 
    fill(glyph.bits, h, paddedW, area, T1_byte, T1_bit, T1_wordsize );
428
 
  }
429
 
  
430
 
  /* make sure to get rid of 'area' before leaving! */
431
 
  KillRegion (area);
432
 
  
433
 
  /* Cache glyph if requested, also if it contains only white space */
434
 
  if (cache_flag){
435
 
    /* Copy glyph to cache but be careful not to modify the pixmap
436
 
       entry */
437
 
    font_ptr->pFontCache[ucharcode].metrics.leftSideBearing=glyph.metrics.leftSideBearing;
438
 
    font_ptr->pFontCache[ucharcode].metrics.rightSideBearing=glyph.metrics.rightSideBearing;
439
 
    font_ptr->pFontCache[ucharcode].metrics.advanceX=glyph.metrics.advanceX;
440
 
    font_ptr->pFontCache[ucharcode].metrics.advanceY=glyph.metrics.advanceY;
441
 
    font_ptr->pFontCache[ucharcode].metrics.ascent=glyph.metrics.ascent;
442
 
    font_ptr->pFontCache[ucharcode].metrics.descent=glyph.metrics.descent;
443
 
    font_ptr->pFontCache[ucharcode].pFontCacheInfo=glyph.pFontCacheInfo;
444
 
    font_ptr->pFontCache[ucharcode].bpp=glyph.bpp;
445
 
    if (glyph.bits==NULL) {
446
 
      font_ptr->pFontCache[ucharcode].bits=NULL;
447
 
    }
448
 
    else {
449
 
      font_ptr->pFontCache[ucharcode].bits = (char *)malloc(memsize*sizeof( char));
450
 
      if (font_ptr->pFontCache[ucharcode].bits == NULL){
451
 
        T1_errno=T1ERR_ALLOC_MEM;
452
 
        return(NULL);
453
 
      }
454
 
      /* ... and copy bitmap to cache area: */
455
 
      memcpy( font_ptr->pFontCache[ucharcode].bits, glyph.bits, memsize);
456
 
    }
457
 
    
458
 
  }
459
 
 
460
 
 
461
 
  return(&glyph);
462
 
}
463
 
 
464
 
 
465
 
 
466
 
/* T1_SetString(...): Generate the bitmap for a string of characters */
467
 
GLYPH *T1_SetString( int FontID, char *string, volatile int len, 
468
 
                     long spaceoff, int modflag, float size,
469
 
                     T1_TMATRIX *transform)
470
 
{
471
 
  volatile int i, j=0, k;
472
 
  int mode;
473
 
  /* initialize this to NULL just to be on the safe side */
474
 
  struct region *area = NULL;
475
 
  struct XYspace *Current_S, *S;
476
 
  int cache_flag=1;
477
 
  volatile int rot_flag=0;
478
 
  int *kern_pairs;       /* use for accessing the kern pairs if kerning is
479
 
                            requested */
480
 
  int no_chars=0;        /* The number of characters in the string */
481
 
  static int lastno_chars=0;
482
 
  float factor;
483
 
  long spacewidth;       /* This is given to fontfcnb_string() */
484
 
  float strokewidth = 0.0f;
485
 
  volatile int strokeextraflag = 0;
486
 
  
487
 
  
488
 
  FONTSIZEDEPS *font_ptr;
489
 
  FONTPRIVATE  *fontarrayP;
490
 
  
491
 
 
492
 
  volatile int memsize=0;
493
 
 
494
 
  long h,w;
495
 
  long paddedW, char_paddedW;
496
 
  int h_anchor, v_anchor;
497
 
  static int *pixel_h_anchor_corr=NULL;
498
 
  static int *flags=NULL;
499
 
  int lsb_min, rsb_max;
500
 
  long overallwidth=0;
501
 
  long overallascent=0;
502
 
  long overalldescent=0;
503
 
 
504
 
  int underline_startx, underline_starty, underline_endx, underline_endy;
505
 
  int overline_startx, overline_starty, overline_endx, overline_endy;
506
 
  int overstrike_startx, overstrike_starty, overstrike_endx, overstrike_endy;
507
 
  int start, middle;
508
 
  int afm_ind;
509
 
  
510
 
  char startmask, endmask;
511
 
  static unsigned char *r2lstring;
512
 
  static int r2l_len=0;
513
 
  
514
 
  static GLYPH string_glyph={NULL,{0,0,0,0,0,0},NULL,1};
515
 
  GLYPH *currchar;
516
 
 
517
 
  
518
 
  
519
 
  /* The following are for bitmap blitting */
520
 
  long BitShift;
521
 
  long ByteOffset;
522
 
  /* pad=8 */
523
 
  unsigned T1_AA_TYPE16 BitBuf_c;
524
 
  unsigned char *p_c;
525
 
  unsigned char *Target_c;
526
 
  /* pad=16 */
527
 
  unsigned T1_AA_TYPE32 BitBuf_s;
528
 
  unsigned T1_AA_TYPE16 *p_s;
529
 
  unsigned T1_AA_TYPE16 *Target_s;
530
 
#ifdef T1_AA_TYPE64 
531
 
  /* pad=32 */
532
 
  unsigned T1_AA_TYPE64 BitBuf_l;
533
 
  unsigned T1_AA_TYPE32 *p_l;
534
 
  unsigned T1_AA_TYPE32 *Target_l;
535
 
#endif
536
 
  unsigned char *ustring;
537
 
  
538
 
 
539
 
  /* We return to this if something goes wrong deep in the rasterizer */
540
 
  if ((i=setjmp( stck_state))!=0) {
541
 
    T1_errno=T1ERR_TYPE1_ABORT;
542
 
    sprintf( err_warn_msg_buf, "t1_abort: Reason: %s",
543
 
             t1_get_abort_message( i));
544
 
    T1_PrintLog( "T1_SetString()", err_warn_msg_buf,
545
 
               T1LOG_ERROR);
546
 
    return( NULL);
547
 
  }
548
 
 
549
 
  /* force string elements into unsigned */
550
 
  ustring=(unsigned char*)string;
551
 
 
552
 
 
553
 
  /* Check for valid string */
554
 
  if (string==NULL){
555
 
    T1_errno=T1ERR_INVALID_PARAMETER;
556
 
    return(NULL);
557
 
  }
558
 
 
559
 
  /* Reorganize if required */
560
 
  if (modflag & T1_RIGHT_TO_LEFT){
561
 
    if (len)
562
 
      i=len;
563
 
    else
564
 
      i=j=strlen( string);
565
 
    if (i+1>r2l_len){
566
 
      if (r2lstring!=NULL)
567
 
        free( r2lstring);
568
 
      r2lstring=(unsigned char *)malloc( (i+1)*sizeof(char));
569
 
      r2l_len=i+1;
570
 
    }
571
 
    j--;
572
 
    while ( i--) {
573
 
      r2lstring[j-i]=ustring[i];
574
 
    }
575
 
    ustring=r2lstring;
576
 
    len=j+1;
577
 
  }
578
 
  
579
 
  
580
 
  /* Reset string glyph, if necessary */
581
 
  if (string_glyph.bits!=NULL){
582
 
    free(string_glyph.bits);
583
 
    string_glyph.bits=NULL;
584
 
  }
585
 
  string_glyph.metrics.leftSideBearing=0;
586
 
  string_glyph.metrics.rightSideBearing=0;
587
 
  string_glyph.metrics.advanceX=0;
588
 
  string_glyph.metrics.advanceY=0;
589
 
  string_glyph.metrics.ascent=0;
590
 
  string_glyph.metrics.descent=0;
591
 
  string_glyph.pFontCacheInfo=NULL;
592
 
  string_glyph.bpp=1;
593
 
  
594
 
  /* We don't want to cache the resulting bitmap: */
595
 
  cache_flag=0;
596
 
  
597
 
  /* First, check for a correct ID */
598
 
  i=T1_CheckForFontID(FontID);
599
 
  if (i==-1){
600
 
    T1_errno=T1ERR_INVALID_FONTID;
601
 
    return(NULL);
602
 
  }
603
 
  
604
 
  /* if necessary load font into memory */
605
 
  if (i==0)
606
 
    if (T1_LoadFont(FontID))
607
 
      return(NULL);
608
 
 
609
 
  /* If no AFM info is present, we return an error */
610
 
  if (pFontBase->pFontArray[FontID].pAFMData==NULL) {
611
 
    T1_errno=T1ERR_NO_AFM_DATA;
612
 
    return(NULL);
613
 
  }
614
 
 
615
 
  /* Check for valid size */
616
 
  if (size<=0.0){
617
 
    T1_errno=T1ERR_INVALID_PARAMETER;
618
 
    return(NULL);
619
 
  }
620
 
 
621
 
  /* Assign padding value */
622
 
  T1_pad=pFontBase->bitmap_pad;
623
 
  if (pFontBase->endian)
624
 
    T1_byte=1;
625
 
  else
626
 
    T1_byte=0;
627
 
  T1_wordsize=T1_pad;
628
 
 
629
 
  fontarrayP=&(pFontBase->pFontArray[FontID]);
630
 
  
631
 
  /* Check if rotation is requested */
632
 
  if (transform!=NULL){
633
 
    /* there's rotation requested => do not cache the resulting bitmap */
634
 
    rot_flag=1;
635
 
    cache_flag=0;
636
 
  }
637
 
  
638
 
  /* handle stroking stuff */
639
 
  if ( pFontBase->pFontArray[FontID].info_flags & RASTER_STROKED) {
640
 
    /* Stroking requested. If caching is not desired, clear cache_flag.
641
 
       Otherwise, leave it unaffected. */
642
 
    if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) == 0 ) {
643
 
      /* filled glyphs are cached, indicate that character is to be rendered
644
 
         on the fly and not to be cached */
645
 
      strokeextraflag = 1;
646
 
      cache_flag = 0;
647
 
    }
648
 
    strokewidth = pFontBase->pFontArray[FontID].StrokeWidth;
649
 
  }
650
 
  else {
651
 
    /* filling requested. */
652
 
    if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) != 0 ) {
653
 
      /* stroked glyphs are cached, indicate that character is to be rendered
654
 
         on the fly and not to be cached */
655
 
      strokeextraflag = 1;
656
 
      cache_flag = 0;
657
 
    }
658
 
    strokewidth = 0.0f;
659
 
  }
660
 
  
661
 
  /* font is now loaded into memory =>
662
 
     Check for size: */
663
 
  if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
664
 
    font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS);
665
 
    if (font_ptr==NULL){
666
 
      T1_errno=T1ERR_ALLOC_MEM;
667
 
      return(NULL);
668
 
    }
669
 
  }
670
 
  
671
 
  /* Now comes string specific stuff: Get length of string and create an
672
 
     array of integers where to store the bitmap positioning dimens: */
673
 
  if (len<0){  /* invalid length */
674
 
    T1_errno=T1ERR_INVALID_PARAMETER;
675
 
    return(NULL);
676
 
  }
677
 
  
678
 
  if (len==0) /* should be computed assuming "normal" 0-terminated string,
679
 
                 or R2L-part has already been computed! */
680
 
    no_chars=strlen(string);
681
 
  else        /* use value given on command line */
682
 
    no_chars=len;
683
 
 
684
 
  /* If necessary, allocate memory */
685
 
  if (no_chars>lastno_chars){
686
 
    if (pixel_h_anchor_corr!=NULL){
687
 
      free(pixel_h_anchor_corr);
688
 
    }
689
 
    if (flags!=NULL){
690
 
      free(flags);
691
 
    }
692
 
    pixel_h_anchor_corr=(int *)calloc(no_chars, sizeof(int));
693
 
    flags=(int *)calloc(no_chars, sizeof(int));
694
 
    lastno_chars=no_chars;
695
 
  }
696
 
  else{
697
 
    /* Reset flags  and position array */
698
 
    for (i=0; i<no_chars; i++){
699
 
      flags[i]=0;
700
 
      pixel_h_anchor_corr[i]=0;
701
 
    }
702
 
  }
703
 
  
704
 
  /* Setup an appropriate charspace matrix. Note that the rasterizer
705
 
     assumes vertical values with inverted sign! Transformation should
706
 
     create a copy of the local charspace matrix which then still has
707
 
     to be made permanent. */
708
 
  if (rot_flag){
709
 
    Current_S=(struct XYspace *) 
710
 
      Permanent(Scale(Transform (font_ptr->pCharSpaceLocal,
711
 
                                 transform->cxx, - transform->cxy,
712
 
                                 transform->cyx, - transform->cyy),
713
 
                      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
714
 
  }
715
 
  else{
716
 
    Current_S=(struct XYspace *)
717
 
      Permanent(Scale(Transform(font_ptr->pCharSpaceLocal,
718
 
                                1.0, 0.0, 0.0, -1.0),
719
 
                      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
720
 
  }
721
 
  
722
 
  /* Compute the correct spacewidth value (in charspace units). The
723
 
     value supplied by the user is interpreted as an offset in
724
 
     char space units:
725
 
     */
726
 
  spacewidth=T1_GetCharWidth(FontID,fontarrayP->space_position)+spaceoff;
727
 
  
728
 
  
729
 
  /* The following if (rot_flag==0){ ... } contains the whole code
730
 
     to execute when the string is oriented horizontal. Then, there's
731
 
     the possibility of concatenating most probably existent bitmaps
732
 
     from the Cache, which should be much faster than every time raster
733
 
     all the characters.
734
 
     */
735
 
  /* First, ensure that all needed characters are in the Cache; if not,
736
 
     generate them */
737
 
  if ( (rot_flag==0) && (strokeextraflag==0) ){
738
 
    overallwidth=0;
739
 
    for (i=0; i<no_chars; i++) {
740
 
      currchar= &(font_ptr->pFontCache[ustring[i]]);
741
 
      if (currchar->bpp<1) {
742
 
        flags[i]=0;
743
 
        mode=0;
744
 
        /*  Don't try to generate space-character: */
745
 
        if (ustring[i]!=fontarrayP->space_position){
746
 
          /* Note: Never underline etc. cached chars --> modflag=0 */ 
747
 
          area=fontfcnB( FontID, 0, Current_S,
748
 
                         fontarrayP->pFontEnc,
749
 
                         ustring[i], &mode,
750
 
                         fontarrayP->pType1Data,
751
 
                         DO_RASTER,
752
 
                         strokewidth);
753
 
 
754
 
          /* fill the glyph-structure */
755
 
          if (mode > 0) {
756
 
            sprintf( err_warn_msg_buf, "fontfcnB() set mode=%d", mode);
757
 
            T1_PrintLog( "T1_SetString()", err_warn_msg_buf, T1LOG_WARNING);
758
 
            T1_errno=mode;
759
 
            /* Make sure to free the region if it's non-NULL */
760
 
            if (area){
761
 
              KillRegion (area);
762
 
            }
763
 
            return(NULL);
764
 
          }
765
 
          if (area == NULL){
766
 
            T1_PrintLog( "T1_SetString()", "area=NULL returned by fontfcnB()", T1LOG_WARNING);
767
 
            T1_errno=mode;
768
 
            return(NULL);
769
 
          }
770
 
          
771
 
          if (mode == FF_NOTDEF_SUBST) {
772
 
            sprintf( err_warn_msg_buf,
773
 
                     "\".notdef\" substituted in string[%d] (=character %d) from font %d",
774
 
                     i, ustring[i], FontID);
775
 
            T1_PrintLog( "T1_SetString()", err_warn_msg_buf, T1LOG_WARNING);
776
 
            mode=0;
777
 
            flags[i]=1; /* indicates that .notdef has been substituted */
778
 
          }
779
 
          
780
 
          h = area->ymax - area->ymin;
781
 
          w = area->xmax - area->xmin;
782
 
          
783
 
          if (h > 0 && w > 0) {  /* bitmap contains pixels */
784
 
            paddedW = PAD(w, T1_pad);
785
 
            memsize = h * paddedW / 8 + 1;
786
 
            currchar->bits = (char *)malloc(memsize*sizeof( char));
787
 
            if (currchar->bits == NULL) {
788
 
              T1_errno=T1ERR_ALLOC_MEM;
789
 
              /* Make sure to free up the region if it's non-NULL */
790
 
              if (area){
791
 
                KillRegion (area);
792
 
              }
793
 
              return(NULL);
794
 
            }
795
 
            (void) memset(currchar->bits, 0, memsize);
796
 
            fill(currchar->bits, h, paddedW, area,
797
 
                 T1_byte, T1_bit, T1_wordsize );
798
 
          }
799
 
          /* area valid -> set metrics in cache for that character */ 
800
 
          currchar->metrics.leftSideBearing  = area->xmin;
801
 
          currchar->metrics.advanceX   = NEARESTPEL(area->ending.x - area->origin.x);
802
 
          currchar->metrics.advanceY   = - NEARESTPEL(area->ending.y - area->origin.y);
803
 
          currchar->metrics.rightSideBearing = area->xmax;
804
 
          currchar->metrics.descent          = - area->ymax;
805
 
          currchar->metrics.ascent           = - area->ymin;
806
 
          currchar->bpp=1;
807
 
          
808
 
          /* By this point, it's clear that the 'area' struct exists,
809
 
             and that we no longer need it, so free it up. */
810
 
          KillRegion (area);
811
 
        }
812
 
      } /* end of if ( ... ), needed characters are now in cache! */
813
 
    } /* end of for (i<no_chars) loop */
814
 
    /* we still have to delete the Space */
815
 
    KillSpace (Current_S);
816
 
 
817
 
    /* We've to compute the scale factor: */
818
 
    factor=size*DeviceSpecifics.scale_x/1000;
819
 
 
820
 
    /* h_anchor is the horizontal position in the resulting bitmap;
821
 
       it is incremented on the fly and of course initially 0! */
822
 
    h_anchor=0;
823
 
    /* These are the initial values for left and right sidebearing */
824
 
    rsb_max=-30000;
825
 
    lsb_min= 30000;
826
 
    overallascent=-30000;
827
 
    overalldescent=30000;
828
 
    for (i=0;i<no_chars;i++){
829
 
      /* first get index into AFM-tables */
830
 
      afm_ind=pFontBase->pFontArray[FontID].pEncMap[(int) ustring[i]];
831
 
      /* Advance to next character in high resolution */
832
 
      if (ustring[i]==fontarrayP->space_position)
833
 
        h_anchor +=(int)spacewidth;
834
 
      /* check for a substituted char or notdef and get missing escapement */
835
 
      else if (afm_ind==0) {
836
 
        /* Setup apropriate charspace matrix */
837
 
        S=(struct XYspace *)IDENTITY;
838
 
        /* Make this permanent so that scaling it in fontfcnB_ByName will
839
 
           make a duplicate of it, and this duplicate can thus be safely
840
 
           destroyed.  Fixes the somewhat smaller memory leak */
841
 
        S=(struct XYspace *)Permanent
842
 
          (Transform(S, pFontBase->pFontArray[FontID].FontTransform[0],
843
 
                     pFontBase->pFontArray[FontID].FontTransform[1],
844
 
                     pFontBase->pFontArray[FontID].FontTransform[2],
845
 
                     pFontBase->pFontArray[FontID].FontTransform[3]));
846
 
        /* Get metrics values */
847
 
        area=fontfcnB_ByName( FontID, 0, S, ".notdef", &mode,
848
 
                              pFontBase->pFontArray[FontID].pType1Data, DO_RASTER);
849
 
        if (area==NULL || mode!=0){
850
 
          sprintf( err_warn_msg_buf,
851
 
                   "Could not get charspace representation of \".notdef\", Font %d, mode=%d!",
852
 
                   FontID, mode);
853
 
          T1_PrintLog( "T1_SetString()", err_warn_msg_buf,
854
 
                       T1LOG_ERROR);
855
 
          T1_errno=mode;
856
 
          return( NULL);
857
 
        }
858
 
        /* value to add to hanchor */ 
859
 
        h_anchor +=NEARESTPEL(area->ending.x);
860
 
        /* make sure to free S */
861
 
        if (S) {
862
 
          KillSpace (S);
863
 
        }
864
 
        /* make sure to free area */
865
 
        if (area) {
866
 
          KillRegion (area);
867
 
        }
868
 
      }
869
 
      else{
870
 
        currchar=&(font_ptr->pFontCache[ustring[i]]);
871
 
        pixel_h_anchor_corr[i]=((int)floor(h_anchor*factor+0.5));
872
 
        /* Store maximum rsb ...*/
873
 
        if ( pixel_h_anchor_corr[i]+currchar->metrics.rightSideBearing > rsb_max){
874
 
          rsb_max=pixel_h_anchor_corr[i]+currchar->metrics.rightSideBearing;
875
 
        }
876
 
        /* ... and minimum lsb */
877
 
        if ( pixel_h_anchor_corr[i]+currchar->metrics.leftSideBearing < lsb_min){
878
 
          lsb_min=pixel_h_anchor_corr[i]+currchar->metrics.leftSideBearing;
879
 
        }
880
 
        /* Advance by current chars width */
881
 
        /*      h_anchor +=T1_GetCharWidth( FontID, ustring[i]); */
882
 
        if (afm_ind>0) { /* we have a standard character */
883
 
          h_anchor +=(fontarrayP->pAFMData->cmi[afm_ind-1].wx) * fontarrayP->extend;
884
 
        }
885
 
        else { /* afm_ind must be negative so that we have a composite char */
886
 
          h_anchor +=(fontarrayP->pAFMData->ccd[-(afm_ind+1)].wx) * fontarrayP->extend;
887
 
        }
888
 
        /* If kerning, insert kerning amount */
889
 
        if ((i<no_chars -1) && (modflag & T1_KERNING))
890
 
          h_anchor +=T1_GetKerning( FontID, ustring[i], ustring[i+1]);
891
 
        
892
 
        /* We still have to care for vertical metrics: */
893
 
        if (currchar->metrics.ascent>overallascent)
894
 
          overallascent=currchar->metrics.ascent;
895
 
        if (currchar->metrics.descent<overalldescent)
896
 
          overalldescent=currchar->metrics.descent;
897
 
      }
898
 
    }
899
 
    string_glyph.metrics.advanceX=(int)floor(h_anchor*factor+0.5);
900
 
 
901
 
    /* We have to check for underlining and such things. They may affect the
902
 
       bounding box of the glyph */
903
 
    if (modflag & T1_UNDERLINE){
904
 
      T1_ComputeLineParameters( FontID, T1_UNDERLINE,
905
 
                                string_glyph.metrics.advanceX,
906
 
                                size,
907
 
                                &underline_startx, &underline_endx,
908
 
                                &underline_starty, &underline_endy);
909
 
      /* Check whether rsb is affected ...*/
910
 
      if ( underline_endx > rsb_max){
911
 
        rsb_max=underline_endx;
912
 
      }
913
 
      /* ... and for lsb */
914
 
      if ( underline_startx < lsb_min){
915
 
        lsb_min=underline_startx;
916
 
      }
917
 
 
918
 
      /* Vertical metrics may also be affected. */
919
 
      if (underline_starty > overallascent)
920
 
        overallascent=underline_starty;
921
 
      if (underline_endy < overalldescent)
922
 
        overalldescent=underline_endy;
923
 
    }
924
 
    if (modflag & T1_OVERLINE){
925
 
      T1_ComputeLineParameters( FontID, T1_OVERLINE,
926
 
                                string_glyph.metrics.advanceX,
927
 
                                size,
928
 
                                &overline_startx, &overline_endx,
929
 
                                &overline_starty, &overline_endy);
930
 
      /* Check whether rsb is affected ...*/
931
 
      if ( overline_endx > rsb_max){
932
 
        rsb_max=overline_endx;
933
 
      }
934
 
      /* ... and for lsb */
935
 
      if ( overline_startx < lsb_min){
936
 
        lsb_min=overline_startx;
937
 
      }
938
 
 
939
 
      /* Vertical metrics may also be affected. */
940
 
      if (overline_starty > overallascent)
941
 
        overallascent=overline_starty;
942
 
      if (overline_endy < overalldescent)
943
 
        overalldescent=overline_endy;
944
 
    }
945
 
    if (modflag & T1_OVERSTRIKE){
946
 
      T1_ComputeLineParameters( FontID, T1_OVERSTRIKE,
947
 
                                string_glyph.metrics.advanceX,
948
 
                                size,
949
 
                                &overstrike_startx, &overstrike_endx,
950
 
                                &overstrike_starty, &overstrike_endy);
951
 
      /* Check whether rsb is affected ...*/
952
 
      if ( overstrike_endx > rsb_max){
953
 
        rsb_max=overstrike_endx;
954
 
      }
955
 
      /* ... and for lsb */
956
 
      if ( overstrike_startx < lsb_min){
957
 
        lsb_min=overstrike_startx;
958
 
      }
959
 
 
960
 
      /* Vertical metrics may also be affected. */
961
 
      if (overstrike_starty > overallascent)
962
 
        overallascent=overstrike_starty;
963
 
      if (overstrike_endy < overalldescent)
964
 
        overalldescent=overstrike_endy;
965
 
    }
966
 
    
967
 
 
968
 
    
969
 
    /* Set the string-glyphs' metrics: */
970
 
    /* Bearings: */
971
 
    string_glyph.metrics.rightSideBearing=rsb_max;      
972
 
    string_glyph.metrics.leftSideBearing=lsb_min;
973
 
    /* ascent and descent: */
974
 
    string_glyph.metrics.ascent=overallascent;
975
 
    string_glyph.metrics.descent=overalldescent;
976
 
 
977
 
    
978
 
 
979
 
    /* Now, allocate memory for the resulting bitmap and set it to 0: */
980
 
    h=overallascent - overalldescent;
981
 
    w=string_glyph.metrics.rightSideBearing-string_glyph.metrics.leftSideBearing;
982
 
    
983
 
    paddedW = PAD( w, T1_pad);
984
 
    if ( h > 0 && w > 0){
985
 
      memsize = h * paddedW / 8;
986
 
      /* We alloc some amount more in order to avoid alignment check in
987
 
         bit-blitting loop */
988
 
      memsize += T1_pad/8;
989
 
      string_glyph.bits = (char *)malloc( memsize);
990
 
      if (string_glyph.bits == NULL) {
991
 
        T1_errno=T1ERR_ALLOC_MEM;
992
 
        return(NULL);
993
 
      }
994
 
      
995
 
    }
996
 
    else {
997
 
    /* We have only characters without pixels in the string ->
998
 
       we allow this and only set the advance width in the glyph.
999
 
       The bits pointer will be NULL. We reset rsb and lsb */
1000
 
      string_glyph.metrics.rightSideBearing=0;      
1001
 
      string_glyph.metrics.leftSideBearing=0;
1002
 
      string_glyph.metrics.ascent=0;      
1003
 
      string_glyph.metrics.descent=0;
1004
 
    }
1005
 
    
1006
 
    if (string_glyph.bits != NULL) {
1007
 
      
1008
 
      memset(string_glyph.bits, 0, memsize);
1009
 
      
1010
 
      /* Now comes the loop for bitmap blitting: */
1011
 
      for (i=0;i<no_chars;i++){
1012
 
        /* Get pointer to character number i of string: */
1013
 
        currchar=&(font_ptr->pFontCache[ustring[i]]);
1014
 
        
1015
 
        /* First, we have to correct the positioning values to refer to
1016
 
           the bitmap BBox */
1017
 
        pixel_h_anchor_corr[i] -= lsb_min;
1018
 
        pixel_h_anchor_corr[i] += currchar->metrics.leftSideBearing;    
1019
 
        
1020
 
        /* Compute vertical anchor for current char-bitmap: */
1021
 
        v_anchor=overallascent - currchar->metrics.ascent;
1022
 
        char_paddedW=PAD( currchar->metrics.rightSideBearing
1023
 
                          - currchar->metrics.leftSideBearing , T1_pad);
1024
 
        /* We have to check for Big Endian. In that case, we have to
1025
 
           act on byte-level */
1026
 
        if (T1_byte){
1027
 
          BitShift =  pixel_h_anchor_corr[i] % 8;
1028
 
          ByteOffset = pixel_h_anchor_corr[i] / 8;
1029
 
        }
1030
 
        else { 
1031
 
          BitShift =  pixel_h_anchor_corr[i] % T1_pad;
1032
 
          ByteOffset = pixel_h_anchor_corr[i] / T1_pad;
1033
 
          if (T1_pad==32)
1034
 
            ByteOffset *=4;
1035
 
          else if (T1_pad==16)
1036
 
            ByteOffset *=2;
1037
 
        }  
1038
 
#ifdef T1_AA_TYPE64
1039
 
        /* We compile this part only if long is 64 bits to be conform to ANSI C */
1040
 
        if (T1_pad==32 && T1_byte==0){
1041
 
          /* The following loop steps through the lines of the character bitmap: */
1042
 
          for (j=0;j<currchar->metrics.ascent-currchar->metrics.descent;j++){
1043
 
            Target_l= (unsigned T1_AA_TYPE32 *)(string_glyph.bits +((v_anchor+j)*paddedW/8)
1044
 
                                        +ByteOffset);
1045
 
            /* The following loop copies the scanline of a character bitmap: */
1046
 
            if (currchar->bits != NULL) {
1047
 
              p_l = (unsigned T1_AA_TYPE32 *)(currchar->bits+(char_paddedW/8*j));
1048
 
              if (BitShift == 0) {
1049
 
                for (k=char_paddedW >> 5; k; k--)
1050
 
                  *Target_l++ |= *p_l++;
1051
 
              } else {
1052
 
                for (k=0; k < char_paddedW / 32 ; k++){
1053
 
                  BitBuf_l= ((T1_AA_TYPE64)(*p_l++)) << BitShift;
1054
 
                  *Target_l++ |= BitBuf_l;
1055
 
                  *Target_l |= BitBuf_l>>l_shift;
1056
 
                } /* End of for ( .. ) stepping through columns */
1057
 
              }
1058
 
            } /* End of if(currchar->bits != NULL) */
1059
 
          } /* End of for( .. ) steppin' through lines of char bitmap */
1060
 
        }/* end if (T1_pad==32) */
1061
 
        else
1062
 
#endif 
1063
 
          if (T1_pad==16 && T1_byte==0){
1064
 
            /* The following loop steps through the lines of the character bitmap: */
1065
 
            for (j=0;j<currchar->metrics.ascent-currchar->metrics.descent;j++){
1066
 
              Target_s= (unsigned T1_AA_TYPE16 *)(string_glyph.bits +((v_anchor+j)*paddedW/8)
1067
 
                                           +ByteOffset);
1068
 
              /* The following loop copies the scanline of a character bitmap: */
1069
 
              if (currchar->bits != NULL) {
1070
 
                p_s = (unsigned  T1_AA_TYPE16 *)(currchar->bits+(char_paddedW/8*j));
1071
 
                if (BitShift == 0) {
1072
 
                  for (k=char_paddedW >> 4; k; k--)
1073
 
                    *Target_s++ |= *p_s++;
1074
 
                }
1075
 
                else{
1076
 
                  for (k=char_paddedW >> 4; k; k--){
1077
 
                    BitBuf_s= ((T1_AA_TYPE32)(*p_s++))<<BitShift;
1078
 
                    *Target_s++ |= BitBuf_s;
1079
 
                    *Target_s |= BitBuf_s>>s_shift;
1080
 
                  } /* End of for ( .. ) stepping through columns */
1081
 
                }
1082
 
              } /* End of if(currchar->bits != NULL) */
1083
 
            } /* End of for( .. ) steppin' through lines of char bitmap */
1084
 
          }/* end if (T1_pad==16 */
1085
 
          else{ /* T1_pad = 8 or Big Endian machine */
1086
 
            /* The following loop steps through the lines of the character bitmap: */
1087
 
            for (j=0;j<currchar->metrics.ascent-currchar->metrics.descent;j++){
1088
 
              Target_c= (unsigned char *)(string_glyph.bits +((v_anchor+j)*paddedW/8)
1089
 
                                          +ByteOffset);
1090
 
              /* The following loop copies the scanline of a character bitmap: */
1091
 
              if (currchar->bits != NULL) {
1092
 
                p_c = (unsigned char *)(currchar->bits+(char_paddedW/8*j));
1093
 
                if (BitShift == 0){
1094
 
                  for (k=char_paddedW >> 3; k; k--)
1095
 
                    *Target_c++ |= *p_c++;
1096
 
                }
1097
 
                else{
1098
 
                  for (k=char_paddedW >> 3; k; k--){
1099
 
                    BitBuf_c = ((T1_AA_TYPE16)(*p_c++)) << BitShift;
1100
 
                    *Target_c++ |= BitBuf_c;
1101
 
                    *Target_c |= BitBuf_c>>c_shift;
1102
 
                  } /* End of for ( .. ) stepping through columns */
1103
 
                }
1104
 
              } /* End of if(currchar->bits != NULL) */
1105
 
            } /* End of for( .. ) steppin' through lines of char bitmap */
1106
 
          } /* end if (T1_pad==8) and/or BigEndian  */
1107
 
      }
1108
 
    } /* if (string_glyph.bits != NULL) */
1109
 
    
1110
 
    
1111
 
    /* We now put the underlining rule on the glyph */
1112
 
    if (modflag & T1_UNDERLINE){
1113
 
      start=-string_glyph.metrics.leftSideBearing;
1114
 
      for (i=string_glyph.metrics.ascent-underline_starty;
1115
 
           i<string_glyph.metrics.ascent-underline_endy; i++){
1116
 
        start =-string_glyph.metrics.leftSideBearing +
1117
 
          (int) floor((double)(string_glyph.metrics.ascent-i)
1118
 
                      *fontarrayP->slant+0.5);
1119
 
        middle = ((start+string_glyph.metrics.advanceX) / 8) - (start / 8);
1120
 
        startmask = 0xFF << (start % 8);
1121
 
        endmask = (char) ~(0xFF << ((start+string_glyph.metrics.advanceX) % 8));
1122
 
        Target_c= (unsigned char *)(string_glyph.bits +(i*paddedW/8)
1123
 
                                    + (start / 8));
1124
 
        j=middle;
1125
 
        if (j == 0)
1126
 
          *Target_c++ |= startmask & endmask;
1127
 
        else {
1128
 
          *Target_c++ |= startmask;
1129
 
          while (--j > 0)
1130
 
            *Target_c++ = (unsigned char) 0xFF;
1131
 
          if ((endmask))
1132
 
            *Target_c |= endmask;
1133
 
        }
1134
 
      }
1135
 
    }
1136
 
    /* Put an overstrike rule on the glyph */
1137
 
    if (modflag & T1_OVERSTRIKE){
1138
 
      start=-string_glyph.metrics.leftSideBearing;
1139
 
      for (i=string_glyph.metrics.ascent-overstrike_starty;
1140
 
           i<string_glyph.metrics.ascent-overstrike_endy; i++){
1141
 
        start =-string_glyph.metrics.leftSideBearing +
1142
 
          (int) floor((double)(string_glyph.metrics.ascent-i)
1143
 
                      *fontarrayP->slant+0.5);
1144
 
        middle = ((start+string_glyph.metrics.advanceX) / 8) - (start / 8);
1145
 
        startmask = 0xFF << (start % 8);
1146
 
        endmask = (char) ~(0xFF << ((start+string_glyph.metrics.advanceX) % 8));
1147
 
        Target_c= (unsigned char *)(string_glyph.bits +(i*paddedW/8)
1148
 
                                    + (start / 8));
1149
 
        j=middle;
1150
 
        if (j == 0)
1151
 
          *Target_c++ |= startmask & endmask;
1152
 
        else {
1153
 
          *Target_c++ |= startmask;
1154
 
          while (--j > 0)
1155
 
            *Target_c++ = (unsigned char) 0xFF;
1156
 
          if ((endmask))
1157
 
            *Target_c |= endmask;
1158
 
        }
1159
 
      }
1160
 
    }
1161
 
    /* Put an overline rule */
1162
 
    if (modflag & T1_OVERLINE){
1163
 
      start=-string_glyph.metrics.leftSideBearing;
1164
 
      for (i=string_glyph.metrics.ascent-overline_starty;
1165
 
           i<string_glyph.metrics.ascent-overline_endy; i++){
1166
 
        start =-string_glyph.metrics.leftSideBearing +
1167
 
          (int) floor((double)(string_glyph.metrics.ascent-i)
1168
 
                      *fontarrayP->slant+0.5);
1169
 
        middle = ((start+string_glyph.metrics.advanceX) / 8) - (start / 8);
1170
 
        startmask = 0xFF << (start % 8);
1171
 
        endmask = (char) ~(0xFF << ((start+string_glyph.metrics.advanceX) % 8));
1172
 
        Target_c= (unsigned char *)(string_glyph.bits +(i*paddedW/8)
1173
 
                                    + (start / 8));
1174
 
        j=middle;
1175
 
        if (j == 0)
1176
 
          *Target_c++ |= startmask & endmask;
1177
 
        else {
1178
 
          *Target_c++ |= startmask;
1179
 
          while (--j > 0)
1180
 
            *Target_c++ = (unsigned char) 0xFF;
1181
 
          if ((endmask))
1182
 
            *Target_c |= endmask;
1183
 
        }
1184
 
      }
1185
 
    }
1186
 
 
1187
 
    /* Check for writing direction and re-compute dimensions appropriately: */
1188
 
    if (modflag & T1_RIGHT_TO_LEFT){
1189
 
      string_glyph.metrics.advanceX *= -1;
1190
 
      string_glyph.metrics.leftSideBearing += string_glyph.metrics.advanceX;
1191
 
      string_glyph.metrics.rightSideBearing += string_glyph.metrics.advanceX;
1192
 
    } 
1193
 
    
1194
 
    return(&string_glyph);
1195
 
  } /* end of "if (rot_flag==0.0)" */
1196
 
 
1197
 
 
1198
 
  /* fnt_ptr now points to the correct FontSizeDeps-struct =>
1199
 
     lets now raster the character */
1200
 
  mode=0;
1201
 
  kern_pairs=(int *)calloc(no_chars, sizeof(int));
1202
 
  if ((modflag & T1_KERNING))
1203
 
    for (i=0; i<no_chars -1; i++)
1204
 
      kern_pairs[i]=T1_GetKerning( FontID, ustring[i], ustring[i+1]);
1205
 
  area=fontfcnB_string( FontID, modflag, Current_S,
1206
 
                        fontarrayP->pFontEnc,
1207
 
                        ustring, no_chars, &mode,
1208
 
                        fontarrayP->pType1Data,
1209
 
                        kern_pairs, spacewidth,
1210
 
                        DO_RASTER,
1211
 
                        strokewidth);
1212
 
  KillSpace (Current_S);
1213
 
  
1214
 
  /* In all cases, free memory for kerning pairs */
1215
 
  free(kern_pairs);
1216
 
  
1217
 
  /* fill the string_glyph-structure */
1218
 
  if (mode > 0) {
1219
 
    sprintf( err_warn_msg_buf, "fontfcnB() set mode=%d", mode);
1220
 
    T1_PrintLog( "T1_SetString()", err_warn_msg_buf, T1LOG_WARNING);
1221
 
    T1_errno=mode;
1222
 
    /* make sure to get rid of area if it's there */
1223
 
    if (area){
1224
 
      KillRegion (area);
1225
 
    }
1226
 
    return(NULL);
1227
 
  }
1228
 
  if (area == NULL){
1229
 
    T1_PrintLog( "T1_SetString()", "area=NULL returned by fontfcnB()", T1LOG_WARNING);
1230
 
    T1_errno=mode;
1231
 
    return(NULL);
1232
 
  }
1233
 
  
1234
 
  if (mode == FF_NOTDEF_SUBST) {
1235
 
    sprintf( err_warn_msg_buf,
1236
 
             "\".notdef\" substituted somewhere in string from font %d",
1237
 
             FontID);
1238
 
    T1_PrintLog( "T1_SetString()", err_warn_msg_buf, T1LOG_WARNING);
1239
 
    mode=0;
1240
 
  }
1241
 
  
1242
 
  h = area->ymax - area->ymin;
1243
 
  w = area->xmax - area->xmin;
1244
 
  paddedW = PAD(w, T1_pad);
1245
 
  if (h > 0 && w > 0) {
1246
 
    memsize = h * paddedW / 8 + 1;
1247
 
    /* This is for the users copy of the character, for security-reasons
1248
 
       the original pointer to the cache area is not used. The entry string_glyph.bits
1249
 
       is free'ed every time this function is called: */
1250
 
    string_glyph.bits = (char *)malloc(memsize*sizeof( char));
1251
 
    if (string_glyph.bits == NULL) {
1252
 
      T1_errno=T1ERR_ALLOC_MEM;
1253
 
      /* make sure to get rid of area if it's there */
1254
 
      if (area){
1255
 
        KillRegion (area);
1256
 
      }
1257
 
      /* it's safe to free this, since this is a rotated glyph and
1258
 
         therefore it's a copy of the original one */
1259
 
      return(NULL);
1260
 
    }
1261
 
  }
1262
 
  else {
1263
 
    h = w = 0;
1264
 
    area->xmin = area->xmax = 0;
1265
 
    area->ymin = area->ymax = 0;
1266
 
  }
1267
 
  
1268
 
  string_glyph.metrics.leftSideBearing=area->xmin;
1269
 
  string_glyph.metrics.advanceX=NEARESTPEL(area->ending.x - area->origin.x);
1270
 
  string_glyph.metrics.advanceY=-NEARESTPEL(area->ending.y - area->origin.y);
1271
 
  string_glyph.metrics.rightSideBearing=area->xmax; 
1272
 
  string_glyph.metrics.descent=-area->ymax;  
1273
 
  string_glyph.metrics.ascent=-area->ymin; 
1274
 
 
1275
 
  if (h > 0 && w > 0) {
1276
 
    (void) memset(string_glyph.bits, 0, memsize);
1277
 
    fill(string_glyph.bits, h, paddedW, area, T1_byte, T1_bit, T1_wordsize );
1278
 
  }
1279
 
  else { /* We have no black pixels */
1280
 
    string_glyph.metrics.leftSideBearing=0;
1281
 
    string_glyph.metrics.advanceX=NEARESTPEL(area->ending.x - area->origin.x);
1282
 
    string_glyph.metrics.advanceY=-NEARESTPEL(area->ending.y - area->origin.y);
1283
 
    string_glyph.metrics.rightSideBearing=0; 
1284
 
    string_glyph.metrics.descent=0;  
1285
 
    string_glyph.metrics.ascent=0; 
1286
 
  }
1287
 
  
1288
 
 
1289
 
  /* make sure to get rid of area if it's there */
1290
 
  if (area){
1291
 
    KillRegion (area);
1292
 
  }
1293
 
  /* Check for writing direction and re-compute dimensions appropriately: */
1294
 
  if (modflag & T1_RIGHT_TO_LEFT){
1295
 
    string_glyph.metrics.advanceX *= -1;
1296
 
    string_glyph.metrics.advanceY *= -1;
1297
 
    string_glyph.metrics.leftSideBearing += string_glyph.metrics.advanceX;
1298
 
    string_glyph.metrics.rightSideBearing += string_glyph.metrics.advanceX;
1299
 
    string_glyph.metrics.descent += string_glyph.metrics.advanceY;
1300
 
    string_glyph.metrics.ascent += string_glyph.metrics.advanceY;
1301
 
  } 
1302
 
  return(&string_glyph);
1303
 
}
1304
 
 
1305
 
 
1306
 
 
1307
 
void fill(dest, h, w, area, byte, bit, wordsize)
1308
 
     register char *dest;  /* destination bitmap                           */
1309
 
     int h,w;              /* dimensions of 'dest', w padded               */
1310
 
     register struct region *area;  /* region to write to 'dest'           */
1311
 
     int byte,bit;         /* flags; LSBFirst or MSBFirst                  */
1312
 
     int wordsize;         /* number of bits per word for LSB/MSB purposes */
1313
 
{
1314
 
  register struct edgelist *edge;  /* for looping through edges         */
1315
 
  register char *p;     /* current scan line in 'dest'                  */
1316
 
  register int y;       /* for looping through scans                    */
1317
 
  register int wbytes = w / 8;  /* number of bytes in width             */
1318
 
  register pel *leftP,*rightP;  /* pointers to X values, left and right */
1319
 
  int xmin = area->xmin;  /* upper left X                               */
1320
 
  int ymin = area->ymin;  /* upper left Y                               */
1321
 
  
1322
 
  for (edge = area->anchor; VALIDEDGE(edge); edge = edge->link->link) {
1323
 
    
1324
 
    p = dest + (edge->ymin - ymin) * wbytes;
1325
 
    leftP = edge->xvalues;
1326
 
    rightP = edge->link->xvalues;
1327
 
    
1328
 
    for (y = edge->ymin; y < edge->ymax; y++) {
1329
 
      fillrun(p, *leftP++ - xmin , *rightP++ - xmin, bit);
1330
 
      p += wbytes;
1331
 
    }
1332
 
  }
1333
 
  /* 
1334
 
    Now, as an afterthought, we'll go reorganize if odd byte order requires
1335
 
    it:
1336
 
    */
1337
 
  /* We do not reorganize since t1lib internally always uses LSBFirst */
1338
 
  /*
1339
 
  if ( 0 && wordsize != 8) {
1340
 
    register int i; 
1341
 
    printf("Reorganizing data ..\n");
1342
 
    
1343
 
    switch (wordsize) { 
1344
 
    case 16: 
1345
 
      { 
1346
 
        register unsigned short data,*p; 
1347
 
        p = (unsigned short *) dest; 
1348
 
        for (i = h * w /16; --i >= 0;) { 
1349
 
          data = *p; 
1350
 
          *p++ = (data << 8) + (data >> 8); 
1351
 
        } 
1352
 
        break; 
1353
 
      } 
1354
 
    case 64: 
1355
 
    case 32: 
1356
 
      { 
1357
 
        register ULONG data,*p; 
1358
 
        p = (ULONG *) dest; 
1359
 
        for (i = h * w / 32; --i >= 0;) { 
1360
 
          data = *p; 
1361
 
          *p++ = (data << 24) + (data >> 24) 
1362
 
            + (0xFF00 & (data >> 8)) 
1363
 
            + (0xFF0000 & (data << 8)); 
1364
 
        } 
1365
 
        if (wordsize == 64) { 
1366
 
          p = (ULONG *) dest; 
1367
 
          for (i = h * w / 64; --i >= 0;) { 
1368
 
            data = *p++; 
1369
 
            p[-1] = p[0]; 
1370
 
            *p++ = data; 
1371
 
          } 
1372
 
        }
1373
 
        break; 
1374
 
      } 
1375
 
    default: 
1376
 
      abort("xiFill: unknown format"); 
1377
 
    } 
1378
 
  }
1379
 
  */
1380
 
}
1381
 
 
1382
 
#define  ALLONES  0xFF
1383
 
 
1384
 
void fillrun(register char *p, pel x0, pel x1, int bit)
1385
 
{
1386
 
  register int startmask,endmask;  /* bits to set in first and last char*/
1387
 
  register int middle;  /* number of chars between start and end + 1    */
1388
 
 
1389
 
  if (x1 <= x0)
1390
 
    return;
1391
 
  middle = x1/8 - x0/8;
1392
 
  p += x0/8;
1393
 
  x0 &= 7;  x1 &= 7;
1394
 
  if (bit == LSBFirst) {
1395
 
    startmask = ALLONES << x0;
1396
 
    endmask = ~(ALLONES << x1);
1397
 
  }
1398
 
  else {
1399
 
    startmask = ALLONES >> x0;
1400
 
    endmask = ~(ALLONES >> x1);
1401
 
  }
1402
 
  if (middle == 0)
1403
 
    *p++ |= startmask & endmask;
1404
 
  else {
1405
 
    *p++ |= startmask;
1406
 
    while (--middle > 0){
1407
 
      *p++ = (unsigned char)ALLONES;
1408
 
    }
1409
 
    if (endmask)
1410
 
      *p |= endmask;
1411
 
  }
1412
 
}
1413
 
 
1414
 
 
1415
 
/* outline */
1416
 
#undef CHECK_OUTLINEFILL
1417
 
#ifdef CHECK_OUTLINEFILL
1418
 
void fill(dest, h, w, area, byte, bit, wordsize)
1419
 
     register char *dest;  /* destination bitmap                           */
1420
 
     int h,w;              /* dimensions of 'dest', w padded               */
1421
 
     register struct region *area;  /* region to write to 'dest'           */
1422
 
     int byte,bit;         /* flags; LSBFirst or MSBFirst                  */
1423
 
     int wordsize;         /* number of bits per word for LSB/MSB purposes */
1424
 
{
1425
 
  register struct edgelist *edge;  /* for looping through edges         */
1426
 
  register char *p;     /* current scan line in 'dest'                  */
1427
 
  register int y;       /* for looping through scans                    */
1428
 
  register int wbytes = w / 8;  /* number of bytes in width             */
1429
 
  register pel *leftP,*rightP;  /* pointers to X values, left and right */
1430
 
  int xmin = area->xmin;  /* upper left X                               */
1431
 
  int ymin = area->ymin;  /* upper left Y                               */
1432
 
  
1433
 
  for (edge = area->anchor; VALIDEDGE(edge); edge = edge->link->link) {
1434
 
    
1435
 
    p = dest + (edge->ymin - ymin) * wbytes;
1436
 
    leftP = edge->xvalues;
1437
 
    rightP = edge->link->xvalues;
1438
 
 
1439
 
    printf("leftP=%d, RightP=%d,\n", *leftP, *rightP);
1440
 
    
1441
 
    
1442
 
    for (y = edge->ymin; y < edge->ymax; y++) {
1443
 
      printf("leftP=%d, RightP=%d,y=%d\n", *leftP, *rightP, y);
1444
 
      
1445
 
      fillrun(p, *leftP++ - xmin, *rightP++ - xmin, bit);
1446
 
      p += wbytes;
1447
 
    }
1448
 
  }
1449
 
}
1450
 
#endif
1451
 
 
1452
 
 
1453
 
/* T1_CopyGlyph(): Make a copy of an existent glyph-structure to save it
1454
 
   for later usage by the user. */
1455
 
GLYPH *T1_CopyGlyph( GLYPH *glyph)
1456
 
{
1457
 
  GLYPH *dest;
1458
 
  long size;
1459
 
  
1460
 
 
1461
 
  if (glyph==NULL){
1462
 
    T1_errno=T1ERR_INVALID_PARAMETER;
1463
 
    return(NULL);
1464
 
  }
1465
 
  
1466
 
  /* Assign padding value */
1467
 
  T1_pad=pFontBase->bitmap_pad;
1468
 
  /* Allocate memory for struct: */
1469
 
  if ((dest=(GLYPH *)malloc(sizeof(GLYPH)))==NULL){
1470
 
    T1_errno=T1ERR_ALLOC_MEM;
1471
 
    return(NULL);
1472
 
  }
1473
 
  
1474
 
  /* Copy the structure members: */
1475
 
  *dest=*glyph;
1476
 
  /* Allocate memory for bitmap, initialize pointer to it and copy bitmap: */
1477
 
  size=PAD((dest->metrics.rightSideBearing-dest->metrics.leftSideBearing)*
1478
 
           glyph->bpp, T1_pad) / 8;
1479
 
  size=size*(dest->metrics.ascent-dest->metrics.descent);
1480
 
   /* We must check whether there's actually a bits-pointer different from
1481
 
      NULL. If not omit the following step: */
1482
 
  if (glyph->bits!=NULL){
1483
 
    if ((dest->bits=(char *)malloc(size*sizeof(char)))==NULL){
1484
 
      free(dest);
1485
 
      T1_errno=T1ERR_ALLOC_MEM;
1486
 
      return(NULL);
1487
 
    }
1488
 
    memcpy(dest->bits,glyph->bits,size);
1489
 
  }
1490
 
  return(dest);
1491
 
}
1492
 
 
1493
 
/* T1_DumpGlyph(): Dump a glyph-representation to stdout: */
1494
 
void T1_DumpGlyph( GLYPH *glyph)
1495
 
{
1496
 
  int i,j,h,w;   /* i=line-index, j=column-index */ 
1497
 
  long paddedW;
1498
 
  
1499
 
  
1500
 
  printf("Dataformat: T1_bit=%d, T1_byte=%d, T1_wordsize=%d, T1_pad=%d\n",
1501
 
         T1_bit, T1_byte, T1_pad, T1_pad);
1502
 
 
1503
 
  if (glyph==NULL){
1504
 
    return;
1505
 
  }
1506
 
  
1507
 
  h=glyph->metrics.ascent-glyph->metrics.descent;
1508
 
  w=glyph->metrics.rightSideBearing-glyph->metrics.leftSideBearing;
1509
 
  
1510
 
  paddedW=PAD(w,T1_pad);
1511
 
  
1512
 
  printf("GlyphInfo: h=%d, w=%d, paddedW=%ld\n", h, w, paddedW);
1513
 
  
1514
 
  for ( i=0; i<h; i++){
1515
 
    if (T1_pad==8)
1516
 
      for (j=0; j<paddedW/T1_pad; j++)
1517
 
        bin_dump_c(glyph->bits[i*paddedW/T1_pad+j], 1);
1518
 
    else if (T1_pad==16)
1519
 
      for (j=0; j<paddedW/T1_pad; j++){
1520
 
        bin_dump_s(((unsigned short *)glyph->bits)[i*paddedW/T1_pad+j], 1);
1521
 
      }
1522
 
    else
1523
 
      for (j=0; j<paddedW/T1_pad; j++){
1524
 
        bin_dump_l(((unsigned long *)glyph->bits)[i*paddedW/T1_pad+j], 1);
1525
 
      }
1526
 
    printf("\n");
1527
 
  } 
1528
 
1529
 
 
1530
 
 
1531
 
 
1532
 
/* This function will essentially return the bounding box of the
1533
 
   line-rule */
1534
 
static void T1_ComputeLineParameters( int FontID, int mode,
1535
 
                                      int width, float size,
1536
 
                                      int *startx, int *endx,
1537
 
                                      int *starty, int *endy)
1538
 
{
1539
 
  float position=0.0, thickness=0.0;
1540
 
  int startx1, startx2, endx1, endx2;
1541
 
  
1542
 
  if (mode & T1_UNDERLINE){
1543
 
    position=pFontBase->pFontArray[FontID].UndrLnPos
1544
 
      * DeviceSpecifics.scale_y;
1545
 
    thickness=pFontBase->pFontArray[FontID].UndrLnThick
1546
 
      * DeviceSpecifics.scale_y;
1547
 
  }
1548
 
  else if (mode & T1_OVERLINE){
1549
 
    position=pFontBase->pFontArray[FontID].OvrLnPos
1550
 
      * DeviceSpecifics.scale_y;
1551
 
    thickness=pFontBase->pFontArray[FontID].OvrLnThick
1552
 
      * DeviceSpecifics.scale_y;
1553
 
  }
1554
 
  else if (mode & T1_OVERSTRIKE){
1555
 
    position=pFontBase->pFontArray[FontID].OvrStrkPos
1556
 
      * DeviceSpecifics.scale_y;
1557
 
    thickness=pFontBase->pFontArray[FontID].OvrStrkThick
1558
 
      * DeviceSpecifics.scale_y;
1559
 
  }
1560
 
  
1561
 
  *starty=(int) floor((position+0.5*(thickness-DeviceSpecifics.y_resolution/1000.0))
1562
 
                      *size/1000.0 +0.5 );
1563
 
  startx1=(int) floor(*starty*pFontBase->pFontArray[FontID].slant+0.5);
1564
 
  *endy  =*starty - (int) floor(thickness/1000.0*size+0.5);
1565
 
  startx2=(int) floor(*endy*pFontBase->pFontArray[FontID].slant+0.5);
1566
 
  *startx=startx1 < startx2 ? startx1 : startx2;
1567
 
  endx1  = width +
1568
 
    (int) floor(*starty*pFontBase->pFontArray[FontID].slant+0.5);
1569
 
  endx2  = width +
1570
 
    (int) floor(*endy*pFontBase->pFontArray[FontID].slant+0.5);
1571
 
  *endx=endx1 < endx2 ? endx2 : endx1;
1572
 
 
1573
 
  /* We take care that at least one pixel is drawn */
1574
 
  if (*starty==*endy)
1575
 
    *endy -=1;
1576
 
  
1577
 
  return;
1578
 
 
1579
 
}
1580
 
 
1581
 
 
1582
 
 
1583
 
/* The following function concatenates two glyphs. Optional offsets
1584
 
   x_off, y_off are respected. By the function.
1585
 
   If either glyph is NULL or the glyphs have distinct depth, NULL is
1586
 
   returned. */
1587
 
GLYPH *T1_ConcatGlyphs( GLYPH *glyph_1, GLYPH *glyph_2,
1588
 
                        int x_off, int y_off, int modflag)
1589
 
{
1590
 
 
1591
 
  int lsb1, lsb2, rsb1, rsb2;
1592
 
  int advanceX1, advanceX2, advanceY1, advanceY2;
1593
 
  int ascent1, ascent2, descent1, descent2;
1594
 
  int rsb, lsb, ascent, descent, advanceX, advanceY;
1595
 
  int vanchor, w, h, wscanline, wscanline1, wscanline2, bpp;
1596
 
  int memsize, BitShift;
1597
 
  GLYPH *glyph1, *glyph2;
1598
 
  unsigned T1_AA_TYPE16 BitBuf_c;
1599
 
  unsigned T1_AA_TYPE32 BitBuf_s;
1600
 
  unsigned long BitBuf_l;   /* This is only actually used if sizeof long = 8 */
1601
 
  int i, j, k;
1602
 
  int ByteOffset;
1603
 
  
1604
 
  unsigned char *Target_c, *p_c;
1605
 
  unsigned T1_AA_TYPE16 *Target_s, *p_s;
1606
 
  unsigned T1_AA_TYPE32 *Target_l, *p_l;
1607
 
  
1608
 
  static GLYPH glyph={NULL,{0,0,0,0,0,0},NULL,1};
1609
 
  
1610
 
 
1611
 
  /* We handle the Right-To-Left concatenation the simple way:
1612
 
     1) Change the order of the two glyphs
1613
 
     2) Invert the sign of the y-part of the offset
1614
 
     3) Recalculate the dimensions of the resulating glyph.
1615
 
  */
1616
 
  /* Check for writing direction and reorganize appropriately: */
1617
 
  if (modflag & T1_RIGHT_TO_LEFT){
1618
 
    glyph1=glyph_2;
1619
 
    glyph2=glyph_1;
1620
 
    y_off=-y_off;
1621
 
  }
1622
 
  else {
1623
 
    glyph1=glyph_1;
1624
 
    glyph2=glyph_2;
1625
 
  }
1626
 
  
1627
 
  if (glyph1==NULL){
1628
 
    T1_errno=T1ERR_INVALID_PARAMETER;
1629
 
    return( NULL);
1630
 
  }
1631
 
  if (glyph2==NULL){
1632
 
    T1_errno=T1ERR_INVALID_PARAMETER;
1633
 
    return( NULL);
1634
 
  }
1635
 
  if (glyph1->bpp != glyph2->bpp){
1636
 
    T1_errno=T1ERR_INVALID_PARAMETER;
1637
 
    return( NULL);
1638
 
  }
1639
 
  
1640
 
  /* We have two glyph different from NULL */
1641
 
  /* Reset glyph, if necessary */
1642
 
  if (glyph.bits!=NULL){
1643
 
    free(glyph.bits);
1644
 
    glyph.bits=NULL;
1645
 
  }
1646
 
  glyph.metrics.leftSideBearing=0;
1647
 
  glyph.metrics.rightSideBearing=0;
1648
 
  glyph.metrics.advanceX=0;
1649
 
  glyph.metrics.advanceY=0;
1650
 
  glyph.metrics.ascent=0;
1651
 
  glyph.metrics.descent=0;
1652
 
  glyph.pFontCacheInfo=NULL;
1653
 
  glyph.bpp=1;
1654
 
 
1655
 
  /* Assign dimens */
1656
 
  lsb1=glyph1->metrics.leftSideBearing;
1657
 
  rsb1=glyph1->metrics.rightSideBearing;
1658
 
  ascent1=glyph1->metrics.ascent;
1659
 
  descent1=glyph1->metrics.descent;
1660
 
  advanceX1=glyph1->metrics.advanceX + x_off;
1661
 
  advanceY1=glyph1->metrics.advanceY + y_off;
1662
 
  
1663
 
  lsb2=glyph2->metrics.leftSideBearing;
1664
 
  rsb2=glyph2->metrics.rightSideBearing;
1665
 
  ascent2=glyph2->metrics.ascent;
1666
 
  descent2=glyph2->metrics.descent;
1667
 
  advanceX2=glyph2->metrics.advanceX;
1668
 
  advanceY2=glyph2->metrics.advanceY;
1669
 
  
1670
 
  lsb=lsb1 < lsb2+advanceX1 ? lsb1 : lsb2+advanceX1;
1671
 
  rsb=rsb1 > rsb2+advanceX1 ? rsb1 : rsb2+advanceX1;
1672
 
  ascent=ascent1 > ascent2+advanceY1 ? ascent1 : ascent2+advanceY1;
1673
 
  descent=descent1 < descent2+advanceY1 ? descent1 : descent2+advanceY1;
1674
 
  advanceX=advanceX1+advanceX2;
1675
 
  advanceY=advanceY1+advanceY2;
1676
 
 
1677
 
  bpp=glyph1->bpp;
1678
 
  w=rsb-lsb;
1679
 
  h=ascent-descent;
1680
 
  wscanline=PAD( w*bpp, T1_pad) / 8;
1681
 
  wscanline1=PAD( (rsb1-lsb1)*bpp, T1_pad) / 8;
1682
 
  wscanline2=PAD( (rsb2-lsb2)*bpp, T1_pad) / 8;
1683
 
  memsize=wscanline*h;
1684
 
  if ((glyph.bits=(char *)calloc( memsize + 1, sizeof(unsigned char)))==NULL){
1685
 
    T1_errno=T1ERR_ALLOC_MEM;
1686
 
    return(NULL);
1687
 
  }
1688
 
  
1689
 
  if (bpp==1){
1690
 
    if (T1_pad==32 && T1_byte==0 && sizeof(long)==8){
1691
 
      /* The following loop steps through the lines of the first glyph: */
1692
 
      vanchor=ascent-ascent1;
1693
 
      BitShift=(lsb1-lsb) % 32;
1694
 
      ByteOffset=(lsb1-lsb)/32*4;
1695
 
      for ( i=0; i<ascent1-descent1; i++){
1696
 
        Target_l= (unsigned T1_AA_TYPE32 *)(glyph.bits +((vanchor+i)*wscanline)
1697
 
                                            +ByteOffset);
1698
 
        p_l = (unsigned T1_AA_TYPE32 *)(glyph1->bits+(wscanline1*i));
1699
 
        if (BitShift == 0){
1700
 
          for (k=wscanline1/4; k; k--)
1701
 
            *Target_l++ |= *p_l++;
1702
 
        }
1703
 
        else{
1704
 
          for (k=wscanline1/4; k; k--){
1705
 
            BitBuf_l = ((long)*p_l++) << BitShift;
1706
 
            *Target_l++ |= BitBuf_l;
1707
 
            *Target_l |= BitBuf_l>>l_shift;
1708
 
          }
1709
 
        }
1710
 
      }
1711
 
      /* The following loop steps through the lines of the second glyph: */
1712
 
      vanchor=ascent-(ascent2+advanceY1);
1713
 
      BitShift=(lsb2+advanceX1-lsb) % 32;
1714
 
      ByteOffset=(lsb2+advanceX1-lsb)/32*4;
1715
 
      for ( i=0; i<ascent2-descent2; i++){
1716
 
        Target_l= (unsigned T1_AA_TYPE32 *)(glyph.bits +((vanchor+i)*wscanline)
1717
 
                                            +ByteOffset);
1718
 
        p_l = (unsigned T1_AA_TYPE32 *)(glyph2->bits+(wscanline2*i));
1719
 
        if (BitShift == 0){
1720
 
          for (k=wscanline2/4; k; k--)
1721
 
            *Target_l++ |= *p_l++;
1722
 
        }
1723
 
        else{
1724
 
          for (k=wscanline2/4; k; k--){
1725
 
            BitBuf_l = ((long)*p_l++) << BitShift;
1726
 
            *Target_l++ |= BitBuf_l;
1727
 
            *Target_l |= BitBuf_l>>l_shift;
1728
 
          } 
1729
 
        } 
1730
 
      }
1731
 
    }
1732
 
    else if(T1_pad==16 && T1_byte==0){
1733
 
      /* The following loop steps through the lines of the first glyph: */
1734
 
      vanchor=ascent-ascent1;
1735
 
      BitShift=(lsb1-lsb) % 16;
1736
 
      ByteOffset=(lsb1-lsb)/16*2;
1737
 
      for ( i=0; i<ascent1-descent1; i++){
1738
 
        Target_s= (unsigned T1_AA_TYPE16 *)(glyph.bits +((vanchor+i)*wscanline)
1739
 
                                            +ByteOffset);
1740
 
        p_s = (unsigned T1_AA_TYPE16 *)(glyph1->bits+(wscanline1*i));
1741
 
        if (BitShift == 0){
1742
 
          for (k=wscanline1/2; k; k--)
1743
 
            *Target_s++ |= *p_s++;
1744
 
        }
1745
 
        else{
1746
 
          for (k=wscanline1/2; k; k--){
1747
 
            BitBuf_s = ((T1_AA_TYPE32)*p_s++) << BitShift;
1748
 
            *Target_s++ |= BitBuf_s;
1749
 
            *Target_s |= BitBuf_s>>s_shift;
1750
 
          }
1751
 
        }
1752
 
      }
1753
 
      /* The following loop steps through the lines of the second glyph: */
1754
 
      vanchor=ascent-(ascent2+advanceY1);
1755
 
      BitShift=(lsb2+advanceX1-lsb) % 16;
1756
 
      ByteOffset=(lsb2+advanceX1-lsb)/16*2;
1757
 
      for ( i=0; i<ascent2-descent2; i++){
1758
 
        Target_s= (unsigned T1_AA_TYPE16 *)(glyph.bits +((vanchor+i)*wscanline)
1759
 
                                            +ByteOffset);
1760
 
        p_s = (unsigned T1_AA_TYPE16 *)(glyph2->bits+(wscanline2*i));
1761
 
        if (BitShift == 0){
1762
 
          for (k=wscanline2/2; k; k--)
1763
 
            *Target_s++ |= *p_s++;
1764
 
        }
1765
 
        else{
1766
 
          for (k=wscanline2/2; k; k--){
1767
 
            BitBuf_s = ((T1_AA_TYPE32)*p_s++) << BitShift;
1768
 
            *Target_s++ |= BitBuf_s;
1769
 
            *Target_s |= BitBuf_s>>s_shift;
1770
 
          } 
1771
 
        } 
1772
 
      }
1773
 
    }
1774
 
    else{ /* T1_pad==8 or Big Endian machine */
1775
 
      /* The following loop steps through the lines of the first glyph: */
1776
 
      vanchor=ascent-ascent1;
1777
 
      BitShift=(lsb1-lsb) % 8;
1778
 
      ByteOffset=(lsb1-lsb) / 8;
1779
 
      for ( i=0; i<ascent1-descent1; i++){
1780
 
        Target_c= (unsigned char *)(glyph.bits +((vanchor+i)*wscanline)
1781
 
                                    +ByteOffset);
1782
 
        p_c = (unsigned char *)(glyph1->bits+(wscanline1*i));
1783
 
        if (BitShift == 0){
1784
 
          for (k=wscanline1; k; k--)
1785
 
            *Target_c++ |= *p_c++;
1786
 
        }
1787
 
        else{
1788
 
          for (k=wscanline1; k; k--){
1789
 
            BitBuf_c = ((T1_AA_TYPE16)*p_c++) << BitShift;
1790
 
            *Target_c++ |= BitBuf_c;
1791
 
            *Target_c |= BitBuf_c>>c_shift;
1792
 
          }
1793
 
        }
1794
 
      }
1795
 
      /* The following loop steps through the lines of the second glyph: */
1796
 
      vanchor=ascent-(ascent2+advanceY1);
1797
 
      BitShift=(lsb2+advanceX1-lsb) % 8;
1798
 
      ByteOffset=(lsb2+advanceX1-lsb) / 8;
1799
 
      for ( i=0; i<ascent2-descent2; i++){
1800
 
        Target_c= (unsigned char *)(glyph.bits +((vanchor+i)*wscanline)
1801
 
                                    +ByteOffset);
1802
 
        p_c = (unsigned char *)(glyph2->bits+(wscanline2*i));
1803
 
        if (BitShift == 0){
1804
 
          for (k=wscanline2; k; k--)
1805
 
            *Target_c++ |= *p_c++;
1806
 
        }
1807
 
        else{
1808
 
          for (k=wscanline2; k; k--){
1809
 
            BitBuf_c = ((T1_AA_TYPE16)*p_c++) << BitShift;
1810
 
            *Target_c++ |= BitBuf_c;
1811
 
            *Target_c |= BitBuf_c>>c_shift;
1812
 
          } 
1813
 
        } 
1814
 
      }
1815
 
    }
1816
 
  } /* end of if (bpp==1) ... */
1817
 
  else if (bpp==8){
1818
 
    /* Set background */
1819
 
    for ( i=0; i<memsize; i++)
1820
 
      ((char *)glyph.bits)[i]=(char) T1aa_bg;
1821
 
    /* The following loop steps through the lines of the first glyph: */
1822
 
    vanchor=ascent-ascent1;
1823
 
    for ( i=0; i<ascent1-descent1; i++){
1824
 
      Target_c= (unsigned char *)(glyph.bits +((vanchor+i)*wscanline)
1825
 
                                  +(lsb1-lsb));
1826
 
      p_c = (unsigned char *)(glyph1->bits+(wscanline1*i));
1827
 
      memcpy( Target_c, p_c, (rsb1-lsb1));
1828
 
    }
1829
 
    /* The following loop steps through the lines of the second glyph.
1830
 
       Note that we only set the pixel if it is not background! */
1831
 
    vanchor=ascent-(ascent2+advanceY1);
1832
 
    for ( i=0; i<ascent2-descent2; i++){
1833
 
      Target_c= (unsigned char *)(glyph.bits +((vanchor+i)*wscanline)
1834
 
                                  +(lsb2+advanceX1-lsb));
1835
 
      p_c = (unsigned char *)(glyph2->bits+(wscanline2*i));
1836
 
      for (j=0; j<(rsb2-lsb2); j++)
1837
 
        if (p_c[j] != (unsigned char) T1aa_bg)
1838
 
          Target_c[j]=p_c[j];
1839
 
    }
1840
 
  } /* end of if (bpp==8) ... */
1841
 
  else if (bpp==16){
1842
 
    /* Set background */
1843
 
    for ( i=0; i<memsize/2; i++)
1844
 
      ((T1_AA_TYPE16 *)glyph.bits)[i]=(T1_AA_TYPE16) T1aa_bg;
1845
 
    /* The following loop steps through the lines of the first glyph: */
1846
 
    vanchor=ascent-ascent1;
1847
 
    for ( i=0; i<ascent1-descent1; i++){
1848
 
      Target_s= (unsigned T1_AA_TYPE16 *)(glyph.bits +((vanchor+i)*wscanline)
1849
 
                                  +(lsb1-lsb)*2);
1850
 
      p_s = (unsigned T1_AA_TYPE16 *)(glyph1->bits+(wscanline1*i));
1851
 
      memcpy( Target_s, p_s, (rsb1-lsb1)*2);
1852
 
    }
1853
 
    /* The following loop steps through the lines of the second glyph.
1854
 
       Note that we only set the pixel if it is not background! */
1855
 
    vanchor=ascent-(ascent2+advanceY1);
1856
 
    for ( i=0; i<ascent2-descent2; i++){
1857
 
      Target_s= (unsigned T1_AA_TYPE16 *)(glyph.bits +((vanchor+i)*wscanline)
1858
 
                                  +(lsb2+advanceX1-lsb)*2);
1859
 
      p_s = (unsigned T1_AA_TYPE16 *)(glyph2->bits+(wscanline2*i));
1860
 
      for (j=0; j<(rsb2-lsb2); j++)
1861
 
        if (p_s[j] != (unsigned T1_AA_TYPE16) T1aa_bg)
1862
 
          Target_s[j]=p_s[j];
1863
 
    }
1864
 
  } /* end of if (bpp==16) ... */
1865
 
  else if (bpp==32){
1866
 
    /* Set background */
1867
 
    for ( i=0; i<memsize/4; i++)
1868
 
      ((T1_AA_TYPE32 *)glyph.bits)[i]=(T1_AA_TYPE32) T1aa_bg;
1869
 
    /* The following loop steps through the lines of the first glyph: */
1870
 
    vanchor=ascent-ascent1;
1871
 
    for ( i=0; i<ascent1-descent1; i++){
1872
 
      Target_l= (unsigned T1_AA_TYPE32 *)(glyph.bits +((vanchor+i)*wscanline)
1873
 
                                  +(lsb1-lsb)*4);
1874
 
      p_l = (unsigned T1_AA_TYPE32 *)(glyph1->bits+(wscanline1*i));
1875
 
      memcpy( Target_l, p_l, (rsb1-lsb1)*4);
1876
 
    }
1877
 
    /* The following loop steps through the lines of the second glyph.
1878
 
       Note that we only set the pixel if it is not background! */
1879
 
    vanchor=ascent-(ascent2+advanceY1);
1880
 
    for ( i=0; i<ascent2-descent2; i++){
1881
 
      Target_l= (unsigned T1_AA_TYPE32 *)(glyph.bits +((vanchor+i)*wscanline)
1882
 
                                  +(lsb2+advanceX1-lsb)*4);
1883
 
      p_l = (unsigned T1_AA_TYPE32 *)(glyph2->bits+(wscanline2*i));
1884
 
      for (j=0; j<(rsb2-lsb2); j++)
1885
 
        if (p_l[j] != (unsigned T1_AA_TYPE32) T1aa_bg)
1886
 
          Target_l[j]=p_l[j];
1887
 
    }
1888
 
  } /* end of if (bpp==32) ... */
1889
 
  
1890
 
  
1891
 
  /* Check for writing direction and re-compute dimens appropriately: */
1892
 
  if (modflag & T1_RIGHT_TO_LEFT){
1893
 
    advanceX=-advanceX1-advanceX2;
1894
 
    advanceY=-advanceY1-advanceY2;
1895
 
    lsb=lsb1 < lsb2+advanceX1 ? advanceX+lsb1 : advanceX+lsb2+advanceX1;
1896
 
    rsb=rsb1 > rsb2+advanceX1 ? advanceX+rsb1 : advanceX+rsb2+advanceX1;
1897
 
    ascent=ascent1 > ascent2+advanceY1 ? ascent1 : ascent2+advanceY1;
1898
 
    descent=descent1 < descent2+advanceY1 ? descent1 : descent2+advanceY1;
1899
 
    ascent += advanceY;
1900
 
    descent += advanceY;
1901
 
  } 
1902
 
  
1903
 
  glyph.metrics.leftSideBearing=lsb;
1904
 
  glyph.metrics.rightSideBearing=rsb;
1905
 
  glyph.metrics.advanceX=advanceX;
1906
 
  glyph.metrics.advanceY=advanceY;
1907
 
  glyph.metrics.ascent=ascent;
1908
 
  glyph.metrics.descent=descent;
1909
 
  glyph.bpp=bpp;
1910
 
  
1911
 
  /*
1912
 
  printf("lsb=%d, rsb=%d, adX=%d, adY=%d asc=%d, desc=%d\n",
1913
 
         glyph.metrics.leftSideBearing,
1914
 
         glyph.metrics.rightSideBearing,
1915
 
         glyph.metrics.advanceX,
1916
 
         glyph.metrics.advanceY,
1917
 
         glyph.metrics.ascent,
1918
 
         glyph.metrics.descent );
1919
 
         */
1920
 
  
1921
 
  return( &glyph);
1922
 
  
1923
 
}
1924
 
 
1925
 
 
1926
 
 
1927
 
/* T1_FillOutline(): Create a filled glyph from an outline description */
1928
 
GLYPH *T1_FillOutline( T1_OUTLINE *path, int modflag)
1929
 
{
1930
 
  struct region *area=NULL;
1931
 
 
1932
 
  static GLYPH glyph={NULL,{0,0,0,0,0,0},NULL,1};
1933
 
  volatile int memsize=0;
1934
 
  int i;
1935
 
  LONG h,w;
1936
 
  LONG paddedW;
1937
 
 
1938
 
  
1939
 
  /* We return to this if something goes wrong deep in the rasterizer */
1940
 
  if ((i=setjmp( stck_state))!=0) {
1941
 
    T1_errno=T1ERR_TYPE1_ABORT;
1942
 
    sprintf( err_warn_msg_buf, "t1_abort: Reason: %s",
1943
 
             t1_get_abort_message( i));
1944
 
    T1_PrintLog( "T1_FillOutline()", err_warn_msg_buf,
1945
 
               T1LOG_ERROR);
1946
 
    return( NULL);
1947
 
  }
1948
 
 
1949
 
  /* Reset character glyph, if necessary */
1950
 
  if (glyph.bits!=NULL){
1951
 
    free(glyph.bits);
1952
 
    glyph.bits=NULL;
1953
 
  }
1954
 
  glyph.metrics.leftSideBearing=0;
1955
 
  glyph.metrics.rightSideBearing=0;
1956
 
  glyph.metrics.advanceX=0;
1957
 
  glyph.metrics.advanceY=0;
1958
 
  glyph.metrics.ascent=0;
1959
 
  glyph.metrics.descent=0;
1960
 
  glyph.pFontCacheInfo=NULL;
1961
 
  glyph.bpp=1;  
1962
 
  
1963
 
  
1964
 
  /* Assign padding value */
1965
 
  T1_pad=pFontBase->bitmap_pad;
1966
 
  if (pFontBase->endian)
1967
 
    T1_byte=1;
1968
 
  else
1969
 
    T1_byte=0;
1970
 
  T1_wordsize=T1_pad;
1971
 
 
1972
 
  /* Create a region from outline */
1973
 
  area=(struct region *)Interior( (struct segment *)path,
1974
 
                                  WINDINGRULE+CONTINUITY);
1975
 
 
1976
 
  /* fill the glyph-structure */
1977
 
  if (area == NULL){
1978
 
    T1_PrintLog( "T1_FillOutline()", "area=NULL returned by Interior()", T1LOG_WARNING);
1979
 
    T1_errno=1000;
1980
 
    return(NULL);
1981
 
  }
1982
 
  h = area->ymax - area->ymin;
1983
 
  w = area->xmax - area->xmin;
1984
 
 
1985
 
  
1986
 
  paddedW = PAD(w, T1_pad);
1987
 
  if ( (area->xmin > area->xmax) || (area->ymin > area->ymax) ){
1988
 
    /* There was a character like .notdef or space, that didn't
1989
 
       produce any black pixels on the bitmap! -> we return a glyph with
1990
 
       correct metrics and bitmap pointer set to NULL */
1991
 
    sprintf( err_warn_msg_buf,
1992
 
             "No black pixels in outline %p", path);
1993
 
    T1_PrintLog( "T1_FillOutline()", err_warn_msg_buf, T1LOG_WARNING);
1994
 
    
1995
 
    glyph.metrics.leftSideBearing  = 0;
1996
 
    glyph.metrics.advanceX   = NEARESTPEL(area->ending.x - area->origin.x);
1997
 
    glyph.metrics.advanceY   = - NEARESTPEL(area->ending.y - area->origin.y);
1998
 
    glyph.metrics.rightSideBearing = 0;
1999
 
    glyph.metrics.descent          = 0;
2000
 
    glyph.metrics.ascent           = 0;
2001
 
    /* make sure to get rid of 'area' before leaving! */
2002
 
    KillRegion (area);
2003
 
    return( &glyph);
2004
 
  }
2005
 
  if (h > 0 && w > 0) {
2006
 
    memsize = h * paddedW / 8 + 1;
2007
 
    /* This is for the users copy of the character, for security-reasons
2008
 
       the original pointer to the cache area is not used. The entry glyph.bits
2009
 
       is free'ed every time this function is called: */
2010
 
    glyph.bits = (char *)malloc(memsize*sizeof( char));
2011
 
    if (glyph.bits == NULL){
2012
 
      T1_errno=T1ERR_ALLOC_MEM;
2013
 
      /* make sure to get rid of area if it's there */
2014
 
      if (area){
2015
 
        KillRegion (area);
2016
 
      }
2017
 
      return(NULL);
2018
 
    }
2019
 
    
2020
 
  }
2021
 
  else {
2022
 
    h = w = 0;
2023
 
    area->xmin = area->xmax = 0;
2024
 
    area->ymin = area->ymax = 0;
2025
 
  }
2026
 
  
2027
 
  glyph.metrics.leftSideBearing  = area->xmin;
2028
 
  glyph.metrics.advanceX   = NEARESTPEL(area->ending.x - area->origin.x);
2029
 
  glyph.metrics.advanceY   = - NEARESTPEL(area->ending.y - area->origin.y);
2030
 
  glyph.metrics.rightSideBearing = area->xmax;
2031
 
  glyph.metrics.descent          = - area->ymax;
2032
 
  glyph.metrics.ascent           = - area->ymin;
2033
 
  
2034
 
  
2035
 
  if (h > 0 && w > 0) {
2036
 
    (void) memset(glyph.bits, 0, memsize);
2037
 
    fill(glyph.bits, h, paddedW, area, T1_byte, T1_bit, T1_wordsize );
2038
 
  }
2039
 
 
2040
 
  /* Check for writing direction and re-compute dimensions appropriately: */
2041
 
  if (modflag & T1_RIGHT_TO_LEFT){
2042
 
    glyph.metrics.advanceX *= -1;
2043
 
    glyph.metrics.advanceY *= -1;
2044
 
    glyph.metrics.leftSideBearing += glyph.metrics.advanceX;
2045
 
    glyph.metrics.rightSideBearing += glyph.metrics.advanceX;
2046
 
    glyph.metrics.descent += glyph.metrics.advanceY;
2047
 
    glyph.metrics.ascent += glyph.metrics.advanceY;
2048
 
  } 
2049
 
  
2050
 
  /* make sure to get rid of area if it's there */
2051
 
  if (area){
2052
 
    KillRegion (area);
2053
 
  }
2054
 
  return( &glyph);
2055
 
  
2056
 
  
2057
 
}
2058
 
 
2059
 
 
2060
 
/* T1_SetRect(): Raster a rectangle, whose size is given in charspace units.
2061
 
   The resulting glyph does not cause any escapement. */
2062
 
GLYPH* T1_SetRect( int FontID, float size,
2063
 
                   float width, float height, T1_TMATRIX *transform)
2064
 
{
2065
 
  int i;
2066
 
  int mode;
2067
 
  struct region *area;
2068
 
  struct XYspace *Current_S;
2069
 
  float strokewidth = 0.0f;
2070
 
  
2071
 
  FONTSIZEDEPS *font_ptr;
2072
 
  FONTPRIVATE  *fontarrayP;
2073
 
  
2074
 
  volatile int memsize=0;
2075
 
  LONG h,w;
2076
 
  LONG paddedW;
2077
 
 
2078
 
  static GLYPH glyph={NULL,{0,0,0,0,0,0},NULL,1};
2079
 
 
2080
 
 
2081
 
  /* We return to this if something goes wrong deep in the rasterizer */
2082
 
  if ((i=setjmp( stck_state))!=0) {
2083
 
    T1_errno=T1ERR_TYPE1_ABORT;
2084
 
    sprintf( err_warn_msg_buf, "t1_abort: Reason: %s",
2085
 
             t1_get_abort_message( i));
2086
 
    T1_PrintLog( "T1_SetRect()", err_warn_msg_buf,
2087
 
               T1LOG_ERROR);
2088
 
    return( NULL);
2089
 
  }
2090
 
 
2091
 
  font_ptr = NULL;
2092
 
  
2093
 
  /* Reset character glyph, if necessary */
2094
 
  if (glyph.bits!=NULL){
2095
 
    free(glyph.bits);
2096
 
    glyph.bits=NULL;
2097
 
  }
2098
 
  glyph.metrics.leftSideBearing=0;
2099
 
  glyph.metrics.rightSideBearing=0;
2100
 
  glyph.metrics.advanceX=0;
2101
 
  glyph.metrics.advanceY=0;
2102
 
  glyph.metrics.ascent=0;
2103
 
  glyph.metrics.descent=0;
2104
 
  glyph.pFontCacheInfo=NULL;
2105
 
  glyph.bpp=1;  
2106
 
  
2107
 
  /* First, check for a correct ID. */
2108
 
  i=T1_CheckForFontID(FontID);
2109
 
  if ( i == -1 ) {
2110
 
    return NULL;
2111
 
  }
2112
 
  /* if necessary load font into memory */
2113
 
  if ( i == 0 )
2114
 
    if ( T1_LoadFont( FontID) )
2115
 
      return NULL;
2116
 
 
2117
 
  /* Check for valid size */
2118
 
  if (size<=0.0){
2119
 
    T1_errno=T1ERR_INVALID_PARAMETER;
2120
 
    return(NULL);
2121
 
  }
2122
 
 
2123
 
  /* Assign padding value */
2124
 
  T1_pad=pFontBase->bitmap_pad;
2125
 
  if (pFontBase->endian)
2126
 
    T1_byte=1;
2127
 
  else
2128
 
    T1_byte=0;
2129
 
  T1_wordsize=T1_pad;
2130
 
 
2131
 
  if ( i > 0 ) {
2132
 
    /* FontID identifies a valid font */
2133
 
    fontarrayP = &(pFontBase->pFontArray[FontID]);
2134
 
    
2135
 
    /* Check for size and create it if necessary */
2136
 
    if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
2137
 
      font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS);
2138
 
      if (font_ptr==NULL){
2139
 
        T1_errno=T1ERR_ALLOC_MEM;
2140
 
        return(NULL);
2141
 
      }
2142
 
    }
2143
 
    
2144
 
    /* handle stroking stuff */
2145
 
    if ( fontarrayP->info_flags & RASTER_STROKED) {
2146
 
      strokewidth = pFontBase->pFontArray[FontID].StrokeWidth;
2147
 
    }
2148
 
    else {
2149
 
      strokewidth = 0.0f;
2150
 
    }
2151
 
  }
2152
 
  else {
2153
 
    fontarrayP = NULL;
2154
 
    strokewidth = 0.0f;
2155
 
  }
2156
 
  
2157
 
  
2158
 
  /* Setup an appropriate charspace matrix. Note that the rasterizer
2159
 
     assumes vertical values with inverted sign! Transformation should
2160
 
     create a copy of the local charspace matrix which then still has
2161
 
     to be made permanent. */
2162
 
  if ( transform != NULL ) {
2163
 
    Current_S = (struct XYspace *) 
2164
 
      Permanent(Scale(Transform (font_ptr->pCharSpaceLocal,
2165
 
                                 transform->cxx, - transform->cxy,
2166
 
                                 transform->cyx, - transform->cyy),
2167
 
                      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
2168
 
  }
2169
 
  else{
2170
 
    Current_S = (struct XYspace *)
2171
 
      Permanent(Scale(Transform(font_ptr->pCharSpaceLocal,
2172
 
                                1.0, 0.0, 0.0, -1.0),
2173
 
                      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
2174
 
  }
2175
 
  
2176
 
  mode=0;
2177
 
  area=fontfcnRect( width,
2178
 
                    height,
2179
 
                    Current_S,
2180
 
                    &mode,
2181
 
                    DO_RASTER,
2182
 
                    strokewidth);
2183
 
  KillSpace (Current_S);
2184
 
  
2185
 
  /* fill the glyph-structure */
2186
 
  if ( mode > 0 ) {
2187
 
    sprintf( err_warn_msg_buf, "fontfcnRect() set mode=%d", mode);
2188
 
    T1_PrintLog( "T1_SetRect()", err_warn_msg_buf, T1LOG_WARNING);
2189
 
    T1_errno=mode;
2190
 
    return(NULL);
2191
 
  }
2192
 
  if ( area == NULL ) {
2193
 
    T1_PrintLog( "T1_SetRect()", "area=NULL returned by fontfcnRect()", T1LOG_WARNING);
2194
 
    T1_errno=mode;
2195
 
    return(NULL);
2196
 
  }
2197
 
  h = area->ymax - area->ymin;
2198
 
  w = area->xmax - area->xmin;
2199
 
 
2200
 
  paddedW = PAD(w, T1_pad);
2201
 
  
2202
 
  if (h > 0 && w > 0) {
2203
 
    memsize = h * paddedW / 8 + 1;
2204
 
    /* This is for the users copy of the character, for security-reasons
2205
 
       the original pointer to the cache area is not used. The entry glyph.bits
2206
 
       is free'ed every time this function is called: */
2207
 
    glyph.bits = (char *)malloc(memsize*sizeof( char));
2208
 
    if ( glyph.bits == NULL ) {
2209
 
      T1_errno=T1ERR_ALLOC_MEM;
2210
 
      /* make sure to get rid of 'area' before leaving! */
2211
 
      KillRegion (area);
2212
 
      return(NULL);
2213
 
    }
2214
 
  }
2215
 
  else {
2216
 
    h = w = 0;
2217
 
    area->xmin = area->xmax = 0;
2218
 
    area->ymin = area->ymax = 0;
2219
 
  }
2220
 
 
2221
 
  /* Assign metrics */
2222
 
  glyph.metrics.leftSideBearing  = area->xmin;
2223
 
  glyph.metrics.advanceX   = NEARESTPEL(area->ending.x - area->origin.x);
2224
 
  glyph.metrics.advanceY   = - NEARESTPEL(area->ending.y - area->origin.y);
2225
 
  glyph.metrics.rightSideBearing = area->xmax;
2226
 
  glyph.metrics.descent          = - area->ymax;
2227
 
  glyph.metrics.ascent           = - area->ymin;
2228
 
 
2229
 
  
2230
 
  if (h > 0 && w > 0) {
2231
 
    (void) memset(glyph.bits, 0, memsize);
2232
 
    fill(glyph.bits, h, paddedW, area, T1_byte, T1_bit, T1_wordsize );
2233
 
  }
2234
 
  
2235
 
  /* make sure to get rid of 'area' before leaving! */
2236
 
  KillRegion (area);
2237
 
  
2238
 
  return(&glyph);
2239
 
}