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 #include "CEGUIFont_xmlHandler.h"
00027
00028 #include "CEGUIExceptions.h"
00029 #include "CEGUIImageset.h"
00030 #include "CEGUILogger.h"
00031 #include "CEGUIXMLAttributes.h"
00032
00033 #include <ft2build.h>
00034 #include FT_FREETYPE_H
00035
00036
00037
00038 namespace CEGUI
00039 {
00040
00041
00042
00043
00044
00045
00046 const String Font_xmlHandler::FontElement( (utf8*)"Font" );
00047 const String Font_xmlHandler::MappingElement( (utf8*)"Mapping" );
00048 const String Font_xmlHandler::FontTypeStatic( (utf8*)"Static" );
00049 const String Font_xmlHandler::FontTypeDynamic( (utf8*)"Dynamic" );
00050 const String Font_xmlHandler::GlyphElement( (utf8*)"Glyph" );
00051 const String Font_xmlHandler::GlyphRangeElement( (utf8*)"GlyphRange" );
00052 const String Font_xmlHandler::GlyphSetElement( (utf8*)"GlyphSet" );
00053 const char Font_xmlHandler::FontNameAttribute[] = "Name";
00054 const char Font_xmlHandler::FontFilenameAttribute[] = "Filename";
00055 const char Font_xmlHandler::FontResourceGroupAttribute[] = "ResourceGroup";
00056 const char Font_xmlHandler::FontTypeAttribute[] = "Type";
00057 const char Font_xmlHandler::FontSizeAttribute[] = "Size";
00058 const char Font_xmlHandler::FontFirstCodepointAttribute[] = "FirstCodepoint";
00059 const char Font_xmlHandler::FontLastCodepointAttribute[] = "LastCodepoint";
00060 const char Font_xmlHandler::FontNativeHorzResAttribute[] = "NativeHorzRes";
00061 const char Font_xmlHandler::FontNativeVertResAttribute[] = "NativeVertRes";
00062 const char Font_xmlHandler::FontAutoScaledAttribute[] = "AutoScaled";
00063 const char Font_xmlHandler::FontAntiAliasedAttribute[] = "AntiAlias";
00064 const char Font_xmlHandler::MappingCodepointAttribute[] = "Codepoint";
00065 const char Font_xmlHandler::MappingImageAttribute[] = "Image";
00066 const char Font_xmlHandler::MappingHorzAdvanceAttribute[] = "HorzAdvance";
00067 const char Font_xmlHandler::GlyphCodepointAttribute[] = "Codepoint";
00068 const char Font_xmlHandler::GlyphRangeStartCodepointAttribute[] = "StartCodepoint";
00069 const char Font_xmlHandler::GlyphRangeEndCodepointAttribute[] = "EndCodepoint";
00070 const char Font_xmlHandler::GlyphSetGlyphsAttribute[] = "Glyphs";
00071
00072
00073 const int Font_xmlHandler::AutoGenerateHorzAdvance = -1;
00074
00077
00078
00079
00080
00081 void Font_xmlHandler::elementStart(const String& element, const XMLAttributes& attributes)
00082 {
00083
00084 if (element == MappingElement)
00085 {
00086 if (!d_font->d_freetype)
00087 {
00088 String image_name(attributes.getValueAsString(MappingImageAttribute));
00089 utf32 codepoint = (utf32)attributes.getValueAsInteger(MappingCodepointAttribute);
00090 int horzAdvance = attributes.getValueAsInteger(MappingHorzAdvanceAttribute, -1);
00091
00092 Font::glyphDat mapDat;
00093 mapDat.d_image = &d_font->d_glyph_images->getImage(image_name);
00094
00095
00096 if (horzAdvance == AutoGenerateHorzAdvance)
00097 {
00098 horzAdvance = (int)(mapDat.d_image->getWidth() + mapDat.d_image->getOffsetX());
00099 }
00100
00101 mapDat.d_horz_advance_unscaled = horzAdvance;
00102 mapDat.d_horz_advance = (uint)(((float)horzAdvance) * (d_font->d_autoScale ? d_font->d_horzScaling : 1.0f));
00103 d_font->d_cp_map[codepoint] = mapDat;
00104 }
00105 else
00106 {
00107 Logger::getSingleton().logEvent((utf8*)"Mapping element encountered. This element is invalid for dynamic fonts.", Informative);
00108 }
00109 }
00110
00111 else if (element == FontElement)
00112 {
00113
00114 String font_name(attributes.getValueAsString(FontNameAttribute));
00115
00116
00117 String filename(attributes.getValueAsString(FontFilenameAttribute));
00118
00119 String resourceGroup(attributes.getValueAsString(FontResourceGroupAttribute));
00120
00121 Logger::getSingleton().logEvent("Started creation of Font '" + font_name + "' via XML file.", Informative);
00122
00123
00124
00125
00126 float hres, vres;
00127 bool auto_scale;
00128
00129
00130 hres = (float)attributes.getValueAsInteger(FontNativeHorzResAttribute, 640);
00131
00132
00133 vres = (float)attributes.getValueAsInteger(FontNativeVertResAttribute, 480);
00134
00135
00136 auto_scale = attributes.getValueAsBool(FontAutoScaledAttribute, false);
00137
00138
00139
00140
00141 String font_type(attributes.getValueAsString(FontTypeAttribute));
00142
00143
00144 if (font_type == FontTypeDynamic)
00145 {
00146
00147 uint size = (uint)attributes.getValueAsInteger(FontSizeAttribute, 12);
00148
00149
00150 utf32 first_codepoint = (utf32)attributes.getValueAsInteger(FontFirstCodepointAttribute, 32);
00151 utf32 last_codepoint = (utf32)attributes.getValueAsInteger(FontLastCodepointAttribute, 127);
00152
00153
00154 for (;first_codepoint <= last_codepoint; ++first_codepoint)
00155 {
00156 d_glyphSet += first_codepoint;
00157 }
00158
00159 uint flags = attributes.getValueAsBool(FontAntiAliasedAttribute, true) ? 0 : NoAntiAlias;
00160
00161
00162 d_font->setNativeResolution(Size(hres, vres));
00163 d_font->setAutoScalingEnabled(auto_scale);
00164
00165
00166
00167 d_font->constructor_impl(font_name, filename, resourceGroup, size, flags, String(""));
00168 }
00169
00170 else if (font_type == FontTypeStatic)
00171 {
00172 d_font->d_name = font_name;
00173 d_font->d_freetype = false;
00174
00175
00176 d_font->d_glyph_images = ImagesetManager::getSingleton().createImageset(filename, resourceGroup);
00177
00178 d_font->setNativeResolution(Size(hres, vres));
00179 d_font->setAutoScalingEnabled(auto_scale);
00180 }
00181
00182 else
00183 {
00184 throw FileIOException("Font::xmlHandler::startElement - The unknown Font:Type attribute value '" + font_type + "' was encountered while processing the Font file.");
00185 }
00186
00187 d_font->d_sourceFilename = filename;
00188 }
00189
00190 else if (element == GlyphElement)
00191 {
00192 if (d_font->d_freetype)
00193 {
00194 utf32 codepoint = (utf32)attributes.getValueAsInteger(GlyphCodepointAttribute);
00195
00196 if (d_glyphSet.find(codepoint) == String::npos)
00197 {
00198 d_glyphSet.append(1, codepoint);
00199 }
00200 }
00201 else
00202 {
00203 Logger::getSingleton().logEvent((utf8*)"Glyph element encountered. This element is invalid for static fonts.", Informative);
00204 }
00205 }
00206
00207 else if (element == GlyphRangeElement)
00208 {
00209 if (d_font->d_freetype)
00210 {
00211 utf32 start = (utf32)attributes.getValueAsInteger(GlyphRangeStartCodepointAttribute);
00212 utf32 end = (utf32)attributes.getValueAsInteger(GlyphRangeEndCodepointAttribute);
00213
00214 for (utf32 codepoint = start; codepoint <= end; ++codepoint)
00215 {
00216 if (d_glyphSet.find(codepoint) == String::npos)
00217 {
00218 d_glyphSet.append(1, codepoint);
00219 }
00220 }
00221
00222 }
00223 else
00224 {
00225 Logger::getSingleton().logEvent((utf8*)"GlyphRange element encountered. This element is invalid for static fonts.", Informative);
00226 }
00227 }
00228
00229 else if (element == GlyphSetElement)
00230 {
00231 if (d_font->d_freetype)
00232 {
00233 String glyphs(attributes.getValueAsString(GlyphSetGlyphsAttribute));
00234
00235 for (String::size_type i = 0; i < glyphs.length(); ++i)
00236 {
00237 utf32 codepoint = glyphs[i];
00238
00239 if (d_glyphSet.find(codepoint) == String::npos)
00240 {
00241 d_glyphSet.append(1, codepoint);
00242 }
00243
00244 }
00245
00246 }
00247 else
00248 {
00249 Logger::getSingleton().logEvent((utf8*)"GlyphSet element encountered. This element is invalid for static fonts.", Informative);
00250 }
00251 }
00252
00253 else
00254 {
00255 throw FileIOException("Font::xmlHandler::startElement - Unexpected data was found while parsing the Font file: '" + element + "' is unknown.");
00256 }
00257
00258 }
00259
00260 void Font_xmlHandler::elementEnd(const String& element)
00261 {
00262 if (element == FontElement)
00263 {
00264
00265 if (d_font->d_freetype)
00266 {
00267 d_font->defineFontGlyphs(d_glyphSet);
00268 }
00269
00270 Logger::getSingleton().logEvent("Finished creation of Font '" + d_font->d_name + "' via XML file.", Informative);
00271 }
00272
00273 }
00274
00275 }