GLK: Splitting font related info from Conf into their own classes

This commit is contained in:
Paul Gilbert 2018-12-31 18:34:42 -08:00
parent f25b3d93c1
commit 1021da132b
18 changed files with 351 additions and 221 deletions

View file

@ -68,35 +68,23 @@ Conf::Conf(InterpreterType interpType) {
_imageW = g_system->getWidth(); _imageW = g_system->getWidth();
_imageH = g_system->getHeight(); _imageH = g_system->getHeight();
_cellW = _cellH = 8; _cellW = _cellH = 8;
_leading = 0;
_baseLine = 0;
get("moreprompt", _morePrompt, "\207 more \207"); get("moreprompt", _propInfo._morePrompt, "\207 more \207");
get("morecolor", _moreColor); get("morecolor", _propInfo._moreColor);
get("morecolor", _moreSave); get("morecolor", _propInfo._moreSave);
get("morefont", _moreFont, PROPB); get("morefont", _propInfo._moreFont, PROPB);
get("morealign", _moreAlign); get("morealign", _propInfo._moreAlign);
get("monoaspect", _monoAspect, 1.0); get("monoaspect", _monoInfo._aspect, 1.0);
get("propaspect", _propAspect, 1.0); get("propaspect", _propInfo._aspect, 1.0);
get("monosize", _monoSize, 11); get("monosize", _monoInfo._size, 11);
get("monor", _monoR); get("propsize", _propInfo._size, 12);
get("monob", _monoR);
get("monoi", _monoI);
get("monoz", _monoZ);
get("monofont", _monoFont, "Liberation Mono");
get("propsize", _propSize, 12);
get("propr", _propR);
get("propb", _propR);
get("propi", _propI);
get("propz", _propZ);
get("propfont", _propFont, "Linux Libertine O");
get("rows", _rows, 25); get("rows", _rows, 25);
get("cols", _cols, 60); get("cols", _cols, 60);
if (ConfMan.hasKey("leading")) if (ConfMan.hasKey("leading"))
_leading = static_cast<int>(atof(ConfMan.get("leading").c_str()) + 0.5); _monoInfo._leading = _propInfo._leading = static_cast<int>(atof(ConfMan.get("leading").c_str()) + 0.5);
if (ConfMan.hasKey("baseline")) if (ConfMan.hasKey("baseline"))
_baseLine = static_cast<int>(atof(ConfMan.get("baseline").c_str()) + 0.5); _propInfo._baseLine = static_cast<int>(atof(ConfMan.get("baseline").c_str()) + 0.5);
if (ConfMan.hasKey("minrows")) if (ConfMan.hasKey("minrows"))
_rows = MAX(_rows, strToInt(ConfMan.get("minrows").c_str())); _rows = MAX(_rows, strToInt(ConfMan.get("minrows").c_str()));
@ -125,27 +113,30 @@ Conf::Conf(InterpreterType interpType) {
get("tmarginy", _tMarginY, 7); get("tmarginy", _tMarginY, 7);
get("gamma", _gamma, 1.0); get("gamma", _gamma, 1.0);
get("caretcolor", _caretColor); get("linkcolor", _propInfo._linkColor, BLUE);
get("caretcolor", _caretSave); Common::copy(&_propInfo._linkColor[0], &_propInfo._linkSave[3], &_monoInfo._linkColor[0]);
get("linkcolor", _linkColor, BLUE); Common::copy(&_propInfo._linkColor[0], &_propInfo._linkSave[3], &_propInfo._linkSave[0]);
get("linkcolor", _linkSave, BLUE);
get("bordercolor", _borderColor); get("bordercolor", _borderColor);
get("bordercolor", _borderSave); get("bordercolor", _borderSave);
get("windowcolor", _windowColor, WHITE); get("windowcolor", _windowColor, WHITE);
get("windowcolor", _windowSave, WHITE); get("windowcolor", _windowSave, WHITE);
get("lcd", _lcd, 1); get("lcd", _lcd, 1);
get("caretshape", _caretShape, 2); get("caretcolor", _propInfo._caretColor);
get("caretcolor", _propInfo._caretSave);
get("caretshape", _propInfo._caretShape, 2);
_linkStyle = ConfMan.hasKey("linkstyle") && !strToInt(ConfMan.get("linkstyle").c_str()) ? 0 : 1; _propInfo._linkStyle = _monoInfo._linkStyle = ConfMan.hasKey("linkstyle")
&& !strToInt(ConfMan.get("linkstyle").c_str()) ? 0 : 1;
get("scrollwidth", _scrollWidth); get("scrollwidth", _scrollWidth);
get("scrollbg", _scrollBg, SCROLL_BG); get("scrollbg", _scrollBg, SCROLL_BG);
get("scrollfg", _scrollFg, SCROLL_FG); get("scrollfg", _scrollFg, SCROLL_FG);
get("justify", _justify); get("justify", _propInfo._justify);
get("quotes", _quotes, 1); get("quotes", _propInfo._quotes, 1);
get("dashes", _dashes, 1); get("dashes", _propInfo._dashes, 1);
get("spaces", _spaces); get("spaces", _propInfo._spaces);
get("caps", _caps); get("caps", _propInfo._caps);
get("graphics", _graphics, true); get("graphics", _graphics, true);
get("sound", _sound, true); get("sound", _sound, true);
get("speak", _speak); get("speak", _speak);

View file

@ -24,6 +24,7 @@
#define GLK_CONF_H #define GLK_CONF_H
#include "glk/glk_types.h" #include "glk/glk_types.h"
#include "glk/fonts.h"
#include "glk/windows.h" #include "glk/windows.h"
namespace Glk { namespace Glk {
@ -68,26 +69,8 @@ private:
*/ */
void parseColor(const Common::String &str, byte *color); void parseColor(const Common::String &str, byte *color);
public: public:
Common::String _morePrompt; MonoFontInfo _monoInfo;
byte _moreColor[3], _moreSave[3]; PropFontInfo _propInfo;
FACES _moreFont;
int _moreAlign;
double _monoAspect;
double _propAspect;
double _monoSize;
Common::String _monoR;
Common::String _monoB;
Common::String _monoI;
Common::String _monoZ;
Common::String _monoFont;
double _propSize;
Common::String _propR;
Common::String _propB;
Common::String _propI;
Common::String _propZ;
Common::String _propFont;
int _leading;
int _baseLine;
int _cols, _rows; int _cols, _rows;
int _lockCols, _lockRows; int _lockCols, _lockRows;
int _wMarginX, _wMarginY; int _wMarginX, _wMarginY;
@ -96,20 +79,11 @@ public:
int _wBorderX, _wBorderY; int _wBorderX, _wBorderY;
int _tMarginX, _tMarginY; int _tMarginX, _tMarginY;
double _gamma; double _gamma;
byte _caretColor[3], _caretSave[3];
byte _linkColor[3], _linkSave[3];
byte _borderColor[3], _borderSave[3]; byte _borderColor[3], _borderSave[3];
byte _windowColor[3], _windowSave[3]; byte _windowColor[3], _windowSave[3];
int _lcd; int _lcd;
int _caretShape;
int _linkStyle;
int _scrollWidth; int _scrollWidth;
byte _scrollBg[3], _scrollFg[3]; byte _scrollBg[3], _scrollFg[3];
int _justify;
int _quotes;
int _dashes;
int _spaces;
int _caps;
bool _graphics; bool _graphics;
bool _sound; bool _sound;
bool _speak; bool _speak;

View file

@ -87,7 +87,7 @@ void Events::initializeCursors() {
// Setup selection cusor sized to the vertical line size // Setup selection cusor sized to the vertical line size
Surface &sel = _cursors[CURSOR_IBEAM]; Surface &sel = _cursors[CURSOR_IBEAM];
sel.create(5, g_conf->_leading, g_system->getScreenFormat()); sel.create(5, g_conf->_propInfo._leading, g_system->getScreenFormat());
sel.fillRect(Common::Rect(0, 0, sel.w, sel.h), TRANSPARENT); sel.fillRect(Common::Rect(0, 0, sel.w, sel.h), TRANSPARENT);
sel.hLine(0, 0, 4, 0); sel.hLine(0, 0, 4, 0);
sel.hLine(0, sel.h - 1, 4, 0); sel.hLine(0, sel.h - 1, 4, 0);

83
engines/glk/fonts.cpp Normal file
View file

@ -0,0 +1,83 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "glk/fonts.h"
#include "glk/glk.h"
#include "glk/screen.h"
#include "glk/windows.h"
namespace Glk {
FontInfo::FontInfo() : _size(0), _aspect(0), _cellW(0), _cellH(0), _leading(0), _baseLine(0),
_linkStyle(0), _moreFont(PROPB), _moreAlign(0), _caps(0) {
Common::fill(&_linkColor[0], &_linkColor[3], 0);
Common::fill(&_linkSave[0], &_linkSave[3], 0);
Common::fill(&_moreColor[0], &_moreColor[3], 0);
Common::fill(&_moreSave[0], &_moreSave[3], 0);
}
/*--------------------------------------------------------------------------*/
PropFontInfo::PropFontInfo() : _justify(0), _quotes(0), _dashes(0), _spaces(0), _caretShape(0) {
Common::fill(&_caretColor[0], &_caretColor[3], 0);
Common::fill(&_caretSave[0], &_caretSave[3], 0);
}
/*--------------------------------------------------------------------------*/
void PropFontInfo::drawCaret(const Point &pos) {
const byte *rgb = _caretColor;
Graphics::Screen &s = *g_vm->_screen;
uint color = s.format.RGBToColor(rgb[0], rgb[1], rgb[2]);
int x = pos.x / GLI_SUBPIX, y = pos.y;
switch (_caretShape) {
case SMALL_DOT:
s.hLine(x + 0, y + 1, x + 0, color);
s.hLine(x - 1, y + 2, x + 1, color);
s.hLine(x - 2, y + 3, x + 2, color);
break;
case FAT_DOT:
s.hLine(x + 0, y + 1, x + 0, color);
s.hLine(x - 1, y + 2, x + 1, color);
s.hLine(x - 2, y + 3, x + 2, color);
s.hLine(x - 3, y + 4, x + 3, color);
break;
case THIN_LINE:
s.vLine(x, y - _baseLine + 1, y - 1, color);
break;
case FAT_LINE:
s.fillRect(Rect(x, y - _baseLine + 1, x + 1, y - 1), color);
break;
default:
// BLOCK
s.fillRect(Rect(x, y - _baseLine + 1, x + _cellW, y - 1), color);
break;
}
}
} // End of namespace Glk

90
engines/glk/fonts.h Normal file
View 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef GLK_FONTS_H
#define GLK_FONTS_H
#include "glk/glk_types.h"
#include "glk/utils.h"
namespace Glk {
enum FACES { MONOR, MONOB, MONOI, MONOZ, PROPR, PROPB, PROPI, PROPZ, CUSTOM, CUSTOM2 };
enum TYPES { MONOF, PROPF };
enum STYLES { FONTR, FONTB, FONTI, FONTZ };
/**
* Font configuration info
*/
struct FontInfo {
double _size;
double _aspect;
int _cellW, _cellH;
int _leading;
int _baseLine;
byte _linkColor[3], _linkSave[3];
byte _moreColor[3], _moreSave[3];
int _linkStyle;
FACES _moreFont;
int _moreAlign;
Common::String _morePrompt;
int _caps;
/**
* Constructor
*/
FontInfo();
};
/**
* Font info for mono (fixed size) fonts
*/
struct MonoFontInfo : public FontInfo {
};
/**
* Font info fro proportinate (variable size) fonts
*/
struct PropFontInfo : public MonoFontInfo {
byte _caretColor[3], _caretSave[3];
int _caretShape;
int _justify;
int _quotes;
int _dashes;
int _spaces;
/**
* Constructor
*/
PropFontInfo();
/**
* Draws the text input caret at the given position
* @remarks The position specifies the caret's bottom-left corner,
* and the X position is in multiples of GLI_SUBPIX
*/
void drawCaret(const Point &pos);
};
} // End of namespace Glk
#endif

View file

@ -54,7 +54,7 @@ void FrotzScreen::loadFonts(Common::Archive *archive) {
if (!f.open("NotoSansRunic-Regular.ttf", *archive)) if (!f.open("NotoSansRunic-Regular.ttf", *archive))
error("Could not load font"); error("Could not load font");
_fonts.push_back(Graphics::loadTTFFont(f, g_conf->_propSize, Graphics::kTTFSizeModeCharacter)); _fonts.push_back(Graphics::loadTTFFont(f, g_conf->_propInfo._size, Graphics::kTTFSizeModeCharacter));
f.close(); f.close();
} }

View file

@ -508,8 +508,8 @@ void GlkAPI::glk_stylehint_set(uint wintype, uint style, uint hint, int val) {
} }
if (wintype == wintype_TextBuffer && style == style_Normal && hint == stylehint_TextColor) { if (wintype == wintype_TextBuffer && style == style_Normal && hint == stylehint_TextColor) {
memcpy(g_conf->_moreColor, styles[style].fg, 3); memcpy(g_conf->_propInfo._moreColor, styles[style].fg, 3);
memcpy(g_conf->_caretColor, styles[style].fg, 3); memcpy(g_conf->_propInfo._caretColor, styles[style].fg, 3);
} }
} }

View file

@ -5,6 +5,7 @@ MODULE_OBJS := \
conf.o \ conf.o \
detection.o \ detection.o \
events.o \ events.o \
fonts.o \
glk.o \ glk.o \
glk_api.o \ glk_api.o \
picture.o \ picture.o \

View file

@ -42,16 +42,21 @@ void Screen::initialize() {
if (!loadFonts()) if (!loadFonts())
error("Could not load fonts.dat"); error("Could not load fonts.dat");
// TODO: See if there's any better way for getting the leading and baseline for (int idx = 0; idx < 2; ++idx) {
Common::Rect r1 = _fonts[7]->getBoundingBox('o'); FontInfo *i = (idx == 0) ? &g_conf->_monoInfo : &g_conf->_propInfo;
Common::Rect r2 = _fonts[7]->getBoundingBox('y'); const Graphics::Font *f = (idx == 0) ? _fonts[0] : _fonts[7];
double baseLine = (double)r1.bottom;
double leading = (double)r2.bottom + 2;
g_conf->_leading = static_cast<int>(MAX((double)g_conf->_leading, leading)); // TODO: See if there's any better way for getting the leading and baseline
g_conf->_baseLine = static_cast<int>(MAX((double)g_conf->_baseLine, baseLine)); Common::Rect r1 = f->getBoundingBox('o');
g_conf->_cellW = _fonts[0]->getStringWidth("0"); Common::Rect r2 = f->getBoundingBox('y');
g_conf->_cellH = g_conf->_leading; double baseLine = (double)r1.bottom;
double leading = (double)r2.bottom + 2;
i->_leading = static_cast<int>(MAX((double)i->_leading, leading));
i->_baseLine = static_cast<int>(MAX((double)i->_baseLine, baseLine));
i->_cellW = _fonts[0]->getStringWidth("0");
i->_cellH = i->_leading;
}
} }
void Screen::fill(const byte *rgb) { void Screen::fill(const byte *rgb) {
@ -64,40 +69,6 @@ void Screen::fillRect(const Rect &box, const byte *rgb) {
Graphics::Screen::fillRect(box, color); Graphics::Screen::fillRect(box, color);
} }
void Screen::drawCaret(const Point &pos) {
const byte *rgb = g_conf->_caretColor;
uint color = format.RGBToColor(rgb[0], rgb[1], rgb[2]);
int x = pos.x / GLI_SUBPIX, y = pos.y;
switch (g_conf->_caretShape) {
case SMALL_DOT:
hLine(x + 0, y + 1, x + 0, color);
hLine(x - 1, y + 2, x + 1, color);
hLine(x - 2, y + 3, x + 2, color);
break;
case FAT_DOT:
hLine(x + 0, y + 1, x + 0, color);
hLine(x - 1, y + 2, x + 1, color);
hLine(x - 2, y + 3, x + 2, color);
hLine(x - 3, y + 4, x + 3, color);
break;
case THIN_LINE:
vLine(x, y - g_conf->_baseLine + 1, y - 1, color);
break;
case FAT_LINE:
Graphics::Screen::fillRect(Rect(x, y - g_conf->_baseLine + 1, x + 1, y - 1), color);
break;
default:
// BLOCK
Graphics::Screen::fillRect(Rect(x, y - g_conf->_baseLine + 1, x + g_conf->_cellW, y - 1), color);
break;
}
}
bool Screen::loadFonts() { bool Screen::loadFonts() {
Common::Archive *archive = nullptr; Common::Archive *archive = nullptr;
@ -129,10 +100,10 @@ bool Screen::loadFonts() {
void Screen::loadFonts(Common::Archive *archive) { void Screen::loadFonts(Common::Archive *archive) {
// R ead in the fonts // R ead in the fonts
double monoAspect = g_conf->_monoAspect; double monoAspect = g_conf->_monoInfo._aspect;
double propAspect = g_conf->_propAspect; double propAspect = g_conf->_propInfo._aspect;
double monoSize = g_conf->_monoSize; double monoSize = g_conf->_monoInfo._size;
double propSize = g_conf->_propSize; double propSize = g_conf->_propInfo._size;
_fonts.resize(FONTS_TOTAL); _fonts.resize(FONTS_TOTAL);
_fonts[0] = loadFont(MONOR, archive, monoSize, monoAspect, FONTR); _fonts[0] = loadFont(MONOR, archive, monoSize, monoAspect, FONTR);
@ -172,7 +143,8 @@ FACES Screen::getFontId(const Common::String &name) {
} }
int Screen::drawString(const Point &pos, int fontIdx, const byte *rgb, const Common::String &text, int spw) { int Screen::drawString(const Point &pos, int fontIdx, const byte *rgb, const Common::String &text, int spw) {
Point pt(pos.x / GLI_SUBPIX, pos.y - g_conf->_baseLine); int baseLine = (fontIdx >= PROPR) ? g_conf->_propInfo._baseLine : g_conf->_monoInfo._baseLine;
Point pt(pos.x / GLI_SUBPIX, pos.y - baseLine);
const Graphics::Font *font = _fonts[fontIdx]; const Graphics::Font *font = _fonts[fontIdx];
const uint32 color = format.RGBToColor(rgb[0], rgb[1], rgb[2]); const uint32 color = format.RGBToColor(rgb[0], rgb[1], rgb[2]);
font->drawString(this, text, pt.x, pt.y, w - pt.x, color); font->drawString(this, text, pt.x, pt.y, w - pt.x, color);
@ -182,7 +154,8 @@ int Screen::drawString(const Point &pos, int fontIdx, const byte *rgb, const Com
} }
int Screen::drawStringUni(const Point &pos, int fontIdx, const byte *rgb, const Common::U32String &text, int spw) { int Screen::drawStringUni(const Point &pos, int fontIdx, const byte *rgb, const Common::U32String &text, int spw) {
Point pt(pos.x / GLI_SUBPIX, pos.y - g_conf->_baseLine); int baseLine = (fontIdx >= PROPR) ? g_conf->_propInfo._baseLine : g_conf->_monoInfo._baseLine;
Point pt(pos.x / GLI_SUBPIX, pos.y - baseLine);
const Graphics::Font *font = _fonts[fontIdx]; const Graphics::Font *font = _fonts[fontIdx];
const uint32 color = format.RGBToColor(rgb[0], rgb[1], rgb[2]); const uint32 color = format.RGBToColor(rgb[0], rgb[1], rgb[2]);
font->drawString(this, text, pt.x, pt.y, w - pt.x, color); font->drawString(this, text, pt.x, pt.y, w - pt.x, color);

View file

@ -27,6 +27,7 @@
#include "common/array.h" #include "common/array.h"
#include "graphics/screen.h" #include "graphics/screen.h"
#include "graphics/font.h" #include "graphics/font.h"
#include "glk/fonts.h"
#include "glk/utils.h" #include "glk/utils.h"
namespace Glk { namespace Glk {
@ -37,10 +38,6 @@ enum CaretShape {
SMALL_DOT = 0, FAT_DOT = 1, THIN_LINE = 2, FAT_LINE = 3, BLOCK = 4 SMALL_DOT = 0, FAT_DOT = 1, THIN_LINE = 2, FAT_LINE = 3, BLOCK = 4
}; };
enum FACES { MONOR, MONOB, MONOI, MONOZ, PROPR, PROPB, PROPI, PROPZ, CUSTOM, CUSTOM2 };
enum TYPES { MONOF, PROPF };
enum STYLES { FONTR, FONTB, FONTI, FONTZ };
/** /**
* Screen surface class * Screen surface class
*/ */
@ -94,13 +91,6 @@ public:
*/ */
void fillRect(const Rect &box, const byte *rgb); void fillRect(const Rect &box, const byte *rgb);
/**
* Draws the text input caret at the given position
* @remarks The position specifies the caret's bottom-left corner,
* and the X position is in multiples of GLI_SUBPIX
*/
void drawCaret(const Point &pos);
/** /**
* Draws a string using the specified font at the given co-ordinates * Draws a string using the specified font at the given co-ordinates
* @param pos Position for the bottom-left corner the text will be drawn with * @param pos Position for the bottom-left corner the text will be drawn with

View file

@ -212,8 +212,8 @@ bool Selection::getSelection(const Rect &r, int *rx0, int *rx1) const {
row = (y0 + y1) / 2; row = (y0 + y1) / 2;
upper = row - (row - y0) / 2; upper = row - (row - y0) / 2;
lower = row + (y1 - row) / 2; lower = row + (y1 - row) / 2;
above = upper - (g_conf->_leading) / 2; above = upper - (g_conf->_propInfo._leading) / 2;
below = lower + (g_conf->_leading) / 2; below = lower + (g_conf->_propInfo._leading) / 2;
cx0 = MIN(_select.left, _select.right); cx0 = MIN(_select.left, _select.right);
cx1 = MAX(_select.left, _select.right); cx1 = MAX(_select.left, _select.right);

View file

@ -245,24 +245,26 @@ void WindowStream::setZColors(uint fg, uint bg) {
back[2] = (bg) & 0xff; back[2] = (bg) & 0xff;
if (fg != zcolor_Transparent && fg != zcolor_Cursor) { if (fg != zcolor_Transparent && fg != zcolor_Cursor) {
PropFontInfo *info = &g_conf->_propInfo;
if (fg == zcolor_Default) { if (fg == zcolor_Default) {
_window->_attr.fgset = 0; _window->_attr.fgset = 0;
_window->_attr.fgcolor = 0; _window->_attr.fgcolor = 0;
Windows::_overrideFgSet = false; Windows::_overrideFgSet = false;
Windows::_overrideFgVal = 0; Windows::_overrideFgVal = 0;
Common::copy(g_conf->_moreSave, g_conf->_moreSave + 3, g_conf->_moreColor); Common::copy(info->_moreSave, info->_moreSave + 3, info->_moreColor);
Common::copy(g_conf->_caretSave, g_conf->_caretSave + 3, g_conf->_caretColor); Common::copy(info->_caretSave, info->_caretSave + 3, info->_caretColor);
Common::copy(g_conf->_linkSave, g_conf->_linkSave + 3, g_conf->_linkColor); Common::copy(info->_linkSave, info->_linkSave + 3, info->_linkColor);
} else if (fg != zcolor_Current) { } else if (fg != zcolor_Current) {
_window->_attr.fgset = 1; _window->_attr.fgset = 1;
_window->_attr.fgcolor = fg; _window->_attr.fgcolor = fg;
Windows::_overrideFgSet = true; Windows::_overrideFgSet = true;
Windows::_overrideFgVal = fg; Windows::_overrideFgVal = fg;
Common::copy(fore, fore + 3, g_conf->_moreColor); Common::copy(fore, fore + 3, info->_moreColor);
Common::copy(fore, fore + 3, g_conf->_caretColor); Common::copy(fore, fore + 3, info->_caretColor);
Common::copy(fore, fore + 3, g_conf->_linkColor); Common::copy(fore, fore + 3, info->_linkColor);
} }
} }

View file

@ -37,11 +37,11 @@ namespace Glk {
TextBufferWindow::TextBufferWindow(Windows *windows, uint rock) : Window(windows, rock), TextBufferWindow::TextBufferWindow(Windows *windows, uint rock) : Window(windows, rock),
_historyPos(0), _historyFirst(0), _historyPresent(0), _lastSeen(0), _scrollPos(0), _font(g_conf->_propInfo), _historyPos(0), _historyFirst(0), _historyPresent(0),
_scrollMax(0), _scrollBack(SCROLLBACK), _width(-1), _height(-1), _inBuf(nullptr), _lastSeen(0), _scrollPos(0), _scrollMax(0), _scrollBack(SCROLLBACK), _width(-1), _height(-1),
_lineTerminators(nullptr), _echoLineInput(true), _ladjw(0), _radjw(0), _ladjn(0), _inBuf(nullptr), _lineTerminators(nullptr), _echoLineInput(true), _ladjw(0), _radjw(0),
_radjn(0), _numChars(0), _chars(nullptr), _attrs(nullptr), _ladjn(0), _radjn(0), _numChars(0), _chars(nullptr), _attrs(nullptr), _spaced(0), _dashed(0),
_spaced(0), _dashed(0), _copyBuf(0), _copyPos(0) { _copyBuf(0), _copyPos(0) {
_type = wintype_TextBuffer; _type = wintype_TextBuffer;
_history.resize(HISTORYLEN); _history.resize(HISTORYLEN);
@ -75,11 +75,11 @@ void TextBufferWindow::rearrange(const Rect &box) {
int newwid, newhgt; int newwid, newhgt;
int rnd; int rnd;
newwid = (box.width() - g_conf->_tMarginX * 2 - g_conf->_scrollWidth) / g_conf->_cellW; newwid = (box.width() - g_conf->_tMarginX * 2 - g_conf->_scrollWidth) / _font._cellW;
newhgt = (box.height() - g_conf->_tMarginY * 2) / g_conf->_cellH; newhgt = (box.height() - g_conf->_tMarginY * 2) / _font._cellH;
// align text with bottom // align text with bottom
rnd = newhgt * g_conf->_cellH + g_conf->_tMarginY * 2; rnd = newhgt * _font._cellH + g_conf->_tMarginY * 2;
_yAdj = (box.height() - rnd); _yAdj = (box.height() - rnd);
_bbox.top += (box.height() - rnd); _bbox.top += (box.height() - rnd);
@ -245,7 +245,7 @@ bool TextBufferWindow::putPicture(Picture *pic, uint align, uint linkval) {
return false; return false;
_radjw = (pic->w + g_conf->_tMarginX) * GLI_SUBPIX; _radjw = (pic->w + g_conf->_tMarginX) * GLI_SUBPIX;
_radjn = (pic->h + g_conf->_cellH - 1) / g_conf->_cellH; _radjn = (pic->h + _font._cellH - 1) / _font._cellH;
_lines[0]._rPic = pic; _lines[0]._rPic = pic;
_lines[0]._rm = _radjw; _lines[0]._rm = _radjw;
_lines[0]._rHyper = linkval; _lines[0]._rHyper = linkval;
@ -257,7 +257,7 @@ bool TextBufferWindow::putPicture(Picture *pic, uint align, uint linkval) {
return false; return false;
_ladjw = (pic->w + g_conf->_tMarginX) * GLI_SUBPIX; _ladjw = (pic->w + g_conf->_tMarginX) * GLI_SUBPIX;
_ladjn = (pic->h + g_conf->_cellH - 1) / g_conf->_cellH; _ladjn = (pic->h + _font._cellH - 1) / _font._cellH;
_lines[0]._lPic = pic; _lines[0]._lPic = pic;
_lines[0]._lm = _ladjw; _lines[0]._lm = _ladjw;
_lines[0]._lHyper = linkval; _lines[0]._lHyper = linkval;
@ -366,12 +366,12 @@ void TextBufferWindow::touch(int line) {
_lines[line]._dirty = true; _lines[line]._dirty = true;
g_vm->_selection->clearSelection(); g_vm->_selection->clearSelection();
int y = _bbox.top + g_conf->_tMarginY + (_height - line - 1) * g_conf->_leading; int y = _bbox.top + g_conf->_tMarginY + (_height - line - 1) * _font._leading;
_windows->repaint(Rect(_bbox.left, y - 2, _bbox.right, y + g_conf->_leading + 2)); _windows->repaint(Rect(_bbox.left, y - 2, _bbox.right, y + _font._leading + 2));
} }
uint TextBufferWindow::getSplit(uint size, bool vertical) const { uint TextBufferWindow::getSplit(uint size, bool vertical) const {
return (vertical) ? size * g_conf->_cellW : size * g_conf->_cellH; return (vertical) ? size * _font._cellW : size * _font._cellH;
} }
void TextBufferWindow::putCharUni(uint32 ch) { void TextBufferWindow::putCharUni(uint32 ch) {
@ -400,9 +400,9 @@ void TextBufferWindow::putCharUni(uint32 ch) {
return; return;
} }
if (g_conf->_quotes) { if (_font._quotes) {
// fails for 'tis a wonderful day in the '80s // fails for 'tis a wonderful day in the '80s
if (g_conf->_quotes > 1 && ch == '\'') { if (_font._quotes > 1 && ch == '\'') {
if (_numChars == 0 || leftquote(_chars[_numChars - 1])) if (_numChars == 0 || leftquote(_chars[_numChars - 1]))
ch = UNI_LSQUO; ch = UNI_LSQUO;
} }
@ -421,12 +421,12 @@ void TextBufferWindow::putCharUni(uint32 ch) {
} }
} }
if (g_conf->_dashes && _attr.style != style_Preformatted) { if (_font._dashes && _attr.style != style_Preformatted) {
if (ch == '-') { if (ch == '-') {
_dashed++; _dashed++;
if (_dashed == 2) { if (_dashed == 2) {
_numChars--; _numChars--;
if (g_conf->_dashes == 2) if (_font._dashes == 2)
ch = UNI_NDASH; ch = UNI_NDASH;
else else
ch = UNI_MDASH; ch = UNI_MDASH;
@ -441,11 +441,11 @@ void TextBufferWindow::putCharUni(uint32 ch) {
} }
} }
if (g_conf->_spaces && _attr.style != style_Preformatted if (_font._spaces && _attr.style != style_Preformatted
&& _styles[_attr.style].bg == color && _styles[_attr.style].bg == color
&& !_styles[_attr.style].reverse) { && !_styles[_attr.style].reverse) {
// turn (period space space) into (period space) // turn (period space space) into (period space)
if (g_conf->_spaces == 1) { if (_font._spaces == 1) {
if (ch == '.') if (ch == '.')
_spaced = 1; _spaced = 1;
else if (ch == ' ' && _spaced == 1) else if (ch == ' ' && _spaced == 1)
@ -459,7 +459,7 @@ void TextBufferWindow::putCharUni(uint32 ch) {
} }
// Turn (per sp x) into (per sp sp x) // Turn (per sp x) into (per sp sp x)
if (g_conf->_spaces == 2) { if (_font._spaces == 2) {
if (ch == '.') if (ch == '.')
_spaced = 1; _spaced = 1;
else if (ch == ' ' && _spaced == 1) else if (ch == ' ' && _spaced == 1)
@ -789,7 +789,7 @@ void TextBufferWindow::redraw() {
int a, b; int a, b;
uint link; uint link;
int font; int font;
unsigned char *color; const byte *color;
int i; int i;
int hx0, hx1, hy0, hy1; int hx0, hx1, hy0, hy1;
int selrow, selchar, sx0, sx1, selleft, selright; int selrow, selchar, sx0, sx1, selleft, selright;
@ -818,12 +818,12 @@ void TextBufferWindow::redraw() {
for (i = _scrollPos + _height - 1; i >= _scrollPos; i--) { for (i = _scrollPos + _height - 1; i >= _scrollPos; i--) {
// top of line // top of line
y = y0 + (_height - (i - _scrollPos) - 1) * g_conf->_leading; y = y0 + (_height - (i - _scrollPos) - 1) * _font._leading;
// check if part of line is selected // check if part of line is selected
if (selBuf) { if (selBuf) {
selrow = g_vm->_selection->getSelection(Rect(x0 / GLI_SUBPIX, y, selrow = g_vm->_selection->getSelection(Rect(x0 / GLI_SUBPIX, y,
x1 / GLI_SUBPIX, y + g_conf->_leading), &sx0, &sx1); x1 / GLI_SUBPIX, y + _font._leading), &sx0, &sx1);
selleft = (sx0 == x0 / GLI_SUBPIX); selleft = (sx0 == x0 / GLI_SUBPIX);
selright = (sx1 == x1 / GLI_SUBPIX); selright = (sx1 == x1 / GLI_SUBPIX);
} else { } else {
@ -843,7 +843,7 @@ void TextBufferWindow::redraw() {
// repaint previously selected lines if needed // repaint previously selected lines if needed
if (ln->_repaint && !Windows::_forceRedraw) if (ln->_repaint && !Windows::_forceRedraw)
_windows->redrawRect(Rect(x0 / GLI_SUBPIX, y, _windows->redrawRect(Rect(x0 / GLI_SUBPIX, y,
x1 / GLI_SUBPIX, y + g_conf->_leading)); x1 / GLI_SUBPIX, y + _font._leading));
// keep selected line dirty and flag for repaint // keep selected line dirty and flag for repaint
if (!selrow) { if (!selrow) {
@ -873,7 +873,7 @@ void TextBufferWindow::redraw() {
/* /*
* count spaces and width for justification * count spaces and width for justification
*/ */
if (g_conf->_justify && !ln->_newLine && i > 0) { if (_font._justify && !ln->_newLine && i > 0) {
for (a = 0, nsp = 0; a < linelen; a++) for (a = 0, nsp = 0; a < linelen; a++)
if (ln->_chars[a] == ' ') if (ln->_chars[a] == ' ')
nsp ++; nsp ++;
@ -947,13 +947,13 @@ void TextBufferWindow::redraw() {
// clear any stored hyperlink coordinates // clear any stored hyperlink coordinates
g_vm->_selection->putHyperlink(0, x0 / GLI_SUBPIX, y, g_vm->_selection->putHyperlink(0, x0 / GLI_SUBPIX, y,
x1 / GLI_SUBPIX, y + g_conf->_leading); x1 / GLI_SUBPIX, y + _font._leading);
/* /*
* fill in background colors * fill in background colors
*/ */
color = Windows::_overrideBgSet ? g_conf->_windowColor : _bgColor; color = Windows::_overrideBgSet ? g_conf->_windowColor : _bgColor;
screen.fillRect(Rect::fromXYWH(x0 / GLI_SUBPIX, y, (x1 - x0) / GLI_SUBPIX, g_conf->_leading), screen.fillRect(Rect::fromXYWH(x0 / GLI_SUBPIX, y, (x1 - x0) / GLI_SUBPIX, _font._leading),
color); color);
x = x0 + SLOP + ln->_lm; x = x0 + SLOP + ln->_lm;
@ -964,14 +964,14 @@ void TextBufferWindow::redraw() {
font = ln->_attrs[a].attrFont(_styles); font = ln->_attrs[a].attrFont(_styles);
color = ln->_attrs[a].attrBg(_styles); color = ln->_attrs[a].attrBg(_styles);
w = screen.stringWidthUni(font, Common::U32String(ln->_chars + a, b - a), spw); w = screen.stringWidthUni(font, Common::U32String(ln->_chars + a, b - a), spw);
screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX, y, w / GLI_SUBPIX, g_conf->_leading), screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX, y, w / GLI_SUBPIX, _font._leading),
color); color);
if (link) { if (link) {
screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX + 1, y + g_conf->_baseLine + 1, screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX + 1, y + _font._baseLine + 1,
w / GLI_SUBPIX + 1, g_conf->_linkStyle), g_conf->_linkColor); w / GLI_SUBPIX + 1, _font._linkStyle), _font._linkColor);
g_vm->_selection->putHyperlink(link, x / GLI_SUBPIX, y, g_vm->_selection->putHyperlink(link, x / GLI_SUBPIX, y,
x / GLI_SUBPIX + w / GLI_SUBPIX, x / GLI_SUBPIX + w / GLI_SUBPIX,
y + g_conf->_leading); y + _font._leading);
} }
x += w; x += w;
a = b; a = b;
@ -981,18 +981,18 @@ void TextBufferWindow::redraw() {
font = ln->_attrs[a].attrFont(_styles); font = ln->_attrs[a].attrFont(_styles);
color = ln->_attrs[a].attrBg(_styles); color = ln->_attrs[a].attrBg(_styles);
w = screen.stringWidthUni(font, Common::U32String(ln->_chars + a, b - a), spw); w = screen.stringWidthUni(font, Common::U32String(ln->_chars + a, b - a), spw);
screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX, y, w / GLI_SUBPIX, g_conf->_leading), color); screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX, y, w / GLI_SUBPIX, _font._leading), color);
if (link) { if (link) {
screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX + 1, y + g_conf->_baseLine + 1, screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX + 1, y + _font._baseLine + 1,
w / GLI_SUBPIX + 1, g_conf->_linkStyle), g_conf->_linkColor); w / GLI_SUBPIX + 1, _font._linkStyle), _font._linkColor);
g_vm->_selection->putHyperlink(link, x / GLI_SUBPIX, y, g_vm->_selection->putHyperlink(link, x / GLI_SUBPIX, y,
x / GLI_SUBPIX + w / GLI_SUBPIX, x / GLI_SUBPIX + w / GLI_SUBPIX,
y + g_conf->_leading); y + _font._leading);
} }
x += w; x += w;
color = Windows::_overrideBgSet ? g_conf->_windowColor : _bgColor; color = Windows::_overrideBgSet ? g_conf->_windowColor : _bgColor;
screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX, y, x1 / GLI_SUBPIX - x / GLI_SUBPIX, g_conf->_leading), color); screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX, y, x1 / GLI_SUBPIX - x / GLI_SUBPIX, _font._leading), color);
/* /*
* draw caret * draw caret
@ -1000,8 +1000,8 @@ void TextBufferWindow::redraw() {
if (_windows->getFocusWindow() == this && i == 0 && (_lineRequest || _lineRequestUni)) { if (_windows->getFocusWindow() == this && i == 0 && (_lineRequest || _lineRequestUni)) {
w = calcWidth(_chars, _attrs, 0, _inCurs, spw); w = calcWidth(_chars, _attrs, 0, _inCurs, spw);
if (w < pw - g_conf->_caretShape * 2 * GLI_SUBPIX) if (w < pw - _font._caretShape * 2 * GLI_SUBPIX)
screen.drawCaret(Point(x0 + SLOP + ln->_lm + w, y + g_conf->_baseLine)); _font.drawCaret(Point(x0 + SLOP + ln->_lm + w, y + _font._baseLine));
} }
/* /*
@ -1014,16 +1014,16 @@ void TextBufferWindow::redraw() {
if (ln->_attrs[a] != ln->_attrs[b]) { if (ln->_attrs[a] != ln->_attrs[b]) {
link = ln->_attrs[a].hyper; link = ln->_attrs[a].hyper;
font = ln->_attrs[a].attrFont(_styles); font = ln->_attrs[a].attrFont(_styles);
color = link ? g_conf->_linkColor : ln->_attrs[a].attrFg(_styles); color = link ? _font._linkColor : ln->_attrs[a].attrFg(_styles);
x = screen.drawStringUni(Point(x, y + g_conf->_baseLine), x = screen.drawStringUni(Point(x, y + _font._baseLine),
font, color, Common::U32String(ln->_chars + a, b - a), spw); font, color, Common::U32String(ln->_chars + a, b - a), spw);
a = b; a = b;
} }
} }
link = ln->_attrs[a].hyper; link = ln->_attrs[a].hyper;
font = ln->_attrs[a].attrFont(_styles); font = ln->_attrs[a].attrFont(_styles);
color = link ? g_conf->_linkColor : ln->_attrs[a].attrFg(_styles); color = link ? _font._linkColor : ln->_attrs[a].attrFg(_styles);
screen.drawStringUni(Point(x, y + g_conf->_baseLine), font, color, Common::U32String(ln->_chars + a, linelen - a), spw); screen.drawStringUni(Point(x, y + _font._baseLine), font, color, Common::U32String(ln->_chars + a, linelen - a), spw);
} }
/* /*
@ -1031,26 +1031,26 @@ void TextBufferWindow::redraw() {
*/ */
if (_scrollPos && _height > 1) { if (_scrollPos && _height > 1) {
x = x0 + SLOP; x = x0 + SLOP;
y = y0 + (_height - 1) * g_conf->_leading; y = y0 + (_height - 1) * _font._leading;
g_vm->_selection->putHyperlink(0, x0 / GLI_SUBPIX, y, g_vm->_selection->putHyperlink(0, x0 / GLI_SUBPIX, y,
x1 / GLI_SUBPIX, y + g_conf->_leading); x1 / GLI_SUBPIX, y + _font._leading);
color = Windows::_overrideBgSet ? g_conf->_windowColor : _bgColor; color = Windows::_overrideBgSet ? g_conf->_windowColor : _bgColor;
screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX, y, x1 / GLI_SUBPIX - x / GLI_SUBPIX, g_conf->_leading), color); screen.fillRect(Rect::fromXYWH(x / GLI_SUBPIX, y, x1 / GLI_SUBPIX - x / GLI_SUBPIX, _font._leading), color);
w = screen.stringWidth(g_conf->_moreFont, g_conf->_morePrompt); w = screen.stringWidth(_font._moreFont, _font._morePrompt);
if (g_conf->_moreAlign == 1) if (_font._moreAlign == 1)
// center // center
x = x0 + SLOP + (x1 - x0 - w - SLOP * 2) / 2; x = x0 + SLOP + (x1 - x0 - w - SLOP * 2) / 2;
if (g_conf->_moreAlign == 2) if (_font._moreAlign == 2)
// right // right
x = x1 - SLOP - w; x = x1 - SLOP - w;
color = Windows::_overrideFgSet ? g_conf->_moreColor : _fgColor; color = Windows::_overrideFgSet ? _font._moreColor : _fgColor;
screen.drawString(Point(x, y + g_conf->_baseLine), screen.drawString(Point(x, y + _font._baseLine),
g_conf->_moreFont, color, g_conf->_morePrompt); _font._moreFont, color, _font._morePrompt);
y1 = y; // don't want pictures overdrawing "[more]" y1 = y; // don't want pictures overdrawing "[more]"
// try to claim the focus // try to claim the focus
@ -1058,7 +1058,7 @@ void TextBufferWindow::redraw() {
Windows::_moreFocus = true; Windows::_moreFocus = true;
} else { } else {
_moreRequest = false; _moreRequest = false;
y1 = y0 + _height * g_conf->_leading; y1 = y0 + _height * _font._leading;
} }
/* /*
@ -1067,7 +1067,7 @@ void TextBufferWindow::redraw() {
for (i = 0; i < _scrollBack; i++) { for (i = 0; i < _scrollBack; i++) {
memcpy(ln, &_lines[i], sizeof(TextBufferRow)); memcpy(ln, &_lines[i], sizeof(TextBufferRow));
y = y0 + (_height - (i - _scrollPos) - 1) * g_conf->_leading; y = y0 + (_height - (i - _scrollPos) - 1) * _font._leading;
if (ln->_lPic) { if (ln->_lPic) {
if (y < y1 && y + ln->_lPic->h > y0) { if (y < y1 && y + ln->_lPic->h > y0) {
@ -1359,7 +1359,7 @@ void TextBufferWindow::acceptReadLine(uint32 arg) {
default: default:
if (arg >= 32 && arg <= 0x10FFFF) { if (arg >= 32 && arg <= 0x10FFFF) {
if (g_conf->_caps && (arg > 0x60 && arg < 0x7b)) if (_font._caps && (arg > 0x60 && arg < 0x7b))
arg -= 0x20; arg -= 0x20;
putTextUni(&arg, 1, _inCurs, 0); putTextUni(&arg, 1, _inCurs, 0);
} }
@ -1609,9 +1609,9 @@ int TextBufferWindow::calcWidth(uint32 *chars, Attributes *attrs, int startchar,
void TextBufferWindow::getSize(uint *width, uint *height) const { void TextBufferWindow::getSize(uint *width, uint *height) const {
if (width) if (width)
*width = (_bbox.width() - g_conf->_tMarginX * 2) / g_conf->_cellW; *width = (_bbox.width() - g_conf->_tMarginX * 2) / _font._cellW;
if (height) if (height)
*height = (_bbox.height() - g_conf->_tMarginY * 2) / g_conf->_cellH; *height = (_bbox.height() - g_conf->_tMarginY * 2) / _font._cellH;
} }
void TextBufferWindow::flowBreak() { void TextBufferWindow::flowBreak() {

View file

@ -26,6 +26,7 @@
#include "glk/windows.h" #include "glk/windows.h"
#include "glk/picture.h" #include "glk/picture.h"
#include "glk/speech.h" #include "glk/speech.h"
#include "glk/conf.h"
#include "common/array.h" #include "common/array.h"
#include "common/ustr.h" #include "common/ustr.h"
@ -53,6 +54,8 @@ class TextBufferWindow : public Window, Speech {
TextBufferRow(); TextBufferRow();
}; };
typedef Common::Array<TextBufferRow> TextBufferRows; typedef Common::Array<TextBufferRow> TextBufferRows;
private:
PropFontInfo &_font;
private: private:
void reflow(); void reflow();
void touchScroll(); void touchScroll();
@ -149,6 +152,11 @@ public:
uint drawPicture(uint image, uint align, uint scaled, uint width, uint height); uint drawPicture(uint image, uint align, uint scaled, uint width, uint height);
/**
* Get the font info structure associated with the window
*/
virtual FontInfo *getFontInfo() override { return &_font; }
/** /**
* Rearranges the window * Rearranges the window
*/ */

