tsm: move unicode.[ch] to tsm_unicode.[ch]
[platform/upstream/kmscon.git] / src / text_bbulk.c
1 /*
2  * kmscon - Bit-Blitting Bulk Text Renderer Backend
3  *
4  * Copyright (c) 2012 David Herrmann <dh.herrmann@googlemail.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files
8  * (the "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25
26 /**
27  * SECTION:text_bbulk.c
28  * @short_description: Bit-Blitting Bulk Text Renderer Backend
29  * @include: text.h
30  *
31  * Similar to the bblit renderer but assembles an array of blit-requests and
32  * pushes all of them at once to the video device.
33  */
34
35 #include <errno.h>
36 #include <stdbool.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include "log.h"
40 #include "text.h"
41 #include "tsm_unicode.h"
42 #include "uterm.h"
43
44 #define LOG_SUBSYSTEM "text_bbulk"
45
46 struct bbulk {
47         struct uterm_video_blend_req *reqs;
48 };
49
50 #define FONT_WIDTH(txt) ((txt)->font->attr.width)
51 #define FONT_HEIGHT(txt) ((txt)->font->attr.height)
52
53 #define SCREEN_WIDTH(txt) uterm_screen_width((txt)->screen)
54 #define SCREEN_HEIGHT(txt) uterm_screen_height((txt)->screen)
55
56 static int bbulk_init(struct kmscon_text *txt)
57 {
58         struct bbulk *bb;
59
60         bb = malloc(sizeof(*bb));
61         if (!bb)
62                 return -ENOMEM;
63
64         txt->data = bb;
65         return 0;
66 }
67
68 static void bbulk_destroy(struct kmscon_text *txt)
69 {
70         struct bbulk *bb = txt->data;
71
72         free(bb);
73 }
74
75 static int bbulk_set(struct kmscon_text *txt)
76 {
77         struct bbulk *bb = txt->data;
78         unsigned int sw, sh, i, j;
79         struct uterm_video_blend_req *req;
80
81         memset(bb, 0, sizeof(*bb));
82
83         sw = SCREEN_WIDTH(txt);
84         sh = SCREEN_HEIGHT(txt);
85
86         txt->cols = sw / FONT_WIDTH(txt);
87         txt->rows = sh / FONT_HEIGHT(txt);
88
89         bb->reqs = malloc(sizeof(*bb->reqs) * txt->cols * txt->rows);
90         if (!bb->reqs)
91                 return -ENOMEM;
92         memset(bb->reqs, 0, sizeof(*bb->reqs) * txt->cols * txt->rows);
93
94         for (i = 0; i < txt->rows; ++i) {
95                 for (j = 0; j < txt->cols; ++j) {
96                         req = &bb->reqs[i * txt->cols + j];
97                         req->x = j * FONT_WIDTH(txt);
98                         req->y = i * FONT_HEIGHT(txt);
99                 }
100         }
101
102         return 0;
103 }
104
105 static void bbulk_unset(struct kmscon_text *txt)
106 {
107         struct bbulk *bb = txt->data;
108
109         free(bb->reqs);
110         bb->reqs = NULL;
111 }
112
113 static int bbulk_draw(struct kmscon_text *txt, tsm_symbol_t ch,
114                       unsigned int posx, unsigned int posy,
115                       const struct kmscon_console_attr *attr)
116 {
117         struct bbulk *bb = txt->data;
118         const struct kmscon_glyph *glyph;
119         int ret;
120         struct uterm_video_blend_req *req;
121
122         if (ch == 0 || ch == ' ') {
123                 ret = kmscon_font_render_empty(txt->font, &glyph);
124         } else {
125                 ret = kmscon_font_render(txt->font, ch, &glyph);
126         }
127
128         if (ret) {
129                 ret = kmscon_font_render_inval(txt->font, &glyph);
130                 if (ret)
131                         return ret;
132         }
133
134         req = &bb->reqs[posy * txt->cols + posx];
135         req->buf = &glyph->buf;
136         if (attr->inverse) {
137                 req->fr = attr->br;
138                 req->fg = attr->bg;
139                 req->fb = attr->bb;
140                 req->br = attr->fr;
141                 req->bg = attr->fg;
142                 req->bb = attr->fb;
143         } else {
144                 req->fr = attr->fr;
145                 req->fg = attr->fg;
146                 req->fb = attr->fb;
147                 req->br = attr->br;
148                 req->bg = attr->bg;
149                 req->bb = attr->bb;
150         }
151
152         return 0;
153 }
154
155 static int bbulk_render(struct kmscon_text *txt)
156 {
157         struct bbulk *bb = txt->data;
158
159         return uterm_screen_blendv(txt->screen, bb->reqs,
160                                    txt->cols * txt->rows);
161 }
162
163 static const struct kmscon_text_ops kmscon_text_bbulk_ops = {
164         .name = "bbulk",
165         .init = bbulk_init,
166         .destroy = bbulk_destroy,
167         .set = bbulk_set,
168         .unset = bbulk_unset,
169         .prepare = NULL,
170         .draw = bbulk_draw,
171         .render = bbulk_render,
172         .abort = NULL,
173 };
174
175 int kmscon_text_bbulk_load(void)
176 {
177         int ret;
178
179         ret = kmscon_text_register(&kmscon_text_bbulk_ops);
180         if (ret) {
181                 log_error("cannot register bbulk renderer");
182                 return ret;
183         }
184
185         return 0;
186 }
187
188 void kmscon_text_bbulk_unload(void)
189 {
190         kmscon_text_unregister(kmscon_text_bbulk_ops.name);
191 }