pingus-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pingus-CVS] r3972 - in trunk/pingus: . src


From: grumbel at BerliOS
Subject: [Pingus-CVS] r3972 - in trunk/pingus: . src
Date: Thu, 26 Feb 2009 13:33:32 +0100

Author: grumbel
Date: 2009-02-26 13:33:31 +0100 (Thu, 26 Feb 2009)
New Revision: 3972

Modified:
   trunk/pingus/TODO
   trunk/pingus/src/string_format.cpp
   trunk/pingus/src/utf8_iterator.cpp
   trunk/pingus/src/utf8_iterator.hpp
Log:
Made line breaking code work with Unicode (still some bug with font width left)

Modified: trunk/pingus/TODO
===================================================================
--- trunk/pingus/TODO   2009-02-26 11:17:25 UTC (rev 3971)
+++ trunk/pingus/TODO   2009-02-26 12:33:31 UTC (rev 3972)
@@ -51,6 +51,9 @@
 "Important" Stuff and Random Notes:
 ===================================
 
+* line_width handling is broken either in Font or in StringFormat,
+  leading to overflow in the StoryScreen
+
 * Automatically generate Levelsets for User generated levels, maybe allow to 
edit them somehow
 
 * Valgrind results:

Modified: trunk/pingus/src/string_format.cpp
===================================================================
--- trunk/pingus/src/string_format.cpp  2009-02-26 11:17:25 UTC (rev 3971)
+++ trunk/pingus/src/string_format.cpp  2009-02-26 12:33:31 UTC (rev 3972)
@@ -14,10 +14,11 @@
 //  You should have received a copy of the GNU General Public License
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+#include <sstream>
 #include "font.hpp"
 #include "string_format.hpp"
+#include "utf8_iterator.hpp"
 
-
 std::string
 StringFormat::break_line (std::string text, int width, const Font& font)
 {
@@ -59,27 +60,36 @@
   while ((pos = text.find("  ", pos)) != std::string::npos)
     text.replace(pos, 2, 1, ' ');
 
-  size_t start_pos      = 0;
-  size_t previous_space = 0;
-  pos = 0;
-
-  while ((pos = text.find(' ', pos + 1)) != std::string::npos)
+  // Text is now normalized, time to start breaking the lines
+  std::string::const_iterator beg = text.begin();
+  int line_width = 0;
+  std::ostringstream out;
+  for(std::string::const_iterator it = beg; it != text.end(); it = 
UTF8::advance(it))
     {
-      if (font.get_width(text.substr(start_pos, pos - start_pos)) > width)
+      std::string word(beg, UTF8::advance(it));
+      int word_width = font.get_width(word);
+      
+      if 
(UTF8::is_linebreak_character(UTF8Iterator::decode_utf8(std::string(it, 
const_cast<const std::string&>(text).end()))))
         {
-         text[previous_space] = '\n';
-         start_pos = previous_space + 1;
-       }
-      else if (font.get_width(text.substr(start_pos, text.length())) <= width)
-        break;
-
-      previous_space = pos;
+          if ((line_width + word_width) > width)
+            {
+              out << "\n" << word;
+              line_width = 0;
+            }
+          else
+            {
+              out << word;
+              line_width += word_width;
+            }
+          
+          beg = UTF8::advance(it);
+        }
     }
+  
+  std::string::const_iterator end = text.end();
+  out << std::string(beg, end);
 
-  if (font.get_width(text.substr(start_pos, text.length() - start_pos)) > 
width)
-    text[text.rfind(' ')] = '\n';
-
-  return text;
+  return out.str();
 }
 
 

Modified: trunk/pingus/src/utf8_iterator.cpp
===================================================================
--- trunk/pingus/src/utf8_iterator.cpp  2009-02-26 11:17:25 UTC (rev 3971)
+++ trunk/pingus/src/utf8_iterator.cpp  2009-02-26 12:33:31 UTC (rev 3972)
@@ -19,6 +19,19 @@
 #include <stdexcept>
 #include "utf8_iterator.hpp"
 
+bool
+UTF8::is_linebreak_character(uint32_t unicode)
+{
+  if (unicode == ' ' || unicode >= 0x3400)
+    {
+      return true;
+    } 
+  else
+    {
+      return false;
+    }
+}
+
 std::string::size_type
 UTF8::length(const std::string& str)
 {
@@ -124,6 +137,13 @@
   return ((c & 0300) == 0200);
 }
 
+uint32_t
+UTF8Iterator::decode_utf8(const std::string& text)
+{
+  size_t p = 0;
+  return decode_utf8(text, p);
+}
+
 /**
  * gets unicode character at byte position @a p of UTF-8 encoded @a
  * text, then advances @a p to the next character.

Modified: trunk/pingus/src/utf8_iterator.hpp
===================================================================
--- trunk/pingus/src/utf8_iterator.hpp  2009-02-26 11:17:25 UTC (rev 3971)
+++ trunk/pingus/src/utf8_iterator.hpp  2009-02-26 12:33:31 UTC (rev 3972)
@@ -27,6 +27,9 @@
   static std::string::size_type length(const std::string& str);
   static std::string substr(const std::string& text, std::string::size_type 
pos, std::string::size_type n);
   static std::string::const_iterator advance(std::string::const_iterator it, 
std::string::size_type n = 1);
+
+  /** return true if a linebreak is allowed after this character */
+  static bool is_linebreak_character(uint32_t unicode);
 };
 
 class UTF8Iterator
@@ -36,10 +39,11 @@
   std::string::size_type pos;
   uint32_t chr;
 
+public:
   /**
    * returns true if this byte matches a bitmask of 10xx.xxxx, i.e. it is the 
2nd, 3rd or 4th byte of a multibyte utf8 string
    */
-  bool has_multibyte_mark(unsigned char c);
+  static bool has_multibyte_mark(unsigned char c);
 
   /**
    * gets unicode character at byte position @a p of UTF-8 encoded @a
@@ -48,8 +52,10 @@
    * @throws std::runtime_error if decoding fails.
    * See unicode standard section 3.10 table 3-5 and 3-6 for details.
    */
-  uint32_t decode_utf8(const std::string& text, size_t& p);
+  static uint32_t decode_utf8(const std::string& text, size_t& p);
 
+  static uint32_t decode_utf8(const std::string& text);
+  
 public:
   UTF8Iterator(const std::string& text_);
   bool done() const;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]