View file

@ -28,7 +28,8 @@
namespace Glk { namespace Glk {
TextGridWindow::TextGridWindow(Windows *windows, uint rock) : Window(windows, rock) { TextGridWindow::TextGridWindow(Windows *windows, uint rock) : Window(windows, rock),
_font(g_conf->_monoInfo) {
_type = wintype_TextGrid; _type = wintype_TextGrid;
_width = _height = 0; _width = _height = 0;
_curX = _curY = 0; _curX = _curY = 0;
@ -56,8 +57,8 @@ void TextGridWindow::rearrange(const Rect &box) {
Window::rearrange(box); Window::rearrange(box);
int newwid, newhgt; int newwid, newhgt;
newwid = box.width() / g_conf->_cellW; newwid = box.width() / _font._cellW;
newhgt = box.height() / g_conf->_cellH; newhgt = box.height() / _font._cellH;
if (newwid == _width && newhgt == _height) if (newwid == _width && newhgt == _height)
return; return;
@ -74,13 +75,13 @@ void TextGridWindow::rearrange(const Rect &box) {
} }
void TextGridWindow::touch(int line) { void TextGridWindow::touch(int line) {
int y = _bbox.top + line * g_conf->_leading; int y = _bbox.top + line * _font._leading;
_lines[line].dirty = true; _lines[line].dirty = true;
_windows->repaint(Rect(_bbox.left, y, _bbox.right, y + g_conf->_leading)); _windows->repaint(Rect(_bbox.left, y, _bbox.right, y + _font._leading));
} }
uint TextGridWindow::getSplit(uint size, bool vertical) const { uint TextGridWindow::getSplit(uint size, bool vertical) const {
return vertical ? size * g_conf->_cellW : size * g_conf->_cellH; return vertical ? size * _font._cellW : size * _font._cellH;
} }
void TextGridWindow::putCharUni(uint32 ch) { void TextGridWindow::putCharUni(uint32 ch) {
@ -197,7 +198,7 @@ void TextGridWindow::click(const Point &newPos) {
_windows->setFocus(this); _windows->setFocus(this);
if (_mouseRequest) { if (_mouseRequest) {
g_vm->_events->store(evtype_MouseInput, this, x / g_conf->_cellW, y / g_conf->_leading); g_vm->_events->store(evtype_MouseInput, this, x / _font._cellW, y / _font._leading);
_mouseRequest = false; _mouseRequest = false;
if (g_conf->_safeClicks) if (g_conf->_safeClicks)
g_vm->_events->_forceClick = true; g_vm->_events->_forceClick = true;
@ -546,7 +547,7 @@ void TextGridWindow::acceptReadLine(uint32 arg) {
if (arg < 32 || arg > 0xff) if (arg < 32 || arg > 0xff)
return; return;
if (g_conf->_caps && (arg > 0x60 && arg < 0x7b)) if (_font._caps && (arg > 0x60 && arg < 0x7b))
arg -= 0x20; arg -= 0x20;
for (ix = _inLen; ix > _inCurs; ix--) for (ix = _inLen; ix > _inCurs; ix--)
@ -571,7 +572,7 @@ void TextGridWindow::redraw() {
int i, a, b, k, o; int i, a, b, k, o;
uint link; uint link;
int font; int font;
byte *fgcolor, *bgcolor; const byte *fgcolor, *bgcolor;
Screen &screen = *g_vm->_screen; Screen &screen = *g_vm->_screen;
Window::redraw(); Window::redraw();
@ -585,30 +586,30 @@ void TextGridWindow::redraw() {
ln->dirty = false; ln->dirty = false;
x = x0; x = x0;
y = y0 + i * g_conf->_leading; y = y0 + i * _font._leading;
// clear any stored hyperlink coordinates // clear any stored hyperlink coordinates
g_vm->_selection->putHyperlink(0, x0, y, x0 + g_conf->_cellW * _width, y + g_conf->_leading); g_vm->_selection->putHyperlink(0, x0, y, x0 + _font._cellW * _width, y + _font._leading);
a = 0; a = 0;
for (b = 0; b < _width; b++) { for (b = 0; b < _width; b++) {
if (ln->_attrs[a] != ln->_attrs[b]) { if (ln->_attrs[a] != ln->_attrs[b]) {
link = ln->_attrs[a].hyper; link = ln->_attrs[a].hyper;
font = ln->_attrs[a].attrFont(_styles); font = ln->_attrs[a].attrFont(_styles);
fgcolor = link ? g_conf->_linkColor : ln->_attrs[a].attrFg(_styles); fgcolor = link ? _font._linkColor : ln->_attrs[a].attrFg(_styles);
bgcolor = ln->_attrs[a].attrBg(_styles); bgcolor = ln->_attrs[a].attrBg(_styles);
w = (b - a) * g_conf->_cellW; w = (b - a) * _font._cellW;
screen.fillRect(Rect::fromXYWH(x, y, w, g_conf->_leading), bgcolor); screen.fillRect(Rect::fromXYWH(x, y, w, _font._leading), bgcolor);
o = x; o = x;
for (k = a, o = x; k < b; k++, o += g_conf->_cellW) { for (k = a, o = x; k < b; k++, o += _font._cellW) {
screen.drawStringUni(Point(o * GLI_SUBPIX, y + g_conf->_baseLine), font, screen.drawStringUni(Point(o * GLI_SUBPIX, y + _font._baseLine), font,
fgcolor, Common::U32String(&ln->_chars[k], 1), -1); fgcolor, Common::U32String(&ln->_chars[k], 1), -1);
} }
if (link) { if (link) {
screen.fillRect(Rect::fromXYWH(x, y + g_conf->_baseLine + 1, w, screen.fillRect(Rect::fromXYWH(x, y + _font._baseLine + 1, w,
g_conf->_linkStyle), g_conf->_linkColor); _font._linkStyle), _font._linkColor);
g_vm->_selection->putHyperlink(link, x, y, x + w, y + g_conf->_leading); g_vm->_selection->putHyperlink(link, x, y, x + w, y + _font._leading);
} }
x += w; x += w;
@ -617,20 +618,19 @@ void TextGridWindow::redraw() {
} }
link = ln->_attrs[a].hyper; link = ln->_attrs[a].hyper;
font = ln->_attrs[a].attrFont(_styles); font = ln->_attrs[a].attrFont(_styles);
fgcolor = link ? g_conf->_linkColor : ln->_attrs[a].attrFg(_styles); fgcolor = link ? _font._linkColor : ln->_attrs[a].attrFg(_styles);
bgcolor = ln->_attrs[a].attrBg(_styles); bgcolor = ln->_attrs[a].attrBg(_styles);
w = (b - a) * g_conf->_cellW; w = (b - a) * _font._cellW;
w += _bbox.right - (x + w); w += _bbox.right - (x + w);
screen.fillRect(Rect::fromXYWH(x, y, w, g_conf->_leading), bgcolor); screen.fillRect(Rect::fromXYWH(x, y, w, _font._leading), bgcolor);
for (k = a, o = x; k < b; k++, o += g_conf->_cellW) { for (k = a, o = x; k < b; k++, o += _font._cellW) {
screen.drawStringUni(Point(o * GLI_SUBPIX, y + g_conf->_baseLine), font, screen.drawStringUni(Point(o * GLI_SUBPIX, y + _font._baseLine), font,
fgcolor, Common::U32String(&ln->_chars[k], 1)); fgcolor, Common::U32String(&ln->_chars[k], 1));
} }
if (link) { if (link) {
screen.fillRect(Rect::fromXYWH(x, y + g_conf->_baseLine + 1, w, g_conf->_linkStyle), screen.fillRect(Rect::fromXYWH(x, y + _font._baseLine + 1, w, _font._linkStyle), _font._linkColor);
g_conf->_linkColor); g_vm->_selection->putHyperlink(link, x, y, x + w, y + _font._leading);
g_vm->_selection->putHyperlink(link, x, y, x + w, y + g_conf->_leading);
} }
} }
} }
@ -638,9 +638,9 @@ void TextGridWindow::redraw() {
void TextGridWindow::getSize(uint *width, uint *height) const { void TextGridWindow::getSize(uint *width, uint *height) const {
if (width) if (width)
*width = _bbox.width() / g_conf->_cellW; *width = _bbox.width() / _font._cellW;
if (height) if (height)
*height = _bbox.height() / g_conf->_cellH; *height = _bbox.height() / _font._cellH;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/

View file

@ -24,6 +24,7 @@
#define GLK_WINDOW_TEXT_GRID_H #define GLK_WINDOW_TEXT_GRID_H
#include "glk/windows.h" #include "glk/windows.h"
#include "glk/conf.h"
namespace Glk { namespace Glk {
@ -50,6 +51,8 @@ class TextGridWindow : public Window {
void resize(size_t newSize); void resize(size_t newSize);
}; };
typedef Common::Array<TextGridRow> TextGridRows; typedef Common::Array<TextGridRow> TextGridRows;
private:
MonoFontInfo &_font;
private: private:
/** /**
* Mark a given text row as modified * Mark a given text row as modified
@ -87,6 +90,11 @@ public:
*/ */
virtual ~TextGridWindow(); virtual ~TextGridWindow();
/**
* Get the font info structure associated with the window
*/
virtual FontInfo *getFontInfo() override { return &_font; }
/** /**
* Rearranges the window * Rearranges the window
*/ */

View file

@ -502,7 +502,7 @@ Window::Window(Windows *windows, uint rock) : _windows(windows), _rock(rock),
_attr.hyper = 0; _attr.hyper = 0;
Common::copy(&g_conf->_windowColor[0], &g_conf->_windowColor[3], &_bgColor[0]); Common::copy(&g_conf->_windowColor[0], &g_conf->_windowColor[3], &_bgColor[0]);
Common::copy(&g_conf->_moreColor[0], &g_conf->_moreColor[3], _fgColor); Common::copy(&g_conf->_propInfo._moreColor[0], &g_conf->_propInfo._moreColor[3], _fgColor);
_dispRock.num = 0; _dispRock.num = 0;
Streams &streams = *g_vm->_streams; Streams &streams = *g_vm->_streams;
@ -562,6 +562,10 @@ void Window::close(bool recurse) {
delete this; delete this;
} }
FontInfo *Window::getFontInfo() {
error("Tried to get font info for a non-text window");
}
void Window::cancelLineEvent(Event *ev) { void Window::cancelLineEvent(Event *ev) {
Event dummyEv; Event dummyEv;
if (!ev) if (!ev)

View file

@ -28,6 +28,7 @@
#include "common/rect.h" #include "common/rect.h"
#include "graphics/screen.h" #include "graphics/screen.h"
#include "glk/events.h" #include "glk/events.h"
#include "glk/fonts.h"
#include "glk/glk_types.h" #include "glk/glk_types.h"
#include "glk/screen.h" #include "glk/screen.h"
#include "glk/selection.h" #include "glk/selection.h"
@ -413,6 +414,11 @@ public:
*/ */
void close(bool recurse = true); void close(bool recurse = true);
/**
* Get the font info structure associated with the window
*/
virtual FontInfo *getFontInfo();
/** /**
* Rearranges the window * Rearranges the window
*/ */