TextWidget.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2003-2006  The Pentagram Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 #include "pent_include.h"
00019 #include "TextWidget.h"
00020 #include "ShapeFont.h"
00021 #include "RenderedText.h"
00022 #include "RenderSurface.h"
00023 #include "FontManager.h"
00024 #include "IDataSource.h"
00025 #include "ODataSource.h"
00026 #include "TTFont.h"
00027 #include "BarkGump.h"
00028 #include "AskGump.h"
00029 #include "ButtonWidget.h"
00030 
00031 DEFINE_RUNTIME_CLASSTYPE_CODE(TextWidget,Gump);
00032 
00033 TextWidget::TextWidget()
00034         : Gump(), cached_text(0)
00035 {
00036 
00037 }
00038 
00039 TextWidget::TextWidget(int X, int Y, std::string txt, bool gamefont_, int font,
00040                                            int w, int h, Font::TextAlign align) :
00041         Gump(X, Y, w, h), text(txt), gamefont(gamefont_), fontnum(font),
00042         blendColour(0), current_start(0), current_end(0),
00043         targetwidth(w), targetheight(h), cached_text(0), textalign(align)
00044 {
00045 
00046 }
00047 
00048 TextWidget::~TextWidget(void)
00049 {
00050         delete cached_text;
00051         cached_text = 0;
00052 }
00053 
00054 // Init the gump, call after construction
00055 void TextWidget::InitGump(Gump* newparent, bool take_focus)
00056 {
00057         Gump::InitGump(newparent, take_focus);
00058 
00059         Pentagram::Font *font = getFont();
00060 
00061         // Y offset is always baseline
00062         dims.y = -font->getBaseline();
00063 
00064         // No X offset
00065         dims.x = 0;
00066 
00067         if (gamefont && getFont()->isHighRes()) {
00068                 int w = 0;
00069                 int x = 0, y = 0;
00070                 ScreenSpaceToGumpRect(x, y, w, dims.y, ROUND_OUTSIDE);
00071 
00072                 int tx = dims.x;
00073                 int ty = dims.y;
00074 
00075                 // Note that GumpRectToScreenSpace is guaranteed to keep
00076                 // targetwidth/targetheight zero if they already were.
00077                 GumpRectToScreenSpace(tx,ty, targetwidth,targetheight, ROUND_OUTSIDE);
00078 
00079                 dims.w = targetwidth;
00080                 dims.h = targetheight;
00081                 x = 0; y = 0;
00082                 ScreenSpaceToGumpRect(x, y, dims.w, dims.h, ROUND_OUTSIDE);
00083         }
00084 
00085         setupNextText();
00086 }
00087 
00088 int TextWidget::getVlead()
00089 {
00090         renderText();
00091         assert(cached_text);
00092 
00093         int vlead = cached_text->getVlead();
00094 
00095         if (gamefont && getFont()->isHighRes()) {
00096                 int x=0,y=0,w=0;
00097                 ScreenSpaceToGumpRect(x, y, w, vlead, ROUND_OUTSIDE);
00098         }
00099 
00100         return vlead;
00101 }
00102 
00103 Pentagram::Font* TextWidget::getFont() const
00104 {
00105         if (gamefont)
00106                 return FontManager::get_instance()->getGameFont(fontnum, true);
00107         else
00108                 return FontManager::get_instance()->getTTFont(fontnum);
00109 }
00110 
00111 bool TextWidget::setupNextText()
00112 {
00113         current_start = current_end;
00114 
00115         if (current_start >= text.size()) return false;
00116 
00117         Pentagram::Font *font = getFont();
00118 
00119         unsigned int remaining;
00120         font->getTextSize(text.substr(current_start), tx, ty, remaining,
00121                                           targetwidth, targetheight, textalign, true);
00122 
00123 
00124         dims.w = tx;
00125         dims.h = ty;
00126         dims.y = -font->getBaseline();
00127         dims.x = 0;
00128         current_end = current_start + remaining;
00129 
00130         delete cached_text;
00131         cached_text = 0;
00132 
00133         if (gamefont) 
00134         {
00135                 Pentagram::Font *font = getFont();
00136                 if (font->isHighRes())
00137                 {
00138                         int x = 0, y = 0;
00139                         ScreenSpaceToGumpRect(x,y, dims.w,dims.h, ROUND_OUTSIDE);
00140 
00141                         int w = 0;
00142                         x = 0; y = 0;
00143                         ScreenSpaceToGumpRect(x, y, w, dims.y, ROUND_OUTSIDE);
00144                 }
00145         }
00146 
00147         return true;
00148 }
00149 
00150 void TextWidget::rewind()
00151 {
00152         current_start = 0;
00153         current_end = 0;
00154         setupNextText();
00155 }
00156 
00157 void TextWidget::renderText()
00158 {
00159         if (!cached_text) {
00160                 Pentagram::Font *font = getFont();
00161 
00162                 unsigned int remaining;
00163                 cached_text = font->renderText(text.substr(current_start,
00164                                                                                                    current_end-current_start),
00165                                                                            remaining, targetwidth, targetheight,
00166                                                                            textalign, true);
00167         }
00168 }
00169 
00170 // Overloadable method to Paint just this Gump (RenderSurface is relative to this)
00171 void TextWidget::PaintThis(RenderSurface*surf, sint32 lerp_factor, bool scaled)
00172 {
00173         Gump::PaintThis(surf,lerp_factor,scaled);
00174 
00175         renderText();
00176 
00177         if (scaled && gamefont && getFont()->isHighRes())
00178         {
00179                 surf->FillAlpha(0xFF,dims.x,dims.y,dims.w, dims.h);
00180                 return;
00181         }
00182 
00183         if (!blendColour)
00184                 cached_text->draw(surf, 0, 0);
00185         else
00186                 cached_text->drawBlended(surf, 0, 0, blendColour);
00187 }
00188 
00189 // Overloadable method to Paint just this gumps unscaled components that require compositing (RenderSurface is relative to parent).
00190 void TextWidget::PaintComposited(RenderSurface* surf, sint32 lerp_factor, sint32 sx, sint32 sy)
00191 {
00192         Pentagram::Font *font = getFont();
00193 
00194         if (!gamefont || !font->isHighRes()) return;
00195 
00196         int x=0,y=0;
00197         GumpToScreenSpace(x,y,ROUND_BOTTOMRIGHT);
00198 
00199         if (!blendColour)
00200                 cached_text->draw(surf, x, y, true);
00201         else
00202                 cached_text->drawBlended(surf, x, y, blendColour, true);
00203 
00204         if (parent->IsOfType<BarkGump>()) return;
00205 
00206         if (parent->IsOfType<ButtonWidget>() && parent->GetParent()->IsOfType<AskGump>()) return;
00207 
00208         x=dims.x; y=dims.y;
00209         int w=dims.w, h=dims.h;
00210         GumpRectToScreenSpace(x, y, w, h, ROUND_OUTSIDE);
00211         surf->FillAlpha(0x00, x, y, w, h);
00212 }
00213 
00214 // don't handle any mouse motion events, so let parent handle them for us.
00215 Gump* TextWidget::OnMouseMotion(int mx, int my)
00216 {
00217         return 0;
00218 }
00219 
00220 
00221 void TextWidget::saveData(ODataSource* ods)
00222 {
00223         Gump::saveData(ods);
00224 
00225         ods->write1(gamefont ? 1 : 0);
00226         ods->write4(static_cast<uint32>(fontnum));
00227         ods->write4(blendColour);
00228         ods->write4(static_cast<uint32>(current_start));
00229         ods->write4(static_cast<uint32>(current_end));
00230         ods->write4(static_cast<uint32>(targetwidth));
00231         ods->write4(static_cast<uint32>(targetheight));
00232         ods->write2(static_cast<uint16>(textalign));
00233         ods->write4(text.size());
00234         ods->write(text.c_str(), text.size());
00235 }
00236 
00237 bool TextWidget::loadData(IDataSource* ids, uint32 version)
00238 {
00239         if (!Gump::loadData(ids, version)) return false;
00240 
00241         gamefont = (ids->read1() != 0);
00242         fontnum = static_cast<int>(ids->read4());
00243         blendColour = ids->read4();
00244         current_start = static_cast<int>(ids->read4());
00245         current_end = static_cast<int>(ids->read4());
00246         targetwidth = static_cast<int>(ids->read4());
00247         targetheight = static_cast<int>(ids->read4());
00248         textalign = static_cast<Font::TextAlign>(ids->read2());
00249 
00250         uint32 slen = ids->read4();
00251         if (slen > 0) {
00252                 char* buf = new char[slen+1];
00253                 ids->read(buf, slen);
00254                 buf[slen] = 0;
00255                 text = buf;
00256                 delete[] buf;
00257         } else {
00258                 text = "";
00259         }
00260 
00261         // HACK ALERT: this is to deal with possibly changing font sizes
00262         // after loading.
00263         Pentagram::Font *font = getFont();
00264 
00265         int tx, ty;
00266         unsigned int remaining;
00267         font->getTextSize(text.substr(current_start), tx, ty, remaining,
00268                                           targetwidth, targetheight, textalign, true);
00269 
00270         // Y offset is always baseline
00271         dims.y = -font->getBaseline();
00272         dims.w = tx;
00273         dims.h = ty;
00274         current_end = current_start + remaining;
00275 
00276         return true;
00277 }
00278 
00279 
00280 // COLOURLESS PROTECTION

Generated on Fri Jul 27 22:27:42 2007 for pentagram by  doxygen 1.4.7