Evince
Evince is a document viewer capable of displaying multiple and single page document formats like PDF and Postscript.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
conv.c
Go to the documentation of this file.
1 /* Copyright 2015 the unarr project authors (see AUTHORS file).
2  License: LGPLv3 */
3 
4 #include "unarr-imp.h"
5 
6 #include <time.h>
7 
8 /* data from http://en.wikipedia.org/wiki/Cp437 */
9 static const wchar_t gCp437[256] = {
10  0, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266C, 0x263C,
11  0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC,
12  ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
13  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
14  '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
15  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
16  '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
17  'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 0x2302,
18  0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
19  0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
20  0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
21  0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
22  0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
23  0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
24  0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
25  0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0,
26 };
27 
28 size_t ar_conv_rune_to_utf8(wchar_t rune, char *out, size_t size)
29 {
30  if (size < 1)
31  return 0;
32  if (rune < 0x0080) {
33  *out++ = rune & 0x7F;
34  return 1;
35  }
36  if (rune < 0x0800 && size >= 2) {
37  *out++ = 0xC0 | ((rune >> 6) & 0x1F);
38  *out++ = 0x80 | (rune & 0x3F);
39  return 2;
40  }
41  if (size >= 3) {
42  if ((0xD800 <= rune && rune <= 0xDFFF) || rune >= 0x10000)
43  rune = 0xFFFD;
44  *out++ = 0xE0 | ((rune >> 12) & 0x0F);
45  *out++ = 0x80 | ((rune >> 6) & 0x3F);
46  *out++ = 0x80 | (rune & 0x3F);
47  return 3;
48  }
49  *out++ = '?';
50  return 1;
51 }
52 
53 char *ar_conv_dos_to_utf8(const char *astr)
54 {
55  char *str, *out;
56  const char *in;
57  size_t size;
58 
59  size = 0;
60  for (in = astr; *in; in++) {
61  char buf[4];
62  size += ar_conv_rune_to_utf8(gCp437[(uint8_t)*in], buf, sizeof(buf));
63  }
64 
65  if (size == (size_t)-1)
66  return NULL;
67  str = malloc(size + 1);
68  if (!str)
69  return NULL;
70 
71  for (in = astr, out = str; *in; in++) {
72  out += ar_conv_rune_to_utf8(gCp437[(uint8_t)*in], out, str + size - out);
73  }
74  *out = '\0';
75 
76  return str;
77 }
78 
80 {
81  struct tm tm;
82  time_t t1, t2;
83 
84  tm.tm_sec = (dosdate & 0x1F) * 2;
85  tm.tm_min = (dosdate >> 5) & 0x3F;
86  tm.tm_hour = (dosdate >> 11) & 0x1F;
87  tm.tm_mday = (dosdate >> 16) & 0x1F;
88  tm.tm_mon = ((dosdate >> 21) & 0x0F) - 1;
89  tm.tm_year = ((dosdate >> 25) & 0x7F) + 80;
90  tm.tm_isdst = -1;
91 
92  t1 = mktime(&tm);
93  t2 = mktime(gmtime(&t1));
94 
95  return (time64_t)(2 * t1 - t2 + 11644473600) * 10000000;
96 }