frptofchar.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. Point
  8. _frptofcharptb(Frame *f, ulong p, Point pt, int bn)
  9. {
  10. uchar *s;
  11. Frbox *b;
  12. int w, l;
  13. Rune r;
  14. for(b = &f->box[bn]; bn<f->nbox; bn++,b++){
  15. _frcklinewrap(f, &pt, b);
  16. if(p < (l=NRUNE(b))){
  17. if(b->nrune > 0)
  18. for(s=b->ptr; p>0; s+=w, p--){
  19. if((r = *s) < Runeself)
  20. w = 1;
  21. else
  22. w = chartorune(&r, (char*)s);
  23. pt.x += stringnwidth(f->font, (char*)s, 1);
  24. if(r==0 || pt.x>f->r.max.x)
  25. drawerror(f->display, "frptofchar");
  26. }
  27. break;
  28. }
  29. p -= l;
  30. _fradvance(f, &pt, b);
  31. }
  32. return pt;
  33. }
  34. Point
  35. frptofchar(Frame *f, ulong p)
  36. {
  37. return _frptofcharptb(f, p, f->r.min, 0);
  38. }
  39. Point
  40. _frptofcharnb(Frame *f, ulong p, int nb) /* doesn't do final _fradvance to next line */
  41. {
  42. Point pt;
  43. int nbox;
  44. nbox = f->nbox;
  45. f->nbox = nb;
  46. pt = _frptofcharptb(f, p, f->r.min, 0);
  47. f->nbox = nbox;
  48. return pt;
  49. }
  50. static
  51. Point
  52. _frgrid(Frame *f, Point p)
  53. {
  54. p.y -= f->r.min.y;
  55. p.y -= p.y%f->font->height;
  56. p.y += f->r.min.y;
  57. if(p.x > f->r.max.x)
  58. p.x = f->r.max.x;
  59. return p;
  60. }
  61. ulong
  62. frcharofpt(Frame *f, Point pt)
  63. {
  64. Point qt;
  65. int w, bn;
  66. uchar *s;
  67. Frbox *b;
  68. ulong p;
  69. Rune r;
  70. pt = _frgrid(f, pt);
  71. qt = f->r.min;
  72. for(b=f->box,bn=0,p=0; bn<f->nbox && qt.y<pt.y; bn++,b++){
  73. _frcklinewrap(f, &qt, b);
  74. if(qt.y >= pt.y)
  75. break;
  76. _fradvance(f, &qt, b);
  77. p += NRUNE(b);
  78. }
  79. for(; bn<f->nbox && qt.x<=pt.x; bn++,b++){
  80. _frcklinewrap(f, &qt, b);
  81. if(qt.y > pt.y)
  82. break;
  83. if(qt.x+b->wid > pt.x){
  84. if(b->nrune < 0)
  85. _fradvance(f, &qt, b);
  86. else{
  87. s = b->ptr;
  88. for(;;){
  89. if((r = *s) < Runeself)
  90. w = 1;
  91. else
  92. w = chartorune(&r, (char*)s);
  93. if(r == 0)
  94. drawerror(f->display, "end of string in frcharofpt");
  95. qt.x += stringnwidth(f->font, (char*)s, 1);
  96. s += w;
  97. if(qt.x > pt.x)
  98. break;
  99. p++;
  100. }
  101. }
  102. }else{
  103. p += NRUNE(b);
  104. _fradvance(f, &qt, b);
  105. }
  106. }
  107. return p;
  108. }