tgetsubfont.c - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
tgetsubfont.c (3076B)
---
     1 #include 
     2 #include 
     3 #include 
     4 #include "defont.h"
     5 
     6 /*
     7  * Default version: treat as file name
     8  */
     9 
    10 int _fontpipe(char*);
    11 static int defaultpipe(void);
    12 
    13 static void scalesubfont(Subfont*, int);
    14 
    15 Subfont*
    16 _getsubfont(Display *d, char *name)
    17 {
    18         int fd;
    19         Subfont *f;
    20         int scale;
    21         char *fname;
    22 
    23         scale = parsefontscale(name, &fname);
    24         if(strcmp(fname, "*default*") == 0)
    25                 fd = defaultpipe();
    26         else
    27                 fd = open(fname, OREAD);
    28         if(fd < 0 && strncmp(fname, "/mnt/font/", 10) == 0)
    29                 fd = _fontpipe(fname+10);
    30         if(fd < 0){
    31                 fprint(2, "getsubfont: can't open %s: %r\n", fname);
    32                 return 0;
    33         }
    34         /*
    35          * unlock display so i/o happens with display released, unless
    36          * user is doing his own locking, in which case this could break things.
    37          * _getsubfont is called only from string.c and stringwidth.c,
    38          * which are known to be safe to have this done.
    39          */
    40         if(d && d->locking == 0)
    41                 unlockdisplay(d);
    42         f = readsubfont(d, name, fd, d && d->locking==0);
    43         if(d && d->locking == 0)
    44                 lockdisplay(d);
    45         if(f == 0)
    46                 fprint(2, "getsubfont: can't read %s: %r\n", name);
    47         close(fd);
    48         if(scale > 1)
    49                 scalesubfont(f, scale);
    50         return f;
    51 }
    52 
    53 static int
    54 defaultpipe(void)
    55 {
    56         int p[2], pid;
    57 
    58         // Used to assume that defontdata (<5k) fit in the
    59         // pipe buffer, especially since p9pipe is actually
    60         // a socket pair. But OpenBSD in particular saw hangs,
    61         // so feed the pipe it the "right" way with a subprocess.
    62         if(pipe(p) < 0)
    63                 return -1;
    64         if((pid = fork()) < 0) {
    65                 close(p[0]);
    66                 close(p[1]);
    67                 return -1;
    68         }
    69         if(pid == 0) {
    70                 close(p[0]);
    71                 write(p[1], defontdata, sizeof defontdata);
    72                 close(p[1]);
    73                 _exit(0);
    74         }
    75         return p[0];
    76 }
    77 
    78 static void
    79 scalesubfont(Subfont *f, int scale)
    80 {
    81         Image *i;
    82         Rectangle r, r2;
    83         int y, x, x2, j;
    84         uchar *src, *dst;
    85         int srcn, dstn, n, mask, v, pack;
    86 
    87         r = f->bits->r;
    88         r2 = r;
    89         r2.min.x *= scale;
    90         r2.min.y *= scale;
    91         r2.max.x *= scale;
    92         r2.max.y *= scale;
    93 
    94         srcn = bytesperline(r, f->bits->depth);
    95         src = malloc(srcn);
    96         dstn = bytesperline(r2, f->bits->depth);
    97         dst = malloc(dstn+1);
    98         i = allocimage(f->bits->display, r2, f->bits->chan, 0, DBlack);
    99         for(y=r.min.y; y < r.max.y; y++) {
   100                 n = unloadimage(f->bits, Rect(r.min.x, y, r.max.x, y+1), src, srcn);
   101                 if(n != srcn) {
   102                         abort();
   103                         sysfatal("scalesubfont: bad unload %R %R: %d < %d: %r", f->bits->r, Rect(r.min.x, y, r.max.x, y+1), n, srcn);
   104                 }
   105                 memset(dst, 0, dstn+1);
   106                 pack = 8 / f->bits->depth;
   107                 mask = (1<bits->depth) - 1;
   108                 for(x=0; xbits->depth)) >> (8 - f->bits->depth)) & mask;
   110                         for(j=0; jbits->depth) >> ((x2%pack)*f->bits->depth);
   113                         }
   114                 }
   115                 if(dst[dstn] != 0)
   116                         sysfatal("overflow dst");
   117                 for(j=0; jbits);
   121         f->bits = i;
   122         f->height *= scale;
   123         f->ascent *= scale;
   124 
   125         for(j=0; jn; j++) {
   126                 f->info[j].x *= scale;
   127                 f->info[j].top *= scale;
   128                 f->info[j].bottom *= scale;
   129                 f->info[j].left *= scale;
   130                 f->info[j].width *= scale;
   131         }
   132 }