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