[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Wesnoth-cvs-commits] wesnoth/src font.cpp language.hpp language.cpp
From: |
Jon Daniel |
Subject: |
[Wesnoth-cvs-commits] wesnoth/src font.cpp language.hpp language.cpp |
Date: |
Wed, 02 Mar 2005 09:18:39 -0500 |
CVSROOT: /cvsroot/wesnoth
Module name: wesnoth
Branch:
Changes by: Jon Daniel <address@hidden> 05/03/02 14:18:39
Modified files:
src : font.cpp language.hpp language.cpp
Log message:
* Changed the text_chunk to contain a UTF-8 string instead of a UCS4
string
* Updated split text to convert UTF-8 to UCS4 to look up the subset id
and add UTF-8 strings to the text_chunk in the same loop.
* Changed some text_surface inspectors to be public.
* Changed text_surface::measure to use TTF_SizeUTF8
* Changed text_surface::get_surfaces to use TTF_RenderUTF8_Blended
* Changed text_surface::equal to text_surface::equals and let it use
operator==(const SDL_Color&, const SDL_Color&)
* Moved byte_size_from_utf8_first out of the anonymous namespace and
added a prototype in language hpp.
* Moved the invalid_utf8_exception to language.hpp
I think all the character encoding string conversion functions should
be moved to serialization/string_utils.
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/font.cpp.diff?tr1=1.107&tr2=1.108&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/language.hpp.diff?tr1=1.30&tr2=1.31&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/language.cpp.diff?tr1=1.71&tr2=1.72&r1=text&r2=text
Patches:
Index: wesnoth/src/font.cpp
diff -u wesnoth/src/font.cpp:1.107 wesnoth/src/font.cpp:1.108
--- wesnoth/src/font.cpp:1.107 Tue Mar 1 21:12:42 2005
+++ wesnoth/src/font.cpp Wed Mar 2 14:18:38 2005
@@ -1,4 +1,4 @@
-/* $Id: font.cpp,v 1.107 2005/03/01 21:12:42 gruikya Exp $ */
+/* $Id: font.cpp,v 1.108 2005/03/02 14:18:38 j_daniel Exp $ */
/*
Copyright (C) 2003 by David White <address@hidden>
Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
@@ -64,51 +64,75 @@
struct text_chunk
{
- text_chunk(subset_id subset, const wide_string& text) : subset(subset),
text(text) {};
+ text_chunk(subset_id subset, const std::string& text) : subset(subset),
text(text) {};
subset_id subset;
- wide_string text;
+ std::string text;
};
std::vector<subset_id> font_map;
-//Splits the text into chunks of text using the same font.
-std::vector<text_chunk> split_text(wide_string text)
-{
- wide_string current_chunk;
- std::vector<text_chunk> res;
+//Splits the UTF-8 text into chunks of UTF-8 text using the same font.
+//Converts UTF-8 bytes into one wchar_t at a time and gets the subset
+//id for it. The correspondending UTF-8 bytes then are appended to a
+//chunk.
+std::vector<text_chunk> split_text(const std::string& utf8_text) {
bool first = true;
int current_font = 0;
+ std::string current_chunk;
+ std::vector<text_chunk> chunks;
+
+ try {
+ size_t i = 0;
+ while(i < utf8_text.size()) {
+ wchar_t ch = (unsigned char)utf8_text[i];
+ const int num_bytes = byte_size_from_utf8_first(ch);
+
+ if(i + num_bytes > utf8_text.size()) {
+ throw invalid_utf8_exception();
+ }
- for(wide_string::const_iterator itor = text.begin(); itor !=
text.end(); ++itor) {
+ if(num_bytes != 1) {
+ ch &= 0xFF >> (num_bytes + 1);
+ }
- if(first) {
- if(*itor < font_map.size() && font_map[*itor] >= 0) {
- current_font = font_map[*itor];
+ for(size_t j = i + 1; j != i + num_bytes; ++j) {
+ const unsigned char ch2 = utf8_text[j];
+ if((ch2 & 0xC0) != 0x80) {
+ throw invalid_utf8_exception();
+ }
+ ch = (ch << 6) | (ch2 & 0x3F);
+ }
+
+ if(first) {
+ if(ch < font_map.size() && font_map[ch] >= 0) {
+ current_font = font_map[ch];
+ } else {
+ current_font = 0;
+ }
+ first = false;
+ }
+
+ if(ch >= font_map.size() || font_map[ch] < 0) {
+ current_chunk.append(utf8_text, i, num_bytes);
+ } else if(font_map[ch] == current_font) {
+ current_chunk.append(utf8_text, i, num_bytes);
} else {
- current_font = 0;
+ chunks.push_back(text_chunk(current_font,
current_chunk));
+ current_chunk.clear();
+ current_chunk.append(utf8_text, i, num_bytes);
+ current_font = font_map[ch];
}
- first = false;
+ i += num_bytes;
}
-
- // If the current character is outside the text map, we do not
- // know how to do about it. So, just push it into the current
- // chunk.
- if(*itor >= font_map.size() || font_map[*itor] < 0) {
- current_chunk.push_back(*itor);
- } else if(font_map[*itor] == current_font) {
- current_chunk.push_back(*itor);
- } else {
- res.push_back(text_chunk(current_font, current_chunk));
- current_chunk.clear();
- current_chunk.push_back(*itor);
- current_font = font_map[*itor];
+ if (!current_chunk.empty()) {
+ chunks.push_back(text_chunk(current_font,
current_chunk));
}
}
- if (!current_chunk.empty()) {
- res.push_back(text_chunk(current_font, current_chunk));
+ catch(invalid_utf8_exception e) {
+ WRN_FT << "Invalid UTF-8 string: \"" << utf8_text << "\"\n";
}
- return res;
+ return chunks;
}
TTF_Font* open_font(const std::string& fname, int size)
@@ -312,11 +336,15 @@
text_surface(std::string const &str, int size, SDL_Color color, int
style);
text_surface(int size, SDL_Color color, int style);
void set_text(std::string const &str);
- bool operator==(text_surface const &t) const { return hash_ == t.hash_
&& equal(t); }
- bool operator!=(text_surface const &t) const { return hash_ != t.hash_
|| !equal(t); }
+
+ void measure() const;
size_t width() const;
size_t height() const;
std::vector<surface> const & get_surfaces() const;
+
+ bool equals(text_surface const &t) const;
+ bool operator==(text_surface const &t) const { return hash_ == t.hash_
&& equals(t); }
+ bool operator!=(text_surface const &t) const { return hash_ != t.hash_
|| !equals(t); }
private:
int hash_;
int font_size_;
@@ -327,8 +355,6 @@
mutable std::vector<surface> surfs_;
mutable bool initialized_;
void hash();
- void measure() const;
- bool equal(text_surface const &t) const;
};
text_surface::text_surface(std::string const &str, int size, SDL_Color color,
int style)
@@ -345,6 +371,7 @@
void text_surface::set_text(std::string const &str)
{
str_ = str;
+ initialized_ = false;
hash();
}
@@ -356,10 +383,10 @@
hash_ = h;
}
-bool text_surface::equal(text_surface const &t) const
+bool text_surface::equals(text_surface const &t) const
{
return font_size_ == t.font_size_
- && color_.r == t.color_.r && color_.g == t.color_.g && color_.b
== t.color_.b
+ && color_ == t.color_
&& style_ == t.style_
&& str_ == t.str_;
}
@@ -369,8 +396,7 @@
w_ = 0;
h_ = 0;
- wide_string ws = string_to_wstring(str_);
- std::vector<text_chunk> substrings = split_text(ws);
+ std::vector<text_chunk> substrings = split_text(str_);
for(std::vector<text_chunk>::const_iterator itor = substrings.begin();
itor != substrings.end(); ++itor) {
@@ -380,19 +406,10 @@
continue;
font_style_setter const style_setter(ttfont, style_);
- //Convert the wide_string into something usable by sdl_ttf.
- //This is pretty ugly.
- util::scoped_array<Uint16> text(new Uint16[itor->text.size() +
1]);
- wide_string::const_iterator c = itor->text.begin();
- int i;
- for(i = 0; c != itor->text.end(); ++c, ++i)
- text[i] = *c;
- text[i] = 0;
-
int w;
int h;
- TTF_SizeUNICODE(ttfont, text, &w, &h);
+ TTF_SizeUTF8(ttfont, itor->text.c_str(), &w, &h);
w_ += w;
h_ = maximum<int>(h_, h);
}
@@ -424,8 +441,7 @@
if(width() > max_text_line_width)
return surfs_;
- wide_string ws = string_to_wstring(str_);
- std::vector<text_chunk> substrings = split_text(ws);
+ std::vector<text_chunk> substrings = split_text(str_);
for(std::vector<text_chunk>::const_iterator itor = substrings.begin();
itor != substrings.end(); ++itor) {
@@ -434,16 +450,7 @@
continue;
font_style_setter const style_setter(ttfont, style_);
- //Convert the wide_string into something usable by sdl_ttf.
- //This is pretty ugly.
- util::scoped_array<Uint16> text(new Uint16[itor->text.size() +
1]);
- wide_string::const_iterator c = itor->text.begin();
- int i;
- for(i = 0; c != itor->text.end(); ++c, ++i)
- text[i] = *c;
- text[i] = 0;
-
- surface s = surface(TTF_RenderUNICODE_Blended(ttfont, text,
color_));
+ surface s = surface(TTF_RenderUTF8_Blended(ttfont,
itor->text.c_str(), color_));
if(!s.null())
surfs_.push_back(s);
}
Index: wesnoth/src/language.cpp
diff -u wesnoth/src/language.cpp:1.71 wesnoth/src/language.cpp:1.72
--- wesnoth/src/language.cpp:1.71 Sun Feb 27 12:14:59 2005
+++ wesnoth/src/language.cpp Wed Mar 2 14:18:38 2005
@@ -1,4 +1,4 @@
-/* $Id: language.cpp,v 1.71 2005/02/27 12:14:59 ydirson Exp $ */
+/* $Id: language.cpp,v 1.72 2005/03/02 14:18:38 j_daniel Exp $ */
/*
Copyright (C) 2003 by David White <address@hidden>
Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
@@ -209,9 +209,6 @@
return known_languages[0];
}
-class invalid_utf8_exception : public std::exception {
-};
-
namespace
{
std::string wstring_to_utf8(const wide_string &src)
@@ -265,28 +262,6 @@
}
}
-int byte_size_from_utf8_first(unsigned char ch)
-{
- int count;
-
- if ((ch & 0x80) == 0)
- count = 1;
- else if ((ch & 0xE0) == 0xC0)
- count = 2;
- else if ((ch & 0xF0) == 0xE0)
- count = 3;
- else if ((ch & 0xF8) == 0xF0)
- count = 4;
- else if ((ch & 0xFC) == 0xF8)
- count = 5;
- else if ((ch & 0xFE) == 0xFC)
- count = 6;
- else
- throw invalid_utf8_exception(); /* stop on invalid characters */
-
- return count;
-}
-
wide_string utf8_to_wstring(const std::string &src)
{
wide_string ret;
@@ -327,6 +302,28 @@
}
+int byte_size_from_utf8_first(unsigned char ch)
+{
+ int count;
+
+ if ((ch & 0x80) == 0)
+ count = 1;
+ else if ((ch & 0xE0) == 0xC0)
+ count = 2;
+ else if ((ch & 0xF0) == 0xE0)
+ count = 3;
+ else if ((ch & 0xF8) == 0xF0)
+ count = 4;
+ else if ((ch & 0xFC) == 0xF8)
+ count = 5;
+ else if ((ch & 0xFE) == 0xFC)
+ count = 6;
+ else
+ throw invalid_utf8_exception(); /* stop on invalid characters */
+
+ return count;
+}
+
std::vector<std::string> split_utf8_string(const std::string &src)
{
std::vector<std::string> ret;
Index: wesnoth/src/language.hpp
diff -u wesnoth/src/language.hpp:1.30 wesnoth/src/language.hpp:1.31
--- wesnoth/src/language.hpp:1.30 Tue Nov 30 21:41:18 2004
+++ wesnoth/src/language.hpp Wed Mar 2 14:18:38 2005
@@ -1,4 +1,4 @@
-/* $Id: language.hpp,v 1.30 2004/11/30 21:41:18 silene Exp $ */
+/* $Id: language.hpp,v 1.31 2005/03/02 14:18:38 j_daniel Exp $ */
/*
Copyright (C) 2003 by David White <address@hidden>
Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
@@ -67,6 +67,9 @@
//functions for converting Unicode wide-char strings to UTF-8 encoded
//strings, back and forth
+class invalid_utf8_exception : public std::exception {
+};
+int byte_size_from_utf8_first(unsigned char ch);
std::vector<std::string> split_utf8_string(const std::string &src);
std::string wstring_to_string(const wide_string &);
wide_string string_to_wstring(const std::string &);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Wesnoth-cvs-commits] wesnoth/src font.cpp language.hpp language.cpp,
Jon Daniel <=