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