The R Project SVN R

Rev

Rev 42521 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 42521 Rev 45017
Line 30... Line 30...
30
 
30
 
31
#define COMPRESS_WHITESPACE 0
31
#define COMPRESS_WHITESPACE 0
32
 
32
 
33
static const char *get_next_line(char *line, int width, const char *s)
33
static const char *get_next_line(char *line, int width, const char *s)
34
{
34
{
35
	const char *t; char  *k;
35
    const char *t; char  *k;
36
	int	word_width, line_width;
36
    int	word_width, line_width;
37
	int	sp, tab, nl;
37
    int	sp, tab, nl;
38
 
38
 
39
	line_width  = 0;
39
    line_width  = 0;
40
 
40
 
41
	for (t=s, k=line; *t!='\0'; line=k, s=t)
41
    for (t=s, k=line; *t!='\0'; line=k, s=t)
-
 
42
    {
-
 
43
	for (nl=tab=sp=0; (*t!='\0') && isspace(*t) && !nl; t++)
42
	{
44
	{
43
		for (nl=tab=sp=0; (*t!='\0') && isspace(*t) && !nl; t++)
-
 
44
		{
-
 
45
#if COMPRESS_WHITESPACE
45
#if COMPRESS_WHITESPACE
46
			if (*t == '\n') nl++;
46
	    if (*t == '\n') nl++;
47
			else if (*t == '\t') tab++;
47
	    else if (*t == '\t') tab++;
48
			else sp++;
48
	    else sp++;
49
#else
49
#else
50
			if (*t == '\n') nl++;
50
	    if (*t == '\n') nl++;
51
			else if (*t == '\t') { /* expand tabs */
51
	    else if (*t == '\t') { /* expand tabs */
52
				for (tab=4; tab; tab--)
52
		for (tab=4; tab; tab--)
53
					*k++ = ' ';
53
		    *k++ = ' ';
54
			}
54
	    }
55
			else
55
	    else
56
				*k++ = *t;
56
		*k++ = *t;
57
#endif
57
#endif
58
		}
58
	}
59
 
-
 
60
		s = t;
-
 
61
 
59
 
62
		if (nl)      	{ *k++ = '\n'; break; }
-
 
63
		else if (tab)	{ *k++ = ' '; *k++ = ' '; }
-
 
64
		else if (sp) 	{ *k++ = ' ';  }
-
 
65
 
-
 
66
		/* fetch the next word to draw */
-
 
67
 
-
 
68
		for (*k='\0'; (*t!='\0') && !isspace(*t); *k='\0') {
-
 
69
			if (*t == '-') {
-
 
70
				*k++ = *t++;
-
 
71
				*k = '\0';
-
 
72
				break;
-
 
73
			}
-
 
74
			*k++ = *t++;
60
	s = t;
75
		}
-
 
76
 
61
 
-
 
62
	if (nl)	{ *k++ = '\n'; break; }
-
 
63
	else if (tab)	{ *k++ = ' '; *k++ = ' '; }
-
 
64
	else if (sp)	{ *k++ = ' ';  }
-
 
65
 
77
		/* determine where the word should be drawn */
66
	/* fetch the next word to draw */
-
 
67
 
-
 
68
	for (*k='\0'; (*t!='\0') && !isspace(*t); *k='\0') {
-
 
69
	    if (*t == '-') {
-
 
70
		*k++ = *t++;
-
 
71
		*k = '\0';
-
 
72
		break;
-
 
73
	    }
-
 
74
	    *k++ = *t++;
-
 
75
	}
78
 
76
 
79
		while (((word_width = strwidth(current->fnt,line)) > width)
77
	/* determine where the word should be drawn */
80
				&& (k>line))
-
 
81
		{
-
 
82
			*(--k) = '\0';
-
 
83
			--t;
-
 
84
		}
-
 
85
 
78
 
86
		if (word_width > (width - line_width)) {
79
	while (((word_width = strwidth(current->fnt,line)) > width)
87
			k = line;
80
	       && (k>line))
-
 
81
	{
88
			break;
82
	    *(--k) = '\0';
89
		} else
83
	    --t;
90
			line_width += word_width;
-
 
91
	}
84
	}
92
 
85
 
-
 
86
	if (word_width > (width - line_width)) {
93
	*k = '\0';
87
	    k = line;
-
 
88
	    break;
-
 
89
	} else
-
 
90
	    line_width += word_width;
-
 
91
    }
94
 
92
 
-
 
93
    *k = '\0';
-
 
94
 
95
	return (*s == '\0') ? NULL : s;
95
    return (*s == '\0') ? NULL : s;
96
}
96
}
97
 
