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 <sstream>
00060
00061 #include "guichan/exception.h"
00062 #include "guichan/imagefont.h"
00063 #include "guichan/image.h"
00064
00065 namespace gcn
00066 {
00067 ImageFont::ImageFont(const std::string& filename, const std::string& glyphs)
00068 {
00069 if (Image::_getImageLoader() == NULL)
00070 {
00071 throw GCN_EXCEPTION("I have no ImageLoader!");
00072 }
00073
00074 ImageLoader* imageLoader = Image::_getImageLoader();
00075 mFilename = filename;
00076 Image::_getImageLoader()->prepare(filename);
00077 Color separator = Image::_getImageLoader()->getPixel(0, 0);
00078
00079 int i = 0;
00080 for (i=0; separator == imageLoader->getPixel(i, 0)
00081 && i < imageLoader->getWidth(); ++i)
00082 {
00083 }
00084
00085 if (i >= imageLoader->getWidth())
00086 {
00087 throw GCN_EXCEPTION("Corrupt image.");
00088 }
00089
00090 int j = 0;
00091 for (j = 0; j < imageLoader->getHeight(); ++j)
00092 {
00093 if (separator == imageLoader->getPixel(i, j))
00094 {
00095 break;
00096 }
00097 }
00098
00099 mHeight = j;
00100 int x = 0, y = 0;
00101 unsigned char k;
00102
00103 for (i=0; i < (int)glyphs.size(); ++i)
00104 {
00105 k = glyphs.at(i);
00106 addGlyph(k, x, y, separator);
00107 }
00108
00109 int w = imageLoader->getWidth();
00110 int h = imageLoader->getHeight();
00111 void* data = imageLoader->finalize();
00112
00113 mImage = new Image(data, w, h);
00114 mRowSpacing = 0;
00115 mGlyphSpacing = 0;
00116 }
00117
00118 ImageFont::ImageFont(const std::string& filename, unsigned char glyphsFrom, unsigned char glyphsTo)
00119 {
00120 if (Image::_getImageLoader() == NULL)
00121 {
00122 throw GCN_EXCEPTION("I have no ImageLoader!");
00123 }
00124
00125 ImageLoader* imageLoader = Image::_getImageLoader();
00126 mFilename = filename;
00127 Image::_getImageLoader()->prepare(filename);
00128 Color separator = Image::_getImageLoader()->getPixel(0, 0);
00129
00130 int i = 0;
00131 for (i=0; separator == imageLoader->getPixel(i, 0)
00132 && i < imageLoader->getWidth(); ++i)
00133 {
00134 }
00135
00136 if (i >= imageLoader->getWidth())
00137 {
00138 throw GCN_EXCEPTION("Corrupt image.");
00139 }
00140
00141 int j = 0;
00142 for (j = 0; j < imageLoader->getHeight(); ++j)
00143 {
00144 if (separator == imageLoader->getPixel(i, j))
00145 {
00146 break;
00147 }
00148 }
00149
00150 mHeight = j;
00151 int x = 0, y = 0;
00152
00153 for (i=glyphsFrom; i<glyphsTo+1; i++)
00154 {
00155 addGlyph(i, x, y, separator);
00156 }
00157
00158 int w = imageLoader->getWidth();
00159 int h = imageLoader->getHeight();
00160 void* data = imageLoader->finalize();
00161
00162 mImage = new Image(data, w, h);
00163 mRowSpacing = 0;
00164 mGlyphSpacing = 0;
00165 }
00166
00167 ImageFont::~ImageFont()
00168 {
00169 Image::_getImageLoader()->free(mImage);
00170 delete mImage;
00171 }
00172
00173 int ImageFont::getWidth(unsigned char glyph) const
00174 {
00175 if (mGlyph[glyph].width == 0)
00176 {
00177 return mGlyph[(int)(' ')].width + mGlyphSpacing;
00178 }
00179
00180 return mGlyph[glyph].width + mGlyphSpacing;
00181 }
00182
00183 int ImageFont::getHeight() const
00184 {
00185 return mHeight + mRowSpacing;
00186 }
00187
00188 int ImageFont::drawGlyph(Graphics* graphics, unsigned char glyph, int x, int y)
00189 {
00190
00191 int yoffset = getRowSpacing() >> 1;
00192
00193 if (mGlyph[glyph].width == 0)
00194 {
00195 graphics->drawRectangle(Rectangle(x, y + 1 + yoffset, mGlyph[(int)(' ')].width - 1,
00196 mGlyph[(int)(' ')].height - 2));
00197
00198 return mGlyph[(int)(' ')].width + mGlyphSpacing;
00199 }
00200
00201 graphics->drawImage(mImage, mGlyph[glyph].x, mGlyph[glyph].y, x,
00202 y + yoffset, mGlyph[glyph].width, mGlyph[glyph].height);
00203
00204 return mGlyph[glyph].width + mGlyphSpacing;
00205 }
00206
00207 void ImageFont::drawString(Graphics* graphics, const std::string& text, int x, int y)
00208 {
00209 unsigned int i;
00210
00211 for (i = 0; i< text.size(); ++i)
00212 {
00213 drawGlyph(graphics, text.at(i), x, y);
00214 x += getWidth(text.at(i));
00215 }
00216 }
00217
00218 void ImageFont::setRowSpacing(int spacing)
00219 {
00220 mRowSpacing = spacing;
00221 }
00222
00223 int ImageFont::getRowSpacing()
00224 {
00225 return mRowSpacing;
00226 }
00227
00228 void ImageFont::setGlyphSpacing(int spacing)
00229 {
00230 mGlyphSpacing = spacing;
00231 }
00232
00233 int ImageFont::getGlyphSpacing()
00234 {
00235 return mGlyphSpacing;
00236 }
00237
00238 void ImageFont::addGlyph(unsigned char c, int &x,
00239 int &y, const Color& separator)
00240 {
00241 ImageLoader* il = Image::_getImageLoader();
00242
00243 Color color;
00244 do
00245 {
00246 ++x;
00247
00248 if (x >= il->getWidth())
00249 {
00250 y += mHeight + 1;
00251 x = 0;
00252
00253 if (y >= il->getHeight())
00254 {
00255 std::string str;
00256 std::ostringstream os(str);
00257 os << "Image ";
00258 os << mFilename;
00259 os << " with font is corrupt near character '";
00260 os << c;
00261 os << "'";
00262 throw GCN_EXCEPTION(os.str());
00263 }
00264 }
00265
00266 color = il->getPixel(x, y);
00267
00268 } while (color == separator);
00269
00270 int w = 0;
00271
00272 do
00273 {
00274 ++w;
00275
00276 if (x+w >= il->getWidth())
00277 {
00278 std::string str;
00279 std::ostringstream os(str);
00280 os << "Image ";
00281 os << mFilename;
00282 os << " with font is corrupt near character '";
00283 os << c;
00284 os << "'";
00285 throw GCN_EXCEPTION(os.str());
00286 }
00287
00288 color = il->getPixel(x + w, y);
00289
00290 } while (color != separator);
00291
00292 mGlyph[c] = Rectangle(x, y, w, mHeight);
00293
00294 x += w;
00295 }
00296
00297 int ImageFont::getWidth(const std::string& text) const
00298 {
00299 unsigned int i;
00300 int size = 0;
00301
00302 for (i = 0; i < text.size(); ++i)
00303 {
00304 size += getWidth(text.at(i));
00305 }
00306
00307 return size;
00308 }
00309
00310 int ImageFont::getStringIndexAt(const std::string& text, int x)
00311 {
00312 unsigned int i;
00313 int size = 0;
00314
00315 for (i = 0; i < text.size(); ++i)
00316 {
00317 size += getWidth(text.at(i));
00318
00319 if (size > x)
00320 {
00321 return i;
00322 }
00323 }
00324
00325 return text.size();
00326 }
00327 }