00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <nds.h>
00021
00022 #include <string>
00023 #include "utf8.h"
00024 #include <ft2build.h>
00025 #include FT_FREETYPE_H
00026 #include "types.h"
00027 #include "textbox.h"
00028 #include "graphics.h"
00029
00030 using std::string;
00031
00032 void TextBox::Init (Types::Screen::selector screen,
00033 int bgid, FT_Face face, int size, int x, int y,
00034 int width, int height)
00035 {
00036 screen_ = screen;
00037 bgid_ = bgid;
00038 face_ = face;
00039 size_ = size;
00040 x_ = x;
00041 y_ = y;
00042 width_ = (width==0) ? SCREEN_WIDTH - x - 20 : width;
00043 height_ = (height==0) ? ((size_*3)>>1) : height;
00044 mutable_height_ = (height == 0);
00045 floats_ = independent_ = false;
00046 visible_ = true;
00047 }
00048
00049 std::string TextBox::text () const
00050 {
00051 return text_;
00052 }
00053
00054 int TextBox::size () const
00055 {
00056 return size_;
00057 }
00058
00059 int TextBox::x () const
00060 {
00061 return x_;
00062 }
00063
00064 int TextBox::y () const
00065 {
00066 return y_;
00067 }
00068
00069 int TextBox::width () const
00070 {
00071 return width_;
00072 }
00073
00074 int TextBox::height () const
00075 {
00076 return height_;
00077 }
00078
00079 int TextBox::bgid () const
00080 {
00081 return bgid_;
00082 }
00083
00084 bool TextBox::floats () const
00085 {
00086 return floats_;
00087 }
00088
00089 bool TextBox::independent () const
00090 {
00091 return independent_;
00092 }
00093
00094 bool TextBox::visible () const
00095 {
00096 return visible_;
00097 }
00098
00099 Types::Screen::selector TextBox::screen () const
00100 {
00101 return screen_;
00102 }
00103
00104 void TextBox::floats (bool f)
00105 {
00106 floats_ = f;
00107 }
00108
00109 void TextBox::independent (bool i)
00110 {
00111 independent_ = i;
00112 }
00113
00114 void TextBox::visible (bool v)
00115 {
00116 visible_ = v;
00117 }
00118
00119 void TextBox::SetProperties (int x, int y, int width, int height)
00120 {
00121 Move(x,y);
00122 width_ = (width==0) ? SCREEN_WIDTH - x - 10 : width;
00123 height_ = (height==0) ? ((size_*3)>>1) : height;
00124 }
00125
00126 void TextBox::text (const std::string& str, bool convert_to_romaji)
00127 {
00128 if (convert_to_romaji)
00129 text_ = ConvertToRomaji(str);
00130 else
00131 text_ = str;
00132 }
00133
00134 void TextBox::Move (int x, int y)
00135 {
00136 x_ = x;
00137 y_ = y;
00138 }
00139
00140 void TextBox::Adjust (int y)
00141 {
00142
00143
00144
00145
00146 if (y > (y_ - 5))
00147 {
00148 y_ = y +5;
00149 }
00150 }
00151
00152 void TextBox::Print ()
00153 {
00154
00155
00156 FT_Set_Char_Size (face_, size_ << 6, 0, 110, 110);
00157
00158 int pen_x = x_;
00159 int pen_y = y_ + ((size_*3)>>1);
00160 string::const_iterator it = text_.begin();
00161 while (it != text_.end())
00162 {
00163 int glyph_index;
00164 u32 utf8character = utf8::unchecked::next(it);
00165 if (utf8character == 32)
00166 {
00167 pen_x += size_*2/3;
00168 if ((pen_x - x_) > width_)
00169 {
00170 pen_y += face_->height>>6;
00171 pen_x = x_;
00172 if ((pen_y - y_) > height_)
00173 {
00174
00175 if (mutable_height_)
00176 height_ = pen_y - y_;
00177 else
00178 return;
00179 }
00180 }
00181 }
00182 else
00183 {
00184 glyph_index = FT_Get_Char_Index (face_, utf8character);
00185
00186 FT_Load_Glyph (face_, glyph_index, FT_LOAD_RENDER);
00187
00188 pen_x += face_->glyph->metrics.horiBearingX>>6;
00189 if (visible_)
00190 {
00191
00192 Graphics::PrintBitmap (pen_x,
00193 pen_y - (face_->glyph->metrics.horiBearingY>>6),
00194 face_->glyph->bitmap.width,
00195 face_->glyph->bitmap.rows,
00196 face_->glyph->bitmap.buffer, bgid_, screen_);
00197 }
00198
00199 pen_x += (face_->glyph->advance.x >> 6) -
00200 (face_->glyph->metrics.horiBearingX >> 6);
00201 if ((pen_x - x_) > width_)
00202 {
00203 pen_y += face_->height >> 6;
00204 pen_x = x_;
00205 if ((pen_y - y_) > height_)
00206 {
00207
00208 if (mutable_height_)
00209 height_ = pen_y - y_;
00210 else
00211 return;
00212 }
00213 }
00214 }
00215 }
00216 }
00217
00219 const char* kana_table =
00220 "a a i i u u e e o o ka ga ki gi ku gu "
00221 "ke ge ko go sa za shiji su zu se ze so zo ta da "
00222 "chiji tsutsutzute de to do na ni nu ne no ha ba "
00223 "pa hi bi pi fu bu pu he be pe ho bo po ma mi mu "
00224 "me mo ya ya yu yu yo yo ra ri ru re ro wa wa wi "
00225 "we wo n ";
00226
00228 inline string no_spaces(const string& str)
00229 {
00230 string no_spaces_str;
00231 for (size_t i = 0; i < str.size(); ++i)
00232 if (str[i] != ' ')
00233 no_spaces_str.push_back(str[i]);
00234
00235 return no_spaces_str;
00236 }
00237
00238 string TextBox::ConvertToRomaji (string str)
00239 {
00240 string romaji;
00241 string::iterator it = str.begin();
00242 uint32_t prev_utf8c = 0;
00243 uint32_t utf8c = 0;
00244 uint32_t kana_base = 0;
00245 uint32_t prev_kana_base = 0;
00246 while (it != str.end())
00247 {
00248 if (prev_utf8c)
00249 {
00250 if (prev_kana_base)
00251 romaji += no_spaces(string(kana_table+((prev_utf8c-prev_kana_base)*3), 3));
00252 else
00253 utf8::unchecked::utf32to8(&prev_utf8c, &prev_utf8c + 1, back_inserter(romaji));
00254 }
00255 prev_utf8c = utf8c;
00256 prev_kana_base = kana_base;
00257
00258 utf8c = utf8::unchecked::next(it);
00259 if (utf8c > 12352 && utf8c < 12436)
00260 {
00261
00262 kana_base = 12353;
00263 }
00264 else if (utf8c > 12448 && utf8c < 12535)
00265 {
00266
00267 kana_base = 12449;
00268 }
00269 else
00270 kana_base = 0;
00271
00272 if (kana_base && prev_utf8c == (prev_kana_base + 34))
00273 {
00274 romaji += no_spaces(string(kana_table+((utf8c-kana_base)*3), 1) +
00275 string(kana_table+((utf8c-kana_base)*3), 3));
00276 prev_utf8c = utf8c = 0;
00277 }
00278 else if (kana_base && utf8c == (kana_base + 66))
00279 {
00280 switch(prev_utf8c-prev_kana_base)
00281 {
00282 case 12: romaji += "kya";
00283 break;
00284 case 22: romaji += "sha";
00285 break;
00286 case 23: romaji += "ja";
00287 break;
00288 case 32: romaji += "cha";
00289 break;
00290 case 33: romaji += "ja";
00291 break;
00292 case 42: romaji += "nya";
00293 break;
00294 case 49: romaji += "hya";
00295 break;
00296 case 50: romaji += "bya";
00297 break;
00298 case 51: romaji += "pya";
00299 break;
00300 case 62: romaji += "mya";
00301 break;
00302 case 73: romaji += "rya";
00303 break;
00304 default: romaji += no_spaces(
00305 string(kana_table+((prev_utf8c-prev_kana_base)*3), 3)) +
00306 no_spaces(string(kana_table+((utf8c-kana_base)*3), 3));
00307 }
00308 prev_utf8c = utf8c = 0;
00309 }
00310 else if (kana_base && utf8c == (kana_base + 68))
00311 {
00312 switch(prev_utf8c-prev_kana_base)
00313 {
00314 case 12: romaji += "kyu";
00315 break;
00316 case 22: romaji += "shu";
00317 break;
00318 case 23: romaji += "ju";
00319 break;
00320 case 32: romaji += "chu";
00321 break;
00322 case 33: romaji += "ju";
00323 break;
00324 case 42: romaji += "nyu";
00325 break;
00326 case 49: romaji += "hyu";
00327 break;
00328 case 50: romaji += "byu";
00329 break;
00330 case 51: romaji += "pyu";
00331 break;
00332 case 62: romaji += "myu";
00333 break;
00334 case 73: romaji += "ryu";
00335 break;
00336 default: romaji += no_spaces(
00337 string(kana_table+((prev_utf8c-prev_kana_base)*3), 3)) +
00338 no_spaces(string(kana_table+((utf8c-kana_base)*3), 3));
00339 }
00340 prev_utf8c = utf8c = 0;
00341 }
00342 else if (kana_base && utf8c == (kana_base + 70))
00343 {
00344 switch(prev_utf8c-prev_kana_base)
00345 {
00346 case 12: romaji += "kyo";
00347 break;
00348 case 22: romaji += "sho";
00349 break;
00350 case 23: romaji += "jo";
00351 break;
00352 case 32: romaji += "cho";
00353 break;
00354 case 33: romaji += "jo";
00355 break;
00356 case 42: romaji += "nyo";
00357 break;
00358 case 49: romaji += "hyo";
00359 break;
00360 case 50: romaji += "byo";
00361 break;
00362 case 51: romaji += "pyo";
00363 break;
00364 case 62: romaji += "myo";
00365 break;
00366 case 73: romaji += "ryo";
00367 break;
00368 default: romaji += no_spaces(
00369 string(kana_table+((prev_utf8c-prev_kana_base)*3), 3)) +
00370 no_spaces(string(kana_table+((utf8c-kana_base)*3), 3));
00371 }
00372 prev_utf8c = utf8c = 0;
00373 }
00374 }
00375 if (prev_utf8c)
00376 {
00377 if (prev_kana_base)
00378 romaji += no_spaces(string(kana_table+((prev_utf8c-prev_kana_base)*3), 3));
00379 else
00380 utf8::unchecked::utf32to8(&prev_utf8c, &prev_utf8c + 1, back_inserter(romaji));
00381 }
00382 if (utf8c)
00383 {
00384 if (kana_base)
00385 romaji += no_spaces(string(kana_table+((utf8c-kana_base)*3), 3));
00386 else
00387 utf8::unchecked::utf32to8(&utf8c, &utf8c + 1, back_inserter(romaji));
00388 }
00389 return romaji;
00390 }