/src/ftk_text_layout_normal.c

http://ftk.googlecode.com/ · C · 173 lines · 107 code · 36 blank · 30 comment · 36 complexity · a0b3cf1839ec38f5ca56b3bec822cbb6 MD5 · raw file

  1. /*
  2. * File: ftk_text_layout_normal.c
  3. *
  4. * Author: Li XianJing <xianjimli@hotmail.com>
  5. * Brief: simple implementation for text layout interface.
  6. *
  7. * Copyright (c) 2009 - 2010 Li XianJing <xianjimli@hotmail.com>
  8. *
  9. * Licensed under the Academic Free License version 2.1
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  24. */
  25. /*
  26. * History:
  27. * ================================================================
  28. * 2010-07-18 Li XianJing <xianjimli@hotmail.com> created
  29. *
  30. */
  31. #include "ftk_util.h"
  32. #include "ftk_text_layout.h"
  33. struct _FtkTextLayout
  34. {
  35. int pos;
  36. int len;
  37. size_t width;
  38. FtkCanvas* canvas;
  39. const char* text;
  40. FtkWrapMode wrap_mode;
  41. int pos_v2l[FTK_LINE_CHAR_NR+1];
  42. };
  43. FtkTextLayout* ftk_text_layout_create(void)
  44. {
  45. FtkTextLayout* thiz = FTK_NEW(FtkTextLayout);
  46. return thiz;
  47. }
  48. Ret ftk_text_layout_set_canvas(FtkTextLayout* thiz, FtkCanvas* canvas)
  49. {
  50. return_val_if_fail(thiz != NULL && canvas != NULL, RET_FAIL);
  51. thiz->canvas = canvas;
  52. return RET_OK;
  53. }
  54. Ret ftk_text_layout_set_width(FtkTextLayout* thiz, size_t width)
  55. {
  56. return_val_if_fail(thiz != NULL && width > 0, RET_FAIL);
  57. thiz->width = width;
  58. return RET_OK;
  59. }
  60. Ret ftk_text_layout_set_text(FtkTextLayout* thiz, const char* text, int len)
  61. {
  62. return_val_if_fail(thiz != NULL && text != NULL, RET_FAIL);
  63. thiz->pos = 0;
  64. thiz->text = text;
  65. thiz->len = len < 0 ? strlen(text) : len;
  66. return RET_OK;
  67. }
  68. Ret ftk_text_layout_set_wrap_mode(FtkTextLayout* thiz, FtkWrapMode wrap_mode)
  69. {
  70. return_val_if_fail(thiz != NULL, RET_FAIL);
  71. thiz->wrap_mode = wrap_mode;
  72. return RET_OK;
  73. }
  74. Ret ftk_text_layout_init(FtkTextLayout* thiz, const char* text, int len, FtkCanvas* canvas, size_t width)
  75. {
  76. return_val_if_fail(thiz != NULL && text != NULL && canvas != NULL && width > 0, RET_FAIL);
  77. thiz->pos = 0;
  78. thiz->text = text;
  79. thiz->canvas = canvas;
  80. thiz->width = width;
  81. thiz->wrap_mode = FTK_WRAP_NONE;
  82. thiz->len = len < 0 ? strlen(text) : len;
  83. return RET_OK;
  84. }
  85. Ret ftk_text_layout_skip_to(FtkTextLayout* thiz, int pos)
  86. {
  87. return_val_if_fail(thiz != NULL && pos >= 0 && pos < thiz->len, RET_FAIL);
  88. thiz->pos = pos;
  89. return RET_OK;
  90. }
  91. Ret ftk_text_layout_get_visual_line(FtkTextLayout* thiz, FtkTextLine* line)
  92. {
  93. int i = 0;
  94. int extent = 0;
  95. const char* end = NULL;
  96. return_val_if_fail(thiz != NULL && line != NULL, RET_FAIL);
  97. if(thiz->pos >= thiz->len)
  98. {
  99. return RET_FAIL;
  100. }
  101. line->pos_v2l = thiz->pos_v2l;
  102. line->attr = FTK_TEXT_ATTR_NORMAL;
  103. line->text = thiz->text + thiz->pos;
  104. end = ftk_canvas_calc_str_visible_range(thiz->canvas, thiz->text, thiz->pos, -1, thiz->width, &extent);
  105. if(thiz->wrap_mode == FTK_WRAP_WORD)
  106. {
  107. const char* start = thiz->text + thiz->pos;
  108. const char* new_end = ftk_line_break(start, end);
  109. if(end != new_end && new_end > (start + 2))
  110. {
  111. end = new_end;
  112. extent = ftk_canvas_get_str_extent(thiz->canvas, start, end - start);
  113. }
  114. }
  115. line->len = end - line->text;
  116. line->xoffset = 0;
  117. line->extent = extent;
  118. for(i = 0; i < line->len && i < FTK_LINE_CHAR_NR; i++)
  119. {
  120. line->pos_v2l[i] = i + thiz->pos;
  121. }
  122. thiz->pos += line->len;
  123. for(i = line->len - 1; i >= 0; i--)
  124. {
  125. if(line->text[i] == '\r' || line->text[i] == '\n')
  126. line->len--;
  127. }
  128. return RET_OK;
  129. }
  130. void ftk_text_layout_destroy(FtkTextLayout* thiz)
  131. {
  132. if(thiz != NULL)
  133. {
  134. FTK_FREE(thiz);
  135. }
  136. return;
  137. }