frutil.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. #include <thread.h>
  5. #include <mouse.h>
  6. #include <frame.h>
  7. int
  8. _frcanfit(Frame *f, Point pt, Frbox *b)
  9. {
  10. int left, w, nr;
  11. uchar *p;
  12. Rune r;
  13. left = f->r.max.x-pt.x;
  14. if(b->nrune < 0)
  15. return b->minwid <= left;
  16. if(left >= b->wid)
  17. return b->nrune;
  18. for(nr=0,p=b->ptr; *p; p+=w,nr++){
  19. r = *p;
  20. if(r < Runeself)
  21. w = 1;
  22. else
  23. w = chartorune(&r, (char*)p);
  24. left -= stringnwidth(f->font, (char*)p, 1);
  25. if(left < 0)
  26. return nr;
  27. }
  28. drawerror(f->display, "_frcanfit can't");
  29. return 0;
  30. }
  31. void
  32. _frcklinewrap(Frame *f, Point *p, Frbox *b)
  33. {
  34. if((b->nrune<0? b->minwid : b->wid) > f->r.max.x-p->x){
  35. p->x = f->r.min.x;
  36. p->y += f->font->height;
  37. }
  38. }
  39. void
  40. _frcklinewrap0(Frame *f, Point *p, Frbox *b)
  41. {
  42. if(_frcanfit(f, *p, b) == 0){
  43. p->x = f->r.min.x;
  44. p->y += f->font->height;
  45. }
  46. }
  47. void
  48. _fradvance(Frame *f, Point *p, Frbox *b)
  49. {
  50. if(b->nrune<0 && b->bc=='\n'){
  51. p->x = f->r.min.x;
  52. p->y += f->font->height;
  53. }else
  54. p->x += b->wid;
  55. }
  56. int
  57. _frnewwid(Frame *f, Point pt, Frbox *b)
  58. {
  59. b->wid = _frnewwid0(f, pt, b);
  60. return b->wid;
  61. }
  62. int
  63. _frnewwid0(Frame *f, Point pt, Frbox *b)
  64. {
  65. int c, x;
  66. c = f->r.max.x;
  67. x = pt.x;
  68. if(b->nrune>=0 || b->bc!='\t')
  69. return b->wid;
  70. if(x+b->minwid > c)
  71. x = pt.x = f->r.min.x;
  72. x += f->maxtab;
  73. x -= (x-f->r.min.x)%f->maxtab;
  74. if(x-pt.x<b->minwid || x>c)
  75. x = pt.x+b->minwid;
  76. return x-pt.x;
  77. }
  78. void
  79. _frclean(Frame *f, Point pt, int n0, int n1) /* look for mergeable boxes */
  80. {
  81. Frbox *b;
  82. int nb, c;
  83. c = f->r.max.x;
  84. for(nb=n0; nb<n1-1; nb++){
  85. b = &f->box[nb];
  86. _frcklinewrap(f, &pt, b);
  87. while(b[0].nrune>=0 && nb<n1-1 && b[1].nrune>=0 && pt.x+b[0].wid+b[1].wid<c){
  88. _frmergebox(f, nb);
  89. n1--;
  90. b = &f->box[nb];
  91. }
  92. _fradvance(f, &pt, &f->box[nb]);
  93. }
  94. for(; nb<f->nbox; nb++){
  95. b = &f->box[nb];
  96. _frcklinewrap(f, &pt, b);
  97. _fradvance(f, &pt, &f->box[nb]);
  98. }
  99. f->lastlinefull = 0;
  100. if(pt.y >= f->r.max.y)
  101. f->lastlinefull = 1;
  102. }