all repos — acme @ 27aa20a319d9b390ae5bc6ac230d84b509866dfc

fork of the acme editor from plan9port - keybinds, tweaks, config.h, etc

libframe/frptofchar.c (raw)

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <mouse.h>
#include <frame.h>

Point _frptofcharptb(Frame* f, ulong p, Point pt, int bn) {
  uchar* s;
  Frbox* b;
  int w, l;
  Rune r;

  for (b = &f->box[bn]; bn < f->nbox; bn++, b++) {
    _frcklinewrap(f, &pt, b);
    if (p < (l = NRUNE(b))) {
      if (b->nrune > 0)
        for (s = b->ptr; p > 0; s += w, p--) {
          if ((r = *s) < Runeself)
            w = 1;
          else
            w = chartorune(&r, (char*)s);
          pt.x += stringnwidth(f->font, (char*)s, 1);
          if (r == 0 || pt.x > f->r.max.x)
            drawerror(f->display, "frptofchar");
        }
      break;
    }
    p -= l;
    _fradvance(f, &pt, b);
  }
  return pt;
}

Point frptofchar(Frame* f, ulong p) {
  return _frptofcharptb(f, p, f->r.min, 0);
}

Point _frptofcharnb(
  Frame* f, ulong p, int nb) /* doesn't do final _fradvance to next line */
{
  Point pt;
  int nbox;

  nbox = f->nbox;
  f->nbox = nb;
  pt = _frptofcharptb(f, p, f->r.min, 0);
  f->nbox = nbox;
  return pt;
}

static Point _frgrid(Frame* f, Point p) {
  p.y -= f->r.min.y;
  p.y -= p.y % f->font->height;
  p.y += f->r.min.y;
  if (p.x > f->r.max.x)
    p.x = f->r.max.x;
  return p;
}

ulong frcharofpt(Frame* f, Point pt) {
  Point qt;
  int w, bn;
  uchar* s;
  Frbox* b;
  ulong p;
  Rune r;

  pt = _frgrid(f, pt);
  qt = f->r.min;
  for (b = f->box, bn = 0, p = 0; bn < f->nbox && qt.y < pt.y; bn++, b++) {
    _frcklinewrap(f, &qt, b);
    if (qt.y >= pt.y)
      break;
    _fradvance(f, &qt, b);
    p += NRUNE(b);
  }
  for (; bn < f->nbox && qt.x <= pt.x; bn++, b++) {
    _frcklinewrap(f, &qt, b);
    if (qt.y > pt.y)
      break;
    if (qt.x + b->wid > pt.x) {
      if (b->nrune < 0)
        _fradvance(f, &qt, b);
      else {
        s = b->ptr;
        for (;;) {
          if ((r = *s) < Runeself)
            w = 1;
          else
            w = chartorune(&r, (char*)s);
          if (r == 0)
            drawerror(f->display, "end of string in frcharofpt");
          qt.x += stringnwidth(f->font, (char*)s, 1);
          s += w;
          if (qt.x > pt.x)
            break;
          p++;
        }
      }
    } else {
      p += NRUNE(b);
      _fradvance(f, &qt, b);
    }
  }
  return p;
}