From a683a420a9e43705c972b5e74d55e319729e1a81 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Thu, 29 Jul 2010 19:53:02 +0000 Subject: SWORD25: Importing original sources svn-id: r53171 --- engines/sword25/gfx/fontresource.cpp | 243 +++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100755 engines/sword25/gfx/fontresource.cpp (limited to 'engines/sword25/gfx/fontresource.cpp') diff --git a/engines/sword25/gfx/fontresource.cpp b/engines/sword25/gfx/fontresource.cpp new file mode 100755 index 0000000000..3d2d12e992 --- /dev/null +++ b/engines/sword25/gfx/fontresource.cpp @@ -0,0 +1,243 @@ +// ----------------------------------------------------------------------------- +// This file is part of Broken Sword 2.5 +// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer +// +// Broken Sword 2.5 is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// Broken Sword 2.5 is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Broken Sword 2.5; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +// ----------------------------------------------------------------------------- + +#define BS_LOG_PREFIX "FONTRESOURCE" + +// ----------------------------------------------------------------------------- +// Includes +// ----------------------------------------------------------------------------- + +#include + +#include "kernel/kernel.h" +#include "kernel/string.h" +#include "package/packagemanager.h" +#include "util/tinyxml/tinyxml.h" + +#include "fontresource.h" + +// ----------------------------------------------------------------------------- +// Konstanten +// ----------------------------------------------------------------------------- + +static const unsigned int DEFAULT_LINEHEIGHT = 20; +static const unsigned int DEFAULT_GAPWIDTH = 1; + +// ----------------------------------------------------------------------------- +// Konstruktion / Destruktion +// ----------------------------------------------------------------------------- + +BS_FontResource::BS_FontResource(BS_Kernel* pKernel, const std::string& FileName) : + _pKernel(pKernel), + _Valid(false), + BS_Resource(FileName, BS_Resource::TYPE_FONT) +{ + // XML Fontdatei parsen + TiXmlDocument Doc; + if (!_ParseXMLDocument(FileName, Doc)) + { + BS_LOG_ERRORLN("The following TinyXML-Error occured while parsing \"%s\": %s", GetFileName().c_str(), Doc.ErrorDesc()); + return; + } + + // Font-Tag finden + TiXmlElement* pElement = Doc.FirstChildElement("font"); + if (!pElement) + { + BS_LOG_ERRORLN("No tag found in \"%s\".", GetFileName().c_str()); + return; + } + + // Font-Tag parsen + std::string BitmapFileName; + if (!_ParseFontTag(*pElement, BitmapFileName, _LineHeight, _GapWidth)) + { + BS_LOG_ERRORLN("An error occurred while parsing tag in \"%s\".", GetFileName().c_str()); + return; + } + + // Absoluten, eindeutigen Pfad zur Bitmapdatei bestimmen und dabei auf vorhandensein prüfen + { + // Pointer auf den Package-Manager bekommen + BS_ASSERT(_pKernel); + BS_PackageManager* pPackage = static_cast(_pKernel->GetService("package")); + BS_ASSERT(pPackage); + + // Absoluten, eindeutigen Pfad bestimmen + _BitmapFileName = pPackage->GetAbsolutePath(BitmapFileName); + if (_BitmapFileName == "") + { + BS_LOG_ERRORLN("Image file \"%s\" was specified in tag of \"%s\" but could not be found.", + _BitmapFileName.c_str(), GetFileName().c_str()); + return; + } + + // Bitmapdatei cachen + if (!_pKernel->GetResourceManager()->PrecacheResource(_BitmapFileName)) + { + BS_LOG_ERRORLN("Could not precache \"%s\".", _BitmapFileName.c_str()); + return; + } + } + + // Das Erste Character-Tag finden + pElement = pElement->FirstChildElement("character"); + if (!pElement) + { + BS_LOG_ERRORLN("No tag found in \"%s\".", GetFileName().c_str()); + return; + } + + // Alle Character-Tags parsen + while (pElement) + { + int CharCode; + BS_Rect CharRect; + + // Aktuelles Character-Tag parsen + if (!_ParseCharacterTag(*pElement, CharCode, CharRect)) + { + BS_LOG_ERRORLN("An error occured while parsing a tag in \"%s\".", GetFileName().c_str()); + return; + } + + // Ausgelesene Daten in das _CharacterRects-Array eintragen + BS_ASSERT(CharCode < 256); + _CharacterRects[CharCode] = CharRect; + + // Zum nächsten Character-Tag iterieren + pElement = pElement->NextSiblingElement("character"); + } + + // Erfolg signalisieren + _Valid = true; +} + +// ----------------------------------------------------------------------------- + +bool BS_FontResource::_ParseXMLDocument(const std::string & FileName, TiXmlDocument & Doc) const +{ + // Pointer auf den Package-Manager bekommen + BS_ASSERT(_pKernel); + BS_PackageManager* pPackage = static_cast(_pKernel->GetService("package")); + BS_ASSERT(pPackage); + + // Die Daten werden zunächst über den Package-Manager gelesen und dann in einen um ein Byte größeren Buffer kopiert + // und NULL-Terminiert, da TinyXML NULL-Terminierte Daten benötigt. + unsigned int FileSize; + char * LoadBuffer = (char*) pPackage->GetFile(GetFileName(), &FileSize); + if (!LoadBuffer) + { + BS_LOG_ERRORLN("Could not read \"%s\".", GetFileName().c_str()); + return false; + } + + // Daten kopieren und NULL-terminieren + std::vector WorkBuffer(FileSize + 1); + memcpy(&WorkBuffer[0], LoadBuffer, FileSize); + delete LoadBuffer; + WorkBuffer[FileSize] = '\0'; + + // Daten parsen + Doc.Parse(&WorkBuffer[0]); + + return !Doc.Error(); +} + +// ----------------------------------------------------------------------------- + +bool BS_FontResource::_ParseFontTag(TiXmlElement & Tag, std::string & BitmapFileName, int & Lineheight, int & GapWidth) const +{ + // Bitmap Attribut auslesen + const char * BitmapString = Tag.Attribute("bitmap"); + if (!BitmapString) + { + BS_LOG_ERRORLN(" tag without bitmap attribute occurred in \"%s\".", GetFileName().c_str()); + return false; + } + BitmapFileName = BitmapString; + + // Lineheight Attribut auslesen + const char * LineheightString = Tag.Attribute("lineheight"); + if (!LineheightString || !BS_String::ToInt(std::string(LineheightString), Lineheight) || Lineheight < 0) + { + BS_LOG_WARNINGLN("Illegal or missing lineheight attribute in tag in \"%s\". Assuming default (\"%d\").", + GetFileName().c_str(), DEFAULT_LINEHEIGHT); + Lineheight = DEFAULT_LINEHEIGHT; + } + + + // Gap Attribut auslesen + const char * GapString = Tag.Attribute("gap"); + if (!GapString || !BS_String::ToInt(std::string(GapString), GapWidth) || GapWidth < 0) + { + BS_LOG_WARNINGLN("Illegal or missing gap attribute in tag in \"%s\". Assuming default (\"%d\").", + GetFileName().c_str(), DEFAULT_GAPWIDTH); + GapWidth = DEFAULT_GAPWIDTH; + } + + return true; +} + +// ----------------------------------------------------------------------------- + +bool BS_FontResource::_ParseCharacterTag(TiXmlElement & Tag, int & Code, BS_Rect & Rect) const +{ + // Code Attribut auslesen + const char * CodeString = Tag.Attribute("code"); + if (!CodeString || !BS_String::ToInt(std::string(CodeString), Code) || Code < 0 || Code >= 256) + { + BS_LOG_ERRORLN("Illegal or missing code attribute in tag in \"%s\".", GetFileName().c_str()); + return false; + } + + // Left Attribut auslesen + const char * LeftString = Tag.Attribute("left"); + if (!LeftString || !BS_String::ToInt(std::string(LeftString), Rect.left) || Rect.left < 0) + { + BS_LOG_ERRORLN("Illegal or missing left attribute in tag in \"%s\".", GetFileName().c_str()); + return false; + } + + // Right Attribut auslesen + const char * RightString = Tag.Attribute("right"); + if (!RightString || !BS_String::ToInt(RightString, Rect.right) || Rect.right < 0) + { + BS_LOG_ERRORLN("Illegal or missing right attribute in tag in \"%s\".", GetFileName().c_str()); + return false; + } + + // Top Attribut auslesen + const char * TopString = Tag.Attribute("top"); + if (!TopString || !BS_String::ToInt(TopString, Rect.top) || Rect.top < 0) + { + BS_LOG_ERRORLN("Illegal or missing top attribute in tag in \"%s\".", GetFileName().c_str()); + return false; + } + + // Bottom Attribut auslesen + const char * BottomString = Tag.Attribute("bottom"); + if (!BottomString || !BS_String::ToInt(BottomString, Rect.bottom) || Rect.bottom < 0) + { + BS_LOG_ERRORLN("Illegal or missing bottom attribute in tag in \"%s\".", GetFileName().c_str()); + return false; + } + + return true; +} -- cgit v1.2.3