13 #include <pango/pango.h>
14 #include <pango/pangoft2.h>
20 #define MAXTEXT (1 << 20)
23 #define CTRLKEY(x) ((x) - 96)
33 {"default", "<span size=\"xx-small\">"}
37 static char name
[128];
38 static PangoContext
*context
;
40 static int height
= 1;
42 static PangoFontMap
*fontmap
;
43 static FT_Bitmap
*bitmap
;
44 static char text
[MAXTEXT
];
45 static char *pos
= text
;
48 static FT_Bitmap
*create_bitmap(int width
, int height
)
50 FT_Bitmap
*bitmap
= g_slice_new(FT_Bitmap
);
51 bitmap
->width
= width
;
52 bitmap
->pitch
= (bitmap
->width
+ 3) & ~3;
53 bitmap
->rows
= height
;
54 bitmap
->buffer
= g_malloc(bitmap
->pitch
* bitmap
->rows
);
55 bitmap
->num_grays
= 256;
56 bitmap
->pixel_mode
= ft_pixel_mode_grays
;
57 memset(bitmap
->buffer
, 0, bitmap
->pitch
* bitmap
->rows
);
61 static void destroy_bitmap(FT_Bitmap
*bitmap
)
63 g_free(bitmap
->buffer
);
64 g_slice_free(FT_Bitmap
, bitmap
);
67 #define COLORMERGE(f, b, c) ((b) + (((f) - (b)) * (c) >> 8u))
69 static void view_write(int sr
)
73 int nr
= MIN(height
- sr
, fb_rows());
74 int nc
= MIN(width
, fb_cols());
75 for (r
= 0; r
< nr
; r
++) {
76 for (c
= 0; c
< nc
; c
++) {
77 int v
= bitmap
->buffer
[(sr
+ r
) * bitmap
->pitch
+ c
];
78 int r
= COLORMERGE(0xd5, 0x00, 255 - v
);
79 int g
= COLORMERGE(0xdd, 0x00, 255 - v
);
80 int b
= COLORMERGE(0xff, 0x00, 255 - v
);
81 buf
[c
] = fb_val(r
, g
, b
);
83 fb_set(r
, 0, buf
, width
);
87 static PangoLayout
*make_layout(PangoContext
*context
, char *text
, double size
)
89 static PangoFontDescription
*font_description
;
90 PangoLayout
*layout
= pango_layout_new(context
);
91 pango_layout_set_markup(layout
, text
, -1);
92 pango_layout_set_wrap(layout
, PANGO_WRAP_WORD_CHAR
);
93 pango_layout_set_width(layout
, fb_cols() << 10);
94 pango_layout_set_height(layout
, -1);
95 pango_layout_set_alignment(layout
, PANGO_ALIGN_RIGHT
);
96 pango_layout_set_font_description(layout
, font_description
);
97 pango_font_description_free(font_description
);
101 static void do_output(PangoContext
*context
, char *text
)
104 PangoRectangle logical_rect
;
105 pango_context_set_language(context
, pango_language_get_default());
106 pango_context_set_base_dir(context
, PANGO_DIRECTION_RTL
);
107 layout
= make_layout(context
, text
, -1);
108 pango_layout_get_pixel_extents(layout
, NULL
, &logical_rect
);
109 pango_ft2_render_layout(bitmap
, layout
, 0, 0);
110 width
= MAX(width
, MAX(logical_rect
.x
+ logical_rect
.width
,
111 PANGO_PIXELS(pango_layout_get_width(layout
))));
112 height
= MAX(logical_rect
.y
+ logical_rect
.height
,
113 PANGO_PIXELS(pango_layout_get_height(layout
)));
114 g_object_unref(layout
);
117 static int readkey(void)
120 if (read(STDIN_FILENO
, &b
, 1) <= 0)
125 void txtwin_append(char *s
, char *tag
)
129 for (i
= 0; i
< ntags
; i
++)
130 if (tag
&& !strcmp(tag
, tags
[i
].name
))
132 snprintf(pos
, MAXTEXT
- (pos
- text
),
133 "%s%s</span>", tags
[t
].desc
, s
);
134 pos
= strchr(pos
, '\0');
137 void txtwin_tag(char *name
, char *fg
, char *bg
, char *font
)
139 strcpy(tags
[ntags
].name
, name
);
140 snprintf(tags
[ntags
].desc
, sizeof(tags
[ntags
].desc
),
141 "<span font=\"%s\">", font
);
145 static int getcount(int def
)
147 int result
= count
? count
: def
;
152 static void printinfo(void)
155 printf("CNOOR \t\t\t %d%% \t\t\t %s \x1b[K",
156 head
* 100 / height
, name
);
160 void txtwin_loop(void)
162 int step
= fb_rows() / PAGESTEPS
;
164 struct termios oldtermios
, termios
;
165 tcgetattr(STDIN_FILENO
, &termios
);
166 oldtermios
= termios
;
168 tcsetattr(STDIN_FILENO
, TCSAFLUSH
, &termios
);
169 bitmap
= create_bitmap(width
, height
);
170 do_output(context
, text
);
171 destroy_bitmap(bitmap
);
172 bitmap
= create_bitmap(width
, height
);
173 do_output(context
, text
);
175 while ((c
= readkey()) != -1) {
181 tcsetattr(STDIN_FILENO
, 0, &oldtermios
);
185 count
= count
* 10 + c
- '0';
189 head
+= step
* getcount(1);
192 head
-= step
* getcount(1);
196 head
+= fb_rows() * getcount(1) - step
;
200 head
-= fb_rows() * getcount(1) - step
;
208 head
= height
- fb_rows();
212 head
= height
* getcount(0) / 100;
218 /* no need to redraw */
221 head
= MAX(0, MIN(head
, height
- fb_rows()));
226 void txtwin_gtk_init(int argc
, char **argv
)
229 g_set_prgname("cpan");
230 setlocale(LC_ALL
, "");
233 void txtwin_init(char *sura
)
235 char *clear
= "\x1b[2J\x1b[H";
236 char *hide
= "\x1b[?25l";
237 fontmap
= pango_ft2_font_map_new();
238 pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP(fontmap
), DPI
, DPI
);
239 context
= pango_font_map_create_context(PANGO_FONT_MAP(fontmap
));
243 if (FBM_BPP(fb_mode()) != sizeof(fbval_t
)) {
244 fprintf(stderr
, "cnoor: fbval_t doesn't match fb depth\n");
247 write(STDIN_FILENO
, clear
, strlen(clear
));
248 write(STDIN_FILENO
, hide
, strlen(hide
));
252 void txtwin_free(void)
254 char *show
= "\x1b[?25h\n";
256 destroy_bitmap(bitmap
);
257 g_object_unref(context
);
258 g_object_unref(fontmap
);
259 write(STDIN_FILENO
, show
, strlen(show
));