/Common/util/string_utils.cpp

https://github.com/StormyDay/ags · C++ · 139 lines · 89 code · 19 blank · 31 comment · 31 complexity · dd47ed1d4c30a3922ea36a22296a6a3a MD5 · raw file

  1. //=============================================================================
  2. //
  3. // Adventure Game Studio (AGS)
  4. //
  5. // Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
  6. // The full list of copyright holders can be found in the Copyright.txt
  7. // file, which is part of this source code distribution.
  8. //
  9. // The AGS source code is provided under the Artistic License 2.0.
  10. // A copy of this license can be found in the file License.txt and at
  11. // http://www.opensource.org/licenses/artistic-license-2.0.php
  12. //
  13. //=============================================================================
  14. #include <string.h>
  15. #include "gui/guidefines.h"
  16. #include "util/string_utils.h"
  17. #include "util/datastream.h"
  18. using AGS::Common::DataStream;
  19. #define STD_BUFFER_SIZE 3000
  20. void removeBackslashBracket(char *lbuffer) {
  21. char *slashoffs;
  22. while ((slashoffs = strstr(lbuffer, "\\[")) != NULL) {
  23. // remove the backslash
  24. memmove(slashoffs, slashoffs + 1, strlen(slashoffs));
  25. }
  26. }
  27. char lines[MAXLINE][200];
  28. int numlines;
  29. // Project-dependant implementation
  30. extern int wgettextwidth_compensate(const char *tex, int font);
  31. // Break up the text into lines, using normal Western left-right style
  32. void split_lines_leftright(const char *todis, int wii, int fonnt) {
  33. // v2.56.636: rewrote this function because the old version
  34. // was crap and buggy
  35. int i = 0;
  36. int nextCharWas;
  37. int splitAt;
  38. char *theline;
  39. // make a copy, since we change characters in the original string
  40. // and this might be in a read-only bit of memory
  41. char textCopyBuffer[STD_BUFFER_SIZE];
  42. strcpy(textCopyBuffer, todis);
  43. theline = textCopyBuffer;
  44. while (1) {
  45. splitAt = -1;
  46. if (theline[i] == 0) {
  47. // end of the text, add the last line if necessary
  48. if (i > 0) {
  49. strcpy(lines[numlines], theline);
  50. removeBackslashBracket(lines[numlines]);
  51. numlines++;
  52. }
  53. break;
  54. }
  55. // temporarily terminate the line here and test its width
  56. nextCharWas = theline[i + 1];
  57. theline[i + 1] = 0;
  58. // force end of line with the [ character (except if \[ )
  59. if ((theline[i] == '[') && ((i == 0) || (theline[i - 1] != '\\')))
  60. splitAt = i;
  61. // otherwise, see if we are too wide
  62. else if (wgettextwidth_compensate(theline, fonnt) >= wii) {
  63. int endline = i;
  64. while ((theline[endline] != ' ') && (endline > 0))
  65. endline--;
  66. // single very wide word, display as much as possible
  67. if (endline == 0)
  68. endline = i - 1;
  69. splitAt = endline;
  70. }
  71. // restore the character that was there before
  72. theline[i + 1] = nextCharWas;
  73. if (splitAt >= 0) {
  74. // add this line
  75. nextCharWas = theline[splitAt];
  76. theline[splitAt] = 0;
  77. strcpy(lines[numlines], theline);
  78. removeBackslashBracket(lines[numlines]);
  79. numlines++;
  80. theline[splitAt] = nextCharWas;
  81. if (numlines >= MAXLINE) {
  82. strcat(lines[numlines-1], "...");
  83. break;
  84. }
  85. // the next line starts from here
  86. theline += splitAt;
  87. // skip the space or bracket that caused the line break
  88. if ((theline[0] == ' ') || (theline[0] == '['))
  89. theline++;
  90. i = -1;
  91. }
  92. i++;
  93. }
  94. }
  95. //=============================================================================
  96. // FIXME: remove later when arrays of chars are replaced by string class
  97. void fputstring(const char *sss, Common::DataStream *out)
  98. {
  99. int b = 0;
  100. while (sss[b] != 0) {
  101. out->WriteInt8(sss[b]);
  102. b++;
  103. }
  104. out->WriteInt8(0);
  105. }
  106. void fgetstring_limit(char *sss, Common::DataStream *in, int bufsize)
  107. {
  108. int b = -1;
  109. do {
  110. if (b < bufsize - 1)
  111. b++;
  112. sss[b] = in->ReadInt8();
  113. if (in->EOS())
  114. return;
  115. } while (sss[b] != 0);
  116. }
  117. void fgetstring(char *sss, Common::DataStream *in)
  118. {
  119. fgetstring_limit (sss, in, 50000000);
  120. }