source: toilet/trunk/src/mono9.c @ 1241

Last change on this file since 1241 was 1241, checked in by Sam Hocevar, 14 years ago
  • Make stdin input line-aware so that we don't have to wait until EOF to display stuff.
  • Reorganise stuff and fix memory leaks.
  • Property svn:keywords set to Id
File size: 3.2 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: mono9.c 1241 2006-10-26 13:07:58Z 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_big(context_t *, uint32_t);
30static int flush_big(context_t *);
31static int end_big(context_t *);
32
33int init_big(context_t *cx)
34{
35    char const * const * fonts;
36
37    fonts = cucul_get_font_list();
38    cx->f = cucul_load_font(fonts[0], 0);
39    cx->buf = malloc(4 * cucul_get_font_width(cx->f)
40                       * cucul_get_font_height(cx->f));
41    cx->onechar = cucul_create_canvas(1, 1);
42    cucul_set_color(cx->onechar, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLACK);
43
44    cx->x = cx->y = 0;
45    cx->w = cx->h = 0;
46    cx->cv = cucul_create_canvas(1, 1);
47
48    cx->feed = feed_big;
49    cx->flush = flush_big;
50    cx->end = end_big;
51
52    return 0;
53}
54
55static int feed_big(context_t *cx, uint32_t ch)
56{
57    unsigned int w = cucul_get_font_width(cx->f);
58    unsigned int h = cucul_get_font_height(cx->f);
59    unsigned int x, y;
60
61    switch(ch)
62    {
63        case (uint32_t)'\r':
64            return 0;
65        case (uint32_t)'\n':
66            cx->x = 0;
67            cx->y += h;
68            return 0;
69        case (uint32_t)'\t':
70            cx->x = (((cx->x / w) & ~7) + 8) * w;
71            return 0;
72    }
73
74    /* Check whether we reached the end of the screen */
75    if(cx->x && cx->x + w > cx->term_width)
76    {
77        cx->x = 0;
78        cx->y += h;
79    }
80
81    /* Check whether the current canvas is large enough */
82    if(cx->x + w > cx->w)
83        cx->w = cx->x + w < cx->term_width ? cx->x + w : cx->term_width;
84
85    if(cx->y + h > cx->h)
86        cx->h = cx->y + h;
87
88    cucul_set_canvas_size(cx->cv, cx->w, cx->h);
89
90    /* Render our char */
91    cucul_putchar(cx->onechar, 0, 0, ch);
92    cucul_render_canvas(cx->onechar, cx->f, cx->buf, w, h, 4 * w);
93
94    for(y = 0; y < h; y++)
95       for(x = 0; x < w; x++)
96    {
97        unsigned char c = cx->buf[4 * (x + y * w) + 2];
98
99        if(c >= 0xa0)
100            cucul_putstr(cx->cv, cx->x + x, cx->y + y, "█");
101        else if(c >= 0x80)
102            cucul_putstr(cx->cv, cx->x + x, cx->y + y, "▓");
103        else if(c >= 0x40)
104            cucul_putstr(cx->cv, cx->x + x, cx->y + y, "▒");
105        else if(c >= 0x20)
106            cucul_putstr(cx->cv, cx->x + x, cx->y + y, "░");
107    }
108
109    /* Advance cursor */
110    cx->x += w;
111
112    return 0;
113}
114
115static int flush_big(context_t *cx)
116{
117    cx->torender = cx->cv;
118    cucul_set_canvas_size(cx->torender, cx->w, cx->h);
119
120    cx->x = cx->y = 0;
121    cx->w = cx->h = 0;
122    cx->cv = cucul_create_canvas(1, 1);
123
124    return 0;
125}
126
127static int end_big(context_t *cx)
128{
129    cucul_free_canvas(cx->onechar);
130    cucul_free_canvas(cx->cv);
131    free(cx->buf);
132    cucul_free_font(cx->f);
133
134    return 0;
135}
136
Note: See TracBrowser for help on using the repository browser.