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

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 "CEGUIXMLAttributes.h"
00032 
00033 #include <ft2build.h>
00034 #include FT_FREETYPE_H
00035 
00036 
00037 // Start of CEGUI namespace section
00038 namespace CEGUI
00039 {
00040 
00041 /*************************************************************************
00042 static data definitions
00043 *************************************************************************/
00044 
00045 // XML related strings
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 // General constants
00073 const int       Font_xmlHandler::AutoGenerateHorzAdvance                = -1;
00074 
00077 
00078 /*************************************************************************
00079 SAX2 Handler methods
00080 *************************************************************************/
00081 void Font_xmlHandler::elementStart(const String& element, const XMLAttributes& attributes)
00082 {
00083         // handle a Mapping element
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                         // calculate advance width if it was not specified
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         // handle root Font element
00111         else if (element == FontElement)
00112         {
00113                 // get name of font we are creating
00114                 String font_name(attributes.getValueAsString(FontNameAttribute));
00115 
00116                 // get filename for the font
00117         String filename(attributes.getValueAsString(FontFilenameAttribute));
00118         // get resource group for font file.
00119         String resourceGroup(attributes.getValueAsString(FontResourceGroupAttribute));
00120 
00121                 Logger::getSingleton().logEvent("Started creation of Font '" + font_name + "' via XML file.", Informative);
00122 
00123                 //
00124                 // load auto-scaling configuration
00125                 //
00126                 float hres, vres;
00127                 bool auto_scale;
00128 
00129                 // get native horizontal resolution
00130         hres = (float)attributes.getValueAsInteger(FontNativeHorzResAttribute, 640);
00131 
00132                 // get native vertical resolution
00133         vres = (float)attributes.getValueAsInteger(FontNativeVertResAttribute, 480);
00134 
00135                 // get auto-scaling setting
00136         auto_scale = attributes.getValueAsBool(FontAutoScaledAttribute, false);
00137 
00138                 //
00139                 // get type of font
00140                 //
00141         String  font_type(attributes.getValueAsString(FontTypeAttribute));
00142 
00143                 // dynamic (ttf) font
00144                 if (font_type == FontTypeDynamic)
00145                 {
00146                         // get size of font
00147             uint size = (uint)attributes.getValueAsInteger(FontSizeAttribute, 12);
00148 
00149                         // extract codepoint range
00150             utf32 first_codepoint = (utf32)attributes.getValueAsInteger(FontFirstCodepointAttribute, 32);
00151             utf32 last_codepoint = (utf32)attributes.getValueAsInteger(FontLastCodepointAttribute, 127);
00152 
00153                         // build string containing the required code-points.
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                         // perform pre-initialisation
00162                         d_font->setNativeResolution(Size(hres, vres));
00163                         d_font->setAutoScalingEnabled(auto_scale);
00164 
00165                         // Finalise construction of font without glyphs.
00166                         // Glyphs will defined after we know which ones we need.
00167                         d_font->constructor_impl(font_name, filename, resourceGroup, size, flags, String(""));
00168                 }
00169                 // static (Imageset based) font
00170                 else if (font_type == FontTypeStatic)
00171                 {
00172                         d_font->d_name = font_name;
00173                         d_font->d_freetype = false;
00174 
00175                         // load the Imageset
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                 // error (should never happen)
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         // Glyph element
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         // GlyphRange element
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         // GlyphSet element
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         // anything else is an error which *should* have already been caught by XML validation
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                 // if this is a freetype based font, perform glyph definition
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 } // End of  CEGUI namespace section

Generated on Wed Sep 7 09:56:31 2005 for Crazy Eddies GUI System by  doxygen 1.4.3