stringwidth.c 2.0 KB

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