97
 
98
int textheight(int width, const char *s)
98
int textheight(int width, const char *s)
99
{
99
{
100
	int y;
100
    int y;
101
	char line[256];
101
    char line[256];
102
	int height;
102
    int height;
103
 
103
 
104
	height = getheight(current->fnt);
104
    height = getheight(current->fnt);
-
 
105
 
-
 
106
    for(y=0; s; y+=height)
-
 
107
    {
-
 
108
	s = get_next_line(line, width, s);
-
 
109
    }
105
 
110
 
106
	for(y=0; s; y+=height)
-
 
107
	{
-
 
108
		s = get_next_line(line, width, s);
-
 
109
	}
-
 
110
 
-
 
111
	return y;
111
    return y;
112
}
112
}
113
 
113
 
114
static const char *draw_text_left(char *line, rect r, int line_height,
114
static const char *draw_text_left(char *line, rect r, int line_height,
115
				  int underline, const char *s)
115
				  int underline, const char *s)
116
{
116
{
117
	char *k;
117
    char *k;
118
	point p;
118
    point p;
119
	int width, height;
119
    int width, height;
120
	font f;
120
    font f;
121
 
121
 
122
	f = current->fnt;
122
    f = current->fnt;
123
 
123
 
124
	for(p=pt(r.x,r.y); (p.y<=r.y+r.height) && (s); p.y+=line_height)
124
    for(p=pt(r.x,r.y); (p.y<=r.y+r.height) && (s); p.y+=line_height)
125
	{
125
    {
126
		s = get_next_line(line, r.width, s);
126
	s = get_next_line(line, r.width, s);
127
 
127
 
128
		for (k=line; *k!='\0'; k++)
128
	for (k=line; *k!='\0'; k++)
129
			continue;
129
	    continue;
130
		for (--k; (k>=line) && isspace(*k); k--)
130
	for (--k; (k>=line) && isspace(*k); k--)
131
			*k = '\0';
131
	    *k = '\0';
132
 
132
 
133
		drawstr(p, line);
133
	drawstr(p, line);
134
 
134
 
135
		if (underline) {
135
	if (underline) {
136
			width = strwidth(f, line);
136
	    width = strwidth(f, line);
137
			height = p.y+getheight(f)-getdescent(f)+2;
137
	    height = p.y+getheight(f)-getdescent(f)+2;
138
			drawline(pt(p.x+1, height), pt(p.x+width-1, height));
138
	    drawline(pt(p.x+1, height), pt(p.x+width-1, height));
139
		}
-
 
140
	}
139
	}
-
 
140
    }
141
 
141
 
142
	return s;
142
    return s;
143
}
143
}
144
 
144
 
145
static const char *draw_text_right(char *line, rect r, int line_height,
145
static const char *draw_text_right(char *line, rect r, int line_height,
146
			     int underline, const char *s)
146
			     int underline, const char *s)
147
{
147
{
148
	char *k;
148
    char *k;
149
	int w;
149
    int w;
150
	point p;
150
    point p;
151
	int width, height;
151
    int width, height;
152
	font f;
152
    font f;
153
 
153
 
154
	f = current->fnt;
154
    f = current->fnt;
155
 
155
 
156
	for(p=pt(r.x,r.y); (p.y<=r.y+r.height) && (s); p.y+=line_height)
156
    for(p=pt(r.x,r.y); (p.y<=r.y+r.height) && (s); p.y+=line_height)
157
	{
157
    {
158
		s = get_next_line(line, r.width, s);
158
	s = get_next_line(line, r.width, s);
159
 
159
 
160
		for (k=line; *k!='\0'; k++)
160
	for (k=line; *k!='\0'; k++)
161
			continue;
161
	    continue;
162
		for (--k; (k>=line) && isspace(*k); k--)
162
	for (--k; (k>=line) && isspace(*k); k--)
163
			*k = '\0';
163
	    *k = '\0';
164
		for (k=line; (*k!='\0') && isspace(*k); k++)
164
	for (k=line; (*k!='\0') && isspace(*k); k++)
165
			continue;
165
	    continue;
166
 
166
 
167
		w = strwidth(current->fnt, k);
167
	w = strwidth(current->fnt, k);
168
		p.x = r.x+r.width - w;
168
	p.x = r.x+r.width - w;
169
 
169
 
170
		drawstr(p, k);
170
	drawstr(p, k);
171
 
171
 
172
		if (underline) {
172
	if (underline) {
173
			width = strwidth(f, k);
173
	    width = strwidth(f, k);
174
			height = p.y+getheight(f)-getdescent(f)+2;
174
	    height = p.y+getheight(f)-getdescent(f)+2;
175
			drawline(pt(p.x+1, height), pt(p.x+width-1, height));
175
	    drawline(pt(p.x+1, height), pt(p.x+width-1, height));
176
		}
-
 
177
	}
176
	}
-
 
177
    }
178
 
178
 
179
	return s;
179
    return s;
180
}
180
}
181
 
