1 /*
2  * OpenBOR - http://www.LavaLit.com
3  * -----------------------------------------------------------------------
4  * All rights reserved, see LICENSE in OpenBOR root for details.
5  *
6  * Copyright (c) 2004 - 2011 OpenBOR Team
7  */
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <stdarg.h>
12 #include <string.h>
13 #include "types.h"
14 #include "screen.h"
15 #include "loadimg.h"
16 #include "bitmap.h"
17 #include "sprite.h"
18 #include "spriteq.h"
19 
20 #define		MAX_FONTS		8
21 #define		FONT_LAYER		0x0FFFFFFF
22 
23 
24 typedef struct{
25 	s_sprite *	token[256];
26 	int		token_width[256];
27 	int		font_loaded;
28 }s_font;
29 
30 s_font fonts[MAX_FONTS];
31 
32 int font_heights[MAX_FONTS];
33 int font_monowidths[MAX_FONTS];
34 
font_unload(int which)35 void font_unload(int which){
36 	int i;
37 
38 	which %= MAX_FONTS;
39 
40 	for(i=0; i<256; i++){
41 		if(fonts[which].token[i] != NULL) free(fonts[which].token[i]);
42 		fonts[which].token[i] = NULL;
43 	}
44 	fonts[which].font_loaded = 0;
45 }
46 
47 
48 
font_load(int which,char * filename,char * packfile,int monospace)49 int font_load(int which, char *filename, char *packfile, int monospace){
50 	int x, y;
51 	int index = 0;
52 	int size;
53 	int cx = 0, cy = 0;
54 	s_bitmap *bitmap = NULL;
55 	s_screen *screen = NULL;
56 	int rval = 0;
57 	int tw, th;
58 
59 	which %= MAX_FONTS;
60 
61 	font_unload(which);
62 
63 	if(!loadscreen(filename, packfile, NULL, pixelformat, &screen)) goto err;
64 	font_monowidths[which] = tw = screen->width/16;
65 	font_heights[which] = th = screen->height/16;
66 	if(!(bitmap = allocbitmap(tw,th,pixelformat))) goto err;
67 
68 	if(bitmap->palette && screen->palette)
69 		memcpy(bitmap->palette, screen->palette, PAL_BYTES);
70 
71 	// grab tokens
72 	for(y=0; y<16; y++){
73 		for(x=0; x<16; x++){
74 			getbitmap(x*tw, y*th, tw,th, bitmap, screen);
75 			clipbitmap(bitmap, &cx, NULL, &cy, NULL);
76 			if(index>0)  bitmap->palette=NULL;
77 			size = fakey_encodesprite(bitmap);
78 			fonts[which].token[index] = (s_sprite*)malloc(size);
79 			if(!fonts[which].token[index]){
80 				font_unload(which);
81 				goto err;
82 			}
83 			encodesprite(-cx,-cy, bitmap, fonts[which].token[index]);
84 			fonts[which].token_width[index] = monospace?tw:(fonts[which].token[index]->width+(tw/10));
85 			if(fonts[which].token_width[index] <= 1) fonts[which].token_width[index] = tw/3;
86 			if(index>0)
87 			{
88 				fonts[which].token[index]->palette = fonts[which].token[0]->palette ;
89 				fonts[which].token[index]->pixelformat = screen->pixelformat ;
90 			}
91 			++index;
92 		}
93 	}
94 
95 	rval = 1;
96 	fonts[which].font_loaded = 1;
97 
98 err:
99 	freebitmap(bitmap);
100 	freescreen(&screen);
101 
102 	return rval;
103 }
104 
105 static char b[1024];
106 
font_string_width(int which,char * format,...)107 int font_string_width(int which, char* format, ...)
108 {
109 	int w=0;
110 	char * buf = b;
111 	va_list arglist;
112 
113 	which %= MAX_FONTS;
114 
115 	if(!fonts[which].font_loaded || !format) return 0;
116 
117 	va_start(arglist, format);
118 	vsprintf(buf, format, arglist);
119 	va_end(arglist);
120 
121 	while(*buf)
122 	{
123 	    w += fonts[which].token_width[((int)(*buf)) & 0xFF];
124 	    buf++;
125 	}
126 	return w;
127 }
128 
font_printf(int x,int y,int which,int layeroffset,char * format,...)129 void font_printf(int x, int y, int which, int layeroffset,char *format, ...){
130 	char * buf = b;
131 	va_list arglist;
132 
133 	which %= MAX_FONTS;
134 
135 	if(!fonts[which].font_loaded) return;
136 
137 	va_start(arglist, format);
138 	vsprintf(buf, format, arglist);
139 	va_end(arglist);
140 
141 	while(*buf){
142 		spriteq_add_frame(x,y, FONT_LAYER + layeroffset, fonts[which].token[((int)(*buf)) & 0xFF], NULL, 0);
143 		x += fonts[which].token_width[((int)(*buf)) & 0xFF];
144 		if(*buf=='\n') y += fonts[which].token[0]->height;
145 		buf++;
146 	}
147 }
148 
149 
150 // Print to a screen rather than queueing the sprites
screen_printf(s_screen * screen,int x,int y,int which,char * format,...)151 void screen_printf(s_screen * screen, int x, int y, int which, char *format, ...){
152 	char * buf = b;
153 	va_list arglist;
154 	int ox = x;
155 
156 	which %= MAX_FONTS;
157 
158 	if(!fonts[which].font_loaded) return;
159 
160 	va_start(arglist, format);
161 	vsprintf(buf, format, arglist);
162 	va_end(arglist);
163 
164 	while(*buf){
165 		if(*buf>=32)
166 		{
167 			switch(screen->pixelformat)
168 			{
169 			case PIXEL_8:
170 				putsprite_8(x, y, 0, fonts[which].token[((int)(*buf)) & 0xFF], screen, NULL, NULL);
171 				break;
172 			case PIXEL_16:
173 				putsprite_x8p16(x, y, 0, fonts[which].token[((int)(*buf)) & 0xFF], screen, NULL, NULL);
174 				break;
175 			case PIXEL_32:
176 				putsprite_x8p32(x, y, 0, fonts[which].token[((int)(*buf)) & 0xFF], screen, NULL, NULL);
177 				break;
178 			}
179 			x += fonts[which].token_width[((int)(*buf)) & 0xFF];
180 		}
181 		else if(*buf=='\n'){
182 			x = ox;
183 			y += fonts[which].token[0]->height;;
184 		}
185 		buf++;
186 	}
187 }
188 
189 
190 
191