stringwidth.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. int
  5. _stringnwidth(Font *f, char *s, Rune *r, int len)
  6. {
  7. int wid, twid, n, max, l;
  8. char *name;
  9. enum { Max = 64 };
  10. ushort cbuf[Max];
  11. Rune rune, **rptr;
  12. char *subfontname, **sptr;
  13. Font *def;
  14. if(s == nil){
  15. s = "";
  16. sptr = nil;
  17. }else
  18. sptr = &s;
  19. if(r == nil){
  20. r = L"";
  21. rptr = nil;
  22. }else
  23. rptr = &r;
  24. twid = 0;
  25. while(len>0 && (*s || *r)){
  26. max = Max;
  27. if(len < max)
  28. max = len;
  29. n = 0;
  30. while((l = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){
  31. if(++n > 10){
  32. if(*r)
  33. rune = *r;
  34. else
  35. chartorune(&rune, s);
  36. if(f->name != nil)
  37. name = f->name;
  38. else
  39. name = "unnamed font";
  40. fprint(2, "stringwidth: bad character set for rune 0x%.4ux in %s\n", rune, name);
  41. return twid;
  42. }
  43. if(subfontname){
  44. if(_getsubfont(f->display, subfontname) == 0){
  45. def = f->display->defaultfont;
  46. if(def && f!=def)
  47. f = def;
  48. else
  49. break;
  50. }
  51. }
  52. }
  53. agefont(f);
  54. twid += wid;
  55. len -= l;
  56. }
  57. return twid;
  58. }
  59. int
  60. stringnwidth(Font *f, char *s, int len)
  61. {
  62. return _stringnwidth(f, s, nil, len);
  63. }
  64. int
  65. stringwidth(Font *f, char *s)
  66. {
  67. return _stringnwidth(f, s, nil, 1<<24);
  68. }
  69. Point
  70. stringsize(Font *f, char *s)
  71. {
  72. return Pt(_stringnwidth(f, s, nil, 1<<24), f->height);
  73. }
  74. int
  75. runestringnwidth(Font *f, Rune *r, int len)
  76. {
  77. return _stringnwidth(f, nil, r, len);
  78. }
  79. int
  80. runestringwidth(Font *f, Rune *r)
  81. {
  82. return _stringnwidth(f, nil, r, 1<<24);
  83. }
  84. Point
  85. runestringsize(Font *f, Rune *r)
  86. {
  87. return Pt(_stringnwidth(f, nil, r, 1<<24), f->height);
  88. }