181
 
182
static const char *draw_text_centered(char *line, rect r, int line_height,
182
static const char *draw_text_centered(char *line, rect r, int line_height,
183
				      int underline, const char *s)
183
				      int underline, const char *s)
184
{
184
{
185
	char *k;
185
    char *k;
186
	int w;
186
    int w;
187
	point p;
187
    point p;
188
	int width, height;
188
    int width, height;
189
	font f;
189
    font f;
190
 
190
 
191
	f = current->fnt;
191
    f = current->fnt;
192
 
192
 
193
	for(p=pt(r.x,r.y); (p.y<=r.y+r.height) && (s); p.y+=line_height)
193
    for(p=pt(r.x,r.y); (p.y<=r.y+r.height) && (s); p.y+=line_height)
194
	{
194
    {
195
		s = get_next_line(line, r.width, s);
195
	s = get_next_line(line, r.width, s);
196
 
196
 
197
		for (k=line; *k!='\0'; k++)
197
	for (k=line; *k!='\0'; k++)
198
			continue;
198
	    continue;
199
		for (--k; (k>=line) && isspace(*k); k--)
199
	for (--k; (k>=line) && isspace(*k); k--)
200
			*k = '\0';
200
	    *k = '\0';
201
		for(k=line; (*k!='\0') && isspace(*k); k++)
201
	for(k=line; (*k!='\0') && isspace(*k); k++)
202
			continue;
202
	    continue;
203
 
203
 
204
		w = strwidth(current->fnt, k);
204
	w = strwidth(current->fnt, k);
205
		p.x = r.x + (r.width-w)/2;
205
	p.x = r.x + (r.width-w)/2;
206
 
206
 
207
		drawstr(p, k);
207
	drawstr(p, k);
208
 
208
 
209
		if (underline) {
209
	if (underline) {
210
			width = strwidth(f, k);
210
	    width = strwidth(f, k);
211
			height = p.y+getheight(f)-getdescent(f)+2;
211
	    height = p.y+getheight(f)-getdescent(f)+2;
212
			drawline(pt(p.x+1, height), pt(p.x+width-1, height));
212
	    drawline(pt(p.x+1, height), pt(p.x+width-1, height));
213
		}
-
 
214
	}
213
	}
-
 
214
    }
215
 
215
 
216
	return s;
216
    return s;
217
}
217
}
218
 
218
 
219
static const char *draw_text_justified(char *line, rect r, int line_height,
219
static const char *draw_text_justified(char *line, rect r, int line_height,
220
				       int underline, const char *s)
220
				       int underline, const char *s)
