pingus-cvs
[Top][All Lists]
Advanced

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

[Pingus-CVS] r3970 - trunk/pingus/src


From: grumbel at BerliOS
Subject: [Pingus-CVS] r3970 - trunk/pingus/src
Date: Thu, 26 Feb 2009 12:11:01 +0100

Author: grumbel
Date: 2009-02-26 12:11:00 +0100 (Thu, 26 Feb 2009)
New Revision: 3970

Modified:
   trunk/pingus/src/story_screen.cpp
   trunk/pingus/src/string_format.hpp
   trunk/pingus/src/utf8_iterator.cpp
   trunk/pingus/src/utf8_iterator.hpp
Log:
Added partial UTF-8 handling to StoryScreen

Modified: trunk/pingus/src/story_screen.cpp
===================================================================
--- trunk/pingus/src/story_screen.cpp   2009-02-25 20:38:17 UTC (rev 3969)
+++ trunk/pingus/src/story_screen.cpp   2009-02-26 11:11:00 UTC (rev 3970)
@@ -33,6 +33,7 @@
 #include "stat_manager.hpp"
 #include "credits.hpp"
 #include "display/display.hpp"
+#include "utf8_iterator.hpp"
 #include "sound/sound.hpp"
 
 class StoryScreenComponent : public GUI::Component
@@ -46,7 +47,7 @@
 
   bool page_displayed_completly;
 
-  WorldmapNS::WorldmapStory *story;
+  WorldmapNS::WorldmapStory* story;
   std::vector<StoryPage> pages;
   Sprite page_surface;
   StoryPage  current_page;
@@ -186,9 +187,11 @@
   if (!page_displayed_completly)
     {
       std::string::size_type len = static_cast<std::string::size_type>(20.0f * 
time_passed);
-      display_text = current_page.text.substr(0, 
Math::min(current_page.text.length(), len));
-
-      if (current_page.text.length() < len)
+      std::string::size_type text_len = UTF8::length(current_page.text);
+      
+      display_text = UTF8::substr(current_page.text, 0, Math::min(text_len, 
len));
+       
+      if (text_len < len)
         {
           page_displayed_completly = true;
         }

Modified: trunk/pingus/src/string_format.hpp
===================================================================
--- trunk/pingus/src/string_format.hpp  2009-02-25 20:38:17 UTC (rev 3969)
+++ trunk/pingus/src/string_format.hpp  2009-02-26 11:11:00 UTC (rev 3970)
@@ -24,7 +24,11 @@
 class StringFormat {
 
 public:
-  static std::string break_line (std::string text, int length, const Font& 
font);
+  /** Takes a string \a text and wraps it into multiple lines, each
+      less then \a width long. Line wrappings happens TeX style, i.e.
+      a double newline marks a newline, while other whitespace is
+      joined to a single space. */
+  static std::string break_line(std::string text, int width, const Font& font);
 };
 
 

Modified: trunk/pingus/src/utf8_iterator.cpp
===================================================================
--- trunk/pingus/src/utf8_iterator.cpp  2009-02-25 20:38:17 UTC (rev 3969)
+++ trunk/pingus/src/utf8_iterator.cpp  2009-02-26 11:11:00 UTC (rev 3970)
@@ -18,7 +18,67 @@
 #include <iostream>
 #include <stdexcept>
 #include "utf8_iterator.hpp"
+
+std::string::size_type
+UTF8::length(const std::string& str)
+{
+  // FIXME: Doesn't check if UTF8 sequence is valid
+  std::string::size_type len = 0;  
+  for(std::string::const_iterator i = str.begin(); i != str.end(); ++i)
+    {
+      unsigned char c = *i;
+      if (((c & 0xc0) == 0xc0) || (c < 0x80)) // 0xc0 == 1100_000
+        {
+          len += 1;
+        }
+    }
+  
+  return len;
+}
 
+std::string
+UTF8::substr(const std::string& text, std::string::size_type pos, 
std::string::size_type n)
+{
+  std::string::const_iterator beg_it = UTF8::advance(text.begin(), pos);
+  std::string::const_iterator end_it = UTF8::advance(beg_it, n);
+  
+  return std::string(beg_it, end_it);
+}
+
+std::string::const_iterator
+UTF8::advance(std::string::const_iterator it, std::string::size_type n)
+{
+  for(std::string::size_type i = 0; i < n; ++i)
+    {
+      // FIXME: Doesn't check if UTF8 sequence is valid
+      unsigned char c = *it;
+
+      if (c < 0x80)
+        {
+          it += 1;
+        }
+      else if ((c & 0xf0) == 0xf0)
+        {
+          it += 4;
+        }
+      else if ((c & 0xe0) == 0xe0)
+        {
+          it += 3;
+        }
+      else if ((c & 0xc0) == 0xc0)
+        {
+          it += 2;
+        }
+      else
+        {
+          std::cout << "UTF8: malformed UTF-8 sequence: " << (int)c << 
std::endl;
+          it += 1;
+        }
+    }
+  
+  return it;
+}
+
 // FIXME: Get rid of exceptions in this code
 UTF8Iterator::UTF8Iterator(const std::string& text_)
   : text(text_),
@@ -115,5 +175,24 @@
   }
   throw std::runtime_error("Malformed utf-8 sequence");
 }
+
+#ifdef __TEST__
+int main(int argc, char** argv)
+{
+  if (argc != 2)
+    {
+      std::cout << "Usage: " << argv[0] << " TEXT" << std::endl;
+    }
+  else
+    {
+      std::cout << "ASCII: " << std::string(argv[1]).length() << std::endl;
+      std::cout << "UTF8:  " << UTF8::length(argv[1]) << std::endl;
 
+      std::string res = UTF8::substr(argv[1], 1, 1);
+      std::cout << "substr:  " << res.length() << " " << res << std::endl;
+    }
+  return 0;
+}
+#endif
+
 /* EOF */

Modified: trunk/pingus/src/utf8_iterator.hpp
===================================================================
--- trunk/pingus/src/utf8_iterator.hpp  2009-02-25 20:38:17 UTC (rev 3969)
+++ trunk/pingus/src/utf8_iterator.hpp  2009-02-26 11:11:00 UTC (rev 3970)
@@ -20,7 +20,15 @@
 
 #include <stdint.h>
 #include <string>
-
+
+class UTF8
+{
+public:
+  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);
+};
+
 class UTF8Iterator
 {
 private:
@@ -48,7 +56,7 @@
   UTF8Iterator& operator++();
   uint32_t operator*() const;
 };
-
+
 #endif
 
 /* EOF */





reply via email to

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