00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
#include "guichan/imagefont.hpp"
00060
00061
#include <sstream>
00062
00063
#include "guichan/color.hpp"
00064
#include "guichan/exception.hpp"
00065
#include "guichan/graphics.hpp"
00066
#include "guichan/image.hpp"
00067
00068
namespace gcn
00069 {
00070 ImageFont::ImageFont(
const std::string& filename,
const std::string& glyphs)
00071 {
00072 mFilename = filename;
00073 mImage = Image::load(filename,
false);
00074
00075
Color separator = mImage->
getPixel(0, 0);
00076
00077
int i = 0;
00078
for (i=0; separator == mImage->
getPixel(i, 0)
00079 && i < mImage->
getWidth(); ++i)
00080 {
00081 }
00082
00083
if (i >= mImage->
getWidth())
00084 {
00085
throw GCN_EXCEPTION(
"Corrupt image.");
00086 }
00087
00088
int j = 0;
00089
for (j = 0; j < mImage->
getHeight(); ++j)
00090 {
00091
if (separator == mImage->
getPixel(i, j))
00092 {
00093
break;
00094 }
00095 }
00096
00097 mHeight = j;
00098
int x = 0, y = 0;
00099
unsigned char k;
00100
00101
for (i=0; i < (
int)glyphs.size(); ++i)
00102 {
00103 k = glyphs.at(i);
00104 addGlyph(k, x, y, separator);
00105 }
00106
00107
int w = mImage->
getWidth();
00108
int h = mImage->
getHeight();
00109 mImage->
convertToDisplayFormat();
00110
00111 mRowSpacing = 0;
00112 mGlyphSpacing = 0;
00113 }
00114
00115 ImageFont::ImageFont(
const std::string& filename,
unsigned char glyphsFrom,
unsigned char glyphsTo)
00116 {
00117 mFilename = filename;
00118 mImage = Image::load(filename,
false);
00119
00120
Color separator = mImage->
getPixel(0, 0);
00121
00122
int i = 0;
00123
for (i=0; separator == mImage->
getPixel(i, 0)
00124 && i < mImage->
getWidth(); ++i)
00125 {
00126 }
00127
00128
if (i >= mImage->
getWidth())
00129 {
00130
throw GCN_EXCEPTION(
"Corrupt image.");
00131 }
00132
00133
int j = 0;
00134
for (j = 0; j < mImage->
getHeight(); ++j)
00135 {
00136
if (separator == mImage->
getPixel(i, j))
00137 {
00138
break;
00139 }
00140 }
00141
00142 mHeight = j;
00143
int x = 0, y = 0;
00144
unsigned char k;
00145
00146
for (i=glyphsFrom; i<glyphsTo+1; i++)
00147 {
00148 addGlyph(i, x, y, separator);
00149 }
00150
00151
int w = mImage->
getWidth();
00152
int h = mImage->
getHeight();
00153 mImage->
convertToDisplayFormat();
00154
00155 mRowSpacing = 0;
00156 mGlyphSpacing = 0;
00157 }
00158
00159 ImageFont::~ImageFont()
00160 {
00161
delete mImage;
00162 }
00163
00164 int ImageFont::getWidth(
unsigned char glyph)
const
00165
{
00166
if (mGlyph[glyph].
width == 0)
00167 {
00168
return mGlyph[(
int)(
' ')].
width + mGlyphSpacing;
00169 }
00170
00171
return mGlyph[glyph].
width + mGlyphSpacing;
00172 }
00173
00174 int ImageFont::getHeight()
const
00175
{
00176
return mHeight + mRowSpacing;
00177 }
00178
00179 int ImageFont::drawGlyph(
Graphics* graphics,
unsigned char glyph,
int x,
int y)
00180 {
00181
00182
int yoffset =
getRowSpacing() >> 1;
00183
00184
if (mGlyph[glyph].
width == 0)
00185 {
00186 graphics->
drawRectangle(
Rectangle(x, y + 1 + yoffset, mGlyph[(
int)(
' ')].width - 1,
00187 mGlyph[(
int)(
' ')].height - 2));
00188
00189
return mGlyph[(
int)(
' ')].
width + mGlyphSpacing;
00190 }
00191
00192 graphics->
drawImage(mImage, mGlyph[glyph].x, mGlyph[glyph].y, x,
00193 y + yoffset, mGlyph[glyph].width, mGlyph[glyph].height);
00194
00195
return mGlyph[glyph].
width + mGlyphSpacing;
00196 }
00197
00198 void ImageFont::drawString(
Graphics* graphics,
const std::string& text,
int x,
int y)
00199 {
00200
unsigned int i;
00201
00202
for (i = 0; i< text.size(); ++i)
00203 {
00204
drawGlyph(graphics, text.at(i), x, y);
00205 x +=
getWidth(text.at(i));
00206 }
00207 }
00208
00209 void ImageFont::setRowSpacing(
int spacing)
00210 {
00211 mRowSpacing = spacing;
00212 }
00213
00214 int ImageFont::getRowSpacing()
00215 {
00216
return mRowSpacing;
00217 }
00218
00219 void ImageFont::setGlyphSpacing(
int spacing)
00220 {
00221 mGlyphSpacing = spacing;
00222 }
00223
00224 int ImageFont::getGlyphSpacing()
00225 {
00226
return mGlyphSpacing;
00227 }
00228
00229
void ImageFont::addGlyph(
unsigned char c,
int &x,
00230
int &y,
const Color& separator)
00231 {
00232
Color color;
00233
do
00234 {
00235 ++x;
00236
00237
if (x >= mImage->
getWidth())
00238 {
00239 y += mHeight + 1;
00240 x = 0;
00241
00242
if (y >= mImage->
getHeight())
00243 {
00244 std::string str;
00245 std::ostringstream os(str);
00246 os <<
"Image ";
00247 os << mFilename;
00248 os <<
" with font is corrupt near character '";
00249 os << c;
00250 os <<
"'";
00251
throw GCN_EXCEPTION(os.str());
00252 }
00253 }
00254
00255 color = mImage->getPixel(x, y);
00256
00257 }
while (color == separator);
00258
00259
int w = 0;
00260
00261
do
00262 {
00263 ++w;
00264
00265
if (x+w >= mImage->getWidth())
00266 {
00267 std::string str;
00268 std::ostringstream os(str);
00269 os <<
"Image ";
00270 os << mFilename;
00271 os <<
" with font is corrupt near character '";
00272 os << c;
00273 os <<
"'";
00274
throw GCN_EXCEPTION(os.str());
00275 }
00276
00277 color = mImage->getPixel(x + w, y);
00278
00279 }
while (color != separator);
00280
00281 mGlyph[c] = Rectangle(x, y, w, mHeight);
00282
00283 x += w;
00284 }
00285
00286 int ImageFont::getWidth(
const std::string& text)
const
00287
{
00288
unsigned int i;
00289
int size = 0;
00290
00291
for (i = 0; i < text.size(); ++i)
00292 {
00293 size +=
getWidth(text.at(i));
00294 }
00295
00296
return size;
00297 }
00298
00299 int ImageFont::getStringIndexAt(
const std::string& text,
int x)
00300 {
00301
unsigned int i;
00302
int size = 0;
00303
00304
for (i = 0; i < text.size(); ++i)
00305 {
00306 size +=
getWidth(text.at(i));
00307
00308
if (size > x)
00309 {
00310
return i;
00311 }
00312 }
00313
00314
return text.size();
00315 }
00316 }