source: toilet/trunk/src/render.c @ 1194

Last change on this file since 1194 was 1194, checked in by Sam Hocevar, 16 years ago
  • The mono9 driver works again. With wrapping and stdin reading.
  • Property svn:keywords set to Id
File size: 4.0 KB
Line 
1/*
2 *  TOIlet        The Other Implementation’s letters
3 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: render.c 1194 2006-10-09 23:54:40Z sam $
7 *
8 *  This program is free software; you can redistribute it and/or
9 *  modify it under the terms of the Do What The Fuck You Want To
10 *  Public License, Version 2, as published by Sam Hocevar. See
11 *  http://sam.zoy.org/wtfpl/COPYING for more details.
12 */
13
14/*
15 * This file contains text to canvas rendering functions.
16 */
17
18#include "config.h"
19
20#if defined(HAVE_INTTYPES_H)
21#   include <inttypes.h>
22#endif
23#include <stdlib.h>
24#include <cucul.h>
25
26#include "toilet.h"
27#include "render.h"
28
29static int feed_tiny(context_t *, uint32_t);
30static int end_tiny(context_t *);
31
32static int feed_big(context_t *, uint32_t);
33static int end_big(context_t *);
34
35int init_tiny(context_t *cx)
36{
37    cx->ew = 16;
38    cx->eh = 2;
39    cx->x = cx->y = 0;
40    cx->w = cx->h = 0;
41    cx->cv = cucul_create_canvas(cx->ew, cx->eh);
42
43    cx->feed = feed_tiny;
44    cx->end = end_tiny;
45
46    return 0;
47}
48
49static int feed_tiny(context_t *cx, uint32_t ch)
50{
51    /* Check whether we reached the end of the screen */
52    if(cx->x && cx->x + 1 > cx->term_width)
53    {
54        cx->x = 0;
55        cx->y++;
56    }
57
58    /* Check whether the current canvas is large enough */
59    if(cx->x + 1 > cx->w)
60    {
61        cx->w = cx->x + 1 < cx->term_width ? cx->x + 1 : cx->term_width;
62        if(cx->w > cx->ew)
63            cx->ew = cx->ew + cx->ew / 2;
64    }
65
66    if(cx->y + 1 > cx->h)
67    {
68        cx->h = cx->y + 1;
69        if(cx->h > cx->eh)
70            cx->eh = cx->eh + cx->eh / 2;
71    }
72
73    cucul_set_canvas_size(cx->cv, cx->ew, cx->eh);
74
75    switch(ch)
76    {
77        case (uint32_t)'\r':
78            return 0;
79        case (uint32_t)'\n':
80            cx->x = 0;
81            cx->y++;
82            break;
83        case (uint32_t)'\t':
84            cx->x = (cx->x & ~7) + 8;
85            break;
86        default:
87            cucul_putchar(cx->cv, cx->x, cx->y, ch);
88            cx->x++;
89            break;
90    }
91
92    return 0;
93}
94
95static int end_tiny(context_t *cx)
96{
97    cucul_set_canvas_size(cx->cv, cx->w, cx->h);
98
99    return 0;
100}
101
102int init_big(context_t *cx)
103{
104    char const * const * fonts;
105
106    fonts = cucul_get_font_list();
107    cx->f = cucul_load_font(fonts[0], 0);
108    cx->buf = malloc(4 * cucul_get_font_width(cx->f)
109                       * cucul_get_font_height(cx->f));
110    cx->onechar = cucul_create_canvas(1, 1);
111    cucul_set_color(cx->onechar, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLACK);
112
113    cx->x = cx->y = 0;
114    cx->w = cx->h = 0;
115    cx->cv = cucul_create_canvas(1, 1);
116
117    cx->feed = feed_big;
118    cx->end = end_big;
119
120    return 0;
121}
122
123static int feed_big(context_t *cx, uint32_t ch)
124{
125    unsigned int w = cucul_get_font_width(cx->f);
126    unsigned int h = cucul_get_font_height(cx->f);
127    unsigned int x, y;
128
129    /* Check whether we reached the end of the screen */
130    if(cx->x && cx->x + w > cx->term_width)
131    {
132        cx->x = 0;
133        cx->y += h;
134    }
135
136    /* Check whether the current canvas is large enough */
137    if(cx->x + w > cx->w)
138        cx->w = cx->x + w < cx->term_width ? cx->x + w : cx->term_width;
139
140    if(cx->y + h > cx->h)
141        cx->h = cx->y + h;
142
143    cucul_set_canvas_size(cx->cv, cx->w, cx->h);
144
145    /* Render our char */
146    cucul_putchar(cx->onechar, 0, 0, ch);
147    cucul_render_canvas(cx->onechar, cx->f, cx->buf, w, h, 4 * w);
148
149    for(y = 0; y < h; y++)
150       for(x = 0; x < w; x++)
151    {
152        unsigned char c = cx->buf[4 * (x + y * w) + 2];
153
154        if(c >= 0xa0)
155            cucul_putstr(cx->cv, cx->x + x, cx->y + y, "█");
156        else if(c >= 0x80)
157            cucul_putstr(cx->cv, cx->x + x, cx->y + y, "▓");
158        else if(c >= 0x40)
159            cucul_putstr(cx->cv, cx->x + x, cx->y + y, "▒");
160        else if(c >= 0x20)
161            cucul_putstr(cx->cv, cx->x + x, cx->y + y, "░");
162    }
163
164    /* Advance cursor */
165    cx->x += w;
166
167    return 0;
168}
169
170static int end_big(context_t *cx)
171{
172    cucul_free_canvas(cx->onechar);
173    free(cx->buf);
174    cucul_free_font(cx->f);
175
176    return 0;
177}
178
Note: See TracBrowser for help on using the repository browser.