/* 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 . * */ #include "engines/freescape/freescape.h" #include "engines/freescape/font.h" namespace Freescape { Common::String shiftStr(const Common::String &str, int shift) { Common::String result; for (int i = 0; i < int(str.size()); i++) { int c = shift + str[i]; assert(c < 256); result += char(c); } return result; } Common::String centerAndPadString(const Common::String &str, int size) { Common::String result; if (int(str.size()) >= size) return str; int padding = (size - str.size()) / 2; for (int i = 0; i < padding; i++) result += " "; result += str; if (int(result.size()) >= size) return result; padding = size - result.size(); for (int i = 0; i < padding; i++) result += " "; return result; } Font::Font() { _backgroundColor = 0; _secondaryColor = 0; _kerningOffset = 0; _charWidth = 0; _chars.clear(); } Font::Font(Common::Array &chars) { _chars = chars; _backgroundColor = 0; _secondaryColor = 0; _kerningOffset = 0; _charWidth = 8; } Font::~Font() { /*for (Graphics::ManagedSurface *surface : _chars) { surface->free(); delete surface; }*/ } int Font::getCharWidth(uint32 chr) const { return _charWidth; } int Font::getMaxCharWidth() const { return getCharWidth(0); } int Font::getFontHeight() const { return _chars[0]->h + 1; } void Font::setSecondaryColor(uint32 color) { _secondaryColor = color; } void Font::setBackground(uint32 color) { _backgroundColor = color; } void Font::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const { assert(chr >= 32); chr -= 32; // Check if the character drawing is completely contained in the surface // Make sure you use the correct width for the character int height = getCharWidth(chr); int width = getCharWidth(chr); if (x < 0 || y < 0 || x + width > dst->w || y + height > dst->h) { //warning("drawChar: Character %d (%c) is out of bounds at (%d, %d)", chr + 32, char(chr + 32), x, y); return; } Graphics::ManagedSurface surface = Graphics::ManagedSurface(); surface.copyFrom(*_chars[chr]); uint8 rb, gb, bb; uint8 rp, gp, bp; uint8 rs, gs, bs; dst->format.colorToRGB(color, rp, gp, bp); dst->format.colorToRGB(_secondaryColor, rs, gs, bs); dst->format.colorToRGB(_backgroundColor, rb, gb, bb); byte palette[3][3] = { { rb, gb, bb }, { rp, gp, bp }, { rs, gs, bs }, }; if (surface.format != dst->format) surface.convertToInPlace(dst->format, (byte *)palette, 3); if (_backgroundColor == dst->format.ARGBToColor(0x00, 0x00, 0x00, 0x00)) dst->copyRectToSurfaceWithKey(surface, x, y, Common::Rect(0, 0, MIN(int(surface.w), _charWidth), surface.h), dst->format.ARGBToColor(0xFF, 0x00, 0x00, 0x00)); else dst->copyRectToSurface(surface, x, y, Common::Rect(0, 0, MIN(int(surface.w), _charWidth), surface.h)); surface.free(); } Common::Array FreescapeEngine::getChars(Common::SeekableReadStream *file, int offset, int charsNumber) { byte *fontBuffer = (byte *)malloc(6 * charsNumber); file->seek(offset); file->read(fontBuffer, 6 * charsNumber); Common::BitArray font; font.set_size(48 * charsNumber); // Enough to hold characters for all platforms font.set_bits(fontBuffer); Common::Array chars; int sizeX = 8; int sizeY = 6; int additional = isEclipse() ? 0 : 1; for (int c = 0; c < charsNumber - 1; c++) { int position = sizeX * sizeY * c; Graphics::ManagedSurface *surface = new Graphics::ManagedSurface(); int charWidth = sizeX; if (_renderMode == Common::kRenderHercG || isC64()) charWidth *= 2; surface->create(charWidth, sizeY, Graphics::PixelFormat::createFormatCLUT8()); for (int j = 0; j < sizeY; j++) { for (int i = 0; i < sizeX; i++) { if (font.get(position + additional + j * 8 + i)) { if (_renderMode == Common::kRenderHercG || isC64()) { surface->setPixel(2 * (7 - i), j, 1); surface->setPixel(2 * (7 - i) + 1, j, 1); } else { surface->setPixel(7 - i, j, 1); } } } } chars.push_back(surface); } return chars; } Common::Array FreescapeEngine::getCharsAmigaAtariInternal(int sizeX, int sizeY, int additional, int m1, int m2, Common::SeekableReadStream *file, int offset, int charsNumber) { file->seek(offset); int fontSize = 4654; byte *fontBuffer = (byte *)malloc(fontSize); file->read(fontBuffer, fontSize); Common::BitArray font; font.set_size(8 * fontSize); font.set_bits(fontBuffer); Common::Array chars; for (int c = 0; c < charsNumber - 1; c++) { int position = 8 * (m1 * c + 1); Graphics::ManagedSurface *surface = new Graphics::ManagedSurface(); surface->create(sizeX, sizeY, Graphics::PixelFormat::createFormatCLUT8()); for (int j = 0; j < sizeY; j++) { for (int i = 0; i < sizeX; i++) { if (font.get(position + additional + j * m2 + i + 7)) surface->setPixel(7 - i, j, 2); else if (font.get(position + j * m2 + i)) { surface->setPixel(7 - i, j, 1); } else surface->setPixel(7 - i, j, 0); } } chars.push_back(surface); } free(fontBuffer); return chars; } Common::Array FreescapeEngine::getCharsAmigaAtari(Common::SeekableReadStream *file, int offset, int charsNumber) { return getCharsAmigaAtariInternal(8, 8, isEclipse() ? 0 : 1, isDriller() ? 33 : 16, isDriller() ? 32 : 16, file, offset, charsNumber); } void FreescapeEngine::drawStringInSurface(const Common::String &str, int x, int y, uint32 fontColor, uint32 backColor, Graphics::Surface *surface, int offset) { Common::String ustr = str; if (!isEclipse()) ustr.toUppercase(); _font.setBackground(backColor); _font.drawString(surface, ustr, x, y, _screenW, fontColor); } void FreescapeEngine::drawStringInSurface(const Common::String &str, int x, int y, uint32 primaryColor, uint32 secondaryColor, uint32 backColor, Graphics::Surface *surface, int offset) { Common::String ustr = str; ustr.toUppercase(); _font.setBackground(backColor); _font.setSecondaryColor(secondaryColor); _font.drawString(surface, ustr, x, y, _screenW, primaryColor); } } // End of namespace Freescape