aboutsummaryrefslogtreecommitdiff
path: root/src/libframe/frbox.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-09-30 17:47:43 +0000
committerrsc <devnull@localhost>2003-09-30 17:47:43 +0000
commitb822e0d8035e1c80b86d974e63bd10936a96ed2d (patch)
treee213ab32233fa820bc9ce8a043b8b44173377f4b /src/libframe/frbox.c
parentb5990708483a1fa452b3d4b6ed2bfa998deeeb39 (diff)
downloadplan9port-b822e0d8035e1c80b86d974e63bd10936a96ed2d.tar.gz
plan9port-b822e0d8035e1c80b86d974e63bd10936a96ed2d.tar.bz2
plan9port-b822e0d8035e1c80b86d974e63bd10936a96ed2d.zip
Initial revision
Diffstat (limited to 'src/libframe/frbox.c')
-rw-r--r--src/libframe/frbox.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/libframe/frbox.c b/src/libframe/frbox.c
new file mode 100644
index 00000000..d2593011
--- /dev/null
+++ b/src/libframe/frbox.c
@@ -0,0 +1,156 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <mouse.h>
+#include <frame.h>
+
+#define SLOP 25
+
+void
+_fraddbox(Frame *f, int bn, int n) /* add n boxes after bn, shift the rest up,
+ * box[bn+n]==box[bn] */
+{
+ int i;
+
+ if(bn > f->nbox)
+ drawerror(f->display, "_fraddbox");
+ if(f->nbox+n > f->nalloc)
+ _frgrowbox(f, n+SLOP);
+ for(i=f->nbox; --i>=bn; )
+ f->box[i+n] = f->box[i];
+ f->nbox+=n;
+}
+
+void
+_frclosebox(Frame *f, int n0, int n1) /* inclusive */
+{
+ int i;
+
+ if(n0>=f->nbox || n1>=f->nbox || n1<n0)
+ drawerror(f->display, "_frclosebox");
+ n1++;
+ for(i=n1; i<f->nbox; i++)
+ f->box[i-(n1-n0)] = f->box[i];
+ f->nbox -= n1-n0;
+}
+
+void
+_frdelbox(Frame *f, int n0, int n1) /* inclusive */
+{
+ if(n0>=f->nbox || n1>=f->nbox || n1<n0)
+ drawerror(f->display, "_frdelbox");
+ _frfreebox(f, n0, n1);
+ _frclosebox(f, n0, n1);
+}
+
+void
+_frfreebox(Frame *f, int n0, int n1) /* inclusive */
+{
+ int i;
+
+ if(n1<n0)
+ return;
+ if(n0>=f->nbox || n1>=f->nbox)
+ drawerror(f->display, "_frfreebox");
+ n1++;
+ for(i=n0; i<n1; i++)
+ if(f->box[i].nrune >= 0)
+ free(f->box[i].ptr);
+}
+
+void
+_frgrowbox(Frame *f, int delta)
+{
+ f->nalloc += delta;
+ f->box = realloc(f->box, f->nalloc*sizeof(Frbox));
+ if(f->box == 0)
+ drawerror(f->display, "_frgrowbox");
+}
+
+static
+void
+dupbox(Frame *f, int bn)
+{
+ uchar *p;
+
+ if(f->box[bn].nrune < 0)
+ drawerror(f->display, "dupbox");
+ _fraddbox(f, bn, 1);
+ if(f->box[bn].nrune >= 0){
+ p = _frallocstr(f, NBYTE(&f->box[bn])+1);
+ strcpy((char*)p, (char*)f->box[bn].ptr);
+ f->box[bn+1].ptr = p;
+ }
+}
+
+static
+uchar*
+runeindex(uchar *p, int n)
+{
+ int i, w;
+ Rune rune;
+
+ for(i=0; i<n; i++,p+=w)
+ if(*p < Runeself)
+ w = 1;
+ else{
+ w = chartorune(&rune, (char*)p);
+ USED(rune);
+ }
+ return p;
+}
+
+static
+void
+truncatebox(Frame *f, Frbox *b, int n) /* drop last n chars; no allocation done */
+{
+ if(b->nrune<0 || b->nrune<n)
+ drawerror(f->display, "truncatebox");
+ b->nrune -= n;
+ runeindex(b->ptr, b->nrune)[0] = 0;
+ b->wid = stringwidth(f->font, (char *)b->ptr);
+}
+
+static
+void
+chopbox(Frame *f, Frbox *b, int n) /* drop first n chars; no allocation done */
+{
+ if(b->nrune<0 || b->nrune<n)
+ drawerror(f->display, "chopbox");
+ strcpy((char*)b->ptr, (char*)runeindex(b->ptr, n));
+ b->nrune -= n;
+ b->wid = stringwidth(f->font, (char *)b->ptr);
+}
+
+void
+_frsplitbox(Frame *f, int bn, int n)
+{
+ dupbox(f, bn);
+ truncatebox(f, &f->box[bn], f->box[bn].nrune-n);
+ chopbox(f, &f->box[bn+1], n);
+}
+
+void
+_frmergebox(Frame *f, int bn) /* merge bn and bn+1 */
+{
+ Frbox *b;
+
+ b = &f->box[bn];
+ _frinsure(f, bn, NBYTE(&b[0])+NBYTE(&b[1])+1);
+ strcpy((char*)runeindex(b[0].ptr, b[0].nrune), (char*)b[1].ptr);
+ b[0].wid += b[1].wid;
+ b[0].nrune += b[1].nrune;
+ _frdelbox(f, bn+1, bn+1);
+}
+
+int
+_frfindbox(Frame *f, int bn, ulong p, ulong q) /* find box containing q and put q on a box boundary */
+{
+ Frbox *b;
+
+ for(b = &f->box[bn]; bn<f->nbox && p+NRUNE(b)<=q; bn++, b++)
+ p += NRUNE(b);
+ if(p != q)
+ _frsplitbox(f, bn++, (int)(q-p));
+ return bn;
+}