all repos — acme @ 65086bf370181c8e36a64d572dc51d290e4488a2

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

libframe/frutil.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
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <mouse.h>
#include <frame.h>

int _frcanfit(Frame* f, Point pt, Frbox* b) {
  int left, w, nr;
  uchar* p;
  Rune r;

  left = f->r.max.x - pt.x;
  if (b->nrune < 0)
    return b->minwid <= left;
  if (left >= b->wid)
    return b->nrune;
  for (nr = 0, p = b->ptr; *p; p += w, nr++) {
    r = *p;
    if (r < Runeself)
      w = 1;
    else
      w = chartorune(&r, (char*)p);
    left -= stringnwidth(f->font, (char*)p, 1);
    if (left < 0)
      return nr;
  }
  drawerror(f->display, "_frcanfit can't");
  return 0;
}

void _frcklinewrap(Frame* f, Point* p, Frbox* b) {
  if ((b->nrune < 0 ? b->minwid : b->wid) > f->r.max.x - p->x) {
    p->x = f->r.min.x;
    p->y += f->font->height;
  }
}

void _frcklinewrap0(Frame* f, Point* p, Frbox* b) {
  if (_frcanfit(f, *p, b) == 0) {
    p->x = f->r.min.x;
    p->y += f->font->height;
  }
}

void _fradvance(Frame* f, Point* p, Frbox* b) {
  if (b->nrune < 0 && b->bc == '\n') {
    p->x = f->r.min.x;
    p->y += f->font->height;
  } else
    p->x += b->wid;
}

int _frnewwid(Frame* f, Point pt, Frbox* b) {
  b->wid = _frnewwid0(f, pt, b);
  return b->wid;
}

int _frnewwid0(Frame* f, Point pt, Frbox* b) {
  int c, x;

  c = f->r.max.x;
  x = pt.x;
  if (b->nrune >= 0 || b->bc != '\t')
    return b->wid;
  if (x + b->minwid > c)
    x = pt.x = f->r.min.x;
  x += f->maxtab;
  x -= (x - f->r.min.x) % f->maxtab;
  if (x - pt.x < b->minwid || x > c)
    x = pt.x + b->minwid;
  return x - pt.x;
}

void _frclean(Frame* f, Point pt, int n0, int n1) /* look for mergeable boxes */
{
  Frbox* b;
  int nb, c;

  c = f->r.max.x;
  for (nb = n0; nb < n1 - 1; nb++) {
    b = &f->box[nb];
    _frcklinewrap(f, &pt, b);
    while (b[0].nrune >= 0 && nb < n1 - 1 && b[1].nrune >= 0 &&
           pt.x + b[0].wid + b[1].wid < c) {
      _frmergebox(f, nb);
      n1--;
      b = &f->box[nb];
    }
    _fradvance(f, &pt, &f->box[nb]);
  }
  for (; nb < f->nbox; nb++) {
    b = &f->box[nb];
    _frcklinewrap(f, &pt, b);
    _fradvance(f, &pt, &f->box[nb]);
  }
  f->lastlinefull = 0;
  if (pt.y >= f->r.max.y)
    f->lastlinefull = 1;
}