1 /*
2 * Copyright (C) 2014 haru <uobikiemukot at gmail dot com>
3 * Copyright (C) 2014 Hayaki Saito <user@zuse.jp>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "config.h"
20 #include "yaft.h"
21 #include "util.h"
22 #include "pseudo.h"
23
24 #if HAVE_STRING_H
25 # include <string.h>
26 #endif
27
28 #if !defined(HAVE_MEMCPY)
29 # define memcpy(d, s, n) (bcopy ((s), (d), (n)))
30 #endif
31
draw_sixel(struct pseudobuffer * pb,int line,int col,uint8_t * bitmap)32 static void draw_sixel(struct pseudobuffer *pb, int line, int col, uint8_t *bitmap)
33 {
34 int h, w, src_offset, dst_offset;
35 uint32_t pixel, color = 0;
36
37 for (h = 0; h < CELL_HEIGHT; h++) {
38 for (w = 0; w < CELL_WIDTH; w++) {
39 src_offset = BYTES_PER_PIXEL * (h * CELL_WIDTH + w);
40 memcpy(&color, bitmap + src_offset, BYTES_PER_PIXEL);
41
42 dst_offset = (line * CELL_HEIGHT + h) * pb->line_length + (col * CELL_WIDTH + w) * pb->bytes_per_pixel;
43 //pixel = color2pixel(&pb->vinfo, color);
44 pixel = color;
45 memcpy(pb->buf + dst_offset, &pixel, pb->bytes_per_pixel);
46 }
47 }
48 }
49
draw_line(struct pseudobuffer * pb,struct terminal * term,int line)50 static void draw_line(struct pseudobuffer *pb, struct terminal *term, int line)
51 {
52 int pos, bdf_padding, glyph_width, margin_right;
53 int col, w, h;
54 uint32_t pixel;
55 struct color_pair_t color_pair;
56 struct cell_t *cellp;
57
58 for (col = term->cols - 1; col >= 0; col--) {
59 margin_right = (term->cols - 1 - col) * CELL_WIDTH;
60
61 /* target cell */
62 cellp = &term->cells[col + line * term->cols];
63
64 /* draw sixel bitmap */
65 if (cellp->has_bitmap) {
66 draw_sixel(pb, line, col, cellp->bitmap);
67 continue;
68 }
69
70 /* copy current color_pair (maybe changed) */
71 color_pair = cellp->color_pair;
72
73 /* check wide character or not */
74 glyph_width = (cellp->width == HALF) ? CELL_WIDTH: CELL_WIDTH * 2;
75 bdf_padding = my_ceil(glyph_width, BITS_PER_BYTE) * BITS_PER_BYTE - glyph_width;
76 if (cellp->width == WIDE)
77 bdf_padding += CELL_WIDTH;
78
79 /* check cursor positon */
80 if ((term->mode & MODE_CURSOR && line == term->cursor.y)
81 && (col == term->cursor.x
82 || (cellp->width == WIDE && (col + 1) == term->cursor.x)
83 || (cellp->width == NEXT_TO_WIDE && (col - 1) == term->cursor.x))) {
84 color_pair.fg = term->default_bg;
85 color_pair.bg = term->cursor_color;
86 }
87
88 for (h = 0; h < CELL_HEIGHT; h++) {
89 /* if UNDERLINE attribute on, swap bg/fg */
90 if ((h == (CELL_HEIGHT - 1)) && (cellp->attribute & attr_mask[ATTR_UNDERLINE]))
91 color_pair.bg = color_pair.fg;
92
93 for (w = 0; w < CELL_WIDTH; w++) {
94 pos = (term->width - 1 - margin_right - w) * pb->bytes_per_pixel
95 + (line * CELL_HEIGHT + h) * pb->line_length;
96
97 /* set color palette */
98 if (cellp->glyphp->bitmap[h] & (0x01 << (bdf_padding + w)))
99 pixel = color_list[color_pair.fg];
100 else
101 pixel = color_list[color_pair.bg];
102
103 /* update copy buffer only */
104 memcpy(pb->buf + pos, &pixel, pb->bytes_per_pixel);
105 }
106 }
107 }
108 term->line_dirty[line] = ((term->mode & MODE_CURSOR) && term->cursor.y == line) ? true: false;
109 }
110
refresh(struct pseudobuffer * pb,struct terminal * term)111 void refresh(struct pseudobuffer *pb, struct terminal *term)
112 {
113 int line;
114
115 if (term->mode & MODE_CURSOR)
116 term->line_dirty[term->cursor.y] = true;
117
118 for (line = 0; line < term->lines; line++) {
119 if (term->line_dirty[line])
120 draw_line(pb, term, line);
121 }
122 }
123
124 /* emacs, -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
125 /* vim: set expandtab ts=4 : */
126 /* EOF */
127