AutoWrap.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include "AutoWrap.h"
  2. #include <QStringList>
  3. static CharWidthType char_widths[] = {
  4. { 126, 1 }, { 159, 0 }, { 687, 1 }, { 710, 0 }, { 711, 1 }, { 727, 0 }, { 733, 1 }, { 879, 0 },
  5. { 1154, 1 }, { 1161, 0 }, { 4347, 1 }, { 4447, 2 }, { 7467, 1 }, { 7521, 0 }, { 8369, 1 }, { 8426, 0 },
  6. { 9000, 1 }, { 9002, 2 }, { 11021, 1 }, { 12350, 2 }, { 12351, 1 }, { 12438, 2 }, { 12442, 0 }, { 19893, 2 },
  7. { 19967, 1 }, { 55203, 2 }, { 63743, 1 }, { 64106, 2 }, { 65039, 1 }, { 65059, 0 }, { 65131, 2 }, { 65279, 1 },
  8. { 65376, 2 }, { 65500, 1 }, { 65510, 2 }, { 120831, 1 }, { 262141, 2 }, { 1114109, 1 },
  9. };
  10. int TextWrap::getWidth(QChar c)
  11. {
  12. if (c == 0xe || c == 0xf) {
  13. return 0;
  14. }
  15. for (auto nw : char_widths) {
  16. if (c <= nw.num) {
  17. return nw.width;
  18. }
  19. }
  20. return 1;
  21. }
  22. /**
  23. * @brief Wrap according to string length
  24. * @param text: the text to be wrapped
  25. * @param width: the maximum length of a single line, the length of Chinese characters is 2
  26. * @param once: whether to wrap only once
  27. * @return <wrap_text(QString): text after auto word wrap process, is_wrapped(bool): whether a line break occurs in the
  28. * text>
  29. */
  30. QPair<QString, bool> TextWrap::wrap(const QString &text, int width, bool once)
  31. {
  32. int count = 0;
  33. int lastCount = 0;
  34. QString chars;
  35. bool isWrapped = false;
  36. int breakPos = 0;
  37. bool isBreakAlpha = true;
  38. int nInsideBreak = 0;
  39. int i = 0;
  40. QString txt = text.trimmed();
  41. while (i < txt.count()) {
  42. QChar c = txt.at(i);
  43. int length = TextWrap::getWidth(c);
  44. count += length;
  45. // record the position of blank character
  46. if (c == ' ' || length > 1) {
  47. breakPos = i + nInsideBreak;
  48. lastCount = count;
  49. isBreakAlpha = (length == 1);
  50. }
  51. // No line breaks
  52. if (count <= width) {
  53. chars.append(c);
  54. i++;
  55. continue;
  56. }
  57. // wrap at the position of the previous space
  58. if (breakPos > 0 && isBreakAlpha) {
  59. if (c != ' ') {
  60. chars[breakPos] = '\n';
  61. chars.append(c);
  62. // Wrap inside long words
  63. if (lastCount != 0) {
  64. count -= lastCount;
  65. lastCount = 0;
  66. } else {
  67. chars.insert(i, '\n');
  68. breakPos = i;
  69. nInsideBreak += 1;
  70. }
  71. } else {
  72. chars.append('\n');
  73. count = 0;
  74. lastCount = 0;
  75. }
  76. } else {
  77. chars.append('\n');
  78. chars.append(c);
  79. count = length;
  80. }
  81. isWrapped = true;
  82. // early return
  83. if (once) {
  84. return QPair<QString, bool>(chars + txt.mid(i + 1), true);
  85. }
  86. }
  87. return QPair<QString, bool>(chars, true);
  88. }