mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
ascii replacements for linux virtual terminals
Patch by sgerwk, slightly modified. Taken from Debian.
This commit is contained in:
parent
f2cca12915
commit
faff6b9b63
@ -534,8 +534,10 @@ set_hline(struct html_context *html_context, const char *chars, int charslen,
|
||||
* incomplete character in document->buf, then
|
||||
* the first byte of input can result in a double-cell
|
||||
* character, so we must reserve one extra element. */
|
||||
/* But, ascii replacements complicates this because a single
|
||||
codepoint may be rendered to as much as 20 chars */
|
||||
orig_length = realloc_line(html_context, document,
|
||||
Y(y), X(x) + charslen);
|
||||
Y(y), X(x) + charslen * 20);
|
||||
if (orig_length < 0) /* error */
|
||||
return 0;
|
||||
|
||||
@ -655,7 +657,16 @@ good_char:
|
||||
#endif /* CONFIG_COMBINE */
|
||||
part->spaces[x] = (data == UCS_SPACE);
|
||||
|
||||
if (unicode_to_cell(data) == 0)
|
||||
if (codepoint_replacement(data) != -1) {
|
||||
int i;
|
||||
|
||||
for(i = 0; i < unicode_to_cell(data); i++) {
|
||||
schar->data = encode_utf8(data)[i];
|
||||
part->char_width[x] = 1;
|
||||
copy_screen_chars(&POS(x++, y), schar, 1);
|
||||
}
|
||||
continue;
|
||||
} else if (unicode_to_cell(data) == 0)
|
||||
continue;
|
||||
else if (unicode_to_cell(data) == 2) {
|
||||
schar->data = (unicode_val_T)data;
|
||||
|
@ -14,6 +14,11 @@
|
||||
#include "document/html/parse-meta-refresh.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
/* fake tty get function, needed for charsets.c */
|
||||
int get_ctl_handle() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct meta_refresh_test_case
|
||||
{
|
||||
const char *content;
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
@ -27,6 +29,9 @@
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/kd.h>
|
||||
|
||||
#include "elinks.h"
|
||||
|
||||
#include "document/options.h"
|
||||
@ -40,6 +45,7 @@
|
||||
#include "util/hash.h"
|
||||
#include "util/memory.h"
|
||||
#include "util/string.h"
|
||||
#include "osdep/osdep.h"
|
||||
|
||||
|
||||
/* Fix namespace clash on MacOS. */
|
||||
@ -191,6 +197,46 @@ new_translation_table(struct conv_table *p)
|
||||
} \
|
||||
} \
|
||||
|
||||
/* list of unicode codepoints supported by the current terminal, if this
|
||||
* information is available, otherwise size = -1 */
|
||||
|
||||
struct {
|
||||
int size;
|
||||
unicode_val_T *list;
|
||||
} codepoints;
|
||||
|
||||
int is_codepoint_supported(unicode_val_T u) {
|
||||
int first, last, middle;
|
||||
|
||||
if (codepoints.size == -1)
|
||||
return 1;
|
||||
|
||||
first = 0;
|
||||
last = codepoints.size - 1;
|
||||
|
||||
while (first <= last) {
|
||||
middle = (last + first) / 2;
|
||||
if (codepoints.list[middle] == u)
|
||||
return u;
|
||||
else if (codepoints.list[middle] > u)
|
||||
last = middle - 1;
|
||||
else
|
||||
first = middle + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int codepoint_replacement(unicode_val_T u) {
|
||||
int s;
|
||||
|
||||
if (is_codepoint_supported(u))
|
||||
return -1;
|
||||
|
||||
BIN_SEARCH(unicode_7b, x, N_UNICODE_7B, u, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
static const unicode_val_T strange_chars[32] = {
|
||||
0x20ac, 0x0000, 0x002a, 0x0000, 0x201e, 0x2026, 0x2020, 0x2021,
|
||||
0x005e, 0x2030, 0x0160, 0x003c, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
@ -246,8 +292,15 @@ static char utf_buffer[7];
|
||||
NONSTATIC_INLINE char *
|
||||
encode_utf8(unicode_val_T u)
|
||||
{
|
||||
int s;
|
||||
|
||||
memset(utf_buffer, 0, 7);
|
||||
|
||||
if (!is_codepoint_supported(u)) {
|
||||
BIN_SEARCH(unicode_7b, x, N_UNICODE_7B, u, s);
|
||||
if (s != -1) return unicode_7b[s].s;
|
||||
}
|
||||
|
||||
if (u < 0x80)
|
||||
utf_buffer[0] = u;
|
||||
else if (u < 0x800)
|
||||
@ -619,6 +672,13 @@ invalid_arg:
|
||||
NONSTATIC_INLINE int
|
||||
unicode_to_cell(unicode_val_T c)
|
||||
{
|
||||
int s;
|
||||
|
||||
if (!is_codepoint_supported(c)) {
|
||||
BIN_SEARCH(unicode_7b, x, N_UNICODE_7B, c, s);
|
||||
if (s != -1) return strlen(unicode_7b[s].s);
|
||||
}
|
||||
|
||||
if (c == 0x200e || c == 0x200f)
|
||||
return 0;
|
||||
if (c >= 0x1100
|
||||
@ -872,9 +932,6 @@ add_utf8(struct conv_table *ct, unicode_val_T u, const char *str)
|
||||
else {
|
||||
struct conv_table *nct;
|
||||
|
||||
assertm(ct[*p].u.str == no_str, "bad utf encoding #1");
|
||||
if_assert_failed return;
|
||||
|
||||
nct = (struct conv_table *)mem_calloc(256, sizeof(*nct));
|
||||
if (!nct) return;
|
||||
new_translation_table(nct);
|
||||
@ -885,9 +942,6 @@ add_utf8(struct conv_table *ct, unicode_val_T u, const char *str)
|
||||
p++;
|
||||
}
|
||||
|
||||
assertm(!ct[*p].t, "bad utf encoding #2");
|
||||
if_assert_failed return;
|
||||
|
||||
if (ct[*p].u.str == no_str)
|
||||
ct[*p].u.str = str;
|
||||
}
|
||||
@ -1626,9 +1680,72 @@ get_cp_index(const char *name)
|
||||
|
||||
#endif /* USE_FASTFIND */
|
||||
|
||||
/* create the list of codepoints supported by the terminal */
|
||||
|
||||
#ifdef GIO_UNIMAP
|
||||
int cmpint(const void *a, const void *b) {
|
||||
if (* (int *) a < * (int *) b)
|
||||
return -1;
|
||||
else if (* (int *) a == * (int *) b)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
void make_codepoints() {
|
||||
int tty;
|
||||
struct unimapdesc table;
|
||||
int res;
|
||||
int i;
|
||||
|
||||
tty = get_ctl_handle();
|
||||
if (tty == -1) {
|
||||
codepoints.size = -1;
|
||||
return ;
|
||||
}
|
||||
|
||||
table.entry_ct = 0;
|
||||
table.entries = NULL;
|
||||
res = ioctl(tty, GIO_UNIMAP, &table);
|
||||
if (res && errno != ENOMEM) {
|
||||
#ifdef CONFIG_DEBUG
|
||||
perror("GIO_UNIMAP");
|
||||
#endif
|
||||
codepoints.size = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
table.entries = malloc(table.entry_ct * sizeof(struct unipair));
|
||||
res = ioctl(tty, GIO_UNIMAP, &table);
|
||||
if (res) {
|
||||
#ifdef CONFIG_DEBUG
|
||||
perror("GIO_UNIMAP");
|
||||
#endif
|
||||
close(tty);
|
||||
codepoints.size = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
codepoints.size = table.entry_ct;
|
||||
codepoints.list = malloc(table.entry_ct * sizeof(unicode_val_T));
|
||||
for (i = 0; i < table.entry_ct; i++)
|
||||
codepoints.list[i] = table.entries[i].unicode;
|
||||
|
||||
qsort(codepoints.list, codepoints.size, sizeof(unicode_val_T), cmpint);
|
||||
|
||||
// for (i = 0; i < codepoints.size; i++)
|
||||
// fprintf(stderr, "U+%04X\n", codepoints.list[i]);
|
||||
}
|
||||
#else
|
||||
void make_codepoints() {
|
||||
codepoints.size = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
init_charsets_lookup(void)
|
||||
{
|
||||
make_codepoints();
|
||||
#ifdef USE_FASTFIND
|
||||
fastfind_index(&ff_charsets_index, FF_COMPRESS);
|
||||
#endif
|
||||
|
@ -160,6 +160,8 @@ char *utf8_step_forward(char *, char *,
|
||||
int, enum utf8_step, int *);
|
||||
char *utf8_step_backward(char *, char *,
|
||||
int, enum utf8_step, int *);
|
||||
int is_codepoint_supported(unicode_val_T u);
|
||||
int codepoint_replacement(unicode_val_T u);
|
||||
int unicode_to_cell(unicode_val_T);
|
||||
unicode_val_T unicode_fold_label_case(unicode_val_T);
|
||||
int strlen_utf8(char **);
|
||||
|
@ -12,6 +12,11 @@
|
||||
#include "network/ssl/match-hostname.h"
|
||||
#include "util/string.h"
|
||||
|
||||
/* fake tty get function, needed for charsets.c */
|
||||
int get_ctl_handle() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct match_hostname_pattern_test_case
|
||||
{
|
||||
const char *pattern;
|
||||
|
@ -15,6 +15,11 @@
|
||||
#include "protocol/ftp/parse.h"
|
||||
#include "util/test.h"
|
||||
|
||||
/* fake tty get function, needed for charsets.c */
|
||||
int get_ctl_handle() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
|
@ -10,6 +10,11 @@
|
||||
#include "protocol/uri.h"
|
||||
#include "util/string.h"
|
||||
|
||||
/* fake tty get function, needed for charsets.c */
|
||||
int get_ctl_handle() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user