221
{
221
{
222
	char *j, *k;
222
    char *j, *k;
223
	int w, xw, nl, sc, sw, space_width;
223
    int w, xw, nl, sc, sw, space_width;
224
	point p;
224
    point p;
225
	int width, height;
225
    int width, height;
226
	font f;
226
    font f;
227
 
227
 
228
	space_width = strwidth(current->fnt, " ");
228
    space_width = strwidth(current->fnt, " ");
229
	f = current->fnt;
229
    f = current->fnt;
230
 
230
 
231
	for(p=pt(r.x,r.y); (p.y<=r.y+r.height) && (s); p.y+=line_height)
231
    for(p=pt(r.x,r.y); (p.y<=r.y+r.height) && (s); p.y+=line_height)
232
	{
232
    {
233
		s = get_next_line(line, r.width, s);
233
	s = get_next_line(line, r.width, s);
234
 
234
 
235
		p.x = r.x;
235
	p.x = r.x;
236
 
236
 
237
		for(j=line; (*j!='\0') && isspace(*j); j++)
237
	for(j=line; (*j!='\0') && isspace(*j); j++)
238
			p.x += space_width;
238
	    p.x += space_width;
239
		for (sc=0, k=j; *k!='\0'; k++)
239
	for (sc=0, k=j; *k!='\0'; k++)
240
			if (isspace(*k))
240
	    if (isspace(*k))
241
				sc++;
241
		sc++;
242
		for (nl=0, --k; (k>=j) && isspace(*k); k--) {
242
	for (nl=0, --k; (k>=j) && isspace(*k); k--) {
243
			if (*k == '\n')
243
	    if (*k == '\n')
244
				nl++;
244
		nl++;
245
			*k = '\0';
245
	    *k = '\0';
246
			sc--;
246
	    sc--;
247
		}
247
	}
248
 
248
 
249
		if ((sc==0) || nl || (! s)) {
249
	if ((sc==0) || nl || (! s)) {
250
			drawstr(p, j);
250
	    drawstr(p, j);
251
			width = strwidth(f, j);
251
	    width = strwidth(f, j);
252
		}
252
	}
253
		else {
253
	else {
254
			w = strwidth(f, j);
254
	    w = strwidth(f, j);
255
			sw = space_width + (r.x+r.width-p.x-w)/sc;
255
	    sw = space_width + (r.x+r.width-p.x-w)/sc;
256
			xw = (r.x+r.width-p.x-w)%sc;
256
	    xw = (r.x+r.width-p.x-w)%sc;
257
 
257
 
258
			for(j=strtok(j," "); j; j=strtok(NULL," "))
258
	    for(j=strtok(j," "); j; j=strtok(NULL," "))
259
			{
259
	    {
260
				drawstr(p, j);
260
		drawstr(p, j);
261
				p.x += sw + strwidth(f, j);
261
		p.x += sw + strwidth(f, j);
262
				if (xw) {
262
		if (xw) {
263
					p.x++;
263
		    p.x++;
264
					xw--;
264
		    xw--;
265
				}
-
 
266
			}
-
 
267
			width = r.width;
-
 
268
		}
-
 
269
		if (underline) {
-
 
270
			height = p.y+getheight(f)-getdescent(f)+2;
-
 
271
			drawline(pt(p.x+1, height), pt(p.x+width-1, height));
-
 
272
		}
265
		}
-
 
266
	    }
-
 
267
	    width = r.width;
-
 
268
	}
-
 
269
	if (underline) {
-
 
270
	    height = p.y+getheight(f)-getdescent(f)+2;
-
 
271
	    drawline(pt(p.x+1, height), pt(p.x+width-1, height));
273
	}
272
	}
-
 
273
    }
274
 
274
 
275
	return s;
275
    return s;
276
}
276
}
277
 
277
 
