1 /*
2  * TilEm II
3  *
4  * Copyright (c) 2011 Benjamin Moody
5  *
6  * This program is free software: you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation, either version 3 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <glib.h>
27 #include <ticonv.h>
28 #include <tilem.h>
29 
30 #include "charmap.h"
31 
32 #define UNDEF 0xfffd
33 
34 static const unsigned long ti81chars[256] = {
35 	0,      ' ',    0x2192, 0x2191, 0x2193, 0x25B6, '<',    0x2264,
36 	'=',    0x2260, '>',    0x2265, 0x3D20DE, 0x207C, '+',  '-',
37 	'*',    '/',    '^',    0x221A, '(',    ')',    '[',    ']',
38 	'{',    '}',    '?',    '!',    ':',    ',',    0x2026, 0x207B00B9,
39 	0x207B, 0xB7,   0x2070, 0xB9,   0xB2,   0xB3,   0x2074, 0x2075,
40 	0x2076, 0x2077, 0x2078, 0x2079, 'E',    0x2081, 0x2082, 0x2083,
41 	0x2084, 0x23E8, 0x209C, '"',    0x207B, '.',    '0',    '1',
42 	'2',    '3',    '4',    '5',    '6',    '7',    '8',    '9',
43 	'E',    0x2B3,  0xB0,   0x3B8,  'R',    'T',    0x2E3,  0x2B8,
44 	0x780305, 0x790305, 0x3A3, 0x3C3, 0x3C0, 'A',   'B',    'C',
45 	'D',    'E',    'F',    'G',    'H',    'I',    'J',    'K',
46 	'L',    'M',    'N',    'O',    'P',    'Q',    'R',    'S',
47 	'T',    'U',    'V',    'W',    'X',    'Y',    'Z',    0x3B8,
48 	'a',    'b',    'c',    'd',    'e',    'f',    'g',    'h',
49 	'i',    'l',    'm',    'n',    'o',    'p',    'q',    'r',
50 	's',    't',    'u',    'v',    'w',    'x',    'y',    0xD7,
51 	0x2588, 0x219120DE, 0x4120DE, '_', 0x21910332, 0x410332, UNDEF, UNDEF,
52 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
53 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
54 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
55 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
56 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
57 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
58 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
59 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
60 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
61 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
62 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
63 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
64 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
65 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
66 	UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF };
67 
getmap(int model)68 static const unsigned long * getmap(int model)
69 {
70 	switch (model) {
71 	case TILEM_CALC_TI73:
72 		return ti73_charset;
73 	case TILEM_CALC_TI81:
74 		return ti81chars;
75 	case TILEM_CALC_TI82:
76 		return ti82_charset;
77 	case TILEM_CALC_TI76:
78 	case TILEM_CALC_TI83:
79 		return ti83_charset;
80 	case TILEM_CALC_TI83P:
81 	case TILEM_CALC_TI83P_SE:
82 	case TILEM_CALC_TI84P:
83 	case TILEM_CALC_TI84P_SE:
84 	case TILEM_CALC_TI84P_NSPIRE:
85 		return ti83p_charset;
86 	case TILEM_CALC_TI85:
87 		return ti85_charset;
88 	case TILEM_CALC_TI86:
89 		return ti86_charset;
90 	default:
91 		return ti83p_charset;
92 	}
93 }
94 
95 /* Convert a byte value from the calculator large-font character set
96    into a printable UTF-8 string. */
ti_to_unicode(int model,unsigned int value)97 char *ti_to_unicode(int model, unsigned int value)
98 {
99 	const unsigned long *map = getmap(model);
100 	unsigned long v;
101 	char buf[12];
102 	int n;
103 
104 	v = map[value];
105 	if (v == 0)
106 		v = 0x2400;	/* SYMBOL FOR NULL */
107 	else if (v == '\n')
108 		v = 0x240A;	/* SYMBOL FOR LINE FEED */
109 	else if (v == ' ')
110 		v = 0x2423;	/* OPEN BOX */
111 
112 	/* in the ticonv character tables, non-BMP characters are
113 	   represented by a surrogate pair */
114 	if ((v & 0xfc00fc00) == 0xd800dc00) {
115 		v = (((v & 0x3ff0000) >> 6) | (v & 0x3ff)) + 0x10000;
116 		n = g_unichar_to_utf8(v, buf);
117 	}
118 	else if (v & 0xffff0000) {
119 		n = g_unichar_to_utf8(v >> 16, buf);
120 		n += g_unichar_to_utf8(v & 0xffff, buf + n);
121 	}
122 	else {
123 		n = g_unichar_to_utf8(v, buf);
124 	}
125 
126 	return g_strndup(buf, n);
127 }
128