frptofchar.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <draw.h>
  12. #include <thread.h>
  13. #include <mouse.h>
  14. #include <frame.h>
  15. Point
  16. _frptofcharptb(Frame *f, uint32_t p, Point pt, int bn)
  17. {
  18. uint8_t *s;
  19. Frbox *b;
  20. int w, l;
  21. Rune r;
  22. for(b = &f->box[bn]; bn<f->nbox; bn++,b++){
  23. _frcklinewrap(f, &pt, b);
  24. if(p < (l=NRUNE(b))){
  25. if(b->nrune > 0)
  26. for(s=b->ptr; p>0; s+=w, p--){
  27. if((r = *s) < Runeself)
  28. w = 1;
  29. else
  30. w = chartorune(&r, (char*)s);
  31. pt.x += stringnwidth(f->font,
  32. (char*)s, 1);
  33. if(r==0 || pt.x>f->r.max.x)
  34. drawerror(f->display, "frptofchar");
  35. }
  36. break;
  37. }
  38. p -= l;
  39. _fradvance(f, &pt, b);
  40. }
  41. return pt;
  42. }
  43. Point
  44. frptofchar(Frame *f, uint32_t p)
  45. {
  46. return _frptofcharptb(f, p, f->r.min, 0);
  47. }
  48. Point
  49. _frptofcharnb(Frame *f, uint32_t p, int nb) /* doesn't do final _fradvance to next line */
  50. {
  51. Point pt;
  52. int nbox;
  53. nbox = f->nbox;
  54. f->nbox = nb;
  55. pt = _frptofcharptb(f, p, f->r.min, 0);
  56. f->nbox = nbox;
  57. return pt;
  58. }
  59. static
  60. Point
  61. _frgrid(Frame *f, Point p)
  62. {
  63. p.y -= f->r.min.y;
  64. p.y -= p.y%f->font->height;
  65. p.y += f->r.min.y;
  66. if(p.x > f->r.max.x)
  67. p.x = f->r.max.x;
  68. return p;
  69. }
  70. uint32_t
  71. frcharofpt(Frame *f, Point pt)
  72. {
  73. Point qt;
  74. int w, bn;
  75. uint8_t *s;
  76. Frbox *b;
  77. uint32_t p;
  78. Rune r;
  79. pt = _frgrid(f, pt);
  80. qt = f->r.min;
  81. for(b=f->box,bn=0,p=0; bn<f->nbox && qt.y<pt.y; bn++,b++){
  82. _frcklinewrap(f, &qt, b);
  83. if(qt.y >= pt.y)
  84. break;
  85. _fradvance(f, &qt, b);
  86. p += NRUNE(b);
  87. }
  88. for(; bn<f->nbox && qt.x<=pt.x; bn++,b++){
  89. _frcklinewrap(f, &qt, b);
  90. if(qt.y > pt.y)
  91. break;
  92. if(qt.x+b->wid > pt.x){
  93. if(b->nrune < 0)
  94. _fradvance(f, &qt, b);
  95. else{
  96. s = b->ptr;
  97. for(;;){
  98. if((r = *s) < Runeself)
  99. w = 1;
  100. else
  101. w = chartorune(&r, (char*)s);
  102. if(r == 0)
  103. drawerror(f->display, "end of string in frcharofpt");
  104. qt.x += stringnwidth(f->font,
  105. (char*)s, 1);
  106. s += w;
  107. if(qt.x > pt.x)
  108. break;
  109. p++;
  110. }
  111. }
  112. }else{
  113. p += NRUNE(b);
  114. _fradvance(f, &qt, b);
  115. }
  116. }
  117. return p;
  118. }