278
const char *drawtext(rect r, int alignment, const char *s)
278
const char *drawtext(rect r, int alignment, const char *s)
279
{
279
{
280
	int h;
280
    int h;
281
	int nlines;
281
    int nlines;
282
	int line_height;
282
    int line_height;
283
	int u = 0;
283
    int u = 0;
284
	rect clip;
284
    rect clip;
285
	const char *remains;
285
    const char *remains;
286
	char line[256];
286
    char line[256];
287
 
287
 
288
	initapp(0,0);
288
    initapp(0,0);
289
	if (! s) return (char *) NULL;
289
    if (! s) return (char *) NULL;
290
	if (! current->fnt)
290
    if (! current->fnt)
291
		current->fnt = SystemFont;
291
	current->fnt = SystemFont;
292
 
292
 
293
	clip = getcliprect();
293
    clip = getcliprect();
294
	setcliprect(r);
294
    setcliprect(r);
295
 
295
 
296
	line_height = getheight(current->fnt);
296
    line_height = getheight(current->fnt);
297
 
297
 
298
	if ((alignment & VCenter) == VCenter) {
298
    if ((alignment & VCenter) == VCenter) {
299
		h = textheight(r.width, s);
299
	h = textheight(r.width, s);
300
		if (h < r.height)
300
	if (h < r.height)
301
			r.y += (r.height-h)/2;
301
	    r.y += (r.height-h)/2;
302
	}
302
    }
303
	else if ((alignment & VJustify) == VJustify) {
303
    else if ((alignment & VJustify) == VJustify) {
304
		h = textheight(r.width, s);
304
	h = textheight(r.width, s);
305
		if (h < r.height) {
305
	if (h < r.height) {
306
			nlines = h / line_height;
306
	    nlines = h / line_height;
307
			if (nlines > 1)
307
	    if (nlines > 1)
308
				line_height += ((r.height-h) / (nlines-1));
308
		line_height += ((r.height-h) / (nlines-1));
309
		}
-
 
310
	}
309
	}
-
 
310
    }
311
	else if ((alignment & AlignBottom) == AlignBottom) {
311
    else if ((alignment & AlignBottom) == AlignBottom) {
312
		h = textheight(r.width, s);
312
	h = textheight(r.width, s);
313
		if (h < r.height)
313
	if (h < r.height)
314
			r.y += (r.height-h);
314
	    r.y += (r.height-h);
315
	}
315
    }
316
 
316
 
317
	u = (alignment & Underline);
317
    u = (alignment & Underline);
318
 
318
 
319
	if ((alignment & Center) == Center)
319
    if ((alignment & Center) == Center)
320
		remains = draw_text_centered(line, r, line_height, u, s);
320
	remains = draw_text_centered(line, r, line_height, u, s);
321
	else if ((alignment & Justify) == Justify)
321
    else if ((alignment & Justify) == Justify)
322
		remains = draw_text_justified(line, r, line_height, u, s);
322
	remains = draw_text_justified(line, r, line_height, u, s);
323
	else if ((alignment & AlignRight) == AlignRight)
323
    else if ((alignment & AlignRight) == AlignRight)
324
		remains = draw_text_right(line, r, line_height, u, s);
324
	remains = draw_text_right(line, r, line_height, u, s);
325
	else
325
    else
326
		remains = draw_text_left(line, r, line_height, u, s);
326
	remains = draw_text_left(line, r, line_height, u, s);
327
 
327
 
328
	setcliprect(clip);
328
    setcliprect(clip);
329
	return remains;
329
    return remains;
330
}
330
}
331
 
331
 
332
int gprintf(const char *fmt, ...)
332
int gprintf(const char *fmt, ...)
333
{
333
{
334
	static point p = {0,0};
334
    static point p = {0,0};
335
	int count;
335
    int count;
336
	int line_height;
336
    int line_height;
337
	char *s, *t;
337
    char *s, *t;
338
	va_list argptr;
338
    va_list argptr;
339
	char str[256];
339
    char str[256];
340
 
340
 
341
	va_start(argptr, fmt);
341
    va_start(argptr, fmt);
342
	count = vsprintf(str, fmt, argptr);
342
    count = vsprintf(str, fmt, argptr);
343
 
343
 
344
	initapp(0,0);
344
    initapp(0,0);
345
	if (! current->fnt)
345
    if (! current->fnt)
346
		current->fnt = SystemFont;
346
	current->fnt = SystemFont;
347
	line_height = getheight(current->fnt);
347
    line_height = getheight(current->fnt);
348
 
348
 
349
	for (s=t=str; *s!='\0'; t++) {
349
    for (s=t=str; *s!='\0'; t++) {
350
		if (current->p.y != p.y) {
350
	if (current->p.y != p.y) {
351
			/* typewriter ping! */
351
	    /* typewriter ping! */
352
			p = current->p;
352
	    p = current->p;
353
		}
353
	}
354
		if (*t == '\n') {
354
	if (*t == '\n') {
355
		/* print everything from s to t and move point down */
355
	    /* print everything from s to t and move point down */
356
			*t = '\0';
356
	    *t = '\0';
357
			drawstr(p, s);
357
	    drawstr(p, s);
358
			current->p.y += line_height;
358
	    current->p.y += line_height;
359
			/* go past the substring just printed */
359
	    /* go past the substring just printed */
360
			s = t+1;
360
	    s = t+1;
361
		}
361
	}
362
		else if (*t == '\0') {
362
	else if (*t == '\0') {
363
			/* print final string without newline */
363
	    /* print final string without newline */
364
			p.x += drawstr(p, s);
364
	    p.x += drawstr(p, s);
365
			/* go to end of string, signal termination */
365
	    /* go to end of string, signal termination */
366
			s = t;
366
	    s = t;
367
		}
-
 
368
	}
367
	}
-
 
368
    }
369
 
369
 
370
	va_end(argptr);
370
    va_end(argptr);
371
 
371
 
372
	return count;
372
    return count;
373
}
373
}