summaryrefslogtreecommitdiff
path: root/fonts.c
blob: c13e1fe6a505665bd0fa6209fa83a933c2c07a59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <string.h>
#include <uchar.h>

#include "fonts.h"

void init_symbols_boundaries()
{
  // space needs special treatment
  symbols_boundaries[0][0] = 0;
  symbols_boundaries[0][1] = MAX_SYMBOL_WIDTH - 1;
  for (int i = 1; i < SYMBOL_COUNT; i++) {
    symbols_boundaries[i][0] = -1;
    symbols_boundaries[i][1] = -1;
    for (int j = 0; j < MAX_SYMBOL_WIDTH; j++) {
      if ((symbols_boundaries[i][0] == -1) && (symbols[i * MAX_SYMBOL_WIDTH + j] != 0x00))
        symbols_boundaries[i][0] = j;
      if ((symbols_boundaries[i][1] == -1) && (symbols[i * MAX_SYMBOL_WIDTH + MAX_SYMBOL_WIDTH - 1 - j] != 0x00))
        symbols_boundaries[i][1] = MAX_SYMBOL_WIDTH - 1 - j;
    }
  }
}

int skip_gaps(char16_t *operand)
{
  for (int i=sizeof(skip_ranges)/sizeof(skip_ranges[0])-1; i>=0; i--) {
    if (*operand < skip_ranges[i][0])
      continue;
    if (*operand <= skip_ranges[i][1])
      return 1;
    *operand -= skip_ranges[i][1] - skip_ranges[i][0] + 1;
  }
  if ((*operand < 0) || (*operand >= SYMBOL_COUNT))
    return 1;
  return 0;
}

int render(char *input, int input_len, char *output, int max_output_len, int skip_unprintables)
{
  memset(output, 0, max_output_len);
  int output_i = 0;
  for (int input_i=0; (input_i < input_len) && (output_i < max_output_len) && input[input_i]; input_i++) {
    char16_t c = (unsigned char)input[input_i];
    if ((c == 0xc2) || (c == 0xc3)) {
      input_i++;
      if ((input_i >= input_len) || (! input[input_i]))
        continue;
      c = (c << 8) | (unsigned char)input[input_i];
    }
    if (skip_gaps(&c)) {
      if (skip_unprintables)
        continue;
      c = 0x00; // space
    }
    for (int i = symbols_boundaries[c][0]; i <= symbols_boundaries[c][1]; i++) {
      if (output_i >= max_output_len)
        break;
      output[output_i] = symbols[c * MAX_SYMBOL_WIDTH + i];
      output_i++;
    }
    output_i++;
  }
  if (output_i >= max_output_len)
    return max_output_len;
  else
    return output_i;
}