1 
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include "cpi.h"
6 
7 
8 /* Given a DRFONT, turn it into a conventional font */
cpi_bloat(CPI_FILE * f)9 int cpi_bloat(CPI_FILE *f)
10 {
11 	CP_HEAD *cph;
12 	CP_FONT *cpf;
13 	CP_DRFONT *cpd;
14 	int nsizes, chcount, chlen;
15 	int n, m;
16 	cpi_byte *src, *dest;
17 
18 	if (strcmp(f->format, "DRFONT "))
19 		return 0;	/* Not DRFONT */
20 
21 	nsizes = 0;
22 /* Allocate all the font bitmaps */
23 	for (cph = f->firstpage; cph != NULL; cph = cph->next)
24 	{
25 		for (cpf = cph->fonts; cpf != NULL; cpf = cpf->next)
26 		{
27 			chlen = ((cpf->width + 7) / 8) * cpf->height;
28 			if (cpf->data) { free(cpf->data); cpf->data = NULL; }
29 			cpf->data = malloc(chlen * cpf->nchars);
30 			if (!cpf->data) return CPI_ERR_NOMEM;
31 			cpf->fontsize = chlen * cpf->nchars;
32 		}
33 	}
34 /* Populate the font bitmaps */
35 	for (cph = f->firstpage; cph != NULL; cph = cph->next)
36 	{
37 		chcount = cpi_count_chars(cph);
38 		for (m = 0, cpf = cph->fonts; cpf != NULL; cpf = cpf->next, m++)
39 		{
40 			cpd = NULL;
41 			chlen = ((cpf->width + 7) / 8) * cpf->height;
42 
43 /* Hopefully the mth drfont header is the one we want. */
44 			if (f->drfonts[m].char_len == chlen)
45 			{
46 				cpd = &f->drfonts[m];
47 			}
48 /* If not, try to find one with the right character size. This could, of
49  * course, be fooled by a DRFONT which has (eg) 8x16 and 16x8 characters */
50 			else for (n = 0; n < f->drcount; n++)
51 			{
52 				if (f->drfonts[n].char_len == chlen)
53 				{
54 					cpd = &f->drfonts[n];
55 					break;
56 				}
57 			}
58 			if (!cpd) continue;
59 			for (n = 0; n < chcount; n++)
60 			{
61 				src  = cpd->bitmap + chlen * cph->dr_lookup[n];
62 				dest = cpf->data   + chlen * n;
63 				memcpy(dest, src, chlen);
64 			}
65 		}
66 		/* Codepage migrated. Free its dr_lookup table */
67 		free(cph->dr_lookup);
68 		cph->dr_lookup = NULL;
69 	}
70 /* Switch font header to FONT */
71 	f->magic0 = 0xFF;
72 	strcpy(f->format, "FONT   ");
73 	free(f->drfonts);
74 	f->drfonts = NULL;
75 	f->drcount = 0;
76 	return CPI_ERR_OK;
77 }
78