13 #include <pango/pango.h>
14 #include <pango/pangoft2.h>
19 #define MAXTEXT (1 << 20)
22 #define CTRLKEY(x) ((x) - 96)
24 static char name
[128];
25 static PangoContext
*context
;
27 static int height
= 1;
29 static PangoFontMap
*fontmap
;
30 static FT_Bitmap
*bitmap
;
31 static char text
[MAXTEXT
];
32 static char *pos
= text
;
36 static FT_Bitmap
*create_bitmap(int width
, int height
)
38 FT_Bitmap
*bitmap
= g_slice_new(FT_Bitmap
);
39 bitmap
->width
= width
;
40 bitmap
->pitch
= (bitmap
->width
+ 3) & ~3;
41 bitmap
->rows
= height
;
42 bitmap
->buffer
= g_malloc(bitmap
->pitch
* bitmap
->rows
);
43 bitmap
->num_grays
= 256;
44 bitmap
->pixel_mode
= ft_pixel_mode_grays
;
45 memset(bitmap
->buffer
, 0, bitmap
->pitch
* bitmap
->rows
);
49 static void destroy_bitmap(FT_Bitmap
*bitmap
)
51 g_free(bitmap
->buffer
);
52 g_slice_free(FT_Bitmap
, bitmap
);
55 #define CR(a) (((a) >> 16) & 0x0000ff)
56 #define CG(a) (((a) >> 8) & 0x0000ff)
57 #define CB(a) ((a) & 0x0000ff)
58 #define COLORMERGE(f, b, c) ((b) + (((f) - (b)) * (c) >> 8u))
60 static void view_write(int sr
)
64 int nr
= MIN(height
- sr
, fb_rows());
65 int nc
= MIN(width
, fb_cols());
66 for (r
= 0; r
< nr
; r
++) {
67 for (c
= 0; c
< nc
; c
++) {
68 int v
= bitmap
->buffer
[(sr
+ r
) * bitmap
->pitch
+ c
];
69 int r
= COLORMERGE(CR(COLOR_FG
), CR(COLOR_BG
), v
);
70 int g
= COLORMERGE(CG(COLOR_FG
), CG(COLOR_BG
), v
);
71 int b
= COLORMERGE(CB(COLOR_FG
), CB(COLOR_BG
), v
);
72 buf
[c
] = FB_VAL(r
, g
, b
);
74 fb_set(r
, 0, buf
, width
);
78 static PangoLayout
*make_layout(PangoContext
*context
, char *text
, double size
)
80 static PangoFontDescription
*font_description
;
81 PangoLayout
*layout
= pango_layout_new(context
);
82 pango_layout_set_markup(layout
, text
, -1);
83 pango_layout_set_wrap(layout
, PANGO_WRAP_WORD_CHAR
);
84 pango_layout_set_width(layout
, fb_cols() << 10);
85 pango_layout_set_height(layout
, -1);
86 pango_layout_set_alignment(layout
, PANGO_ALIGN_RIGHT
);
87 pango_layout_set_font_description(layout
, font_description
);
88 pango_font_description_free(font_description
);
92 static void do_output(PangoContext
*context
, char *text
)
95 PangoRectangle logical_rect
;
96 pango_context_set_language(context
, pango_language_get_default());
97 pango_context_set_base_dir(context
, PANGO_DIRECTION_RTL
);
98 layout
= make_layout(context
, text
, -1);
99 pango_layout_get_pixel_extents(layout
, NULL
, &logical_rect
);
100 pango_ft2_render_layout(bitmap
, layout
, 0, 0);
101 width
= MAX(width
, MAX(logical_rect
.x
+ logical_rect
.width
,
102 PANGO_PIXELS(pango_layout_get_width(layout
))));
103 height
= MAX(logical_rect
.y
+ logical_rect
.height
,
104 PANGO_PIXELS(pango_layout_get_height(layout
)));
105 g_object_unref(layout
);
108 static int readkey(void)
111 if (read(STDIN_FILENO
, &b
, 1) <= 0)
116 void txtwin_append(char *s
, char *font
)
118 snprintf(pos
, MAXTEXT
- (pos
- text
),
119 "<span font=\"%s\">%s</span>", font
, s
);
120 pos
= strchr(pos
, '\0');
123 static int getcount(int def
)
125 int result
= count
? count
: def
;
130 static void printinfo(void)
133 printf("CNOOR \t\t\t %d%% \t\t\t %s \x1b[K",
134 head
* 100 / height
, name
);
138 void txtwin_loop(void)
140 int step
= fb_rows() / PAGESTEPS
;
142 struct termios oldtermios
, termios
;
143 tcgetattr(STDIN_FILENO
, &termios
);
144 oldtermios
= termios
;
146 tcsetattr(STDIN_FILENO
, TCSAFLUSH
, &termios
);
147 bitmap
= create_bitmap(width
, height
);
148 do_output(context
, text
);
149 destroy_bitmap(bitmap
);
150 bitmap
= create_bitmap(width
, height
);
151 do_output(context
, text
);
153 while ((c
= readkey()) != -1) {
159 tcsetattr(STDIN_FILENO
, 0, &oldtermios
);
163 count
= count
* 10 + c
- '0';
167 head
+= step
* getcount(1);
170 head
-= step
* getcount(1);
174 head
+= fb_rows() * getcount(1) - step
;
178 head
-= fb_rows() * getcount(1) - step
;
186 head
= height
- fb_rows();
190 head
= height
* getcount(0) / 100;
205 /* no need to redraw */
208 head
= MAX(0, MIN(head
, height
- fb_rows()));
213 void txtwin_gtk_init(int argc
, char **argv
)
216 g_set_prgname("cpan");
217 setlocale(LC_ALL
, "");
220 void txtwin_init(char *sura
)
222 char *clear
= "\x1b[2J\x1b[H";
223 char *hide
= "\x1b[?25l";
224 fontmap
= pango_ft2_font_map_new();
225 pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP(fontmap
), DPI
, DPI
);
226 context
= pango_font_map_create_context(PANGO_FONT_MAP(fontmap
));
230 if (FBM_BPP(fb_mode()) != sizeof(fbval_t
)) {
231 fprintf(stderr
, "cnoor: fbval_t doesn't match fb depth\n");
234 write(STDIN_FILENO
, clear
, strlen(clear
));
235 write(STDIN_FILENO
, hide
, strlen(hide
));
239 void txtwin_free(void)
241 char *show
= "\x1b[?25h\n";
243 destroy_bitmap(bitmap
);
244 g_object_unref(context
);
245 g_object_unref(fontmap
);
246 write(STDIN_FILENO
, show
, strlen(show
));