Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

CEGUIFont_xmlHandler.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002 filename:       CEGUIFont.cpp
00003 created:        21/2/2004
00004 author:         Paul D Turner
00005 
00006 purpose:        Implements Font class
00007 *************************************************************************/
00008 /*************************************************************************
00009 Crazy Eddie's GUI System (http://www.cegui.org.uk)
00010 Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
00011 
00012 This library is free software; you can redistribute it and/or
00013 modify it under the terms of the GNU Lesser General Public
00014 License as published by the Free Software Foundation; either
00015 version 2.1 of the License, or (at your option) any later version.
00016 
00017 This library is distributed in the hope that it will be useful,
00018 but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020 Lesser General Public License for more details.
00021 
00022 You should have received a copy of the GNU Lesser General Public
00023 License along with this library; if not, write to the Free Software
00024 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 // Start of CEGUI namespace section
00041 namespace CEGUI
00042 {
00043 
00044 /*************************************************************************
00045 static data definitions
00046 *************************************************************************/
00047 
00048 // XML related strings
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 // General constants
00076 const int       Font_xmlHandler::AutoGenerateHorzAdvance                = -1;
00077 
00080 
00081 /*************************************************************************
00082 SAX2 Handler methods
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         // handle a Mapping element
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                         // calculate advance width if it was not specified
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         // handle root Font element
00119         else if (element == FontElement)
00120         {
00121                 // get name of font we are creating
00122                 String font_name(XmlHandlerHelper::getAttributeValueAsString(attrs, FontNameAttribute));
00123 
00124                 // get filename for the font
00125                 String filename(XmlHandlerHelper::getAttributeValueAsString(attrs, FontFilenameAttribute));
00126         // get resource group for font file.
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                 // load auto-scaling configuration
00133                 //
00134                 float hres, vres;
00135                 bool auto_scale;
00136 
00137                 // get native horizontal resolution
00138                 hres = (float)XmlHandlerHelper::getAttributeValueAsInteger(attrs, FontNativeHorzResAttribute);
00139 
00140                 // get native vertical resolution
00141                 vres = (float)XmlHandlerHelper::getAttributeValueAsInteger(attrs, FontNativeVertResAttribute);
00142 
00143                 // get auto-scaling setting
00144                 String autoscaleval(XmlHandlerHelper::getAttributeValueAsString(attrs, FontAutoScaledAttribute));
00145                 auto_scale = ((autoscaleval == (utf8*)"true") || (autoscaleval == (utf8*)"1")) ? true : false;
00146 
00147                 //
00148                 // get type of font
00149                 //
00150                 String  font_type(XmlHandlerHelper::getAttributeValueAsString(attrs, FontTypeAttribute));
00151 
00152                 // dynamic (ttf) font
00153                 if (font_type == FontTypeDynamic)
00154                 {
00155                         // get size of font
00156                         uint size = (uint)XmlHandlerHelper::getAttributeValueAsInteger(attrs, FontSizeAttribute);
00157 
00158                         // extract codepoint range
00159                         utf32 first_codepoint = (utf32)XmlHandlerHelper::getAttributeValueAsInteger(attrs, FontFirstCodepointAttribute);
00160                         utf32 last_codepoint = (utf32)XmlHandlerHelper::getAttributeValueAsInteger(attrs, FontLastCodepointAttribute);
00161 
00162                         // build string containing the required code-points.
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                         // perform pre-initialisation
00172                         d_font->setNativeResolution(Size(hres, vres));
00173                         d_font->setAutoScalingEnabled(auto_scale);
00174 
00175                         // Finalise construction of font without glyphs.
00176                         // Glyphs will defined after we know which ones we need.
00177                         d_font->constructor_impl(font_name, filename, resourceGroup, size, flags, String(""));
00178                 }
00179                 // static (Imageset based) font
00180                 else if (font_type == FontTypeStatic)
00181                 {
00182                         d_font->d_name = font_name;
00183                         d_font->d_freetype = false;
00184 
00185                         // load the Imageset
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                 // error (should never happen)
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         // Glyph element
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         // GlyphRange element
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         // GlyphSet element
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         // anything else is an error which *should* have already been caught by XML validation
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                 // if this is a freetype based font, perform glyph definition
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 } // End of  CEGUI namespace section

Generated on Wed Feb 16 12:41:06 2005 for Crazy Eddies GUI System by  doxygen 1.3.9.1