Initial commit
This commit is contained in:
383
engines/ultima/ultima8/gfx/fonts/font.cpp
Normal file
383
engines/ultima/ultima8/gfx/fonts/font.cpp
Normal file
@@ -0,0 +1,383 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima.h"
|
||||
#include "ultima/ultima8/misc/debugger.h"
|
||||
#include "ultima/ultima8/misc/common_types.h"
|
||||
#include "ultima/ultima8/gfx/fonts/font.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
Font::Font() : _highRes(false) {
|
||||
}
|
||||
|
||||
|
||||
Font::~Font() {
|
||||
}
|
||||
|
||||
|
||||
void Font::getTextSize(const Std::string &text,
|
||||
int32 &resultwidth, int32 &resultheight,
|
||||
unsigned int &remaining,
|
||||
int32 width, int32 height, TextAlign align,
|
||||
bool u8specials, bool pagebreaks) {
|
||||
Std::list<PositionedText> tmp;
|
||||
tmp = typesetText<Traits>(this, text, remaining,
|
||||
width, height, align, u8specials, pagebreaks,
|
||||
resultwidth, resultheight);
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
bool Font::Traits::canBreakAfter(Std::string::const_iterator &i) {
|
||||
// It's not really relevant what we do here, because this probably will
|
||||
// not be used at normal font sizes.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
bool Font::SJISTraits::canBreakAfter(Std::string::const_iterator &i) {
|
||||
Std::string::const_iterator j = i;
|
||||
uint32 u1 = unicode(j);
|
||||
|
||||
// See: https://wiki.wesnoth.org/index.php?title=JapaneseTranslation&oldid=23480#Word-Wrapping
|
||||
// and: https://ja.wikipedia.org/wiki/%E7%A6%81%E5%89%87
|
||||
|
||||
switch (u1) {
|
||||
case 0xff08:
|
||||
case 0x3014:
|
||||
case 0xff3b:
|
||||
case 0xff5b:
|
||||
case 0x3008:
|
||||
case 0x300a:
|
||||
case 0x300c:
|
||||
case 0x300e:
|
||||
case 0x3010:
|
||||
case 0x2018:
|
||||
case 0x201c:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint32 u2 = unicode(j);
|
||||
switch (u2) {
|
||||
case 0x3001:
|
||||
case 0x3002:
|
||||
case 0xff0c:
|
||||
case 0xff0e:
|
||||
case 0xff09:
|
||||
case 0x3015:
|
||||
case 0xff3d:
|
||||
case 0xff5d:
|
||||
case 0x3009:
|
||||
case 0x300b:
|
||||
case 0x300d:
|
||||
case 0x300f:
|
||||
case 0x3011:
|
||||
case 0x2019:
|
||||
case 0x201d:
|
||||
case 0x309d:
|
||||
case 0x309e:
|
||||
case 0x30fd:
|
||||
case 0x30fe:
|
||||
case 0x3005:
|
||||
case 0xff1f:
|
||||
case 0xff01:
|
||||
case 0xff1a:
|
||||
case 0xff1b:
|
||||
case 0x3041:
|
||||
case 0x3043:
|
||||
case 0x3045:
|
||||
case 0x3047:
|
||||
case 0x3049:
|
||||
case 0x3083:
|
||||
case 0x3085:
|
||||
case 0x3087:
|
||||
case 0x308e:
|
||||
case 0x30a1:
|
||||
case 0x30a3:
|
||||
case 0x30a5:
|
||||
case 0x30a7:
|
||||
case 0x30a9:
|
||||
case 0x30e3:
|
||||
case 0x30e5:
|
||||
case 0x30e7:
|
||||
case 0x30ee:
|
||||
case 0x3063:
|
||||
case 0x30f5:
|
||||
case 0x30c3:
|
||||
case 0x30f6:
|
||||
case 0x30fb:
|
||||
case 0x2026:
|
||||
case 0x30fc:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Also don't allow breaking between roman characters
|
||||
if (((u1 >= 'A' && u1 <= 'Z') || (u1 >= 'a' && u1 <= 'z')) &&
|
||||
((u2 >= 'A' && u2 <= 'Z') || (u2 >= 'a' && u2 <= 'z'))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static void findWordEnd(const Std::string &text,
|
||||
Std::string::const_iterator &iter, bool u8specials) {
|
||||
while (iter != text.end()) {
|
||||
if (T::isSpace(iter, u8specials)) return;
|
||||
T::advance(iter);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static void passSpace(const Std::string &text,
|
||||
Std::string::const_iterator &iter, bool u8specials) {
|
||||
while (iter != text.end()) {
|
||||
if (!T::isSpace(iter, u8specials)) return;
|
||||
T::advance(iter);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Special characters in U8:
|
||||
|
||||
@ = bullet for conversation options
|
||||
~ = line break
|
||||
% = tab
|
||||
* = line break on graves and plaques, possibly page break in books
|
||||
CHECKME: any others? (page breaks for books?)
|
||||
|
||||
*/
|
||||
|
||||
template<class T>
|
||||
Std::list<PositionedText> typesetText(Font *font,
|
||||
const Std::string &text, unsigned int &remaining, int32 width, int32 height,
|
||||
Font::TextAlign align, bool u8specials, bool pagebreaks, int32 &resultwidth,
|
||||
int32 &resultheight, Std::string::size_type cursor) {
|
||||
|
||||
debugC(kDebugGraphics, "typeset (%d, %d) %s", width, height, text.c_str());
|
||||
|
||||
// be optimistic and assume everything will fit
|
||||
remaining = text.size();
|
||||
|
||||
Std::string curline;
|
||||
|
||||
int totalwidth = 0;
|
||||
int totalheight = 0;
|
||||
|
||||
Std::list<PositionedText> lines;
|
||||
PositionedText line;
|
||||
|
||||
Std::string::const_iterator iter = text.begin();
|
||||
Std::string::const_iterator cursoriter = text.begin();
|
||||
if (cursor != Std::string::npos) cursoriter += cursor;
|
||||
Std::string::const_iterator curlinestart = text.begin();
|
||||
|
||||
bool breakhere = false;
|
||||
while (true) {
|
||||
if (iter == text.end() || breakhere || T::isBreak(iter, u8specials)) {
|
||||
// break here
|
||||
bool atpagebreak = pagebreaks && T::isPageBreak(iter, u8specials);
|
||||
int32 stringwidth = 0, stringheight = 0;
|
||||
font->getStringSize(curline, stringwidth, stringheight);
|
||||
line._dims.left = 0;
|
||||
line._dims.top = totalheight;
|
||||
line._dims.setWidth(stringwidth);
|
||||
line._dims.setHeight(stringheight);
|
||||
line._text = curline;
|
||||
line._cursor = Std::string::npos;
|
||||
if (cursor != Std::string::npos && cursoriter >= curlinestart &&
|
||||
(cursoriter < iter || (!breakhere && cursoriter == iter))) {
|
||||
line._cursor = cursoriter - curlinestart;
|
||||
if (line._dims.width() == 0) {
|
||||
stringwidth = 2;
|
||||
line._dims.setWidth(stringwidth);
|
||||
}
|
||||
}
|
||||
lines.push_back(line);
|
||||
|
||||
if (stringwidth > totalwidth) totalwidth = stringwidth;
|
||||
totalheight += font->getBaselineSkip();
|
||||
|
||||
curline = "";
|
||||
|
||||
if (iter == text.end())
|
||||
break; // done
|
||||
|
||||
if (breakhere) {
|
||||
breakhere = false;
|
||||
curlinestart = iter;
|
||||
} else {
|
||||
T::advance(iter);
|
||||
curlinestart = iter;
|
||||
}
|
||||
|
||||
if (atpagebreak || (height != 0 && totalheight + font->getHeight() > height)) {
|
||||
// next line won't fit
|
||||
remaining = curlinestart - text.begin();
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// see if next word still fits on the current line
|
||||
Std::string::const_iterator nextword = iter;
|
||||
passSpace<T>(text, nextword, u8specials);
|
||||
|
||||
// process spaces
|
||||
bool foundLF = false;
|
||||
Std::string spaces;
|
||||
for (; iter < nextword; T::advance(iter)) {
|
||||
if (T::isBreak(iter, u8specials)) {
|
||||
foundLF = true;
|
||||
break;
|
||||
} else if (T::isTab(iter, u8specials)) {
|
||||
// ignore tabs at beginning of line when centered
|
||||
if (!(curline.empty() && align == Font::TEXT_CENTER))
|
||||
spaces.append(" ");
|
||||
} else if (!curline.empty()) {
|
||||
spaces.append(" ");
|
||||
}
|
||||
}
|
||||
// no next word?
|
||||
if (foundLF || nextword == text.end()) continue;
|
||||
|
||||
// process word
|
||||
Std::string::const_iterator endofnextword = iter;
|
||||
findWordEnd<T>(text, endofnextword, u8specials);
|
||||
int32 stringwidth = 0, stringheight = 0;
|
||||
Std::string newline = curline + spaces +
|
||||
text.substr(nextword - text.begin(), endofnextword - nextword);
|
||||
font->getStringSize(newline, stringwidth, stringheight);
|
||||
|
||||
// if not, break line before this word
|
||||
if (width != 0 && stringwidth > width) {
|
||||
if (!curline.empty()) {
|
||||
iter = nextword;
|
||||
} else {
|
||||
// word is longer than the line; have to break in mid-word
|
||||
// FIXME: this is rather inefficient; binary search?
|
||||
// FIXME: clean up...
|
||||
iter = nextword;
|
||||
Std::string::const_iterator saveiter = nextword; // Dummy initialization
|
||||
Std::string::const_iterator saveiter_fail;
|
||||
Std::string curline_fail;
|
||||
newline = spaces;
|
||||
bool breakok = true;
|
||||
int breakcount = -1;
|
||||
do {
|
||||
if (breakok) {
|
||||
curline = newline;
|
||||
saveiter = iter;
|
||||
breakcount++;
|
||||
}
|
||||
curline_fail = newline;
|
||||
saveiter_fail = iter;
|
||||
|
||||
if (iter == text.end()) break;
|
||||
|
||||
breakok = T::canBreakAfter(iter);
|
||||
|
||||
// try next character
|
||||
T::advance(iter);
|
||||
newline = spaces + text.substr(nextword - text.begin(),
|
||||
iter - nextword);
|
||||
font->getStringSize(newline, stringwidth, stringheight);
|
||||
} while (stringwidth <= width);
|
||||
if (breakcount > 0) {
|
||||
iter = saveiter;
|
||||
} else {
|
||||
iter = saveiter_fail;
|
||||
curline = curline_fail;
|
||||
}
|
||||
}
|
||||
breakhere = true;
|
||||
continue;
|
||||
} else {
|
||||
// copy next word into curline
|
||||
curline = newline;
|
||||
iter = endofnextword;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lines.size() == 1 && align == Font::TEXT_LEFT) {
|
||||
// only one line, so use the actual text width
|
||||
width = totalwidth;
|
||||
}
|
||||
|
||||
if (width != 0) totalwidth = width;
|
||||
|
||||
// adjust total height
|
||||
totalheight -= font->getBaselineSkip();
|
||||
totalheight += font->getHeight();
|
||||
|
||||
// fixup x coordinates of lines
|
||||
for (auto &l : lines) {
|
||||
switch (align) {
|
||||
case Font::TEXT_LEFT:
|
||||
break;
|
||||
case Font::TEXT_RIGHT:
|
||||
l._dims.moveTo(totalwidth - l._dims.width(), l._dims.top);
|
||||
break;
|
||||
case Font::TEXT_CENTER:
|
||||
l._dims.moveTo((totalwidth - l._dims.width()) / 2, l._dims.top);
|
||||
break;
|
||||
}
|
||||
|
||||
debugC(kDebugGraphics, "%d, %d, %d, %d: %s", l._dims.left, l._dims.top,
|
||||
l._dims.width(), l._dims.height(), l._text.c_str());
|
||||
}
|
||||
|
||||
resultwidth = totalwidth;
|
||||
resultheight = totalheight;
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
|
||||
// explicit instantiations
|
||||
template
|
||||
Std::list<PositionedText> typesetText<Font::Traits>
|
||||
(Font *font, const Std::string &text,
|
||||
unsigned int &remaining, int32 width, int32 height,
|
||||
Font::TextAlign align, bool u8specials, bool pagebreaks,
|
||||
int32 &resultwidth, int32 &resultheight, Std::string::size_type cursor);
|
||||
|
||||
template
|
||||
Std::list<PositionedText> typesetText<Font::SJISTraits>
|
||||
(Font *font, const Std::string &text,
|
||||
unsigned int &remaining, int32 width, int32 height,
|
||||
Font::TextAlign align, bool u8specials, bool pagebreaks,
|
||||
int32 &resultwidth, int32 &resultheight, Std::string::size_type cursor);
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
180
engines/ultima/ultima8/gfx/fonts/font.h
Normal file
180
engines/ultima/ultima8/gfx/fonts/font.h
Normal file
@@ -0,0 +1,180 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GFX_FONTS_FONT_H
|
||||
#define ULTIMA8_GFX_FONTS_FONT_H
|
||||
|
||||
#include "common/rect.h"
|
||||
|
||||
#include "ultima/shared/std/containers.h"
|
||||
#include "ultima/shared/std/string.h"
|
||||
#include "ultima/ultima8/misc/encoding.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class RenderedText;
|
||||
|
||||
struct PositionedText {
|
||||
Std::string _text;
|
||||
Common::Rect32 _dims;
|
||||
Std::string::size_type _cursor;
|
||||
};
|
||||
|
||||
class Font {
|
||||
public:
|
||||
Font();
|
||||
virtual ~Font();
|
||||
|
||||
enum TextAlign {
|
||||
TEXT_LEFT,
|
||||
TEXT_CENTER,
|
||||
TEXT_RIGHT
|
||||
};
|
||||
|
||||
//! get the height of the font
|
||||
virtual int getHeight() = 0;
|
||||
|
||||
//! get the baseline of the font (relative from the top)
|
||||
virtual int getBaseline() = 0;
|
||||
|
||||
//! get the baselineskip of the font (distance between two baselines)
|
||||
virtual int getBaselineSkip() = 0;
|
||||
|
||||
//! get the dimensions of a string (not containing any newlines)
|
||||
//! \param text The string
|
||||
//! \param width Returns the width
|
||||
//! \param height Returns the height
|
||||
virtual void getStringSize(const Std::string &text,
|
||||
int32 &width, int32 &height) = 0;
|
||||
|
||||
//! render a string
|
||||
//! \param text The text
|
||||
//! \param remaining Returns index of the first character not printed
|
||||
//! \param width The width of the target rectangle, or 0 for unlimited
|
||||
//! \param height The height of the target rectangle, or 0 for unlimited
|
||||
//! \param align Alignment of the text (left, right, center)
|
||||
//! \param u8specials If true, interpret the special characters U8 uses
|
||||
//! \param pagebreaks If true (and u8specials too), stop at U8 pagebreaks
|
||||
//! \return the rendered text in a RenderedText object
|
||||
virtual RenderedText *renderText(const Std::string &text,
|
||||
unsigned int &remaining, int32 width = 0, int32 height = 0,
|
||||
TextAlign align = TEXT_LEFT, bool u8specials = false,
|
||||
bool pagebreaks = false,
|
||||
Std::string::size_type cursor = Std::string::npos) = 0;
|
||||
|
||||
//! get the dimensions of a rendered string
|
||||
//! \param text The text
|
||||
//! \param resultwidth Returns the resulting width
|
||||
//! \param resultheight Returns the resulting height
|
||||
//! \param remaining Returns index of the first character not printed
|
||||
//! \param width The width of the target rectangle, or 0 for unlimited
|
||||
//! \param height The height of the target rectangle, or 0 for unlimited
|
||||
//! \param align Alignment of the text (left, right, center)
|
||||
//! \param u8specials If true, interpret the special characters U8 uses
|
||||
//! \param pagebreaks If true (and u8specials too), stop at U8 pagebreaks
|
||||
virtual void getTextSize(const Std::string &text,
|
||||
int32 &resultwidth, int32 &resultheight, unsigned int &remaining,
|
||||
int32 width = 0, int32 height = 0, TextAlign align = TEXT_LEFT,
|
||||
bool u8specials = false, bool pagebreaks = false);
|
||||
|
||||
void setHighRes(bool hr) {
|
||||
_highRes = hr;
|
||||
}
|
||||
bool isHighRes() const {
|
||||
return _highRes;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool _highRes;
|
||||
|
||||
struct Traits {
|
||||
static bool isSpace(Std::string::const_iterator &i, bool u8specials) {
|
||||
char c = *i;
|
||||
return (c == ' ' || c == '\t' || c == '\n' || c == '\r' ||
|
||||
(u8specials && (c == '%' || c == '~' || c == '*' || c == '^')));
|
||||
}
|
||||
static bool isTab(Std::string::const_iterator &i, bool u8specials) {
|
||||
char c = *i;
|
||||
return (c == '\t' ||
|
||||
(u8specials && (c == '\t' || c == '%')));
|
||||
}
|
||||
static bool isBreak(Std::string::const_iterator &i, bool u8specials) {
|
||||
char c = *i;
|
||||
return (c == '\n' ||
|
||||
(u8specials && (c == '\n' || c == '~' || c == '*')));
|
||||
}
|
||||
static bool isPageBreak(Std::string::const_iterator &i, bool u8specials) {
|
||||
char c = *i;
|
||||
return (u8specials && c == '*');
|
||||
}
|
||||
static bool canBreakAfter(Std::string::const_iterator &i);
|
||||
static void advance(Std::string::const_iterator &i) {
|
||||
++i;
|
||||
}
|
||||
static Std::string::size_type length(const Std::string &t) {
|
||||
return t.size();
|
||||
}
|
||||
static uint32 unicode(Std::string::const_iterator &i) {
|
||||
return encoding[static_cast<uint8>(*i++)];
|
||||
}
|
||||
};
|
||||
struct SJISTraits : public Traits {
|
||||
static bool canBreakAfter(Std::string::const_iterator &i);
|
||||
static void advance(Std::string::const_iterator &i) {
|
||||
// FIXME: this can advance past the end of a malformed string
|
||||
uint8 c = *i;
|
||||
i++;
|
||||
if (c >= 0x80) i++;
|
||||
}
|
||||
static Std::string::size_type length(const Std::string &t) {
|
||||
Std::string::size_type l = 0;
|
||||
Std::string::const_iterator iter = t.begin();
|
||||
while (iter != t.end()) {
|
||||
advance(iter);
|
||||
l++;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
static uint32 unicode(Std::string::const_iterator &i) {
|
||||
uint16 s = static_cast<uint8>(*i);
|
||||
i++;
|
||||
if (s >= 0x80) {
|
||||
uint16 t = static_cast<uint8>(*i++);
|
||||
s |= (t << 8);
|
||||
}
|
||||
return shiftjis_to_unicode(s);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
Std::list<PositionedText> typesetText(Font *font,
|
||||
const Std::string &text, unsigned int &remaining,
|
||||
int32 width, int32 height, Font::TextAlign align,
|
||||
bool u8specials, bool pagebreaks,
|
||||
int32 &resultwidth, int32 &resultheight,
|
||||
Std::string::size_type cursor = Std::string::npos);
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
212
engines/ultima/ultima8/gfx/fonts/font_manager.cpp
Normal file
212
engines/ultima/ultima8/gfx/fonts/font_manager.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/file.h"
|
||||
|
||||
#include "ultima/ultima.h"
|
||||
#include "ultima/ultima8/misc/common_types.h"
|
||||
|
||||
#include "ultima/ultima8/gfx/fonts/font_manager.h"
|
||||
|
||||
#include "ultima/ultima8/games/game_data.h"
|
||||
#include "ultima/ultima8/gfx/fonts/shape_font.h"
|
||||
#include "ultima/ultima8/gfx/fonts/font_shape_archive.h"
|
||||
#include "ultima/ultima8/gfx/fonts/tt_font.h"
|
||||
#include "ultima/ultima8/gfx/fonts/jp_font.h"
|
||||
#include "ultima/ultima8/gfx/palette.h"
|
||||
#include "ultima/ultima8/gfx/palette_manager.h"
|
||||
|
||||
#include "graphics/fonts/ttf.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
FontManager *FontManager::_fontManager = nullptr;
|
||||
|
||||
FontManager::FontManager() {
|
||||
debug(1, "Creating Font Manager...");
|
||||
|
||||
_fontManager = this;
|
||||
|
||||
ConfMan.registerDefault("font_highres", true);
|
||||
}
|
||||
|
||||
FontManager::~FontManager() {
|
||||
debug(1, "Destroying Font Manager...");
|
||||
|
||||
resetGameFonts();
|
||||
|
||||
assert(_fontManager == this);
|
||||
_fontManager = nullptr;
|
||||
}
|
||||
|
||||
// Reset the font manager
|
||||
void FontManager::resetGameFonts() {
|
||||
for (unsigned int i = 0; i < _overrides.size(); ++i)
|
||||
delete _overrides[i];
|
||||
_overrides.clear();
|
||||
|
||||
for (unsigned int i = 0; i < _ttFonts.size(); ++i)
|
||||
delete _ttFonts[i];
|
||||
_ttFonts.clear();
|
||||
|
||||
for (auto &i : _ttfFonts)
|
||||
delete i._value;
|
||||
_ttfFonts.clear();}
|
||||
|
||||
Font *FontManager::getGameFont(unsigned int fontnum,
|
||||
bool allowOverride) {
|
||||
if (allowOverride && fontnum < _overrides.size() && _overrides[fontnum])
|
||||
return _overrides[fontnum];
|
||||
|
||||
return GameData::get_instance()->getFonts()->getFont(fontnum);
|
||||
}
|
||||
|
||||
Font *FontManager::getTTFont(unsigned int fontnum) {
|
||||
if (fontnum >= _ttFonts.size())
|
||||
return nullptr;
|
||||
return _ttFonts[fontnum];
|
||||
}
|
||||
|
||||
|
||||
Graphics::Font *FontManager::getTTF_Font(const Common::Path &filename, int pointsize, bool antialiasing) {
|
||||
#ifdef USE_FREETYPE2
|
||||
TTFId id;
|
||||
id._filename = filename;
|
||||
id._pointSize = pointsize;
|
||||
|
||||
TTFFonts::iterator iter;
|
||||
iter = _ttfFonts.find(id);
|
||||
|
||||
if (iter != _ttfFonts.end())
|
||||
return iter->_value;
|
||||
|
||||
Common::File* fontids = new Common::File();
|
||||
if (!fontids->open(filename)) {
|
||||
warning("Failed to open TTF: %s", filename.toString().c_str());
|
||||
delete fontids;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// open font using ScummVM TTF API
|
||||
// Note: The RWops and ReadStream will be deleted by the TTF_Font
|
||||
Graphics::TTFRenderMode mode = antialiasing ? Graphics::kTTFRenderModeNormal : Graphics::kTTFRenderModeMonochrome;
|
||||
Graphics::Font *font = Graphics::loadTTFFont(fontids, DisposeAfterUse::YES, pointsize, Graphics::kTTFSizeModeCharacter, 0, 0, mode, 0, false);
|
||||
|
||||
if (!font) {
|
||||
warning("Failed to open TTF: %s", filename.toString().c_str());
|
||||
delete fontids;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
_ttfFonts[id] = font;
|
||||
|
||||
debugC(kDebugGraphics, "Opened TTF: %s.", filename.toString().c_str());
|
||||
return font;
|
||||
#else // !USE_FREETYPE2
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void FontManager::setOverride(unsigned int fontnum, Font *newFont) {
|
||||
if (fontnum >= _overrides.size())
|
||||
_overrides.resize(fontnum + 1);
|
||||
|
||||
if (_overrides[fontnum])
|
||||
delete _overrides[fontnum];
|
||||
|
||||
_overrides[fontnum] = newFont;
|
||||
}
|
||||
|
||||
|
||||
bool FontManager::addTTFOverride(unsigned int fontnum, const Common::Path &filename,
|
||||
int pointsize, uint32 rgb, int bordersize,
|
||||
bool SJIS) {
|
||||
bool antialiasing = ConfMan.getBool("font_antialiasing");
|
||||
Graphics::Font *f = getTTF_Font(filename, pointsize, antialiasing);
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
TTFont *font = new TTFont(f, rgb, bordersize, antialiasing, SJIS);
|
||||
bool highres = ConfMan.getBool("font_highres");
|
||||
font->setHighRes(highres);
|
||||
|
||||
setOverride(fontnum, font);
|
||||
|
||||
debugC(kDebugGraphics, "Added TTF override for font %u", fontnum);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FontManager::addJPOverride(unsigned int fontnum,
|
||||
unsigned int jpfont, uint32 rgb) {
|
||||
ShapeFont *jf = dynamic_cast<ShapeFont *>(GameData::get_instance()->getFonts()->getFont(jpfont));
|
||||
if (!jf)
|
||||
return false;
|
||||
|
||||
JPFont *font = new JPFont(jf, fontnum);
|
||||
|
||||
setOverride(fontnum, font);
|
||||
|
||||
PaletteManager *palman = PaletteManager::get_instance();
|
||||
PaletteManager::PalIndex fontpal = static_cast<PaletteManager::PalIndex>
|
||||
(PaletteManager::Pal_JPFontStart + fontnum);
|
||||
palman->duplicate(PaletteManager::Pal_Game, fontpal);
|
||||
Palette *pal = palman->getPalette(fontpal);
|
||||
// TODO: maybe a small gradient
|
||||
// the main text uses index 3
|
||||
// indices 1,2 and 3 are in use for the bullets for conversation options
|
||||
for (int i = 1; i < 4; ++i) {
|
||||
pal->set(i, (rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, (rgb) & 0xFF);
|
||||
}
|
||||
palman->updatedPalette(fontpal);
|
||||
|
||||
debugC(kDebugGraphics, "Added JP override for font %u", fontnum);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FontManager::loadTTFont(unsigned int fontnum, const Common::Path &filename,
|
||||
int pointsize, uint32 rgb, int bordersize) {
|
||||
bool antialiasing = ConfMan.getBool("font_antialiasing");
|
||||
Graphics::Font *f = getTTF_Font(filename, pointsize, antialiasing);
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
TTFont *font = new TTFont(f, rgb, bordersize, antialiasing, false);
|
||||
|
||||
// TODO: check if this is indeed what we want for non-gamefonts
|
||||
bool highres = ConfMan.getBool("font_highres");
|
||||
font->setHighRes(highres);
|
||||
|
||||
if (fontnum >= _ttFonts.size())
|
||||
_ttFonts.resize(fontnum + 1);
|
||||
|
||||
if (_ttFonts[fontnum])
|
||||
delete _ttFonts[fontnum];
|
||||
|
||||
_ttFonts[fontnum] = font;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
126
engines/ultima/ultima8/gfx/fonts/font_manager.h
Normal file
126
engines/ultima/ultima8/gfx/fonts/font_manager.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GFX_FONTS_FONTMANAGER_H
|
||||
#define ULTIMA8_GFX_FONTS_FONTMANAGER_H
|
||||
|
||||
#include "ultima/shared/std/containers.h"
|
||||
#include "ultima/shared/std/string.h"
|
||||
#include "common/path.h"
|
||||
#include "graphics/font.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class Font;
|
||||
|
||||
// This is TTF_Font struct
|
||||
typedef struct _TTF_Font TTF_Font;
|
||||
|
||||
class TTFont;
|
||||
|
||||
|
||||
class FontManager {
|
||||
private:
|
||||
struct TTFId {
|
||||
Common::Path _filename;
|
||||
int _pointSize;
|
||||
bool operator<(const TTFId &other) const {
|
||||
return (_pointSize < other._pointSize ||
|
||||
(_pointSize == other._pointSize &&
|
||||
_filename < other._filename));
|
||||
}
|
||||
};
|
||||
|
||||
struct TTFHash {
|
||||
uint operator()(const TTFId &x) const {
|
||||
// TODO: See if something better can be used as a hash key
|
||||
int64 val = (int64)&x;
|
||||
return (uint)val;
|
||||
}
|
||||
};
|
||||
struct TTFEqual {
|
||||
bool operator()(const TTFId &x, const TTFId &y) const {
|
||||
return x._filename == y._filename && x._pointSize == y._pointSize;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Common::HashMap<TTFId, Graphics::Font *, TTFHash, TTFEqual> TTFFonts;
|
||||
TTFFonts _ttfFonts;
|
||||
|
||||
//! Get a (possibly cached) TTF_Font structure for filename/pointsize,
|
||||
//! loading it if necessary.
|
||||
Graphics::Font *getTTF_Font(const Common::Path &filename, int pointsize, bool antialiasing);
|
||||
|
||||
//! Override fontnum with specified font
|
||||
void setOverride(unsigned int fontnum, Font *newFont);
|
||||
|
||||
Std::vector<Font *> _overrides;
|
||||
|
||||
Std::vector<Font *> _ttFonts;
|
||||
|
||||
static FontManager *_fontManager;
|
||||
public:
|
||||
FontManager();
|
||||
~FontManager();
|
||||
|
||||
static FontManager *get_instance() {
|
||||
return _fontManager;
|
||||
}
|
||||
|
||||
//! get a Font by fontnum (for game fonts)
|
||||
//! \param fontnum the number of the font
|
||||
//! \param allowOverride if true, allow an override font to be used
|
||||
Font *getGameFont(unsigned int fontnum,
|
||||
bool allowOverride = false);
|
||||
|
||||
//! get a TTF font (for non-game fonts)
|
||||
Font *getTTFont(unsigned int ttfnum);
|
||||
|
||||
//! override a game font with a TTF.
|
||||
//! \param fontnum the font to override
|
||||
//! \param filename the filename of the TTF
|
||||
//! \param pointsize the pointsize to use
|
||||
//! \param rgb the color to use for the font
|
||||
//! \param bordersize the size of the black border to add
|
||||
//! \param SJIS true for a Japanese game font
|
||||
bool addTTFOverride(unsigned int fontnum, const Common::Path &filename,
|
||||
int pointsize, uint32 rgb, int bordersize,
|
||||
bool SJIS = false);
|
||||
|
||||
//! override a game font with a Japanese font.
|
||||
//! \param fontnum the font to override
|
||||
//! \param jpfont the fontnum of the Japanese font to use
|
||||
//! \param rgb the color to use
|
||||
bool addJPOverride(unsigned int fontnum, unsigned int jpfont, uint32 rgb);
|
||||
|
||||
//! load a TTF (for non-game fonts)
|
||||
bool loadTTFont(unsigned int ttfnum, const Common::Path &filename,
|
||||
int pointsize, uint32 rgb, int bordersize);
|
||||
|
||||
// Reset the game fonts
|
||||
void resetGameFonts();
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima // End of namespace Ultima8
|
||||
|
||||
#endif
|
||||
90
engines/ultima/ultima8/gfx/fonts/font_shape_archive.cpp
Normal file
90
engines/ultima/ultima8/gfx/fonts/font_shape_archive.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima8/misc/debugger.h"
|
||||
|
||||
#include "ultima/ultima8/gfx/fonts/font_shape_archive.h"
|
||||
#include "ultima/ultima8/misc/util.h"
|
||||
#include "ultima/ultima8/gfx/fonts/shape_font.h"
|
||||
#include "ultima/ultima8/conf/config_file_manager.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
ShapeFont *FontShapeArchive::getFont(uint32 fontnum) {
|
||||
return dynamic_cast<ShapeFont *>(getShape(fontnum));
|
||||
}
|
||||
|
||||
void FontShapeArchive::cache(uint32 shapenum) {
|
||||
if (shapenum >= _count) return;
|
||||
if (_shapes.empty()) _shapes.resize(_count);
|
||||
|
||||
if (_shapes[shapenum]) return;
|
||||
|
||||
uint32 shpsize;
|
||||
uint8 *data = getRawObject(shapenum, &shpsize);
|
||||
|
||||
if (!data || shpsize == 0) return;
|
||||
|
||||
// Auto detect format
|
||||
if (!_format)
|
||||
_format = Shape::DetectShapeFormat(data, shpsize);
|
||||
|
||||
if (!_format) {
|
||||
delete [] data;
|
||||
warning("Unable to detect shape format for flex.");
|
||||
return;
|
||||
}
|
||||
|
||||
Shape *shape = new ShapeFont(data, shpsize, _format, _id, shapenum);
|
||||
if (_palette) shape->setPalette(_palette);
|
||||
|
||||
_shapes[shapenum] = shape;
|
||||
}
|
||||
|
||||
void FontShapeArchive::setHVLeads() {
|
||||
ConfigFileManager *config = ConfigFileManager::get_instance();
|
||||
|
||||
KeyMap leadkeyvals = config->listKeyValues("game", "fontleads");
|
||||
for (const auto &i : leadkeyvals) {
|
||||
int fontnum = atoi(i._key.c_str());
|
||||
Std::string leaddesc = i._value;
|
||||
|
||||
Std::vector<Std::string> vals;
|
||||
SplitString(leaddesc, ',', vals);
|
||||
if (vals.size() != 2) {
|
||||
warning("Invalid hlead/vlead description: %s", leaddesc.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
int hlead = atoi(vals[0].c_str());
|
||||
int vlead = atoi(vals[1].c_str());
|
||||
|
||||
ShapeFont *font = getFont(fontnum);
|
||||
if (font) {
|
||||
font->setHLead(hlead);
|
||||
font->setVLead(vlead);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
54
engines/ultima/ultima8/gfx/fonts/font_shape_archive.h
Normal file
54
engines/ultima/ultima8/gfx/fonts/font_shape_archive.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GFX_FONTS_FONTSHAPEARCHIVE_H
|
||||
#define ULTIMA8_GFX_FONTS_FONTSHAPEARCHIVE_H
|
||||
|
||||
#include "ultima/ultima8/gfx/shape_archive.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class ShapeFont;
|
||||
|
||||
class FontShapeArchive : public ShapeArchive {
|
||||
public:
|
||||
FontShapeArchive(uint16 id, Palette *pal = 0,
|
||||
const ConvertShapeFormat *format = 0)
|
||||
: ShapeArchive(id, pal, format) { }
|
||||
FontShapeArchive(Common::SeekableReadStream *rs, uint16 id, Palette *pal = 0,
|
||||
const ConvertShapeFormat *format = 0)
|
||||
: ShapeArchive(rs, id, pal, format) { }
|
||||
|
||||
~FontShapeArchive() override { }
|
||||
|
||||
//! load HVLeads from u8.ini
|
||||
void setHVLeads();
|
||||
|
||||
ShapeFont *getFont(uint32 fontnum);
|
||||
|
||||
void cache(uint32 fontnum) override;
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
105
engines/ultima/ultima8/gfx/fonts/jp_font.cpp
Normal file
105
engines/ultima/ultima8/gfx/fonts/jp_font.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima8/misc/debugger.h"
|
||||
#include "ultima/ultima8/misc/common_types.h"
|
||||
#include "ultima/ultima8/gfx/fonts/jp_font.h"
|
||||
#include "ultima/ultima8/gfx/fonts/shape_font.h"
|
||||
#include "ultima/ultima8/gfx/shape_frame.h"
|
||||
#include "ultima/ultima8/gfx/fonts/jp_rendered_text.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
JPFont::JPFont(ShapeFont *jpfont, unsigned int fontnum)
|
||||
: _fontNum(fontnum), _shapeFont(jpfont) {
|
||||
assert(_shapeFont->frameCount() > 256);
|
||||
}
|
||||
|
||||
|
||||
JPFont::~JPFont() {
|
||||
}
|
||||
|
||||
int JPFont::getWidth(int c) {
|
||||
return _shapeFont->getFrame(c)->_width;
|
||||
}
|
||||
|
||||
int JPFont::getHeight() {
|
||||
return _shapeFont->getHeight();
|
||||
}
|
||||
|
||||
int JPFont::getBaseline() {
|
||||
return _shapeFont->getBaseline();
|
||||
}
|
||||
|
||||
int JPFont::getBaselineSkip() {
|
||||
return _shapeFont->getBaselineSkip();
|
||||
}
|
||||
|
||||
|
||||
void JPFont::getStringSize(const Std::string &text, int32 &width, int32 &height) {
|
||||
int hlead = _shapeFont->getHlead();
|
||||
width = hlead;
|
||||
height = getHeight();
|
||||
|
||||
for (unsigned int i = 0; i < text.size(); ++i) {
|
||||
if (text[i] == '\n' || text[i] == '\r') {
|
||||
// ignore
|
||||
} else {
|
||||
uint16 sjis = text[i] & 0xFF;
|
||||
if (sjis >= 0x80) {
|
||||
uint16 t = text[++i] & 0xFF;
|
||||
sjis += (t << 8);
|
||||
}
|
||||
width += getWidth(shiftjis_to_ultima8(sjis)) - hlead;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JPFont::getTextSize(const Std::string &text,
|
||||
int32 &resultwidth, int32 &resultheight,
|
||||
unsigned int &remaining,
|
||||
int32 width, int32 height, TextAlign align,
|
||||
bool u8specials, bool pagebreaks) {
|
||||
Std::list<PositionedText> tmp;
|
||||
tmp = typesetText<SJISTraits>(this, text, remaining,
|
||||
width, height, align, u8specials, pagebreaks,
|
||||
resultwidth, resultheight);
|
||||
}
|
||||
|
||||
RenderedText *JPFont::renderText(const Std::string &text,
|
||||
unsigned int &remaining,
|
||||
int32 width, int32 height, TextAlign align,
|
||||
bool u8specials, bool pagebreaks,
|
||||
Std::string::size_type cursor) {
|
||||
int32 resultwidth, resultheight;
|
||||
Std::list<PositionedText> lines;
|
||||
lines = typesetText<SJISTraits>(this, text, remaining,
|
||||
width, height, align, u8specials, pagebreaks,
|
||||
resultwidth, resultheight,
|
||||
cursor);
|
||||
|
||||
return new JPRenderedText(lines, resultwidth, resultheight,
|
||||
_shapeFont->getVlead(), _shapeFont, _fontNum);
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
65
engines/ultima/ultima8/gfx/fonts/jp_font.h
Normal file
65
engines/ultima/ultima8/gfx/fonts/jp_font.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GFX_FONTS_JPFONT_H
|
||||
#define ULTIMA8_GFX_FONTS_JPFONT_H
|
||||
|
||||
#include "ultima/ultima8/gfx/fonts/font.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class ShapeFont;
|
||||
|
||||
class JPFont : public Font {
|
||||
public:
|
||||
JPFont(ShapeFont *jpfont, unsigned int fontnum);
|
||||
~JPFont() override;
|
||||
|
||||
int getWidth(int c);
|
||||
|
||||
int getHeight() override;
|
||||
int getBaseline() override;
|
||||
int getBaselineSkip() override;
|
||||
|
||||
void getStringSize(const Std::string &text,
|
||||
int32 &width, int32 &height) override;
|
||||
void getTextSize(const Std::string &text, int32 &resultwidth,
|
||||
int32 &resultheight, unsigned int &remaining, int32 width = 0,
|
||||
int32 height = 0, TextAlign align = TEXT_LEFT,
|
||||
bool u8specials = false, bool pagebreaks = false) override;
|
||||
|
||||
RenderedText *renderText(const Std::string &text,
|
||||
unsigned int &remaining, int32 width = 0, int32 height = 0,
|
||||
TextAlign align = TEXT_LEFT, bool u8specials = false,
|
||||
bool pagebreaks = false,
|
||||
Std::string::size_type cursor = Std::string::npos) override;
|
||||
|
||||
protected:
|
||||
|
||||
unsigned int _fontNum;
|
||||
ShapeFont *_shapeFont;
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
127
engines/ultima/ultima8/gfx/fonts/jp_rendered_text.cpp
Normal file
127
engines/ultima/ultima8/gfx/fonts/jp_rendered_text.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima8/misc/debugger.h"
|
||||
#include "ultima/ultima8/misc/common_types.h"
|
||||
#include "ultima/ultima8/gfx/fonts/jp_rendered_text.h"
|
||||
#include "ultima/ultima8/gfx/fonts/shape_font.h"
|
||||
#include "ultima/ultima8/gfx/render_surface.h"
|
||||
#include "ultima/ultima8/gfx/shape_frame.h"
|
||||
#include "ultima/ultima8/gfx/palette_manager.h"
|
||||
#include "ultima/ultima8/gfx/texture.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
JPRenderedText::JPRenderedText(Std::list<PositionedText> &lines, int width, int height,
|
||||
int vLead, ShapeFont *font, unsigned int fontNum)
|
||||
: _lines(lines), _font(font), _fontNum(fontNum) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
_vLead = vLead;
|
||||
}
|
||||
|
||||
JPRenderedText::~JPRenderedText() {
|
||||
}
|
||||
|
||||
void JPRenderedText::draw(RenderSurface *surface, int x, int y, bool /*destmasked*/) {
|
||||
// TODO support masking here??
|
||||
|
||||
PaletteManager *palman = PaletteManager::get_instance();
|
||||
PaletteManager::PalIndex fontpal = static_cast<PaletteManager::PalIndex>
|
||||
(PaletteManager::Pal_JPFontStart + _fontNum);
|
||||
Palette *pal = palman->getPalette(fontpal);
|
||||
const Palette *savepal = _font->getPalette();
|
||||
_font->setPalette(pal);
|
||||
|
||||
uint32 color = TEX32_PACK_RGB(0, 0, 0);
|
||||
|
||||
for (const auto &line : _lines) {
|
||||
int line_x = x + line._dims.left;
|
||||
int line_y = y + line._dims.top;
|
||||
|
||||
size_t textsize = line._text.size();
|
||||
|
||||
for (size_t i = 0; i < textsize; ++i) {
|
||||
uint16 sjis = line._text[i] & 0xFF;
|
||||
if (sjis >= 0x80) {
|
||||
uint16 t = line._text[++i] & 0xFF;
|
||||
sjis += (t << 8);
|
||||
}
|
||||
uint16 u8char = shiftjis_to_ultima8(sjis);
|
||||
surface->Paint(_font, u8char, line_x, line_y);
|
||||
|
||||
if (i == line._cursor) {
|
||||
surface->fill32(color, line_x, line_y - _font->getBaseline(),
|
||||
1, line._dims.height());
|
||||
}
|
||||
|
||||
line_x += (_font->getFrame(u8char))->_width - _font->getHlead();
|
||||
}
|
||||
|
||||
if (line._cursor == textsize) {
|
||||
surface->fill32(color, line_x, line_y - _font->getBaseline(),
|
||||
1, line._dims.height());
|
||||
}
|
||||
}
|
||||
|
||||
_font->setPalette(savepal);
|
||||
}
|
||||
|
||||
void JPRenderedText::drawBlended(RenderSurface *surface, int x, int y,
|
||||
uint32 col, bool /*destmasked*/) {
|
||||
// TODO Support masking here??
|
||||
|
||||
PaletteManager *palman = PaletteManager::get_instance();
|
||||
PaletteManager::PalIndex fontpal = static_cast<PaletteManager::PalIndex>
|
||||
(PaletteManager::Pal_JPFontStart + _fontNum);
|
||||
Palette *pal = palman->getPalette(fontpal);
|
||||
const Palette *savepal = _font->getPalette();
|
||||
_font->setPalette(pal);
|
||||
|
||||
Std::list<PositionedText>::const_iterator iter;
|
||||
|
||||
for (const auto &line : _lines) {
|
||||
int line_x = x + line._dims.left;
|
||||
int line_y = y + line._dims.top;
|
||||
|
||||
size_t textsize = line._text.size();
|
||||
|
||||
for (size_t i = 0; i < textsize; ++i) {
|
||||
uint16 sjis = line._text[i] & 0xFF;
|
||||
if (sjis >= 0x80) {
|
||||
uint16 t = line._text[++i] & 0xFF;
|
||||
sjis += (t << 8);
|
||||
}
|
||||
uint16 u8char = shiftjis_to_ultima8(sjis);
|
||||
|
||||
surface->PaintHighlight(_font, u8char, line_x, line_y,
|
||||
false, false, col);
|
||||
line_x += (_font->getFrame(u8char))->_width - _font->getHlead();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_font->setPalette(savepal);
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
52
engines/ultima/ultima8/gfx/fonts/jp_rendered_text.h
Normal file
52
engines/ultima/ultima8/gfx/fonts/jp_rendered_text.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GFX_FONTS_JPRENDEREDTEXT_H
|
||||
#define ULTIMA8_GFX_FONTS_JPRENDEREDTEXT_H
|
||||
|
||||
#include "ultima/ultima8/gfx/fonts/rendered_text.h"
|
||||
#include "ultima/ultima8/gfx/fonts/font.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class ShapeFont;
|
||||
|
||||
class JPRenderedText : public RenderedText {
|
||||
public:
|
||||
JPRenderedText(Std::list<PositionedText> &lines,
|
||||
int width, int height, int vlead, ShapeFont *font,
|
||||
unsigned int fontnum);
|
||||
~JPRenderedText() override;
|
||||
|
||||
void draw(RenderSurface *surface, int x, int y, bool destmasked = false) override;
|
||||
void drawBlended(RenderSurface *surface, int x, int y, uint32 col, bool destmasked = false) override;
|
||||
|
||||
protected:
|
||||
Std::list<PositionedText> _lines;
|
||||
ShapeFont *_font;
|
||||
unsigned int _fontNum;
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
37
engines/ultima/ultima8/gfx/fonts/rendered_text.cpp
Normal file
37
engines/ultima/ultima8/gfx/fonts/rendered_text.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima8/misc/common_types.h"
|
||||
#include "ultima/ultima8/gfx/fonts/rendered_text.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
RenderedText::RenderedText()
|
||||
: _width(-1), _height(-1), _vLead(0) {
|
||||
}
|
||||
|
||||
|
||||
RenderedText::~RenderedText() {
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
65
engines/ultima/ultima8/gfx/fonts/rendered_text.h
Normal file
65
engines/ultima/ultima8/gfx/fonts/rendered_text.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GFX_FONTS_RENDEREDTEXT_H
|
||||
#define ULTIMA8_GFX_FONTS_RENDEREDTEXT_H
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class RenderSurface;
|
||||
|
||||
class RenderedText {
|
||||
public:
|
||||
RenderedText();
|
||||
virtual ~RenderedText();
|
||||
|
||||
//! Draw self to a rendersurface.
|
||||
//! \param surface The surface to draw to
|
||||
//! \param x X coordinate of target
|
||||
//! \param y Y coordinate of target. This will be the top baseline.
|
||||
virtual void draw(RenderSurface *surface, int x, int y, bool destmasked = false) = 0;
|
||||
|
||||
//! Draw self to a rendersurface blended (0xAABBGGRR, alpha is blend level)
|
||||
virtual void drawBlended(RenderSurface *surface, int x, int y, uint32 col, bool destmasked = false) = 0;
|
||||
|
||||
//! Get dimensions.
|
||||
//! \param x Returns the width
|
||||
//! \param y Returns the height
|
||||
virtual void getSize(int &x, int &y) const {
|
||||
x = _width;
|
||||
y = _height;
|
||||
}
|
||||
|
||||
//! Get vlead
|
||||
virtual int getVlead() {
|
||||
return _vLead;
|
||||
}
|
||||
|
||||
protected:
|
||||
int _width, _height;
|
||||
int _vLead;
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
137
engines/ultima/ultima8/gfx/fonts/shape_font.cpp
Normal file
137
engines/ultima/ultima8/gfx/fonts/shape_font.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima8/misc/common_types.h"
|
||||
#include "ultima/ultima8/ultima8.h"
|
||||
#include "ultima/ultima8/gfx/fonts/shape_font.h"
|
||||
#include "ultima/ultima8/gfx/shape_frame.h"
|
||||
#include "ultima/ultima8/gfx/fonts/shape_rendered_text.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
ShapeFont::ShapeFont(const uint8 *data, uint32 size,
|
||||
const ConvertShapeFormat *format,
|
||||
const uint16 flexId, const uint32 shapeNum)
|
||||
: Font(), Shape(data, size, format, flexId, shapeNum),
|
||||
_height(0), _baseLine(0), _vLead(-1), _hLead(0) {
|
||||
_crusaderCharMap = GAME_IS_CRUSADER && shapeNum == 1;
|
||||
}
|
||||
|
||||
ShapeFont::~ShapeFont() {
|
||||
}
|
||||
|
||||
|
||||
int ShapeFont::getWidth(char c) {
|
||||
const ShapeFrame *frame = getFrame(charToFrameNum(c));
|
||||
if (frame)
|
||||
return frame->_width;
|
||||
else
|
||||
return 7; // small space..
|
||||
}
|
||||
|
||||
int ShapeFont::getHeight() {
|
||||
if (_height == 0) {
|
||||
for (uint32 i = 0; i < frameCount(); i++) {
|
||||
const ShapeFrame *frame = getFrame(i);
|
||||
if (!frame)
|
||||
continue;
|
||||
int h = frame->_height;
|
||||
|
||||
if (h > _height) _height = h;
|
||||
}
|
||||
}
|
||||
|
||||
return _height;
|
||||
}
|
||||
|
||||
int ShapeFont::getBaseline() {
|
||||
if (_baseLine == 0) {
|
||||
for (uint32 i = 0; i < frameCount(); i++) {
|
||||
int b = getFrame(i)->_yoff;
|
||||
|
||||
if (b > _baseLine) _baseLine = b;
|
||||
}
|
||||
}
|
||||
|
||||
return _baseLine;
|
||||
}
|
||||
|
||||
int ShapeFont::getBaselineSkip() {
|
||||
return getHeight() + getVlead();
|
||||
}
|
||||
|
||||
void ShapeFont::getStringSize(const Std::string &text, int32 &width, int32 &height) {
|
||||
width = _hLead;
|
||||
height = getHeight();
|
||||
|
||||
for (unsigned int i = 0; i < text.size(); ++i) {
|
||||
if (text[i] == '\n' || text[i] == '\r') {
|
||||
// ignore
|
||||
} else {
|
||||
width += getWidth(text[i]) - _hLead;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ShapeFont::charToFrameNum(char c) const {
|
||||
if (_crusaderCharMap) {
|
||||
if (c < 41)
|
||||
// ( and ) are combined into a single shape
|
||||
return c;
|
||||
// weirdly X and Y are swapped in both upper and lowercase
|
||||
else if (c == 'X')
|
||||
return 'X';
|
||||
else if (c == 'Y')
|
||||
return 'W';
|
||||
else if (c < 96)
|
||||
return c - 1;
|
||||
else if (c == 96)
|
||||
// no backquote char
|
||||
return charToFrameNum('\'');
|
||||
else if (c == 'x')
|
||||
return 'w';
|
||||
else if (c == 'y')
|
||||
return 'v';
|
||||
else
|
||||
return c - 2;
|
||||
} else {
|
||||
return static_cast<unsigned char>(c);
|
||||
}
|
||||
}
|
||||
|
||||
RenderedText *ShapeFont::renderText(const Std::string &text,
|
||||
unsigned int &remaining,
|
||||
int32 width, int32 height, TextAlign align,
|
||||
bool u8specials, bool pagebreaks,
|
||||
Std::string::size_type cursor) {
|
||||
int32 resultwidth, resultheight;
|
||||
Std::list<PositionedText> lines;
|
||||
lines = typesetText<Traits>(this, text, remaining,
|
||||
width, height, align, u8specials, pagebreaks,
|
||||
resultwidth, resultheight, cursor);
|
||||
|
||||
return new ShapeRenderedText(lines, resultwidth, resultheight,
|
||||
getVlead(), this);
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
77
engines/ultima/ultima8/gfx/fonts/shape_font.h
Normal file
77
engines/ultima/ultima8/gfx/fonts/shape_font.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GFX_FONTS_SHAPEFONT_H
|
||||
#define ULTIMA8_GFX_FONTS_SHAPEFONT_H
|
||||
|
||||
#include "ultima/ultima8/gfx/fonts/font.h"
|
||||
#include "ultima/ultima8/gfx/shape.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class ShapeFont : public Font, public Shape {
|
||||
int _height;
|
||||
int _baseLine;
|
||||
int _vLead;
|
||||
int _hLead;
|
||||
bool _crusaderCharMap;
|
||||
|
||||
public:
|
||||
ShapeFont(const uint8 *data, uint32 size, const ConvertShapeFormat *format,
|
||||
const uint16 flexId, const uint32 shapenum);
|
||||
~ShapeFont() override;
|
||||
|
||||
int getHeight() override;
|
||||
int getBaseline() override;
|
||||
int getBaselineSkip() override;
|
||||
|
||||
int getWidth(char c);
|
||||
int getVlead() const {
|
||||
return _vLead;
|
||||
}
|
||||
int getHlead() const {
|
||||
return _hLead;
|
||||
}
|
||||
|
||||
void setVLead(int vl) {
|
||||
_vLead = vl;
|
||||
}
|
||||
void setHLead(int hl) {
|
||||
_hLead = hl;
|
||||
}
|
||||
|
||||
int charToFrameNum(char c) const;
|
||||
|
||||
void getStringSize(const Std::string &text,
|
||||
int32 &width, int32 &height) override;
|
||||
|
||||
RenderedText *renderText(const Std::string &text,
|
||||
unsigned int &remaining, int32 width = 0, int32 height = 0,
|
||||
TextAlign align = TEXT_LEFT, bool u8specials = false,
|
||||
bool pagebreaks = false,
|
||||
Std::string::size_type cursor = Std::string::npos) override;
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
102
engines/ultima/ultima8/gfx/fonts/shape_rendered_text.cpp
Normal file
102
engines/ultima/ultima8/gfx/fonts/shape_rendered_text.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima8/misc/debugger.h"
|
||||
#include "ultima/ultima8/gfx/fonts/shape_rendered_text.h"
|
||||
|
||||
#include "ultima/ultima8/gfx/fonts/shape_font.h"
|
||||
#include "ultima/ultima8/gfx/render_surface.h"
|
||||
#include "ultima/ultima8/gfx/texture.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
ShapeRenderedText::ShapeRenderedText(const Std::list<PositionedText> &lines,
|
||||
int width, int height, int vLead,
|
||||
ShapeFont *font)
|
||||
: _lines(lines), _font(font) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
_vLead = vLead;
|
||||
}
|
||||
|
||||
ShapeRenderedText::~ShapeRenderedText() {
|
||||
}
|
||||
|
||||
void ShapeRenderedText::draw(RenderSurface *surface, int x, int y, bool /*destmasked*/) {
|
||||
// TODO support masking here???
|
||||
|
||||
uint32 color = TEX32_PACK_RGB(0, 0, 0);
|
||||
Std::list<PositionedText>::const_iterator iter;
|
||||
|
||||
surface->BeginPainting();
|
||||
|
||||
for (const auto &line : _lines) {
|
||||
int line_x = x + line._dims.left;
|
||||
int line_y = y + line._dims.top;
|
||||
|
||||
size_t textsize = line._text.size();
|
||||
|
||||
for (size_t i = 0; i < textsize; ++i) {
|
||||
surface->Paint(_font, _font->charToFrameNum(line._text[i]),
|
||||
line_x, line_y);
|
||||
|
||||
if (i == line._cursor) {
|
||||
surface->fill32(color, line_x, line_y - _font->getBaseline(),
|
||||
1, line._dims.height());
|
||||
}
|
||||
|
||||
line_x += _font->getWidth(line._text[i]) - _font->getHlead();
|
||||
}
|
||||
|
||||
if (line._cursor == textsize) {
|
||||
surface->fill32(color, line_x, line_y - _font->getBaseline(),
|
||||
1, line._dims.height());
|
||||
}
|
||||
}
|
||||
|
||||
surface->EndPainting();
|
||||
}
|
||||
|
||||
void ShapeRenderedText::drawBlended(RenderSurface *surface, int x, int y,
|
||||
uint32 col, bool /*destmasked*/) {
|
||||
// TODO Support masking here ????
|
||||
|
||||
Std::list<PositionedText>::const_iterator iter;
|
||||
|
||||
for (const auto &line : _lines) {
|
||||
int line_x = x + line._dims.left;
|
||||
int line_y = y + line._dims.top;
|
||||
|
||||
size_t textsize = line._text.size();
|
||||
|
||||
for (size_t i = 0; i < textsize; ++i) {
|
||||
surface->PaintHighlight(_font,
|
||||
static_cast<unsigned char>(line._text[i]),
|
||||
line_x, line_y, false, false, col);
|
||||
line_x += _font->getWidth(line._text[i]) - _font->getHlead();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
50
engines/ultima/ultima8/gfx/fonts/shape_rendered_text.h
Normal file
50
engines/ultima/ultima8/gfx/fonts/shape_rendered_text.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GFX_FONTS_SHAPERENDEREDTEXT_H
|
||||
#define ULTIMA8_GFX_FONTS_SHAPERENDEREDTEXT_H
|
||||
|
||||
#include "ultima/ultima8/gfx/fonts/rendered_text.h"
|
||||
#include "ultima/ultima8/gfx/fonts/font.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class ShapeFont;
|
||||
|
||||
class ShapeRenderedText : public RenderedText {
|
||||
public:
|
||||
ShapeRenderedText(const Std::list<PositionedText> &lines,
|
||||
int width, int height, int vlead, ShapeFont *font);
|
||||
~ShapeRenderedText() override;
|
||||
|
||||
void draw(RenderSurface *surface, int x, int y, bool destmasked = false) override;
|
||||
void drawBlended(RenderSurface *surface, int x, int y, uint32 col, bool destmasked = false) override;
|
||||
|
||||
protected:
|
||||
Std::list<PositionedText> _lines;
|
||||
ShapeFont *_font;
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
299
engines/ultima/ultima8/gfx/fonts/tt_font.cpp
Normal file
299
engines/ultima/ultima8/gfx/fonts/tt_font.cpp
Normal file
@@ -0,0 +1,299 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima8/misc/common_types.h"
|
||||
#include "ultima/ultima8/gfx/fonts/tt_font.h"
|
||||
#include "ultima/ultima8/gfx/fonts/ttf_rendered_text.h"
|
||||
#include "ultima/ultima8/gfx/texture.h"
|
||||
|
||||
|
||||
//include iomanip
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
// various unicode characters which look like small black circles
|
||||
static const uint16 BULLETS[] = { 0x2022, 0x30FB, 0x25CF, 0 };
|
||||
|
||||
TTFont::TTFont(Graphics::Font *font, uint32 rgb, int borderSize,
|
||||
bool antiAliased, bool SJIS) :
|
||||
_borderSize(borderSize), _ttfFont(font), _antiAliased(antiAliased), _SJIS(SJIS),
|
||||
_PF_RGBA(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) {
|
||||
_color = _PF_RGBA.RGBToColor((rgb >> 16) & 0xFF, (rgb >> 8) & 0xff, rgb & 0xff);
|
||||
|
||||
_bullet = 0;
|
||||
// scan for a character to use as a conversation option _bullet
|
||||
for (int i = 0; BULLETS[i]; ++i) {
|
||||
Common::Rect box = font->getBoundingBox(BULLETS[i]);
|
||||
|
||||
if (!box.isEmpty()) {
|
||||
_bullet = BULLETS[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_bullet == 0) {
|
||||
_bullet = '*';
|
||||
}
|
||||
}
|
||||
|
||||
TTFont::~TTFont() {
|
||||
|
||||
}
|
||||
|
||||
int TTFont::getHeight() {
|
||||
return _ttfFont->getFontHeight() + 2 * _borderSize; // constant (border)
|
||||
}
|
||||
|
||||
int TTFont::getBaseline() {
|
||||
Common::Rect box = _ttfFont->getBoundingBox('W');
|
||||
return box.bottom;
|
||||
}
|
||||
|
||||
int TTFont::getBaselineSkip() {
|
||||
// TODO: Come up with something more generic than just hardcoding 2 pixel line separation
|
||||
return getHeight() + 2;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static Common::U32String toUnicode(const Std::string &text, uint16 bullet) {
|
||||
Std::string::size_type len = T::length(text);
|
||||
Common::U32String result = Common::U32String(text.c_str(), len);
|
||||
|
||||
Std::string::const_iterator iter = text.begin();
|
||||
for (uint idx = 0; idx < len; ++idx) {
|
||||
uint32 u = T::unicode(iter);
|
||||
if (u == '@') {
|
||||
result.setChar(bullet, idx);
|
||||
} else {
|
||||
result.setChar(u, idx);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void TTFont::getStringSize(const Std::string &text, int32 &width, int32 &height) {
|
||||
// convert to unicode
|
||||
Common::U32String unicodeText;
|
||||
if (!_SJIS)
|
||||
unicodeText = toUnicode<Traits>(text, _bullet);
|
||||
else
|
||||
unicodeText = toUnicode<SJISTraits>(text, _bullet);
|
||||
|
||||
width = _ttfFont->getStringWidth(unicodeText);
|
||||
height = _ttfFont->getFontHeight();
|
||||
|
||||
width += 2 * _borderSize;
|
||||
height += 2 * _borderSize;
|
||||
}
|
||||
|
||||
void TTFont::getTextSize(const Std::string &text,
|
||||
int32 &resultWidth, int32 &resultHeight,
|
||||
unsigned int &remaining,
|
||||
int32 width, int32 height, TextAlign align,
|
||||
bool u8specials, bool pagebreaks) {
|
||||
Std::list<PositionedText> tmp;
|
||||
if (!_SJIS)
|
||||
tmp = typesetText<Traits>(this, text, remaining,
|
||||
width, height, align, u8specials, pagebreaks,
|
||||
resultWidth, resultHeight);
|
||||
else
|
||||
tmp = typesetText<SJISTraits>(this, text, remaining,
|
||||
width, height, align, u8specials, pagebreaks,
|
||||
resultWidth, resultHeight);
|
||||
}
|
||||
|
||||
|
||||
void TTFont::addTextBorder(Graphics::ManagedSurface &textSurf, uint32 *texBuf, const Common::Rect32 &dims, int32 resultWidth, int32 resultHeight, uint32 borderColor) {
|
||||
uint8 bA, bR, bG, bB;
|
||||
_PF_RGBA.colorToARGB(borderColor, bA, bR, bG, bB);
|
||||
|
||||
int sqrSize = _borderSize * _borderSize;
|
||||
int sqrEdge = (_borderSize + 1) * (_borderSize + 1);
|
||||
|
||||
for (int y = 0; y < textSurf.h; y++) {
|
||||
const byte* surfrow = (const byte*)textSurf.getBasePtr(0, y);
|
||||
|
||||
for (int x = 0; x < textSurf.w; x++) {
|
||||
if (_antiAliased) {
|
||||
uint32 sColor = *((const uint32 *)(surfrow + x * 4));
|
||||
uint8 sR, sG, sB, sA;
|
||||
_PF_RGBA.colorToARGB(sColor, sA, sR, sG, sB);
|
||||
|
||||
if (sA == 0x00)
|
||||
continue;
|
||||
|
||||
for (int dx = -_borderSize; dx <= _borderSize; dx++) {
|
||||
for (int dy = -_borderSize; dy <= _borderSize; dy++) {
|
||||
int tx = dims.left + x + _borderSize + dx;
|
||||
int ty = dims.top + y + _borderSize + dy;
|
||||
if (tx >= 0 && tx < resultWidth && ty >= 0 && ty < resultHeight) {
|
||||
uint32 dColor = texBuf[ty * resultWidth + tx];
|
||||
if (borderColor != dColor) {
|
||||
int sqrDist = (dx * dx) + (dy * dy);
|
||||
if (sqrDist < sqrSize) {
|
||||
texBuf[ty * resultWidth + tx] = borderColor;
|
||||
}
|
||||
else if (sqrDist < sqrEdge) {
|
||||
// Blend border color at source intensity with destination
|
||||
uint8 dA, dR, dG, dB;
|
||||
_PF_RGBA.colorToARGB(dColor, dA, dR, dG, dB);
|
||||
|
||||
double bAlpha = (double)bA / 255.0;
|
||||
double sAlpha = (double)sA / 255.0;
|
||||
double dAlpha = (double)dA / 255.0;
|
||||
dAlpha *= (1.0 - sAlpha);
|
||||
|
||||
dR = static_cast<uint8>((bR * sAlpha + dR * dAlpha) / (sAlpha + dAlpha));
|
||||
dG = static_cast<uint8>((bG * sAlpha + dG * dAlpha) / (sAlpha + dAlpha));
|
||||
dB = static_cast<uint8>((bB * sAlpha + dB * dAlpha) / (sAlpha + dAlpha));
|
||||
dA = static_cast<uint8>(255. * bAlpha * (sAlpha + dAlpha));
|
||||
|
||||
texBuf[ty * resultWidth + tx] = _PF_RGBA.ARGBToColor(dA, dR, dG, dB);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (surfrow[x] == 1) {
|
||||
for (int dx = -_borderSize; dx <= _borderSize; dx++) {
|
||||
for (int dy = -_borderSize; dy <= _borderSize; dy++) {
|
||||
int tx = dims.left + x + _borderSize + dx;
|
||||
int ty = dims.top + y + _borderSize + dy;
|
||||
if (tx >= 0 && tx < resultWidth && ty >= 0 && ty < resultHeight) {
|
||||
int sqrDist = (dx * dx) + (dy * dy);
|
||||
if (sqrDist < sqrEdge) {
|
||||
texBuf[ty * resultWidth + tx] = borderColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderedText *TTFont::renderText(const Std::string &text, unsigned int &remaining,
|
||||
int32 width, int32 height, TextAlign align, bool u8specials, bool pagebreaks,
|
||||
Std::string::size_type cursor) {
|
||||
int32 resultWidth, resultHeight, lineHeight;
|
||||
Std::list<PositionedText> lines;
|
||||
if (!_SJIS)
|
||||
lines = typesetText<Traits>(this, text, remaining, width, height, align, u8specials, pagebreaks,
|
||||
resultWidth, resultHeight, cursor);
|
||||
else
|
||||
lines = typesetText<SJISTraits>(this, text, remaining, width, height, align, u8specials, pagebreaks,
|
||||
resultWidth, resultHeight, cursor);
|
||||
lineHeight = _ttfFont->getFontHeight();
|
||||
|
||||
uint32 borderColor = _PF_RGBA.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
|
||||
|
||||
Graphics::ManagedSurface *texture = new Graphics::ManagedSurface(resultWidth, resultHeight, _PF_RGBA);
|
||||
uint32 *texBuf = (uint32 *)texture->getPixels();
|
||||
|
||||
for (const auto &line : lines) {
|
||||
// convert to unicode
|
||||
Common::U32String unicodeText;
|
||||
if (!_SJIS)
|
||||
unicodeText = toUnicode<Traits>(line._text, _bullet);
|
||||
else
|
||||
unicodeText = toUnicode<SJISTraits>(line._text, _bullet);
|
||||
|
||||
// Create a surface and render the text
|
||||
Graphics::ManagedSurface textSurf;
|
||||
|
||||
if (!_antiAliased) {
|
||||
// When not in antialiased mode, use a paletted surface where '1' is
|
||||
// used for pixels of the text
|
||||
textSurf.create(resultWidth, lineHeight, Graphics::PixelFormat::createFormatCLUT8());
|
||||
_ttfFont->drawString(&textSurf, unicodeText, 0, 0, resultWidth, 1);
|
||||
} else {
|
||||
// Use a high color surface with the specified _color color for text
|
||||
textSurf.create(resultWidth, lineHeight, _PF_RGBA);
|
||||
_ttfFont->drawString(&textSurf, unicodeText, 0, 0, resultWidth, _color);
|
||||
};
|
||||
|
||||
// Add border within radius. Pixels on the edge are alpha blended if antialiased
|
||||
if (_borderSize > 0) {
|
||||
addTextBorder(textSurf, texBuf, line._dims, resultWidth, resultHeight, borderColor);
|
||||
}
|
||||
|
||||
// render the text surface into our texture buffer
|
||||
for (int y = 0; y < textSurf.h; y++) {
|
||||
const byte *surfrow = (const byte *)textSurf.getBasePtr(0, y);
|
||||
|
||||
int ty = line._dims.top + y + _borderSize;
|
||||
for (int x = 0; x < textSurf.w; x++) {
|
||||
int tx = line._dims.left + x + _borderSize;
|
||||
if (_antiAliased) {
|
||||
uint32 sColor = *((const uint32 *)(surfrow + x * 4));
|
||||
uint8 sR, sG, sB, sA;
|
||||
_PF_RGBA.colorToARGB(sColor, sA, sR, sG, sB);
|
||||
|
||||
if (sA == 0xFF) {
|
||||
texBuf[ty * resultWidth + tx] = sColor;
|
||||
}
|
||||
else if (sA != 0x00) {
|
||||
// Blend color with destination
|
||||
int32 dColor = texBuf[ty * resultWidth + tx];
|
||||
uint8 dA, dR, dG, dB;
|
||||
_PF_RGBA.colorToARGB(dColor, dA, dR, dG, dB);
|
||||
|
||||
double sAlpha = (double)sA / 255.0;
|
||||
double dAlpha = (double)dA / 255.0;
|
||||
dAlpha *= (1.0 - sAlpha);
|
||||
|
||||
dR = static_cast<uint8>((sR * sAlpha + dR * dAlpha) / (sAlpha + dAlpha));
|
||||
dG = static_cast<uint8>((sG * sAlpha + dG * dAlpha) / (sAlpha + dAlpha));
|
||||
dB = static_cast<uint8>((sB * sAlpha + dB * dAlpha) / (sAlpha + dAlpha));
|
||||
dA = static_cast<uint8>(255. * (sAlpha + dAlpha));
|
||||
|
||||
texBuf[ty * resultWidth + tx] = _PF_RGBA.ARGBToColor(dA, dR, dG, dB);
|
||||
}
|
||||
}
|
||||
else if (surfrow[x] == 1) {
|
||||
texBuf[ty * resultWidth + tx] = _color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (line._cursor != Std::string::npos) {
|
||||
assert(line._cursor <= line._text.size());
|
||||
unicodeText = unicodeText.substr(0, line._cursor);
|
||||
|
||||
int w = _ttfFont->getStringWidth(unicodeText);
|
||||
|
||||
for (int y = 0; y < line._dims.height(); y++) {
|
||||
int tx = line._dims.left + w + _borderSize;
|
||||
int ty = line._dims.top + y;
|
||||
texBuf[ty * resultWidth + tx] = borderColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new TTFRenderedText(texture, resultWidth, resultHeight,
|
||||
getBaselineSkip() - getHeight(), getBaseline(), isAntialiased());
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
76
engines/ultima/ultima8/gfx/fonts/tt_font.h
Normal file
76
engines/ultima/ultima8/gfx/fonts/tt_font.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GFX_FONTS_TTFONT_H
|
||||
#define ULTIMA8_GFX_FONTS_TTFONT_H
|
||||
|
||||
#include "ultima/ultima8/gfx/fonts/font.h"
|
||||
#include "graphics/font.h"
|
||||
#include "graphics/pixelformat.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class TTFont : public Font {
|
||||
public:
|
||||
TTFont(Graphics::Font *font, uint32 rgb, int bordersize,
|
||||
bool antiAliased, bool SJIS);
|
||||
~TTFont() override;
|
||||
|
||||
int getHeight() override;
|
||||
int getBaseline() override;
|
||||
int getBaselineSkip() override;
|
||||
|
||||
bool isAntialiased() {
|
||||
return _antiAliased;
|
||||
}
|
||||
|
||||
void getStringSize(const Std::string &text,
|
||||
int32 &width, int32 &height) override;
|
||||
|
||||
void getTextSize(const Std::string &text,
|
||||
int32 &resultwidth, int32 &resultheight, unsigned int &remaining,
|
||||
int32 width = 0, int32 height = 0, TextAlign align = TEXT_LEFT,
|
||||
bool u8specials = false, bool pagebreaks = false) override;
|
||||
|
||||
RenderedText *renderText(const Std::string &text,
|
||||
unsigned int &remaining, int32 width = 0, int32 height = 0,
|
||||
TextAlign align = TEXT_LEFT, bool u8specials = false,
|
||||
bool pagebreaks = false,
|
||||
Std::string::size_type cursor = Std::string::npos) override;
|
||||
|
||||
protected:
|
||||
Graphics::Font *_ttfFont;
|
||||
uint32 _color;
|
||||
int _borderSize;
|
||||
bool _antiAliased;
|
||||
bool _SJIS;
|
||||
Graphics::PixelFormat _PF_RGBA;
|
||||
|
||||
uint16 _bullet;
|
||||
|
||||
void addTextBorder(Graphics::ManagedSurface &textSurf, uint32 *texBuf, const Common::Rect32 &dims, int32 resultWidth, int32 resultHeight, uint32 borderColor);
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
61
engines/ultima/ultima8/gfx/fonts/ttf_rendered_text.cpp
Normal file
61
engines/ultima/ultima8/gfx/fonts/ttf_rendered_text.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima8/misc/common_types.h"
|
||||
#include "ultima/ultima8/gfx/fonts/ttf_rendered_text.h"
|
||||
#include "ultima/ultima8/gfx/fonts/tt_font.h"
|
||||
#include "ultima/ultima8/gfx/render_surface.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
TTFRenderedText::TTFRenderedText(Graphics::ManagedSurface *texture, int width, int height,
|
||||
int vLead, int baseline, bool antiAliased) : _texture(texture), _baseline(baseline), _antiAliased(antiAliased) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
_vLead = vLead;
|
||||
}
|
||||
|
||||
TTFRenderedText::~TTFRenderedText() {
|
||||
delete _texture;
|
||||
}
|
||||
|
||||
void TTFRenderedText::draw(RenderSurface *surface, int x, int y, bool destmasked) {
|
||||
if (!_width)
|
||||
return;
|
||||
Common::Rect srcRect(_width, _height);
|
||||
if (!destmasked)
|
||||
surface->Blit(*_texture, srcRect, x, y - _baseline, _antiAliased);
|
||||
else
|
||||
surface->MaskedBlit(*_texture, srcRect, x, y - _baseline, 0, _antiAliased);
|
||||
}
|
||||
|
||||
void TTFRenderedText::drawBlended(RenderSurface *surface, int x, int y,
|
||||
uint32 col, bool destmasked) {
|
||||
Common::Rect srcRect(_width, _height);
|
||||
if (!destmasked)
|
||||
surface->FadedBlit(*_texture, srcRect, x, y - _baseline, col, _antiAliased);
|
||||
else
|
||||
surface->MaskedBlit(*_texture, srcRect, x, y - _baseline, col, _antiAliased);
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
55
engines/ultima/ultima8/gfx/fonts/ttf_rendered_text.h
Normal file
55
engines/ultima/ultima8/gfx/fonts/ttf_rendered_text.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA8_GFX_FONTS_SHAPERENDEREDTEXT_H
|
||||
#define ULTIMA8_GFX_FONTS_SHAPERENDEREDTEXT_H
|
||||
|
||||
#include "ultima/ultima8/gfx/fonts/rendered_text.h"
|
||||
#include "ultima/ultima8/gfx/fonts/font.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
class TTFont;
|
||||
class Texture;
|
||||
|
||||
class TTFRenderedText : public RenderedText {
|
||||
public:
|
||||
TTFRenderedText(Graphics::ManagedSurface *texture, int width, int height, int vlead,
|
||||
int baseline, bool antiAliased);
|
||||
~TTFRenderedText() override;
|
||||
|
||||
void draw(RenderSurface *surface, int x, int y,
|
||||
bool destmasked = false) override;
|
||||
void drawBlended(RenderSurface *surface, int x, int y, uint32 col,
|
||||
bool destmasked = false) override;
|
||||
|
||||
protected:
|
||||
Graphics::ManagedSurface *_texture;
|
||||
int _baseline;
|
||||
bool _antiAliased;
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user