Initial commit
This commit is contained in:
319
graphics/fonts/amigafont.cpp
Normal file
319
graphics/fonts/amigafont.cpp
Normal file
@@ -0,0 +1,319 @@
|
||||
/* 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/stream.h"
|
||||
#include "common/memstream.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "graphics/fonts/amigafont.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
// For the data source and license look into gui/themes/fonts/topaz in ScummVM distribution
|
||||
static const byte amigaTopazFont[2600] = {
|
||||
0x00, 0x00, 0x03, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x79, 0x00, 0x00, 0x03, 0xe9, 0x00, 0x00, 0x02, 0x79,
|
||||
0x70, 0xff, 0x4e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x1a, 0x0f, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x45, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x09, 0x74, 0x00, 0x08,
|
||||
0x00, 0x40, 0x00, 0x08, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x20, 0xff, 0x00, 0x00, 0x00, 0x6e,
|
||||
0x00, 0xbe, 0x00, 0x00, 0x06, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
|
||||
0x6c, 0x6c, 0x18, 0x00, 0x38, 0x18, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3c, 0x18,
|
||||
0x3c, 0x3c, 0x1c, 0x7e, 0x1c, 0x7e, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7c, 0x3c,
|
||||
0x7c, 0x1e, 0x78, 0x7e, 0x7e, 0x3c, 0x66, 0x3c, 0x06, 0xc6, 0x60, 0xc6, 0xc6, 0x3c, 0x7c, 0x78,
|
||||
0x7c, 0x3c, 0x7e, 0x66, 0x66, 0xc6, 0xc3, 0xc3, 0xfe, 0x3c, 0xc0, 0x3c, 0x10, 0x00, 0x18, 0x00,
|
||||
0x60, 0x00, 0x06, 0x00, 0x1c, 0x00, 0x60, 0x18, 0x0c, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x70, 0x72, 0x0f, 0x00, 0x18,
|
||||
0x00, 0x1c, 0x42, 0xc3, 0x18, 0x3c, 0x66, 0x7e, 0x1c, 0x00, 0x3e, 0x7e, 0x7e, 0x3c, 0x18, 0x78,
|
||||
0x78, 0x18, 0x00, 0x3e, 0x00, 0x00, 0x30, 0x38, 0x00, 0x40, 0x40, 0xc0, 0x18, 0x3c, 0x3c, 0x7e,
|
||||
0x06, 0x66, 0x18, 0x7e, 0x7e, 0x36, 0x0c, 0x0c, 0x18, 0x3c, 0xc6, 0x3c, 0x60, 0x76, 0x18, 0x00,
|
||||
0x0c, 0x7e, 0x71, 0x66, 0x00, 0x66, 0x60, 0x0e, 0x7e, 0x66, 0x18, 0x6e, 0x3c, 0x00, 0x18, 0x7e,
|
||||
0x06, 0x66, 0x18, 0x00, 0x7e, 0x34, 0x0c, 0x0c, 0x18, 0x0c, 0x60, 0x00, 0x18, 0x3c, 0x0c, 0x00,
|
||||
0x0c, 0x00, 0x71, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x7e, 0x00, 0x18, 0x3c, 0x00, 0x18, 0x6c, 0x6c,
|
||||
0x3e, 0x66, 0x6c, 0x18, 0x18, 0x18, 0x66, 0x18, 0x00, 0x00, 0x00, 0x06, 0x66, 0x38, 0x66, 0x66,
|
||||
0x3c, 0x60, 0x30, 0x06, 0x66, 0x66, 0x18, 0x18, 0x06, 0x00, 0x60, 0x66, 0xc6, 0x66, 0x66, 0x30,
|
||||
0x6c, 0x60, 0x60, 0x66, 0x66, 0x18, 0x06, 0xcc, 0x60, 0xee, 0xe6, 0x66, 0x66, 0xcc, 0x66, 0x66,
|
||||
0x18, 0x66, 0x66, 0xc6, 0x66, 0x66, 0x0c, 0x30, 0x60, 0x0c, 0x38, 0x00, 0x18, 0x00, 0x60, 0x00,
|
||||
0x06, 0x00, 0x30, 0x00, 0x60, 0x00, 0x00, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x9c, 0x3c, 0x7e, 0x00, 0x0c, 0x36,
|
||||
0x3c, 0x66, 0x18, 0x60, 0x66, 0x81, 0x24, 0x33, 0x06, 0x81, 0x00, 0x66, 0x18, 0x0c, 0x0c, 0x30,
|
||||
0x00, 0x7a, 0x00, 0x00, 0x70, 0x44, 0xcc, 0xc6, 0xc6, 0x23, 0x00, 0x66, 0x18, 0x00, 0x1c, 0x00,
|
||||
0x24, 0x60, 0x00, 0x1c, 0x18, 0x18, 0x00, 0x66, 0xcc, 0x00, 0x60, 0x3c, 0x30, 0xc6, 0x18, 0x00,
|
||||
0x8e, 0x00, 0xc6, 0x66, 0x60, 0x38, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x0c, 0x00,
|
||||
0x24, 0x00, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x7e,
|
||||
0x8e, 0x66, 0x18, 0x00, 0x18, 0x18, 0x00, 0x66, 0x00, 0x18, 0x00, 0x18, 0x00, 0xfe, 0x60, 0xac,
|
||||
0x68, 0x30, 0x30, 0x0c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x6e, 0x78, 0x06, 0x06, 0x6c, 0x7c,
|
||||
0x60, 0x06, 0x66, 0x66, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x06, 0xde, 0x66, 0x66, 0x60, 0x66, 0x60,
|
||||
0x60, 0x60, 0x66, 0x18, 0x06, 0xd8, 0x60, 0xfe, 0xf6, 0x66, 0x66, 0xcc, 0x66, 0x70, 0x18, 0x66,
|
||||
0x66, 0xc6, 0x3c, 0x3c, 0x18, 0x30, 0x30, 0x0c, 0x6c, 0x00, 0x0c, 0x3c, 0x7c, 0x3c, 0x3e, 0x3c,
|
||||
0x7c, 0x3e, 0x7c, 0x18, 0x0c, 0x66, 0x18, 0xec, 0x7c, 0x3c, 0x7c, 0x3e, 0x7c, 0x3c, 0x7c, 0x66,
|
||||
0x66, 0xc6, 0xc6, 0x66, 0x7e, 0x18, 0x18, 0x18, 0x00, 0xf0, 0x66, 0x18, 0x3e, 0x30, 0x66, 0x3c,
|
||||
0x18, 0x3c, 0x00, 0x9d, 0x44, 0x66, 0x00, 0xb9, 0x00, 0x3c, 0x7e, 0x18, 0x18, 0x60, 0x66, 0x7a,
|
||||
0x18, 0x00, 0x30, 0x44, 0x66, 0x4c, 0x4c, 0x66, 0x18, 0x66, 0x18, 0x3c, 0x3c, 0x3c, 0x3c, 0x60,
|
||||
0x7e, 0x3c, 0x7e, 0x7e, 0x7e, 0x60, 0xd8, 0x3c, 0x60, 0x66, 0xc6, 0xe6, 0x3c, 0x3c, 0x3c, 0x3c,
|
||||
0x6c, 0x66, 0x6c, 0x66, 0x66, 0x66, 0x7e, 0x7e, 0x66, 0x3c, 0x18, 0x3c, 0x18, 0x3c, 0x3c, 0x3c,
|
||||
0x3c, 0x18, 0x3c, 0x7e, 0x3c, 0x3e, 0x6c, 0x00, 0x18, 0x3c, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x66, 0x1e, 0x3c, 0x66, 0x00, 0x7e, 0x7e, 0x00, 0x18, 0x00, 0x6c, 0x3c, 0xd8, 0x76, 0x00,
|
||||
0x30, 0x0c, 0xff, 0x7e, 0x00, 0x7e, 0x00, 0x18, 0x7e, 0x18, 0x0c, 0x1c, 0xcc, 0x06, 0x7c, 0x0c,
|
||||
0x3c, 0x3e, 0x00, 0x00, 0x60, 0x00, 0x06, 0x0c, 0xd6, 0x7e, 0x7c, 0x60, 0x66, 0x78, 0x78, 0x6e,
|
||||
0x7e, 0x18, 0x06, 0xf0, 0x60, 0xd6, 0xde, 0x66, 0x7c, 0xcc, 0x7c, 0x3c, 0x18, 0x66, 0x66, 0xd6,
|
||||
0x18, 0x18, 0x30, 0x30, 0x18, 0x0c, 0xc6, 0x00, 0x00, 0x06, 0x66, 0x60, 0x66, 0x66, 0x30, 0x66,
|
||||
0x66, 0x18, 0x0c, 0x6c, 0x18, 0xfe, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x30, 0x66, 0x66, 0xc6,
|
||||
0x6c, 0x66, 0x0c, 0x70, 0x18, 0x0e, 0x00, 0xc3, 0x66, 0x18, 0x6c, 0x78, 0x3c, 0x18, 0x00, 0x66,
|
||||
0x00, 0xb1, 0x3c, 0xcc, 0x00, 0xa5, 0x00, 0x00, 0x18, 0x30, 0x0c, 0x00, 0x66, 0x3a, 0x18, 0x00,
|
||||
0x30, 0x38, 0x33, 0x58, 0x58, 0x2c, 0x30, 0x7e, 0x18, 0x66, 0x66, 0x66, 0x66, 0x78, 0x60, 0x66,
|
||||
0x60, 0x4c, 0x60, 0x6e, 0xf0, 0x18, 0x60, 0x30, 0xe6, 0xf6, 0x66, 0x66, 0x66, 0x66, 0x38, 0x66,
|
||||
0x70, 0x30, 0x66, 0x66, 0x4c, 0x4c, 0x6c, 0x06, 0x18, 0x06, 0x3c, 0x06, 0x06, 0x66, 0x66, 0x3c,
|
||||
0x66, 0x0c, 0x66, 0x66, 0x78, 0x18, 0x18, 0x60, 0x7c, 0x66, 0x3c, 0x3c, 0x3c, 0x3c, 0x7e, 0x66,
|
||||
0x78, 0x60, 0x66, 0x66, 0x0c, 0x0c, 0x00, 0x18, 0x00, 0xfe, 0x06, 0x36, 0xdc, 0x00, 0x30, 0x0c,
|
||||
0x3c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x76, 0x18, 0x18, 0x06, 0xfe, 0x06, 0x66, 0x18, 0x66, 0x06,
|
||||
0x00, 0x00, 0x18, 0x7e, 0x18, 0x18, 0xde, 0x66, 0x66, 0x60, 0x66, 0x60, 0x60, 0x66, 0x66, 0x18,
|
||||
0x06, 0xd8, 0x60, 0xc6, 0xce, 0x66, 0x60, 0xcc, 0x6c, 0x0e, 0x18, 0x66, 0x3c, 0xfe, 0x3c, 0x18,
|
||||
0x60, 0x30, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x60, 0x66, 0x7e, 0x30, 0x66, 0x66, 0x18,
|
||||
0x0c, 0x78, 0x18, 0xd6, 0x66, 0x66, 0x66, 0x66, 0x60, 0x3c, 0x30, 0x66, 0x66, 0xd6, 0x38, 0x66,
|
||||
0x18, 0x18, 0x18, 0x18, 0x00, 0x0f, 0x66, 0x18, 0x3e, 0x30, 0x42, 0x3c, 0x18, 0x3c, 0x00, 0x9d,
|
||||
0x00, 0x66, 0x00, 0xb9, 0x00, 0x00, 0x18, 0x7c, 0x78, 0x00, 0x66, 0x0a, 0x00, 0x00, 0x30, 0x00,
|
||||
0x66, 0x32, 0x3e, 0xd9, 0x60, 0x66, 0x18, 0x7e, 0x40, 0x7e, 0x7e, 0x60, 0x78, 0x40, 0x78, 0x18,
|
||||
0x78, 0x66, 0xd8, 0x18, 0x60, 0x0c, 0xf6, 0xde, 0x66, 0x66, 0x66, 0x66, 0x6c, 0x66, 0xe0, 0x0c,
|
||||
0x66, 0x66, 0x18, 0x18, 0x66, 0x3e, 0x18, 0x3e, 0x60, 0x3e, 0x3e, 0x7e, 0x7e, 0x60, 0x7e, 0x18,
|
||||
0x7e, 0x66, 0x6c, 0x18, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x18, 0x3c,
|
||||
0x66, 0x66, 0x18, 0x18, 0x00, 0x00, 0x00, 0x6c, 0x7c, 0x6a, 0xce, 0x00, 0x18, 0x18, 0x66, 0x18,
|
||||
0x18, 0x00, 0x18, 0x60, 0x66, 0x18, 0x30, 0x66, 0x0c, 0x66, 0x66, 0x18, 0x66, 0x0c, 0x18, 0x18,
|
||||
0x06, 0x00, 0x60, 0x00, 0xc0, 0x66, 0x66, 0x30, 0x6c, 0x60, 0x60, 0x66, 0x66, 0x18, 0x66, 0xcc,
|
||||
0x60, 0xc6, 0xc6, 0x66, 0x60, 0xdc, 0x66, 0x66, 0x18, 0x66, 0x3c, 0xee, 0x66, 0x18, 0xc0, 0x30,
|
||||
0x06, 0x0c, 0x00, 0x00, 0x00, 0x66, 0x66, 0x60, 0x66, 0x60, 0x30, 0x3e, 0x66, 0x18, 0x0c, 0x6c,
|
||||
0x18, 0xc6, 0x66, 0x66, 0x7c, 0x3e, 0x60, 0x06, 0x30, 0x66, 0x3c, 0xfe, 0x6c, 0x3c, 0x30, 0x18,
|
||||
0x18, 0x18, 0x00, 0x3c, 0x66, 0x18, 0x0c, 0x30, 0x00, 0x18, 0x18, 0x06, 0x00, 0x81, 0x7e, 0x33,
|
||||
0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x0a, 0x00, 0x00, 0x00, 0x7c, 0xcc, 0x66,
|
||||
0x62, 0x33, 0x66, 0x66, 0x18, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x66, 0x60, 0x32, 0x60, 0x3e,
|
||||
0xcc, 0x18, 0x7e, 0x66, 0xde, 0xce, 0x66, 0x66, 0x66, 0x66, 0xc6, 0x66, 0x60, 0x66, 0x66, 0x66,
|
||||
0x32, 0x32, 0x66, 0x66, 0x18, 0x66, 0x60, 0x66, 0x66, 0x60, 0x60, 0x60, 0x60, 0x30, 0x60, 0x3e,
|
||||
0x66, 0x18, 0x18, 0x06, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x18, 0x66, 0x18, 0x06, 0x66, 0x66,
|
||||
0x30, 0x30, 0x00, 0x18, 0x00, 0x6c, 0x18, 0xcc, 0x7b, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x18, 0x00,
|
||||
0x18, 0xc0, 0x3c, 0x18, 0x7e, 0x3c, 0x0c, 0x3c, 0x3c, 0x18, 0x3c, 0x38, 0x18, 0x18, 0x00, 0x00,
|
||||
0x00, 0x18, 0x78, 0x66, 0x7c, 0x1e, 0x78, 0x7e, 0x60, 0x3e, 0x66, 0x3c, 0x3c, 0xc6, 0x7e, 0xc6,
|
||||
0xc6, 0x3c, 0x60, 0x7e, 0x66, 0x3c, 0x18, 0x3c, 0x18, 0xc6, 0xc3, 0x18, 0xfe, 0x3c, 0x03, 0x3c,
|
||||
0x00, 0x00, 0x00, 0x3e, 0x7c, 0x3c, 0x3e, 0x3c, 0x30, 0x06, 0x66, 0x0c, 0x0c, 0x66, 0x0c, 0xc6,
|
||||
0x66, 0x3c, 0x60, 0x06, 0x60, 0x7c, 0x1c, 0x3e, 0x18, 0x6c, 0xc6, 0x18, 0x7e, 0x0e, 0x18, 0x70,
|
||||
0x00, 0xf0, 0x7e, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x3c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x81,
|
||||
0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7f, 0x0a, 0x00, 0x18, 0x00, 0x00, 0x00, 0xcf, 0xc4, 0x67,
|
||||
0x3c, 0x67, 0x3e, 0x66, 0x3c, 0x66, 0x66, 0x7f, 0x7e, 0x3c, 0x7e, 0x7e, 0x7e, 0x18, 0x30, 0x3c,
|
||||
0x18, 0x3c, 0xce, 0x18, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x3f, 0x7e, 0x3c, 0x3c, 0x3c, 0x7e, 0x7e,
|
||||
0x6c, 0x3f, 0x1e, 0x3e, 0x3c, 0x3e, 0x3e, 0x3c, 0x3c, 0x3c, 0x3c, 0x7e, 0x3c, 0x06, 0x18, 0x0c,
|
||||
0x0c, 0x7c, 0x66, 0x18, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x3f, 0x0c, 0x7c, 0x3e, 0x3e, 0x7e, 0x7e,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x01, 0x00, 0x03,
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x00, 0x30, 0x00,
|
||||
0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x03,
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x00, 0x18, 0x00,
|
||||
0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x08, 0x00, 0x18, 0x00, 0x08, 0x00, 0x20,
|
||||
0x00, 0x08, 0x00, 0x28, 0x00, 0x08, 0x00, 0x30, 0x00, 0x08, 0x00, 0x38, 0x00, 0x08, 0x00, 0x40,
|
||||
0x00, 0x08, 0x00, 0x48, 0x00, 0x08, 0x00, 0x50, 0x00, 0x08, 0x00, 0x58, 0x00, 0x08, 0x00, 0x60,
|
||||
0x00, 0x08, 0x00, 0x68, 0x00, 0x08, 0x00, 0x70, 0x00, 0x08, 0x00, 0x78, 0x00, 0x08, 0x00, 0x80,
|
||||
0x00, 0x08, 0x00, 0x88, 0x00, 0x08, 0x00, 0x90, 0x00, 0x08, 0x00, 0x98, 0x00, 0x08, 0x00, 0xa0,
|
||||
0x00, 0x08, 0x00, 0xa8, 0x00, 0x08, 0x00, 0xb0, 0x00, 0x08, 0x00, 0xb8, 0x00, 0x08, 0x00, 0xc0,
|
||||
0x00, 0x08, 0x00, 0xc8, 0x00, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x00, 0xd8, 0x00, 0x08, 0x00, 0xe0,
|
||||
0x00, 0x08, 0x00, 0xe8, 0x00, 0x08, 0x00, 0xf0, 0x00, 0x08, 0x00, 0xf8, 0x00, 0x08, 0x01, 0x00,
|
||||
0x00, 0x08, 0x01, 0x08, 0x00, 0x08, 0x01, 0x10, 0x00, 0x08, 0x01, 0x18, 0x00, 0x08, 0x01, 0x20,
|
||||
0x00, 0x08, 0x01, 0x28, 0x00, 0x08, 0x01, 0x30, 0x00, 0x08, 0x01, 0x38, 0x00, 0x08, 0x01, 0x40,
|
||||
0x00, 0x08, 0x01, 0x48, 0x00, 0x08, 0x01, 0x50, 0x00, 0x08, 0x01, 0x58, 0x00, 0x08, 0x01, 0x60,
|
||||
0x00, 0x08, 0x01, 0x68, 0x00, 0x08, 0x01, 0x70, 0x00, 0x08, 0x01, 0x78, 0x00, 0x08, 0x01, 0x80,
|
||||
0x00, 0x08, 0x01, 0x88, 0x00, 0x08, 0x01, 0x90, 0x00, 0x08, 0x01, 0x98, 0x00, 0x08, 0x01, 0xa0,
|
||||
0x00, 0x08, 0x01, 0xa8, 0x00, 0x08, 0x01, 0xb0, 0x00, 0x08, 0x01, 0xb8, 0x00, 0x08, 0x01, 0xc0,
|
||||
0x00, 0x08, 0x01, 0xc8, 0x00, 0x08, 0x01, 0xd0, 0x00, 0x08, 0x01, 0xd8, 0x00, 0x08, 0x01, 0xe0,
|
||||
0x00, 0x08, 0x01, 0xe8, 0x00, 0x08, 0x01, 0xf0, 0x00, 0x08, 0x01, 0xf8, 0x00, 0x08, 0x02, 0x00,
|
||||
0x00, 0x08, 0x02, 0x08, 0x00, 0x08, 0x02, 0x10, 0x00, 0x08, 0x02, 0x18, 0x00, 0x08, 0x02, 0x20,
|
||||
0x00, 0x08, 0x02, 0x28, 0x00, 0x08, 0x02, 0x30, 0x00, 0x08, 0x02, 0x38, 0x00, 0x08, 0x02, 0x40,
|
||||
0x00, 0x08, 0x02, 0x48, 0x00, 0x08, 0x02, 0x50, 0x00, 0x08, 0x02, 0x58, 0x00, 0x08, 0x02, 0x60,
|
||||
0x00, 0x08, 0x02, 0x68, 0x00, 0x08, 0x02, 0x70, 0x00, 0x08, 0x02, 0x78, 0x00, 0x08, 0x02, 0x80,
|
||||
0x00, 0x08, 0x02, 0x88, 0x00, 0x08, 0x02, 0x90, 0x00, 0x08, 0x02, 0x98, 0x00, 0x08, 0x02, 0xa0,
|
||||
0x00, 0x08, 0x02, 0xa8, 0x00, 0x08, 0x02, 0xb0, 0x00, 0x08, 0x02, 0xb8, 0x00, 0x08, 0x02, 0xc0,
|
||||
0x00, 0x08, 0x02, 0xc8, 0x00, 0x08, 0x02, 0xd0, 0x00, 0x08, 0x02, 0xd8, 0x00, 0x08, 0x02, 0xe0,
|
||||
0x00, 0x08, 0x02, 0xe8, 0x00, 0x08, 0x02, 0xf0, 0x00, 0x08, 0x02, 0xf8, 0x00, 0x08, 0x03, 0x00,
|
||||
0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00,
|
||||
0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00,
|
||||
0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00,
|
||||
0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00,
|
||||
0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00,
|
||||
0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00,
|
||||
0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00,
|
||||
0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00,
|
||||
0x00, 0x08, 0x03, 0x08, 0x00, 0x08, 0x03, 0x10, 0x00, 0x08, 0x03, 0x18, 0x00, 0x08, 0x03, 0x20,
|
||||
0x00, 0x08, 0x03, 0x28, 0x00, 0x08, 0x03, 0x30, 0x00, 0x08, 0x03, 0x38, 0x00, 0x08, 0x03, 0x40,
|
||||
0x00, 0x08, 0x03, 0x48, 0x00, 0x08, 0x03, 0x50, 0x00, 0x08, 0x03, 0x58, 0x00, 0x08, 0x03, 0x60,
|
||||
0x00, 0x08, 0x00, 0x68, 0x00, 0x08, 0x03, 0x68, 0x00, 0x08, 0x03, 0x70, 0x00, 0x08, 0x03, 0x78,
|
||||
0x00, 0x08, 0x03, 0x80, 0x00, 0x08, 0x03, 0x88, 0x00, 0x08, 0x03, 0x90, 0x00, 0x08, 0x03, 0x98,
|
||||
0x00, 0x08, 0x03, 0xa0, 0x00, 0x08, 0x03, 0xa8, 0x00, 0x08, 0x03, 0xb0, 0x00, 0x08, 0x03, 0xb8,
|
||||
0x00, 0x08, 0x03, 0xc0, 0x00, 0x08, 0x03, 0xc8, 0x00, 0x08, 0x03, 0xd0, 0x00, 0x08, 0x03, 0xd8,
|
||||
0x00, 0x08, 0x03, 0xe0, 0x00, 0x08, 0x03, 0xe8, 0x00, 0x08, 0x03, 0xf0, 0x00, 0x08, 0x03, 0xf8,
|
||||
0x00, 0x08, 0x04, 0x00, 0x00, 0x08, 0x04, 0x08, 0x00, 0x08, 0x04, 0x10, 0x00, 0x08, 0x04, 0x18,
|
||||
0x00, 0x08, 0x04, 0x20, 0x00, 0x08, 0x04, 0x28, 0x00, 0x08, 0x04, 0x30, 0x00, 0x08, 0x04, 0x38,
|
||||
0x00, 0x08, 0x04, 0x40, 0x00, 0x08, 0x04, 0x48, 0x00, 0x08, 0x04, 0x50, 0x00, 0x08, 0x04, 0x58,
|
||||
0x00, 0x08, 0x04, 0x60, 0x00, 0x08, 0x04, 0x68, 0x00, 0x08, 0x04, 0x70, 0x00, 0x08, 0x04, 0x78,
|
||||
0x00, 0x08, 0x04, 0x80, 0x00, 0x08, 0x04, 0x88, 0x00, 0x08, 0x04, 0x90, 0x00, 0x08, 0x04, 0x98,
|
||||
0x00, 0x08, 0x04, 0xa0, 0x00, 0x08, 0x04, 0xa8, 0x00, 0x08, 0x04, 0xb0, 0x00, 0x08, 0x04, 0xb8,
|
||||
0x00, 0x08, 0x04, 0xc0, 0x00, 0x08, 0x04, 0xc8, 0x00, 0x08, 0x04, 0xd0, 0x00, 0x08, 0x04, 0xd8,
|
||||
0x00, 0x08, 0x04, 0xe0, 0x00, 0x08, 0x04, 0xe8, 0x00, 0x08, 0x04, 0xf0, 0x00, 0x08, 0x04, 0xf8,
|
||||
0x00, 0x08, 0x05, 0x00, 0x00, 0x08, 0x05, 0x08, 0x00, 0x08, 0x05, 0x10, 0x00, 0x08, 0x05, 0x18,
|
||||
0x00, 0x08, 0x05, 0x20, 0x00, 0x08, 0x05, 0x28, 0x00, 0x08, 0x05, 0x30, 0x00, 0x08, 0x05, 0x38,
|
||||
0x00, 0x08, 0x05, 0x40, 0x00, 0x08, 0x05, 0x48, 0x00, 0x08, 0x05, 0x50, 0x00, 0x08, 0x05, 0x58,
|
||||
0x00, 0x08, 0x05, 0x60, 0x00, 0x08, 0x05, 0x68, 0x00, 0x08, 0x05, 0x70, 0x00, 0x08, 0x05, 0x78,
|
||||
0x00, 0x08, 0x05, 0x80, 0x00, 0x08, 0x05, 0x88, 0x00, 0x08, 0x05, 0x90, 0x00, 0x08, 0x05, 0x98,
|
||||
0x00, 0x08, 0x05, 0xa0, 0x00, 0x08, 0x05, 0xa8, 0x00, 0x08, 0x05, 0xb0, 0x00, 0x08, 0x05, 0xb8,
|
||||
0x00, 0x08, 0x05, 0xc0, 0x00, 0x08, 0x05, 0xc8, 0x00, 0x08, 0x05, 0xd0, 0x00, 0x08, 0x05, 0xd8,
|
||||
0x00, 0x08, 0x05, 0xe0, 0x00, 0x08, 0x05, 0xe8, 0x00, 0x08, 0x00, 0x38, 0x00, 0x08, 0x03, 0x00,
|
||||
0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x62,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf2
|
||||
};
|
||||
|
||||
AmigaFont::AmigaFont(Common::SeekableReadStream *stream) {
|
||||
Common::SeekableReadStream *tmp;
|
||||
if (!stream) {
|
||||
tmp = new Common::MemoryReadStream(amigaTopazFont, sizeof(amigaTopazFont), DisposeAfterUse::NO);
|
||||
} else {
|
||||
tmp = stream;
|
||||
}
|
||||
|
||||
tmp->seek(32); // skips dummy header
|
||||
|
||||
uint dataSize = tmp->size() - tmp->pos();
|
||||
_data = (byte *)malloc(dataSize);
|
||||
tmp->read(_data, dataSize);
|
||||
|
||||
if (tmp != stream) {
|
||||
delete tmp;
|
||||
tmp = nullptr;
|
||||
}
|
||||
|
||||
_font = (AmigaDiskFont *)(_data + 78);
|
||||
_font->_ySize = FROM_BE_16(_font->_ySize);
|
||||
_font->_xSize = FROM_BE_16(_font->_xSize);
|
||||
_font->_baseline = FROM_BE_16(_font->_baseline);
|
||||
_font->_modulo = FROM_BE_16(_font->_modulo);
|
||||
|
||||
_charLoc = (CharLoc *)(_data + FROM_BE_32(_font->_charLoc));
|
||||
_charData = _data + FROM_BE_32(_font->_charData);
|
||||
|
||||
_charSpace = 0;
|
||||
_charKern = 0;
|
||||
|
||||
_cp = 0;
|
||||
_pitch = 0;
|
||||
|
||||
if (_font->_charSpace != 0)
|
||||
_charSpace = (uint16 *)(_data + FROM_BE_32(_font->_charSpace));
|
||||
if (_font->_charKern != 0)
|
||||
_charKern = (uint16 *)(_data + FROM_BE_32(_font->_charKern));
|
||||
|
||||
if (_charSpace) {
|
||||
_maxCharWidth = _charSpace[0];
|
||||
for (int i = _font->_hiChar - _font->_loChar; i > 0 ; i--)
|
||||
if (_maxCharWidth < _charSpace[i])
|
||||
_maxCharWidth = _charSpace[i];
|
||||
} else {
|
||||
_maxCharWidth = _font->_xSize;
|
||||
}
|
||||
}
|
||||
|
||||
AmigaFont::~AmigaFont() {
|
||||
free(_data);
|
||||
}
|
||||
|
||||
int AmigaFont::getFontHeight() const {
|
||||
return _font->_ySize;
|
||||
}
|
||||
|
||||
int AmigaFont::getCharWidth(uint32 chr) const {
|
||||
return (_charSpace == 0) ? _font->_xSize : FROM_BE_16(_charSpace[mapChar(chr)]);
|
||||
}
|
||||
|
||||
int AmigaFont::getMaxCharWidth() const {
|
||||
return _maxCharWidth;
|
||||
}
|
||||
|
||||
int AmigaFont::getKerningOffset(uint32 left, uint32 right) const {
|
||||
return (_charKern == 0) ? 0 : FROM_BE_16(_charKern[mapChar(right)]);
|
||||
}
|
||||
|
||||
uint16 AmigaFont::getPixels(byte c) const {
|
||||
return FROM_BE_16(_charLoc[c]._length);
|
||||
}
|
||||
|
||||
uint16 AmigaFont::getOffset(byte c) const {
|
||||
return FROM_BE_16(_charLoc[c]._offset);
|
||||
}
|
||||
|
||||
uint32 AmigaFont::mapChar(uint32 c) const {
|
||||
if (c < _font->_loChar || c > _font->_hiChar)
|
||||
error("character '%c (%x)' not supported by font", c, c);
|
||||
|
||||
return c - _font->_loChar;
|
||||
}
|
||||
|
||||
template<typename PixelType>
|
||||
void drawCharIntern(byte *ptr, uint32 pitch, int num, int bitOffset, byte *charData, int ySize, int modulo, uint32 color) {
|
||||
|
||||
PixelType *d = (PixelType *)ptr;
|
||||
byte *s = charData;
|
||||
|
||||
for (int i = 0; i < ySize; i++) {
|
||||
|
||||
for (int j = bitOffset; j < bitOffset + num; j++) {
|
||||
byte *b = s + (j >> 3);
|
||||
byte bit = *b & (0x80 >> (j & 7));
|
||||
|
||||
if (bit)
|
||||
*d = color;
|
||||
|
||||
d++;
|
||||
}
|
||||
|
||||
s += modulo;
|
||||
d = (PixelType *)((byte *)d + pitch) - num;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AmigaFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const {
|
||||
chr = mapChar(chr);
|
||||
|
||||
byte *ptr = (byte *)dst->getBasePtr(x, y);
|
||||
|
||||
if (dst->format.bytesPerPixel == 1)
|
||||
drawCharIntern<byte>(ptr, dst->pitch, getPixels(chr), getOffset(chr), _charData, _font->_ySize, _font->_modulo, color);
|
||||
else if (dst->format.bytesPerPixel == 2)
|
||||
drawCharIntern<uint16>(ptr, dst->pitch, getPixels(chr), getOffset(chr), _charData, _font->_ySize, _font->_modulo, color);
|
||||
else if (dst->format.bytesPerPixel == 4)
|
||||
drawCharIntern<uint32>(ptr, dst->pitch, getPixels(chr), getOffset(chr), _charData, _font->_ySize, _font->_modulo, color);
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace Graphics
|
||||
98
graphics/fonts/amigafont.h
Normal file
98
graphics/fonts/amigafont.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/* 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 GRAPHICS_FONTS_AMIGAFONT_H
|
||||
#define GRAPHICS_FONTS_AMIGAFONT_H
|
||||
|
||||
#include "graphics/font.h"
|
||||
|
||||
namespace Common {
|
||||
class SeekableReadStream;
|
||||
}
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
class AmigaFont : public Font {
|
||||
|
||||
#include "common/pack-start.h"
|
||||
struct CharLoc {
|
||||
uint16 _offset;
|
||||
uint16 _length;
|
||||
};
|
||||
|
||||
struct AmigaDiskFont {
|
||||
uint16 _ySize;
|
||||
byte _style;
|
||||
byte _flags;
|
||||
uint16 _xSize;
|
||||
uint16 _baseline;
|
||||
uint16 _boldSmear;
|
||||
uint16 _accessors; // unused
|
||||
byte _loChar;
|
||||
byte _hiChar;
|
||||
uint32 _charData;
|
||||
uint16 _modulo;
|
||||
uint32 _charLoc;
|
||||
uint32 _charSpace;
|
||||
uint32 _charKern;
|
||||
};
|
||||
#include "common/pack-end.h"
|
||||
|
||||
AmigaDiskFont *_font;
|
||||
byte *_data;
|
||||
byte *_charData;
|
||||
CharLoc *_charLoc;
|
||||
uint16 *_charSpace;
|
||||
uint16 *_charKern;
|
||||
|
||||
byte *_cp;
|
||||
uint32 _pitch;
|
||||
int _maxCharWidth;
|
||||
|
||||
private:
|
||||
uint16 getPixels(byte c) const;
|
||||
uint16 getOffset(byte c) const;
|
||||
|
||||
uint32 mapChar(uint32 c) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create font in Amiga format.
|
||||
*
|
||||
* @param stream Stream with the font data. If NULL, then the built-in
|
||||
* Topaz font is used.
|
||||
*/
|
||||
AmigaFont(Common::SeekableReadStream *stream = NULL);
|
||||
virtual ~AmigaFont();
|
||||
|
||||
virtual int getFontHeight() const;
|
||||
virtual int getCharWidth(uint32 chr) const;
|
||||
virtual int getMaxCharWidth() const;
|
||||
virtual int getKerningOffset(uint32 left, uint32 right) const;
|
||||
virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const;
|
||||
|
||||
int getLoChar() { return _font->_loChar; }
|
||||
int getHiChar() { return _font->_hiChar; }
|
||||
};
|
||||
|
||||
} // End of namespace Graphics
|
||||
|
||||
#endif
|
||||
957
graphics/fonts/bdf.cpp
Normal file
957
graphics/fonts/bdf.cpp
Normal file
@@ -0,0 +1,957 @@
|
||||
/* 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 "graphics/fonts/bdf.h"
|
||||
|
||||
#include "common/file.h"
|
||||
#include "common/endian.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
#include "graphics/surface.h"
|
||||
|
||||
#define DRAWDEBUG 0
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
BdfFont::BdfFont(const BdfFontData &data, DisposeAfterUse::Flag dispose)
|
||||
: _data(data), _dispose(dispose) {
|
||||
}
|
||||
|
||||
BdfFont::~BdfFont() {
|
||||
if (_dispose == DisposeAfterUse::YES) {
|
||||
for (uint i = 0; i < _data.numCharacters; ++i)
|
||||
delete[] _data.bitmaps[i];
|
||||
delete[] _data.bitmaps;
|
||||
delete[] _data.advances;
|
||||
delete[] _data.boxes;
|
||||
delete[] _data.familyName;
|
||||
delete[] _data.slant;
|
||||
}
|
||||
}
|
||||
|
||||
const char *BdfFont::getFamilyName() const {
|
||||
return _data.familyName;
|
||||
}
|
||||
|
||||
const char *BdfFont::getFontSlant() const {
|
||||
return _data.slant;
|
||||
}
|
||||
|
||||
int BdfFont::getFontHeight() const {
|
||||
return _data.height;
|
||||
}
|
||||
|
||||
int BdfFont::getFontAscent() const {
|
||||
return _data.ascent;
|
||||
}
|
||||
|
||||
int BdfFont::getFontSize() const {
|
||||
return _data.size;
|
||||
}
|
||||
|
||||
int BdfFont::getMaxCharWidth() const {
|
||||
return _data.maxAdvance;
|
||||
}
|
||||
|
||||
int BdfFont::getCharWidth(uint32 chr) const {
|
||||
// In case all font have the same advance value, we use the maximum.
|
||||
if (!_data.advances)
|
||||
return _data.maxAdvance;
|
||||
|
||||
const int ch = mapToIndex(chr);
|
||||
// In case no mapping exists, we use the maximum advance.
|
||||
if (ch < 0)
|
||||
return _data.maxAdvance;
|
||||
else
|
||||
return _data.advances[ch];
|
||||
}
|
||||
|
||||
|
||||
template<typename PixelType>
|
||||
void drawCharIntern(byte *ptr, uint pitch, const byte *src, int h, int width, int minX, int maxX, const PixelType color) {
|
||||
byte data = 0;
|
||||
while (h--) {
|
||||
PixelType *dst = (PixelType *)ptr;
|
||||
|
||||
for (int x = 0; x < width; ++x) {
|
||||
if (!(x % 8))
|
||||
data = *src++;
|
||||
|
||||
if (x >= minX && x <= maxX && (data & 0x80))
|
||||
dst[x] = color;
|
||||
|
||||
data <<= 1;
|
||||
}
|
||||
|
||||
ptr += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
int BdfFont::mapToIndex(uint32 ch) const {
|
||||
// Check whether the character is included
|
||||
if (_data.firstCharacter <= ch && ch <= _data.firstCharacter + _data.numCharacters) {
|
||||
if (_data.bitmaps[ch - _data.firstCharacter])
|
||||
return ch - _data.firstCharacter;
|
||||
}
|
||||
|
||||
return _data.defaultCharacter - _data.firstCharacter;
|
||||
}
|
||||
|
||||
void BdfFont::drawChar(Surface *dst, uint32 chr, const int tx, const int ty, const uint32 color) const {
|
||||
assert(dst != 0);
|
||||
|
||||
// TODO: Where is the relation between the max advance being smaller or
|
||||
// equal to 50 and the decision of the theme designer?
|
||||
// asserting _data.maxAdvance <= 50: let the theme designer decide what looks best
|
||||
//assert(_data.maxAdvance <= 50);
|
||||
assert(dst->format.bytesPerPixel == 1 || dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4);
|
||||
|
||||
const int idx = mapToIndex(chr);
|
||||
if (idx < 0)
|
||||
return;
|
||||
|
||||
int width, height, xOffset, yOffset;
|
||||
|
||||
// Get the bounding box of the character
|
||||
if (!_data.boxes) {
|
||||
width = _data.defaultBox.width;
|
||||
height = _data.defaultBox.height;
|
||||
xOffset = _data.defaultBox.xOffset;
|
||||
yOffset = _data.defaultBox.yOffset;
|
||||
} else {
|
||||
width = _data.boxes[idx].width;
|
||||
height = _data.boxes[idx].height;
|
||||
xOffset = _data.boxes[idx].xOffset;
|
||||
yOffset = _data.boxes[idx].yOffset;
|
||||
}
|
||||
|
||||
int y = ty + _data.ascent - yOffset - height;
|
||||
int x = tx + xOffset;
|
||||
|
||||
const byte *src = _data.bitmaps[idx];
|
||||
|
||||
const int bytesPerRow = (width + 7) / 8;
|
||||
const int originalWidth = width;
|
||||
|
||||
// Make sure we do not draw outside the surface
|
||||
if (y < 0) {
|
||||
src -= y * bytesPerRow;
|
||||
height += y;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
if (y + height > dst->h)
|
||||
height = dst->h - y;
|
||||
|
||||
if (height <= 0)
|
||||
return;
|
||||
|
||||
int xStart = 0;
|
||||
if (x < 0) {
|
||||
xStart = -x;
|
||||
width += x;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if (x + width > dst->w)
|
||||
width = dst->w - x;
|
||||
|
||||
if (width <= 0)
|
||||
return;
|
||||
|
||||
const int xEnd = xStart + width - 1;
|
||||
|
||||
byte *ptr = (byte *)dst->getBasePtr(x, y);
|
||||
|
||||
if (dst->format.bytesPerPixel == 1)
|
||||
drawCharIntern<byte>(ptr, dst->pitch, src, height, originalWidth, xStart, xEnd, color);
|
||||
else if (dst->format.bytesPerPixel == 2)
|
||||
drawCharIntern<uint16>(ptr, dst->pitch, src, height, originalWidth, xStart, xEnd, color);
|
||||
else if (dst->format.bytesPerPixel == 4)
|
||||
drawCharIntern<uint32>(ptr, dst->pitch, src, height, originalWidth, xStart, xEnd, color);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
inline byte hexToInt(char c) {
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte *loadCharacter(Common::SeekableReadStream &stream, int &encoding, int &advance, BdfBoundingBox &box) {
|
||||
Common::String line;
|
||||
byte *bitmap = 0;
|
||||
|
||||
while (true) {
|
||||
line = stream.readLine();
|
||||
line.trim(); // BDF files created from unifont tools (make hex)
|
||||
// have a rogue space character after the "BITMAP" label
|
||||
|
||||
if (stream.err() || stream.eos()) {
|
||||
warning("BdfFont::loadCharacter: Premature end of file");
|
||||
delete[] bitmap;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (line.hasPrefix("ENCODING ")) {
|
||||
if (sscanf(line.c_str(), "ENCODING %d", &encoding) != 1) {
|
||||
warning("BdfFont::loadCharacter: Invalid ENCODING");
|
||||
delete[] bitmap;
|
||||
return 0;
|
||||
}
|
||||
} else if (line.hasPrefix("DWIDTH ")) {
|
||||
int yAdvance;
|
||||
if (sscanf(line.c_str(), "DWIDTH %d %d", &advance, &yAdvance) != 2) {
|
||||
warning("BdfFont::loadCharacter: Invalid DWIDTH");
|
||||
delete[] bitmap;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (yAdvance != 0) {
|
||||
warning("BdfFont::loadCharacter: Character %d has an y advance of %d", encoding, yAdvance);
|
||||
delete[] bitmap;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (advance < 0) {
|
||||
warning("BdfFont::loadCharacter: Character %d has an x advance of %d", encoding, advance);
|
||||
delete[] bitmap;
|
||||
return 0;
|
||||
}
|
||||
} else if (line.hasPrefix("BBX ")) {
|
||||
int width, height, xOffset, yOffset;
|
||||
if (sscanf(line.c_str(), "BBX %d %d %d %d",
|
||||
&width, &height, &xOffset, &yOffset) != 4) {
|
||||
warning("BdfFont::loadCharacter: Invalid BBX");
|
||||
delete[] bitmap;
|
||||
return 0;
|
||||
}
|
||||
|
||||
box.width = width;
|
||||
box.height = height;
|
||||
box.xOffset = xOffset;
|
||||
box.yOffset = yOffset;
|
||||
} else if (line == "BITMAP") {
|
||||
const uint bytesPerRow = (box.width + 7) / 8;
|
||||
|
||||
if (bitmap) {
|
||||
warning("Bdf::loadCharacter(): Double BITMAP definitions");
|
||||
delete[] bitmap;
|
||||
}
|
||||
|
||||
byte *dst = bitmap = new byte[box.height * bytesPerRow];
|
||||
|
||||
for (int y = 0; y < box.height; ++y) {
|
||||
line = stream.readLine();
|
||||
if (stream.err() || stream.eos()) {
|
||||
warning("BdfFont::loadCharacter: Premature end of file");
|
||||
delete[] bitmap;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (line.size() != 2 * bytesPerRow) {
|
||||
warning("BdfFont::loadCharacter: Pixel line has wrong size");
|
||||
delete[] bitmap;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (uint x = 0; x < bytesPerRow; ++x) {
|
||||
char nibble1 = line[x * 2 + 0];
|
||||
char nibble2 = line[x * 2 + 1];
|
||||
*dst++ = (hexToInt(nibble1) << 4) | hexToInt(nibble2);
|
||||
}
|
||||
}
|
||||
} else if (line == "ENDCHAR") {
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void freeBitmaps(byte **bitmaps, int size) {
|
||||
for (int i = 0; i < size; ++i)
|
||||
delete[] bitmaps[i];
|
||||
}
|
||||
|
||||
} // End of anonymous namespace
|
||||
|
||||
BdfFont *BdfFont::loadFont(Common::SeekableReadStream &stream) {
|
||||
BdfFontData font;
|
||||
memset(&font, 0, sizeof(font));
|
||||
font.ascent = -1;
|
||||
font.defaultCharacter = -1;
|
||||
|
||||
// We only load the first 256 characters
|
||||
font.numCharacters = 256;
|
||||
byte **bitmaps = new byte *[font.numCharacters];
|
||||
memset(bitmaps, 0, sizeof(byte *) * font.numCharacters);
|
||||
byte *advances = new byte[font.numCharacters];
|
||||
BdfBoundingBox *boxes = new BdfBoundingBox[font.numCharacters];
|
||||
char *familyName = nullptr;
|
||||
char *slant = nullptr;
|
||||
|
||||
int descent = -1;
|
||||
|
||||
Common::String line;
|
||||
while (true) {
|
||||
line = stream.readLine();
|
||||
if (stream.err() || stream.eos()) {
|
||||
warning("BdfFont::loadFont: Premature end of file");
|
||||
freeBitmaps(bitmaps, font.numCharacters);
|
||||
delete[] bitmaps;
|
||||
delete[] advances;
|
||||
delete[] boxes;
|
||||
delete[] familyName;
|
||||
delete[] slant;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Only parse and handle declarations we actually need
|
||||
if (line.hasPrefix("FONTBOUNDINGBOX ")) {
|
||||
int width, height, xOffset, yOffset;
|
||||
if (sscanf(line.c_str(), "FONTBOUNDINGBOX %d %d %d %d",
|
||||
&width, &height, &xOffset, &yOffset) != 4) {
|
||||
warning("BdfFont::loadFont: Invalid FONTBOUNDINGBOX");
|
||||
freeBitmaps(bitmaps, font.numCharacters);
|
||||
delete[] bitmaps;
|
||||
delete[] advances;
|
||||
delete[] boxes;
|
||||
delete[] familyName;
|
||||
delete[] slant;
|
||||
return 0;
|
||||
}
|
||||
|
||||
font.defaultBox.width = width;
|
||||
font.defaultBox.height = height;
|
||||
font.defaultBox.xOffset = xOffset;
|
||||
font.defaultBox.yOffset = yOffset;
|
||||
} else if (line.hasPrefix("PIXEL_SIZE ")) {
|
||||
if (sscanf(line.c_str(), "PIXEL_SIZE %d", &font.size) != 1) {
|
||||
warning("BdfFont::loadFont: Invalid PIXEL_SIZE");
|
||||
freeBitmaps(bitmaps, font.numCharacters);
|
||||
delete[] bitmaps;
|
||||
delete[] advances;
|
||||
delete[] boxes;
|
||||
delete[] familyName;
|
||||
delete[] slant;
|
||||
return 0;
|
||||
}
|
||||
} else if (line.hasPrefix("FONT_ASCENT ")) {
|
||||
if (sscanf(line.c_str(), "FONT_ASCENT %d", &font.ascent) != 1) {
|
||||
warning("BdfFont::loadFont: Invalid FONT_ASCENT");
|
||||
freeBitmaps(bitmaps, font.numCharacters);
|
||||
delete[] bitmaps;
|
||||
delete[] advances;
|
||||
delete[] boxes;
|
||||
delete[] familyName;
|
||||
delete[] slant;
|
||||
return 0;
|
||||
}
|
||||
} else if (line.hasPrefix("FONT_DESCENT ")) {
|
||||
if (sscanf(line.c_str(), "FONT_DESCENT %d", &descent) != 1) {
|
||||
warning("BdfFont::loadFont: Invalid FONT_DESCENT");
|
||||
freeBitmaps(bitmaps, font.numCharacters);
|
||||
delete[] bitmaps;
|
||||
delete[] advances;
|
||||
delete[] boxes;
|
||||
delete[] familyName;
|
||||
delete[] slant;
|
||||
return 0;
|
||||
}
|
||||
} else if (line.hasPrefix("DEFAULT_CHAR ")) {
|
||||
if (sscanf(line.c_str(), "DEFAULT_CHAR %d", &font.defaultCharacter) != 1) {
|
||||
warning("BdfFont::loadFont: Invalid DEFAULT_CHAR");
|
||||
freeBitmaps(bitmaps, font.numCharacters);
|
||||
delete[] bitmaps;
|
||||
delete[] advances;
|
||||
delete[] boxes;
|
||||
delete[] familyName;
|
||||
delete[] slant;
|
||||
return 0;
|
||||
}
|
||||
} else if (line.hasPrefix("STARTCHAR ")) {
|
||||
BdfBoundingBox box = font.defaultBox;
|
||||
int encoding = -1;
|
||||
int advance = -1;
|
||||
byte *bitmap = loadCharacter(stream, encoding, advance, box);
|
||||
|
||||
// Ignore all characters above 255.
|
||||
if (encoding < 0 || encoding >= (int)font.numCharacters) {
|
||||
delete[] bitmap;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calculate the max advance
|
||||
if (advance > font.maxAdvance)
|
||||
font.maxAdvance = advance;
|
||||
|
||||
if (!bitmap) {
|
||||
warning("BdfFont::loadFont: Character %d invalid", encoding);
|
||||
freeBitmaps(bitmaps, font.numCharacters);
|
||||
delete[] bitmaps;
|
||||
delete[] advances;
|
||||
delete[] boxes;
|
||||
delete[] familyName;
|
||||
delete[] slant;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bitmaps[encoding] = bitmap;
|
||||
advances[encoding] = advance;
|
||||
boxes[encoding] = box;
|
||||
} else if (line.hasPrefix("FAMILY_NAME \"")) {
|
||||
if (familyName != nullptr) {
|
||||
warning("BdfFont::loadFont: Duplicated FAMILY_NAME");
|
||||
delete[] familyName;
|
||||
}
|
||||
familyName = new char[line.size()];
|
||||
Common::strlcpy(familyName, line.c_str() + 13, line.size() - 12); // strlcpy() copies at most size-1 characters and then add a '\0'
|
||||
char *p = &familyName[strlen(familyName)];
|
||||
while (p != familyName && *p != '"')
|
||||
p--;
|
||||
if (p == familyName) {
|
||||
warning("BdfFont::loadFont: Invalid FAMILY_NAME");
|
||||
freeBitmaps(bitmaps, font.numCharacters);
|
||||
delete[] bitmaps;
|
||||
delete[] advances;
|
||||
delete[] boxes;
|
||||
delete[] familyName;
|
||||
delete[] slant;
|
||||
return 0;
|
||||
}
|
||||
*p = '\0'; // Remove last quote
|
||||
} else if (line.hasPrefix("SLANT \"")) {
|
||||
if (slant != nullptr) {
|
||||
warning("BdfFont::loadFont: Duplicated SLANT");
|
||||
delete[] slant;
|
||||
}
|
||||
slant = new char[line.size()];
|
||||
Common::strlcpy(slant, line.c_str() + 7, line.size() - 6); // strlcpy() copies at most size-1 characters and then add a '\0'
|
||||
char *p = &slant[strlen(slant)];
|
||||
while (p != slant && *p != '"')
|
||||
p--;
|
||||
if (p == slant) {
|
||||
warning("BdfFont::loadFont: Invalid SLANT");
|
||||
freeBitmaps(bitmaps, font.numCharacters);
|
||||
delete[] bitmaps;
|
||||
delete[] advances;
|
||||
delete[] boxes;
|
||||
delete[] familyName;
|
||||
delete[] slant;
|
||||
return 0;
|
||||
}
|
||||
*p = '\0'; // Remove last quote
|
||||
} else if (line == "ENDFONT") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (font.ascent < 0 || descent < 0) {
|
||||
warning("BdfFont::loadFont: Invalid ascent or descent");
|
||||
freeBitmaps(bitmaps, font.numCharacters);
|
||||
delete[] bitmaps;
|
||||
delete[] advances;
|
||||
delete[] boxes;
|
||||
delete[] familyName;
|
||||
delete[] slant;
|
||||
return 0;
|
||||
}
|
||||
|
||||
font.height = font.ascent + descent;
|
||||
|
||||
font.bitmaps = bitmaps;
|
||||
font.advances = advances;
|
||||
font.boxes = boxes;
|
||||
font.familyName = familyName;
|
||||
font.slant = slant;
|
||||
|
||||
uint firstCharacter = font.numCharacters;
|
||||
int lastCharacter = -1;
|
||||
bool hasFixedBBox = true;
|
||||
bool hasFixedAdvance = true;
|
||||
|
||||
for (uint i = 0; i < font.numCharacters; ++i) {
|
||||
if (!font.bitmaps[i])
|
||||
continue;
|
||||
|
||||
if (i < firstCharacter)
|
||||
firstCharacter = i;
|
||||
|
||||
if ((int)i > lastCharacter)
|
||||
lastCharacter = i;
|
||||
|
||||
if (font.advances[i] != font.maxAdvance)
|
||||
hasFixedAdvance = false;
|
||||
|
||||
const BdfBoundingBox &bbox = font.boxes[i];
|
||||
if (bbox.width != font.defaultBox.width
|
||||
|| bbox.height != font.defaultBox.height
|
||||
|| bbox.xOffset != font.defaultBox.xOffset
|
||||
|| bbox.yOffset != font.defaultBox.yOffset)
|
||||
hasFixedBBox = false;
|
||||
}
|
||||
|
||||
if (lastCharacter == -1) {
|
||||
warning("BdfFont::loadFont: No glyphs found");
|
||||
delete[] font.bitmaps;
|
||||
delete[] font.advances;
|
||||
delete[] font.boxes;
|
||||
delete[] familyName;
|
||||
delete[] slant;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Free the advance table, in case all glyphs use the same advance
|
||||
if (hasFixedAdvance) {
|
||||
delete[] font.advances;
|
||||
font.advances = 0;
|
||||
}
|
||||
|
||||
// Free the box table, in case all glyphs use the same box
|
||||
if (hasFixedBBox) {
|
||||
delete[] font.boxes;
|
||||
font.boxes = 0;
|
||||
}
|
||||
|
||||
// Adapt for the fact that we never use encoding 0.
|
||||
if (font.defaultCharacter < (int)firstCharacter
|
||||
|| font.defaultCharacter > lastCharacter)
|
||||
font.defaultCharacter = -1;
|
||||
|
||||
font.firstCharacter = firstCharacter;
|
||||
|
||||
const int charsAvailable = lastCharacter - firstCharacter + 1;
|
||||
// Try to compact the tables
|
||||
if (charsAvailable < (int)font.numCharacters) {
|
||||
byte **newBitmaps = new byte *[charsAvailable];
|
||||
boxes = 0;
|
||||
advances = 0;
|
||||
if (!hasFixedBBox)
|
||||
boxes = new BdfBoundingBox[charsAvailable];
|
||||
if (!hasFixedAdvance)
|
||||
advances = new byte[charsAvailable];
|
||||
|
||||
for (int i = 0; i < charsAvailable; ++i) {
|
||||
const int encoding = i + firstCharacter;
|
||||
if (font.bitmaps[encoding]) {
|
||||
newBitmaps[i] = bitmaps[encoding];
|
||||
|
||||
if (!hasFixedBBox)
|
||||
boxes[i] = font.boxes[encoding];
|
||||
if (!hasFixedAdvance)
|
||||
advances[i] = font.advances[encoding];
|
||||
} else {
|
||||
newBitmaps[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] font.bitmaps;
|
||||
font.bitmaps = newBitmaps;
|
||||
delete[] font.advances;
|
||||
font.advances = advances;
|
||||
delete[] font.boxes;
|
||||
font.boxes = boxes;
|
||||
|
||||
font.numCharacters = charsAvailable;
|
||||
}
|
||||
|
||||
return new BdfFont(font, DisposeAfterUse::YES);
|
||||
}
|
||||
|
||||
#define BDF_FONTCACHE_TAG MKTAG('S', 'V', 'F', 'C')
|
||||
#define BDF_FONTCACHE_VERSION 1
|
||||
|
||||
bool BdfFont::cacheFontData(const BdfFont &font, const Common::Path &filename) {
|
||||
Common::DumpFile cacheFile;
|
||||
if (!cacheFile.open(filename)) {
|
||||
warning("BdfFont::cacheFontData: Couldn't open file '%s' for writing", filename.toString(Common::Path::kNativeSeparator).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
const BdfFontData &data = font._data;
|
||||
|
||||
cacheFile.writeUint32BE(BDF_FONTCACHE_TAG);
|
||||
cacheFile.writeUint32BE(BDF_FONTCACHE_VERSION);
|
||||
cacheFile.writeUint16BE(data.maxAdvance);
|
||||
cacheFile.writeByte(data.height);
|
||||
cacheFile.writeByte(data.defaultBox.width);
|
||||
cacheFile.writeByte(data.defaultBox.height);
|
||||
cacheFile.writeSByte(data.defaultBox.xOffset);
|
||||
cacheFile.writeSByte(data.defaultBox.yOffset);
|
||||
cacheFile.writeByte(data.ascent);
|
||||
cacheFile.writeUint16BE(data.firstCharacter);
|
||||
cacheFile.writeSint16BE(data.defaultCharacter);
|
||||
cacheFile.writeUint16BE(data.numCharacters);
|
||||
|
||||
for (uint i = 0; i < data.numCharacters; ++i) {
|
||||
const BdfBoundingBox &box = data.boxes ? data.boxes[i] : data.defaultBox;
|
||||
if (data.bitmaps[i]) {
|
||||
const int bytes = ((box.width + 7) / 8) * box.height;
|
||||
cacheFile.writeUint32BE(bytes);
|
||||
cacheFile.write(data.bitmaps[i], bytes);
|
||||
} else {
|
||||
cacheFile.writeUint32BE(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.advances) {
|
||||
cacheFile.writeByte(0xFF);
|
||||
cacheFile.write(data.advances, data.numCharacters);
|
||||
} else {
|
||||
cacheFile.writeByte(0x00);
|
||||
}
|
||||
|
||||
if (data.boxes) {
|
||||
cacheFile.writeByte(0xFF);
|
||||
|
||||
for (uint i = 0; i < data.numCharacters; ++i) {
|
||||
const BdfBoundingBox &box = data.boxes[i];
|
||||
cacheFile.writeByte(box.width);
|
||||
cacheFile.writeByte(box.height);
|
||||
cacheFile.writeSByte(box.xOffset);
|
||||
cacheFile.writeSByte(box.yOffset);
|
||||
}
|
||||
} else {
|
||||
cacheFile.writeByte(0x00);
|
||||
}
|
||||
|
||||
return !cacheFile.err();
|
||||
}
|
||||
|
||||
BdfFont *BdfFont::loadFromCache(Common::SeekableReadStream &stream) {
|
||||
const uint32 magic = stream.readUint32BE();
|
||||
if (magic != BDF_FONTCACHE_TAG)
|
||||
return nullptr;
|
||||
|
||||
const uint32 version = stream.readUint32BE();
|
||||
if (version != BDF_FONTCACHE_VERSION)
|
||||
return nullptr;
|
||||
|
||||
BdfFontData data;
|
||||
|
||||
data.maxAdvance = stream.readUint16BE();
|
||||
data.height = stream.readByte();
|
||||
data.defaultBox.width = stream.readByte();
|
||||
data.defaultBox.height = stream.readByte();
|
||||
data.defaultBox.xOffset = stream.readSByte();
|
||||
data.defaultBox.yOffset = stream.readSByte();
|
||||
data.ascent = stream.readByte();
|
||||
data.firstCharacter = stream.readUint16BE();
|
||||
data.defaultCharacter = stream.readSint16BE();
|
||||
data.numCharacters = stream.readUint16BE();
|
||||
|
||||
if (stream.err() || stream.eos())
|
||||
return nullptr;
|
||||
|
||||
if (data.numCharacters == 0) {
|
||||
warning("BdfFont::loadFromCache(): Requested to load 0 characters font");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
byte **bitmaps = new byte *[data.numCharacters];
|
||||
byte *advances = 0;
|
||||
BdfBoundingBox *boxes = 0;
|
||||
for (uint i = 0; i < data.numCharacters; ++i) {
|
||||
uint32 size = stream.readUint32BE();
|
||||
|
||||
if (stream.err() || stream.eos()) {
|
||||
for (uint j = 0; j < i; ++j)
|
||||
delete[] bitmaps[j];
|
||||
delete[] bitmaps;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (size) {
|
||||
bitmaps[i] = new byte[size];
|
||||
stream.read(bitmaps[i], size);
|
||||
} else {
|
||||
bitmaps[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (stream.readByte() == 0xFF) {
|
||||
advances = new byte[data.numCharacters];
|
||||
stream.read(advances, data.numCharacters);
|
||||
}
|
||||
|
||||
if (stream.readByte() == 0xFF) {
|
||||
boxes = new BdfBoundingBox[data.numCharacters];
|
||||
for (uint i = 0; i < data.numCharacters; ++i) {
|
||||
boxes[i].width = stream.readByte();
|
||||
boxes[i].height = stream.readByte();
|
||||
boxes[i].xOffset = stream.readSByte();
|
||||
boxes[i].yOffset = stream.readSByte();
|
||||
}
|
||||
}
|
||||
|
||||
if (stream.eos() || stream.err()) {
|
||||
for (uint i = 0; i < data.numCharacters; ++i)
|
||||
delete[] bitmaps[i];
|
||||
delete[] bitmaps;
|
||||
delete[] advances;
|
||||
delete[] boxes;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
data.bitmaps = bitmaps;
|
||||
data.advances = advances;
|
||||
data.boxes = boxes;
|
||||
data.familyName = nullptr;
|
||||
data.slant = nullptr;
|
||||
data.size = data.height;
|
||||
return new BdfFont(data, DisposeAfterUse::YES);
|
||||
}
|
||||
|
||||
static Common::Rect bdfBoxToRect(int ascent, const BdfBoundingBox &bbox) {
|
||||
int top = ascent - bbox.yOffset - bbox.height;
|
||||
int left = bbox.xOffset;
|
||||
int bottom = top + bbox.height;
|
||||
int right = left + bbox.width;
|
||||
|
||||
return Common::Rect(left, top, right, bottom);
|
||||
}
|
||||
|
||||
static BdfBoundingBox rectToBdfBox(int ascent, const Common::Rect &rect) {
|
||||
BdfBoundingBox bbox;
|
||||
|
||||
bbox.yOffset = ascent - rect.top - rect.height();
|
||||
bbox.xOffset = rect.left;
|
||||
bbox.height = rect.height();
|
||||
bbox.width = rect.width();
|
||||
|
||||
return bbox;
|
||||
}
|
||||
|
||||
static BdfBoundingBox scaleBdfBoundingBox(int srcAscent, float srcReferencePointX, float srcReferencePointY, int destAscent, float destReferencePointX, float destReferencePointY, const BdfBoundingBox &srcBBox, float scale) {
|
||||
Common::Rect srcRect = bdfBoxToRect(srcAscent, srcBBox);
|
||||
|
||||
int destLeft = static_cast<int>(floorf((static_cast<float>(srcRect.left) - srcReferencePointX) * scale + destReferencePointX));
|
||||
int destRight = static_cast<int>(ceilf((static_cast<float>(srcRect.right) - srcReferencePointX) * scale + destReferencePointX));
|
||||
int destTop = static_cast<int>(floorf((static_cast<float>(srcRect.top) - srcReferencePointY) * scale + destReferencePointY));
|
||||
int destBottom = static_cast<int>(ceilf((static_cast<float>(srcRect.bottom) - srcReferencePointY) * scale + destReferencePointY));
|
||||
|
||||
return rectToBdfBox(destAscent, Common::Rect(destLeft, destTop, destRight, destBottom));
|
||||
}
|
||||
|
||||
BdfFont *BdfFont::scaleFont(const BdfFont *src, int newSize) {
|
||||
if (!src) {
|
||||
warning("BdfFont::scaleFont(): Empty font reference in scale font");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (src->getFontSize() == 0) {
|
||||
warning("BdfFont::scaleFont(): Requested to scale 0 size font");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (src->_data.numCharacters == 0) {
|
||||
warning("BdfFont::scaleFont(): Requested to scale 0 characters font");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Graphics::Surface srcSurf;
|
||||
srcSurf.create(MAX(src->getFontSize() * 2, newSize * 2), MAX(src->getFontSize() * 2, newSize * 2), PixelFormat::createFormatCLUT8());
|
||||
int dstGraySize = newSize * 20 * newSize;
|
||||
int *dstGray = (int *)malloc(dstGraySize * sizeof(int));
|
||||
|
||||
float scale = (float)newSize / (float)src->getFontSize();
|
||||
|
||||
int scaledAscent = (int)(roundf((float)src->_data.ascent * scale));
|
||||
|
||||
// The reference point is the center point of scaling in the old and new glyph.
|
||||
// The coordinate values are relative to the top-left corner of the draw coordinate pixel.
|
||||
// Since the baseline is located at the top edge of the pixel that is +ascent from the draw
|
||||
// coordinate, we use the intersection of that edge and the left edge of the draw coordinate
|
||||
// as the reference point. This seems to produce good results.
|
||||
float srcReferencePointX = 0.0f;
|
||||
float srcReferencePointY = static_cast<float>(src->_data.ascent);
|
||||
|
||||
float destReferencePointX = 0.0f;
|
||||
float destReferencePointY = static_cast<float>(scaledAscent);
|
||||
|
||||
BdfFontData data;
|
||||
|
||||
data.maxAdvance = (int)(roundf((float)src->_data.maxAdvance * scale));
|
||||
data.height = (int)(roundf((float)src->_data.height * scale));
|
||||
data.size = (int)(roundf((float)src->_data.size * scale));
|
||||
data.ascent = scaledAscent;
|
||||
data.defaultBox = scaleBdfBoundingBox(src->_data.ascent, srcReferencePointX, srcReferencePointY, data.ascent, destReferencePointX, destReferencePointY, src->_data.defaultBox, scale);
|
||||
|
||||
data.defaultBox.width = (int)(roundf((float)src->_data.defaultBox.width * scale));
|
||||
data.defaultBox.height = (int)(roundf((float)src->_data.defaultBox.height * scale));
|
||||
data.defaultBox.xOffset = (int)(roundf((float)src->_data.defaultBox.xOffset * scale));
|
||||
data.defaultBox.yOffset = (int)(roundf((float)src->_data.defaultBox.yOffset * scale));
|
||||
data.firstCharacter = src->_data.firstCharacter;
|
||||
data.defaultCharacter = src->_data.defaultCharacter;
|
||||
data.numCharacters = src->_data.numCharacters;
|
||||
uint sz = 1 + strlen(src->_data.familyName);
|
||||
char *familyName = new char[sz];
|
||||
Common::strcpy_s(familyName, sz, src->_data.familyName);
|
||||
data.familyName = familyName;
|
||||
sz = 1 + strlen(src->_data.slant);
|
||||
char *slant = new char[sz];
|
||||
Common::strcpy_s(slant, sz, src->_data.slant);
|
||||
data.slant = slant;
|
||||
|
||||
Common::Array<Common::Rect> srcRects;
|
||||
|
||||
if (src->_data.boxes) {
|
||||
srcRects.resize(data.numCharacters);
|
||||
|
||||
BdfBoundingBox *boxes = new BdfBoundingBox[data.numCharacters];
|
||||
for (uint i = 0; i < data.numCharacters; ++i)
|
||||
boxes[i] = scaleBdfBoundingBox(src->_data.ascent, srcReferencePointX, srcReferencePointY, data.ascent, destReferencePointX, destReferencePointY, src->_data.boxes[i], scale);
|
||||
data.boxes = boxes;
|
||||
} else {
|
||||
// if the sources have null boxes
|
||||
data.boxes = nullptr;
|
||||
}
|
||||
|
||||
if (src->_data.advances) {
|
||||
byte *advances = new byte[data.numCharacters];
|
||||
for (uint i = 0; i < data.numCharacters; ++i) {
|
||||
advances[i] = (int)(roundf((float)src->_data.advances[i] * scale));
|
||||
}
|
||||
data.advances = advances;
|
||||
} else {
|
||||
// if the sources have null advances
|
||||
data.advances = nullptr;
|
||||
}
|
||||
|
||||
byte **bitmaps = new byte *[data.numCharacters];
|
||||
for (uint i = 0; i < data.numCharacters; i++) {
|
||||
const BdfBoundingBox &box = data.boxes ? data.boxes[i] : data.defaultBox;
|
||||
const BdfBoundingBox &srcBox = data.boxes ? src->_data.boxes[i] : src->_data.defaultBox;
|
||||
|
||||
#if DRAWDEBUG
|
||||
int ccc = 'L';
|
||||
#endif
|
||||
if (src->_data.bitmaps[i]) {
|
||||
int dstPitch = (box.width + 7) / 8 ;
|
||||
const int bytes = dstPitch * box.height;
|
||||
bitmaps[i] = new byte[bytes + 1];
|
||||
|
||||
#if DRAWDEBUG
|
||||
if (i == ccc) {
|
||||
Common::Rect srcRect = bdfBoxToRect(src->_data.ascent, srcBox);
|
||||
debugN("Ascent: %i\n", static_cast<int>(src->_data.ascent));
|
||||
debugN("Source box: (%i,%i) - (%i,%i)\n", static_cast<int>(srcRect.left), static_cast<int>(srcRect.top), static_cast<int>(srcRect.right), static_cast<int>(srcRect.bottom));
|
||||
debugN("Source bitmap:\n");
|
||||
|
||||
int srcPitch = (srcBox.width + 7) / 8;
|
||||
for (int y = 0; y < srcBox.height; y++) {
|
||||
for (int x = 0; x < srcBox.width; x++) {
|
||||
byte b = src->_data.bitmaps[i][y * srcPitch + x / 8];
|
||||
b >>= 7 - (x % 8);
|
||||
b &= 1;
|
||||
|
||||
debugN("%c", b ? '@' : '_');
|
||||
}
|
||||
debugN(" %i\n", static_cast<int>(y + srcRect.top));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Common::Rect rect = bdfBoxToRect(data.ascent, box);
|
||||
Common::Rect srcRect = bdfBoxToRect(src->_data.ascent, srcBox);
|
||||
|
||||
byte *ptr = bitmaps[i];
|
||||
const byte *srcPtr = src->_data.bitmaps[i];
|
||||
int destPitch = (rect.width() + 7) / 8;
|
||||
int srcPitch = (srcRect.width() + 7) / 8;
|
||||
|
||||
memset(ptr, 0, destPitch * rect.height());
|
||||
|
||||
float rcpScale = 1.0f / scale;
|
||||
|
||||
#if DRAWDEBUG
|
||||
if (i == ccc) {
|
||||
debugN("New ascent: %i\n", static_cast<int>(data.ascent));
|
||||
debugN("Dest box: (%i,%i) - (%i,%i)\n", static_cast<int>(rect.left), static_cast<int>(rect.top), static_cast<int>(rect.right), static_cast<int>(rect.bottom));
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int destRelY = 0; destRelY < rect.height(); destRelY++) {
|
||||
|
||||
int destY = destRelY + rect.top;
|
||||
float destPixelCenterY = destY + 0.5f;
|
||||
|
||||
float srcPixelCenterY = (destPixelCenterY - destReferencePointY) * rcpScale + srcReferencePointY;
|
||||
|
||||
int srcY = static_cast<int>(floorf(srcPixelCenterY));
|
||||
|
||||
if (srcY < srcRect.top || srcY >= srcRect.bottom)
|
||||
continue;
|
||||
|
||||
int srcRelY = srcY - srcRect.top;
|
||||
|
||||
byte *rowPtr = ptr + destPitch * destRelY;
|
||||
const byte *srcRowPtr = srcPtr + srcPitch * srcRelY;
|
||||
|
||||
for (int destRelX = 0; destRelX < rect.width(); destRelX++) {
|
||||
|
||||
int destX = destRelX + rect.left;
|
||||
float destPixelCenterX = destX + 0.5f;
|
||||
|
||||
float srcPixelCenterX = (destPixelCenterX - destReferencePointX) * rcpScale + srcReferencePointX;
|
||||
|
||||
int srcX = static_cast<int>(floorf(srcPixelCenterX));
|
||||
|
||||
if (srcX < srcRect.left || srcX >= srcRect.right)
|
||||
continue;
|
||||
|
||||
int srcRelX = srcX - srcRect.left;
|
||||
|
||||
if ((srcRowPtr[srcRelX / 8] << (srcRelX % 8)) & 0x80)
|
||||
rowPtr[destRelX / 8] |= (0x80 >> (destRelX % 8));
|
||||
}
|
||||
}
|
||||
|
||||
#if DRAWDEBUG
|
||||
if (i == ccc) {
|
||||
for (int y = 0; y < box.height; y++) {
|
||||
const byte *srcRow = (const byte *)&bitmaps[i][y * dstPitch];
|
||||
for (int x = 0; x < box.width; x++) {
|
||||
int sx = x;
|
||||
debugN("%c", (srcRow[sx / 8] & (0x80 >> (sx % 8))) ? '#' : '_');
|
||||
}
|
||||
debugN(" %i\n", static_cast<int>(y + rect.top));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
bitmaps[i] = nullptr;
|
||||
}
|
||||
}
|
||||
data.bitmaps = bitmaps;
|
||||
free(dstGray);
|
||||
srcSurf.free();
|
||||
|
||||
return new BdfFont(data, DisposeAfterUse::YES);
|
||||
}
|
||||
|
||||
} // End of namespace Graphics
|
||||
102
graphics/fonts/bdf.h
Normal file
102
graphics/fonts/bdf.h
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GRAPHICS_FONTS_BDF_H
|
||||
#define GRAPHICS_FONTS_BDF_H
|
||||
|
||||
#include "common/system.h"
|
||||
#include "common/types.h"
|
||||
|
||||
#include "graphics/font.h"
|
||||
|
||||
namespace Common {
|
||||
class SeekableReadStream;
|
||||
}
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
struct BdfBoundingBox {
|
||||
uint8 width, height;
|
||||
int8 xOffset, yOffset;
|
||||
};
|
||||
|
||||
struct BdfFontData {
|
||||
const char *familyName;
|
||||
const char *slant;
|
||||
|
||||
int maxAdvance;
|
||||
int height;
|
||||
int size;
|
||||
BdfBoundingBox defaultBox;
|
||||
int ascent;
|
||||
|
||||
uint firstCharacter;
|
||||
int defaultCharacter;
|
||||
uint numCharacters;
|
||||
|
||||
const byte *const *bitmaps;
|
||||
const byte *advances;
|
||||
const BdfBoundingBox *boxes;
|
||||
};
|
||||
|
||||
class BdfFont : public Font {
|
||||
public:
|
||||
BdfFont(const BdfFontData &data, DisposeAfterUse::Flag dispose);
|
||||
~BdfFont();
|
||||
|
||||
virtual int getFontHeight() const;
|
||||
virtual int getFontAscent() const;
|
||||
virtual int getMaxCharWidth() const;
|
||||
|
||||
virtual int getCharWidth(uint32 chr) const;
|
||||
virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const;
|
||||
|
||||
const char *getFamilyName() const;
|
||||
const char *getFontSlant() const;
|
||||
int getFontSize() const;
|
||||
|
||||
static BdfFont *loadFont(Common::SeekableReadStream &stream);
|
||||
static bool cacheFontData(const BdfFont &font, const Common::Path &filename);
|
||||
static BdfFont *loadFromCache(Common::SeekableReadStream &stream);
|
||||
static BdfFont *scaleFont(const BdfFont *src, int newSize);
|
||||
private:
|
||||
int mapToIndex(uint32 ch) const;
|
||||
|
||||
const BdfFontData _data;
|
||||
const DisposeAfterUse::Flag _dispose;
|
||||
};
|
||||
|
||||
#define DEFINE_FONT(n) \
|
||||
const BdfFont *n = 0; \
|
||||
void create_##n() { \
|
||||
n = new BdfFont(desc, DisposeAfterUse::NO); \
|
||||
}
|
||||
|
||||
#define FORWARD_DECLARE_FONT(n) \
|
||||
extern const BdfFont *n; \
|
||||
extern void create_##n()
|
||||
|
||||
#define INIT_FONT(n) \
|
||||
create_##n()
|
||||
|
||||
} // End of namespace Graphics
|
||||
|
||||
#endif
|
||||
213
graphics/fonts/bgifont.cpp
Normal file
213
graphics/fonts/bgifont.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
/* 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 "graphics/fonts/bgifont.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
BgiFont::BgiFont() {
|
||||
}
|
||||
|
||||
BgiFont::~BgiFont() {
|
||||
}
|
||||
|
||||
bool BgiFont::loadChr(const Common::Path &fileName) {
|
||||
|
||||
Common::File fontFile;
|
||||
if (!fontFile.open(fileName)) {
|
||||
error("unable to load font file %s", fileName.toString().c_str());
|
||||
}
|
||||
return loadChr(fontFile);
|
||||
}
|
||||
|
||||
bool BgiFont::loadChr(Common::SeekableReadStream &stream) {
|
||||
/* fileSignature = */ stream.readUint16LE();
|
||||
/*
|
||||
Description until finding value 0x1A
|
||||
*/
|
||||
Common::String description = stream.readString(0x1A);
|
||||
uint16 headerSize = stream.readUint16LE();
|
||||
Common::String name = stream.readString(0, 4);
|
||||
/*uint16 fontSize = */ stream.readUint16LE();
|
||||
/* byte majorVersion = */ stream.readByte();
|
||||
/* byte minorVersion = */ stream.readByte();
|
||||
/* byte majorRevision = */ stream.readByte();
|
||||
/* byte minorRevision = */ stream.readByte();
|
||||
|
||||
int remainingBytes = headerSize - (description.size() + 1 + 14);
|
||||
stream.seek(remainingBytes, SEEK_CUR);
|
||||
|
||||
/* char signature = */ stream.readByte();
|
||||
_charCount = stream.readUint16LE();
|
||||
// undefined byte
|
||||
stream.skip(1);
|
||||
|
||||
_firstChar = stream.readByte();
|
||||
/* uint16 strokeOffset = */ stream.readUint16LE();
|
||||
/*byte scanFlag = */ stream.readByte();
|
||||
|
||||
// Distance from the origin to the font's highest point
|
||||
_originToAscender = stream.readByte();
|
||||
// Distance from the origin to the font's baseline (typically 0). Ignored.
|
||||
/*signed char originToBaseline = */ stream.readByte();
|
||||
// Distance from the origin to the font's lowest point.
|
||||
_originToDescender = stream.readByte();
|
||||
/**
|
||||
* ----------- originToAscender
|
||||
*
|
||||
*
|
||||
*
|
||||
* ----------- 0
|
||||
*
|
||||
* ----------- originToDescender
|
||||
* totalHeight is the distance between originToAscender and originToDescender plus 1 (the baseline or the zero)
|
||||
*/
|
||||
_totalHeight = (_originToAscender - _originToDescender) + 1;
|
||||
// Unused bytes
|
||||
stream.skip(5);
|
||||
|
||||
_glyphs = new GlyphEntry[_charCount];
|
||||
|
||||
// Glyph offsets
|
||||
for (int i = 0; i < _charCount; i++) {
|
||||
_glyphs[i].offset = stream.readUint16LE();
|
||||
}
|
||||
_maxWidth = 0;
|
||||
// Glyph widths
|
||||
for (int i = 0; i < _charCount; i++) {
|
||||
_glyphs[i].charWidth = stream.readByte();
|
||||
if (_maxWidth < _glyphs[i].charWidth)
|
||||
_maxWidth = _glyphs[i].charWidth;
|
||||
}
|
||||
int64 pos = stream.pos();
|
||||
|
||||
// Read drawing instructions until next glyph definition
|
||||
for (int i = 0; i < _charCount; i++) {
|
||||
_totalWidth += _glyphs[i].charWidth;
|
||||
stream.seek(pos + _glyphs[i].offset, SEEK_SET);
|
||||
int m;
|
||||
do {
|
||||
DrawingInstruction *inst = new DrawingInstruction();
|
||||
byte instructionX = stream.readByte();
|
||||
byte instructionY = stream.readByte();
|
||||
// Grabs the most significant bit which is the opcode
|
||||
m = instructionX >> 7 & 0x1;
|
||||
m += m + (instructionY >> 7 & 0x1);
|
||||
instructionX = fixSign(instructionX);
|
||||
instructionY = fixSign(instructionY);
|
||||
|
||||
inst->opCode = m;
|
||||
inst->xCoord = instructionX;
|
||||
inst->yCoord = instructionY;
|
||||
_glyphs[i].insts.push_back(inst);
|
||||
|
||||
} while (m);
|
||||
}
|
||||
_fontCache.push_back(drawCachedFont(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
byte Graphics::BgiFont::fixSign(byte original) {
|
||||
// If negative shifts the sign bit to the right position
|
||||
return (original & 0x7F) | ((original & 0x40) << 1);
|
||||
}
|
||||
|
||||
BgiFont::CachedFont *BgiFont::drawCachedFont(int size) {
|
||||
CachedFont *cachedFont = new CachedFont();
|
||||
Graphics::Surface *surface = new Graphics::Surface();
|
||||
surface->create(_totalWidth, _totalHeight, Graphics::PixelFormat::createFormatCLUT8());
|
||||
uint32 offsetCount = 0;
|
||||
for (int i = 0; i < _charCount; i++) {
|
||||
|
||||
int curPosX = offsetCount;
|
||||
int curPosY = 0;
|
||||
cachedFont->offsets[i] = offsetCount;
|
||||
cachedFont->widths[i] = _glyphs[i].charWidth;
|
||||
|
||||
for (uint j = 0; j < _glyphs[i].insts.size(); j++) {
|
||||
int opCode = _glyphs[i].insts[j]->opCode;
|
||||
// Need to normalize Y coord because the stroke instructions start at origin and extend upwards up to originAscender, downwards to originToDescender
|
||||
int adjustedY = _originToAscender - _glyphs[i].insts[j]->yCoord;
|
||||
|
||||
switch (opCode) {
|
||||
case OPCODE_END:
|
||||
break;
|
||||
case OPCODE_MOVE:
|
||||
break;
|
||||
case OPCODE_DRAW:
|
||||
surface->drawLine(
|
||||
curPosX,
|
||||
curPosY,
|
||||
offsetCount + _glyphs[i].insts[j]->xCoord,
|
||||
adjustedY,
|
||||
255);
|
||||
break;
|
||||
default:
|
||||
/* nothing to do */
|
||||
break;
|
||||
};
|
||||
curPosX = offsetCount + _glyphs[i].insts[j]->xCoord;
|
||||
curPosY = adjustedY;
|
||||
}
|
||||
offsetCount += _glyphs[i].charWidth;
|
||||
}
|
||||
|
||||
cachedFont->surface = surface;
|
||||
return cachedFont;
|
||||
}
|
||||
|
||||
void Graphics::BgiFont::close() {
|
||||
}
|
||||
|
||||
int BgiFont::getCharWidth(uint32 chr) const {
|
||||
return _glyphs[characterToIndex(chr)].charWidth;
|
||||
}
|
||||
|
||||
void BgiFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const {
|
||||
CachedFont *font = _fontCache[0];
|
||||
uint16 charIndex = characterToIndex(chr);
|
||||
int charWidth = font->widths[charIndex];
|
||||
|
||||
for (uint16 i = 0; i < _totalHeight; i++) {
|
||||
for (uint16 j = 0; j < charWidth; j++) {
|
||||
if (font->surface->getPixel(font->offsets[charIndex] + j, i)) {
|
||||
if (dst->format.bytesPerPixel == 1)
|
||||
*((byte *)dst->getBasePtr(x + j, y + i)) = color;
|
||||
else if (dst->format.bytesPerPixel == 2)
|
||||
*((uint16 *)dst->getBasePtr(x + j, y + i)) = color;
|
||||
else if (dst->format.bytesPerPixel == 4)
|
||||
*((uint32 *)dst->getBasePtr(x + j, y + i)) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16 BgiFont::characterToIndex(uint32 character) const {
|
||||
uint16 index = _firstChar;
|
||||
if (character >= _firstChar) {
|
||||
if ((character - _firstChar) < _charCount) {
|
||||
index = character - _firstChar;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
} // End of namespace Graphics
|
||||
96
graphics/fonts/bgifont.h
Normal file
96
graphics/fonts/bgifont.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/* 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 GRAPHICS_FONTS_BGIFONT_H
|
||||
#define GRAPHICS_FONTS_BGIFONT_H
|
||||
|
||||
#include "common/file.h"
|
||||
#include "common/array.h"
|
||||
#include "graphics/font.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
const int OPCODE_END = 0;
|
||||
const int OPCODE_DOSCAN = 1;
|
||||
const int OPCODE_MOVE = 2;
|
||||
const int OPCODE_DRAW = 3;
|
||||
|
||||
class BgiFont : public Font {
|
||||
public:
|
||||
BgiFont();
|
||||
~BgiFont();
|
||||
|
||||
bool loadChr(const Common::Path &fileName);
|
||||
bool loadChr(Common::SeekableReadStream &stream);
|
||||
|
||||
void close();
|
||||
|
||||
int getFontHeight() const { return _totalHeight; }
|
||||
int getCharWidth(uint32 chr) const;
|
||||
int getMaxCharWidth() const { return _maxWidth; }
|
||||
void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const;
|
||||
|
||||
private:
|
||||
struct DrawingInstruction {
|
||||
int opCode;
|
||||
int8 xCoord;
|
||||
int8 yCoord;
|
||||
};
|
||||
|
||||
struct GlyphEntry {
|
||||
GlyphEntry() {
|
||||
charWidth = 0;
|
||||
offset = 0;
|
||||
}
|
||||
~GlyphEntry() {}
|
||||
|
||||
uint16 charWidth;
|
||||
uint32 offset;
|
||||
Common::Array<DrawingInstruction *> insts;
|
||||
} *_glyphs;
|
||||
|
||||
struct CachedFont {
|
||||
int widths[256];
|
||||
int offsets[256];
|
||||
Graphics::Surface *surface;
|
||||
~CachedFont() {
|
||||
delete surface;
|
||||
}
|
||||
};
|
||||
|
||||
uint16 _charCount;
|
||||
byte _firstChar;
|
||||
// uint16 _pixHeight;
|
||||
uint16 _maxWidth = 10;
|
||||
uint32 _totalWidth = 0;
|
||||
int16 _totalHeight = 0;
|
||||
int8 _originToAscender = 0;
|
||||
int8 _originToDescender = 0;
|
||||
Common::Array<CachedFont *> _fontCache;
|
||||
|
||||
uint16 characterToIndex(uint32 character) const;
|
||||
byte fixSign(byte original);
|
||||
CachedFont *drawCachedFont(int size);
|
||||
};
|
||||
|
||||
} // namespace Graphics
|
||||
|
||||
#endif
|
||||
5872
graphics/fonts/consolefont.cpp
Normal file
5872
graphics/fonts/consolefont.cpp
Normal file
File diff suppressed because it is too large
Load Diff
464
graphics/fonts/dosfont.cpp
Normal file
464
graphics/fonts/dosfont.cpp
Normal file
@@ -0,0 +1,464 @@
|
||||
/* 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 "graphics/fonts/dosfont.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
DosFont::DosFont() {}
|
||||
|
||||
int DosFont::getFontHeight() const {
|
||||
return 8;
|
||||
}
|
||||
|
||||
int DosFont::getMaxCharWidth() const {
|
||||
return 8;
|
||||
}
|
||||
|
||||
int DosFont::getCharWidth(uint32 chr) const {
|
||||
return 8;
|
||||
}
|
||||
|
||||
void DosFont::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const {
|
||||
int srcPixel = chr * 8;
|
||||
for (int sy = 0; sy < 8; sy++) {
|
||||
for (int sx = 0; sx < 8; sx++) {
|
||||
if (Graphics::DosFont::fontData_PCBIOS[srcPixel] & 1 << (7 - sx)) {
|
||||
if (dst->format.bytesPerPixel == 1)
|
||||
*((byte *)dst->getBasePtr(x + sx, y + sy)) = color;
|
||||
else if (dst->format.bytesPerPixel == 2)
|
||||
*((uint16 *)dst->getBasePtr(x + sx, y + sy)) = color;
|
||||
else if (dst->format.bytesPerPixel == 4)
|
||||
*((uint32 *)dst->getBasePtr(x + sx, y + sy)) = color;
|
||||
}
|
||||
}
|
||||
srcPixel++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 8x8 font patterns
|
||||
|
||||
// this is basically the standard PC BIOS font, taken from Dos-Box, with a few modifications
|
||||
const uint8 DosFont::fontData_PCBIOS[256 * 8] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E,
|
||||
0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E,
|
||||
0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
|
||||
0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00,
|
||||
0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x7C, 0x38, 0x7C,
|
||||
0x10, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C,
|
||||
0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF,
|
||||
0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00,
|
||||
0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF,
|
||||
0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78,
|
||||
0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18,
|
||||
0x08, 0x0C, 0x0A, 0x0A, 0x08, 0x78, 0xF0, 0x00, // 0x0D changed
|
||||
0x18, 0x14, 0x1A, 0x16, 0x72, 0xE2, 0x0E, 0x1C, // 0x0E changed
|
||||
0x10, 0x54, 0x38, 0xEE, 0x38, 0x54, 0x10, 0x00, // 0x0F changed
|
||||
//0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0, // 0x0D original
|
||||
//0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0, // 0x0E original
|
||||
//0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, // 0x0F original
|
||||
0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00,
|
||||
0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00,
|
||||
0x18, 0x3C, 0x5A, 0x18, 0x5A, 0x3C, 0x18, 0x00, // 0x12 changed
|
||||
//0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18, // 0x12 original
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
|
||||
0x7F, 0xDB, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x00, // 0x14 changed
|
||||
0x1C, 0x22, 0x38, 0x44, 0x44, 0x38, 0x88, 0x70, // 0x14 changed
|
||||
//0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, // 0x14 original
|
||||
//0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0xCC, 0x78, // 0x15 original
|
||||
0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00,
|
||||
0x18, 0x3C, 0x5A, 0x18, 0x5A, 0x3C, 0x18, 0x7E, // 0x17 changed
|
||||
0x18, 0x3C, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x00, // 0x18 changed
|
||||
0x18, 0x18, 0x18, 0x18, 0x5A, 0x3C, 0x18, 0x00, // 0x19 changed
|
||||
//0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, // 0x17 original
|
||||
//0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00, // 0x18 original
|
||||
//0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, // 0x19 original
|
||||
0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00,
|
||||
0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00,
|
||||
0x00, 0x24, 0x42, 0xFF, 0x42, 0x24, 0x00, 0x00, // 0x1D changed
|
||||
0x00, 0x10, 0x38, 0x7C, 0xFE, 0xFE, 0x00, 0x00, // 0x1E changed
|
||||
0x00, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, // 0x1F changed
|
||||
//0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00, // 0x1D original
|
||||
//0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00, // 0x1E original
|
||||
//0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00, // 0x1F original
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20
|
||||
0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00,
|
||||
0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00,
|
||||
0x30, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x30, 0x00,
|
||||
0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00,
|
||||
0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00,
|
||||
0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00,
|
||||
0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
|
||||
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
|
||||
0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60,
|
||||
0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00,
|
||||
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00,
|
||||
0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x7C, 0x00, // 0x30
|
||||
0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00,
|
||||
0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00,
|
||||
0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00,
|
||||
0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00,
|
||||
0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00,
|
||||
0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00,
|
||||
0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00,
|
||||
0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00,
|
||||
0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00,
|
||||
0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00,
|
||||
0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60,
|
||||
0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00,
|
||||
0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00,
|
||||
0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00,
|
||||
0x78, 0xCC, 0x0C, 0x18, 0x30, 0x00, 0x30, 0x00,
|
||||
0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00, // 0x40
|
||||
0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00,
|
||||
0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00,
|
||||
0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00,
|
||||
0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00,
|
||||
0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00,
|
||||
0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00,
|
||||
0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3E, 0x00,
|
||||
0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00,
|
||||
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00,
|
||||
0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00,
|
||||
0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00,
|
||||
0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00,
|
||||
0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00,
|
||||
0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00,
|
||||
0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, // 0x50
|
||||
0x78, 0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x1C, 0x00,
|
||||
0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00,
|
||||
0x78, 0xCC, 0xE0, 0x70, 0x1C, 0xCC, 0x78, 0x00,
|
||||
0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00,
|
||||
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
|
||||
0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00,
|
||||
0xC6, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00,
|
||||
0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00,
|
||||
0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00,
|
||||
0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
|
||||
0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00,
|
||||
0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
|
||||
0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
|
||||
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60
|
||||
0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
|
||||
0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00,
|
||||
0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00,
|
||||
0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00,
|
||||
0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
|
||||
0x38, 0x6C, 0x60, 0xF0, 0x60, 0x60, 0xF0, 0x00,
|
||||
0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
|
||||
0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00,
|
||||
0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78,
|
||||
0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00,
|
||||
0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xC6, 0x00,
|
||||
0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
|
||||
0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
|
||||
0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0, // 0x70
|
||||
0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E,
|
||||
0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0xF0, 0x00,
|
||||
0x00, 0x00, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x00,
|
||||
0x10, 0x30, 0x7C, 0x30, 0x30, 0x34, 0x18, 0x00,
|
||||
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
|
||||
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
|
||||
0x00, 0x00, 0xC6, 0xD6, 0xFE, 0xFE, 0x6C, 0x00,
|
||||
0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00,
|
||||
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
|
||||
0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00,
|
||||
0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00,
|
||||
0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
|
||||
0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00,
|
||||
0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00,
|
||||
0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x18, 0x0C, 0x78, // 0x80
|
||||
0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00,
|
||||
0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
|
||||
0x7E, 0xC3, 0x3C, 0x06, 0x3E, 0x66, 0x3F, 0x00,
|
||||
0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00,
|
||||
0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00,
|
||||
0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00,
|
||||
0x00, 0x00, 0x78, 0xC0, 0xC0, 0x78, 0x0C, 0x38,
|
||||
0x7E, 0xC3, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00,
|
||||
0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
|
||||
0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
|
||||
0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0x7C, 0xC6, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00,
|
||||
0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0xC6, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00,
|
||||
0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00,
|
||||
0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00,
|
||||
0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00,
|
||||
0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00,
|
||||
0x78, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
|
||||
0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
|
||||
0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
|
||||
0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00,
|
||||
0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00,
|
||||
0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
|
||||
0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00,
|
||||
0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
|
||||
0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18,
|
||||
0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00,
|
||||
0xCC, 0xCC, 0x78, 0xFC, 0x30, 0xFC, 0x30, 0x30,
|
||||
0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC7,
|
||||
0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70,
|
||||
0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00,
|
||||
0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
|
||||
0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
|
||||
0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00,
|
||||
0x00, 0xF8, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0x00,
|
||||
0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00,
|
||||
0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00,
|
||||
0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00,
|
||||
0x30, 0x00, 0x30, 0x60, 0xC0, 0xCC, 0x78, 0x00,
|
||||
0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00,
|
||||
0xC3, 0xC6, 0xCC, 0xDE, 0x33, 0x66, 0xCC, 0x0F,
|
||||
0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6F, 0xCF, 0x03,
|
||||
0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00,
|
||||
0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00,
|
||||
0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00,
|
||||
0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
|
||||
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
||||
0xDB, 0x77, 0xDB, 0xEE, 0xDB, 0x77, 0xDB, 0xEE,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36,
|
||||
0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36,
|
||||
0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
|
||||
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00,
|
||||
0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0,
|
||||
0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00,
|
||||
0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00,
|
||||
0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00,
|
||||
0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00,
|
||||
0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0,
|
||||
0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00,
|
||||
0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC,
|
||||
0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00,
|
||||
0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00,
|
||||
0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00,
|
||||
0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00,
|
||||
0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0,
|
||||
0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00,
|
||||
0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
|
||||
0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x00,
|
||||
0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0xFC, 0x00,
|
||||
0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00,
|
||||
0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00,
|
||||
0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70,
|
||||
0x30, 0x30, 0x00, 0xFC, 0x00, 0x30, 0x30, 0x00,
|
||||
0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00,
|
||||
0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C,
|
||||
0x78, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00,
|
||||
0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
// Extended set (0x80-0xFF) for Russian versions of games
|
||||
const uint8 DosFont::fontData_ExtendedRussian[128 * 8] = {
|
||||
0x1E, 0x36, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x00, // 0x80
|
||||
0x7C, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00,
|
||||
0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00,
|
||||
0x7E, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
|
||||
0x38, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0xFE, 0xC6,
|
||||
0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x7E, 0x00,
|
||||
0xDB, 0xDB, 0x7E, 0x3C, 0x7E, 0xDB, 0xDB, 0x00,
|
||||
0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0x00,
|
||||
0x66, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00,
|
||||
0x3C, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00,
|
||||
0x66, 0x6C, 0x78, 0x70, 0x78, 0x6C, 0x66, 0x00,
|
||||
0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00,
|
||||
0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00,
|
||||
0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
|
||||
0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
|
||||
0x7E, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00,
|
||||
0x7C, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x00,
|
||||
0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x00,
|
||||
0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
|
||||
0x66, 0x66, 0x66, 0x3E, 0x06, 0x66, 0x3C, 0x00,
|
||||
0x7E, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x00,
|
||||
0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7F, 0x03,
|
||||
0x66, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00,
|
||||
0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x00,
|
||||
0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x03,
|
||||
0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00,
|
||||
0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00,
|
||||
0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00,
|
||||
0x78, 0x8C, 0x06, 0x3E, 0x06, 0x8C, 0x78, 0x00,
|
||||
0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00,
|
||||
0x3E, 0x66, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x00,
|
||||
0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3A, 0x00,
|
||||
0x00, 0x3C, 0x60, 0x3C, 0x66, 0x66, 0x3C, 0x00,
|
||||
0x00, 0x00, 0x7C, 0x66, 0x7C, 0x66, 0x7C, 0x00,
|
||||
0x00, 0x00, 0x7E, 0x60, 0x60, 0x60, 0x60, 0x00,
|
||||
0x00, 0x00, 0x3C, 0x6C, 0x6C, 0x6C, 0xFE, 0xC6,
|
||||
0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00,
|
||||
0x00, 0x00, 0xDB, 0x7E, 0x3C, 0x7E, 0xDB, 0x00,
|
||||
0x00, 0x00, 0x3C, 0x66, 0x0C, 0x66, 0x3C, 0x00,
|
||||
0x00, 0x00, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x00,
|
||||
0x00, 0x18, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x00,
|
||||
0x00, 0x00, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x00,
|
||||
0x00, 0x00, 0xC6, 0xFE, 0xFE, 0xD6, 0xC6, 0x00,
|
||||
0x00, 0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x00,
|
||||
0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00,
|
||||
0x00, 0x00, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x00,
|
||||
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
|
||||
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
||||
0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18,
|
||||
0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36,
|
||||
0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, 0x36,
|
||||
0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0x18,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
|
||||
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x00,
|
||||
0x00, 0x00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0x00,
|
||||
0x00, 0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00,
|
||||
0x00, 0x00, 0x66, 0x66, 0x3E, 0x06, 0x7C, 0x00,
|
||||
0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x18, 0x00,
|
||||
0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00,
|
||||
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7F, 0x03,
|
||||
0x00, 0x00, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x00,
|
||||
0x00, 0x00, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x00,
|
||||
0x00, 0x00, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x03,
|
||||
0x00, 0x00, 0xE0, 0x60, 0x7C, 0x66, 0x7C, 0x00,
|
||||
0x00, 0x00, 0xC6, 0xC6, 0xF6, 0xDE, 0xF6, 0x00,
|
||||
0x00, 0x00, 0x60, 0x60, 0x7C, 0x66, 0x7C, 0x00,
|
||||
0x00, 0x00, 0x7C, 0x06, 0x3E, 0x06, 0x7C, 0x00,
|
||||
0x00, 0x00, 0xCE, 0xDB, 0xFB, 0xDB, 0xCE, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x66, 0x3E, 0x36, 0x66, 0x00,
|
||||
0x00, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00,
|
||||
0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x7C, 0x00,
|
||||
0x00, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30,
|
||||
0x00, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C,
|
||||
0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70,
|
||||
0x00, 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18,
|
||||
0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00,
|
||||
0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00,
|
||||
0x03, 0x02, 0x06, 0x04, 0xCC, 0x68, 0x38, 0x10,
|
||||
0x3C, 0x42, 0x99, 0xA1, 0xA1, 0x99, 0x42, 0x3C,
|
||||
0x30, 0x48, 0x10, 0x20, 0x78, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7C, 0x7C, 0x7C, 0x7C, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x7E, 0x00
|
||||
};
|
||||
} // end of namespace Graphics
|
||||
47
graphics/fonts/dosfont.h
Normal file
47
graphics/fonts/dosfont.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 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 GRAPHICS_FONTS_DOSFONT_H
|
||||
#define GRAPHICS_FONTS_DOSFONT_H
|
||||
|
||||
#include "graphics/font.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
class DosFont : public Graphics::Font {
|
||||
public:
|
||||
DosFont();
|
||||
|
||||
int getFontHeight() const override;
|
||||
int getMaxCharWidth() const override;
|
||||
int getCharWidth(uint32 chr) const override;
|
||||
void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const override;
|
||||
public:
|
||||
// 8x8 font patterns
|
||||
|
||||
// this is basically the standard PC BIOS font, taken from Dos-Box, with a few modifications
|
||||
static const uint8 fontData_PCBIOS[256 * 8];
|
||||
static const uint8 fontData_ExtendedRussian[128 * 8];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
137
graphics/fonts/freetype.cpp
Normal file
137
graphics/fonts/freetype.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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Since FreeType2 includes files, which contain forbidden symbols, we need to
|
||||
// allow all symbols here.
|
||||
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
#ifdef USE_FREETYPE2
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
#include FT_MODULE_H
|
||||
|
||||
namespace Graphics {
|
||||
namespace FreeType {
|
||||
|
||||
void *Alloc_Callback(FT_Memory memory, long size) {
|
||||
return malloc(static_cast<size_t>(size));
|
||||
}
|
||||
|
||||
void Free_Callback(FT_Memory memory, void *block) {
|
||||
free(block);
|
||||
block = nullptr;
|
||||
}
|
||||
|
||||
void *Realloc_Callback(FT_Memory memory, long cur_size, long new_size, void *block) {
|
||||
return realloc(block, static_cast<size_t>(new_size));
|
||||
}
|
||||
|
||||
FT_Error Init_FreeType_With_Mem(FT_Library *alibrary, FT_Memory *amem) {
|
||||
// It seems FT_New_Memory isn't part of the public API in 2.10.4
|
||||
FT_Memory mem = static_cast<FT_Memory>(malloc(sizeof(FT_MemoryRec_)));
|
||||
if (!mem)
|
||||
return FT_Err_Out_Of_Memory;
|
||||
|
||||
mem->alloc = Alloc_Callback;
|
||||
mem->free = Free_Callback;
|
||||
mem->realloc = Realloc_Callback;
|
||||
mem->user = nullptr;
|
||||
|
||||
FT_Error error = FT_New_Library(mem, alibrary);
|
||||
if (!error) {
|
||||
FT_Add_Default_Modules(*alibrary);
|
||||
*amem = mem;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
FT_Error Init_FreeType(FT_Library *alibrary) {
|
||||
return FT_Init_FreeType(alibrary);
|
||||
}
|
||||
|
||||
FT_Error Done_FreeType(FT_Library library) {
|
||||
return FT_Done_FreeType(library);
|
||||
}
|
||||
|
||||
FT_Error Done_FreeType_With_Mem(FT_Library library, FT_Memory mem) {
|
||||
FT_Error error = FT_Done_Library(library);
|
||||
free(mem);
|
||||
return error;
|
||||
}
|
||||
|
||||
FT_Error Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags) {
|
||||
return FT_Load_Glyph(face, glyph_index, load_flags);
|
||||
}
|
||||
|
||||
FT_Error Get_Glyph(FT_GlyphSlot slot, FT_Glyph *aglyph) {
|
||||
return FT_Get_Glyph(slot, aglyph);
|
||||
}
|
||||
|
||||
FT_Error Glyph_Copy(FT_Glyph source, FT_Glyph *target) {
|
||||
return FT_Glyph_Copy(source, target);
|
||||
}
|
||||
|
||||
FT_Error Glyph_To_Bitmap(FT_Glyph *the_glyph, FT_Render_Mode render_mode,
|
||||
FT_Vector *origin, FT_Bool destroy) {
|
||||
return FT_Glyph_To_Bitmap(the_glyph, render_mode, origin, destroy);
|
||||
}
|
||||
|
||||
void Done_Glyph(FT_Glyph glyph) {
|
||||
return FT_Done_Glyph(glyph);
|
||||
}
|
||||
|
||||
FT_Error Set_Pixel_Sizes(FT_Face face, FT_UInt pixel_width,
|
||||
FT_UInt pixel_height) {
|
||||
return FT_Set_Pixel_Sizes(face, pixel_width, pixel_height);
|
||||
}
|
||||
|
||||
FT_Error New_Face(FT_Library library, const char *pathname,
|
||||
FT_Long face_index, FT_Face *aface) {
|
||||
return FT_New_Face(library, pathname, face_index, aface);
|
||||
}
|
||||
|
||||
FT_Error New_Memory_Face(FT_Library library, const FT_Byte *file_base,
|
||||
FT_Long file_size, FT_Long face_index, FT_Face *aface) {
|
||||
return FT_New_Memory_Face(library, file_base, file_size, face_index, aface);
|
||||
}
|
||||
|
||||
FT_Error Done_Face(FT_Face face) {
|
||||
return FT_Done_Face(face);
|
||||
}
|
||||
|
||||
FT_UInt Get_Char_Index(FT_Face face, FT_ULong charcode) {
|
||||
return FT_Get_Char_Index(face, charcode);
|
||||
}
|
||||
|
||||
FT_Error Get_Kerning(FT_Face face, FT_UInt left_glyph,
|
||||
FT_UInt right_glyph, FT_UInt kern_mode, FT_Vector *akerning) {
|
||||
return FT_Get_Kerning(face, left_glyph, right_glyph, kern_mode, akerning);
|
||||
}
|
||||
|
||||
} // End of namespace FreeType
|
||||
} // End of namespace Graphics
|
||||
|
||||
#endif
|
||||
62
graphics/fonts/freetype.h
Normal file
62
graphics/fonts/freetype.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* 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 GRAPHICS_FONTS_FREETYPE_H
|
||||
#define GRAPHICS_FONTS_FREETYPE_H
|
||||
|
||||
#ifdef USE_FREETYPE2
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
|
||||
namespace Graphics {
|
||||
namespace FreeType {
|
||||
|
||||
extern FT_Error Init_FreeType(FT_Library *alibrary);
|
||||
extern FT_Error Init_FreeType_With_Mem(FT_Library *alibrary, FT_Memory *amem);
|
||||
extern FT_Error Done_FreeType(FT_Library library);
|
||||
extern FT_Error Done_FreeType_With_Mem(FT_Library library, FT_Memory mem);
|
||||
extern FT_Error Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags);
|
||||
extern FT_Error Get_Glyph(FT_GlyphSlot slot, FT_Glyph *aglyph);
|
||||
extern FT_Error Glyph_Copy(FT_Glyph source, FT_Glyph *target);
|
||||
extern FT_Error Glyph_To_Bitmap(FT_Glyph *the_glyph, FT_Render_Mode render_mode,
|
||||
FT_Vector *origin, FT_Bool destroy);
|
||||
extern void Done_Glyph(FT_Glyph glyph);
|
||||
extern FT_Error Set_Pixel_Sizes(FT_Face face, FT_UInt pixel_width,
|
||||
FT_UInt pixel_height);
|
||||
extern FT_Error New_Face(FT_Library library, const char *pathname,
|
||||
FT_Long face_index, FT_Face *aface);
|
||||
extern FT_Error New_Memory_Face(FT_Library library, const FT_Byte *file_base,
|
||||
FT_Long file_size, FT_Long face_index, FT_Face *aface);
|
||||
extern FT_Error Done_Face(FT_Face face);
|
||||
extern FT_UInt Get_Char_Index(FT_Face face, FT_ULong charcode);
|
||||
extern FT_Error Get_Kerning(FT_Face face, FT_UInt left_glyph,
|
||||
FT_UInt right_glyph, FT_UInt kern_mode, FT_Vector *akerning);
|
||||
|
||||
} // End of namespace FreeType
|
||||
} // End of namespace Graphics
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
856
graphics/fonts/macfont.cpp
Normal file
856
graphics/fonts/macfont.cpp
Normal file
@@ -0,0 +1,856 @@
|
||||
/* 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/stream.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
#include "graphics/macgui/macfontmanager.h"
|
||||
#include "graphics/fonts/macfont.h"
|
||||
|
||||
#define DEBUGSCALING 0
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
enum {
|
||||
kFontTypeImageHeightTable = (1 << 0),
|
||||
kFontTypeGlyphWidthTable = (1 << 1),
|
||||
kFontTypeFontColorTable = (1 << 7),
|
||||
kFontTypeSyntheticFont = (1 << 8),
|
||||
kFontTypeFixedWidthFont = (1 << 13),
|
||||
kFontTypeNotExpandable = (1 << 14)
|
||||
};
|
||||
|
||||
enum {
|
||||
kFamilyGlyphWidthTable = (1 << 1),
|
||||
kFamilyFractEnable = (1 << 12),
|
||||
kFamilyIntegerExtra = (1 << 13),
|
||||
kFamilyNoFractionalTable = (1 << 14),
|
||||
kFamilyFixedWidthFonts = (1 << 15)
|
||||
};
|
||||
|
||||
enum {
|
||||
kStylePropertyPlain = 0,
|
||||
kStylePropertyBold = 1,
|
||||
kStylePropertyItalic = 2,
|
||||
kStylePropertyUnderline = 3,
|
||||
kStylePropertyOutline = 4,
|
||||
kStylePropertyShadow = 5,
|
||||
kStylePropertyCondensed = 6,
|
||||
kStylePropertyExtended = 7,
|
||||
kStylePropertyUnused = 8
|
||||
};
|
||||
|
||||
static int getDepth(uint16 _fontType) {
|
||||
// Returns 1, 2, 4, 8
|
||||
|
||||
return 1 << ((_fontType >> 2) & 3);
|
||||
}
|
||||
|
||||
MacFontFamily::MacFontFamily(const Common::String &name) {
|
||||
_name = name;
|
||||
|
||||
_ffFlags = 0;
|
||||
_ffFamID = 0;
|
||||
_ffFirstChar = 0;
|
||||
_ffLastChar = 0;
|
||||
_ffAscent = 0;
|
||||
_ffDescent = 0;
|
||||
_ffLeading = 0;
|
||||
_ffWidMax = 0;
|
||||
_ffWTabOff = 0;
|
||||
_ffKernOff = 0;
|
||||
_ffStylOff = 0;
|
||||
|
||||
for (int i = 0; i < 9; i++)
|
||||
_ffProperty[i] = 0;
|
||||
|
||||
_ffIntl[0] = 0;
|
||||
_ffIntl[1] = 0;
|
||||
_ffVersion = 0;
|
||||
|
||||
_ffNumAssoc = 0;
|
||||
_ffNumOffsets = 0;
|
||||
_ffOffsets = nullptr;
|
||||
_ffNumBBoxes = 0;
|
||||
_ffNumKerns = 0;
|
||||
_ffNumStyleWidths = 0;
|
||||
}
|
||||
|
||||
MacFontFamily::~MacFontFamily() {
|
||||
free(_ffOffsets);
|
||||
}
|
||||
|
||||
bool MacFontFamily::load(Common::SeekableReadStream &stream) {
|
||||
_ffFlags = stream.readUint16BE(); // flags for family
|
||||
_ffFamID = stream.readUint16BE(); // family ID number
|
||||
_ffFirstChar = stream.readUint16BE(); // ASCII code of first character
|
||||
_ffLastChar = stream.readUint16BE(); // ASCII code of last character
|
||||
_ffAscent = stream.readSint16BE(); // maximum ascent for 1-pt font
|
||||
_ffDescent = stream.readSint16BE(); // maximum descent for 1-pt font
|
||||
_ffLeading = stream.readSint16BE(); // maximum leading for 1-pt font
|
||||
_ffWidMax = stream.readSint16BE(); // maximum glyph width for 1-pt font
|
||||
_ffWTabOff = stream.readUint32BE(); // offset to family glyph-width table
|
||||
_ffKernOff = stream.readUint32BE(); // offset to kerning table
|
||||
_ffStylOff = stream.readUint32BE(); // offset to style-mapping table
|
||||
|
||||
debug(10, "flags: %x famid: %d first: %d last: %d", _ffFlags, _ffFamID, _ffFirstChar, _ffLastChar);
|
||||
debug(10, "ascent: %g descent: %g, leading: %g, widmax: %g", _ffAscent / (double)(1<<12),
|
||||
_ffDescent / (double)(1<<12), _ffLeading / (double)(1<<12), _ffWidMax / (double)(1<<12));
|
||||
|
||||
debug(10, "wtaboff: %d kernoff: %d styloff: %d", _ffWTabOff, _ffKernOff, _ffStylOff);
|
||||
|
||||
debugN(10, "Extra width: ");
|
||||
for (int i = 0; i < 9; i++) { // style properties info
|
||||
_ffProperty[i] = stream.readUint16BE();
|
||||
debugN(10, "%d ", _ffProperty[i]);
|
||||
}
|
||||
debug(10, "%s", "");
|
||||
|
||||
_ffIntl[0] = stream.readUint16BE(); // for international use
|
||||
_ffIntl[1] = stream.readUint16BE(); // for international use
|
||||
_ffVersion = stream.readUint16BE(); // version number
|
||||
|
||||
debug(10, "version: %d", _ffVersion);
|
||||
|
||||
_ffNumAssoc = stream.readUint16BE(); // number of entries - 1
|
||||
_ffAssocEntries.resize(_ffNumAssoc + 1);
|
||||
|
||||
debug(10, "association cnt: %d", _ffNumAssoc + 1);
|
||||
|
||||
for (uint i = 0; i <= _ffNumAssoc; i++) {
|
||||
_ffAssocEntries[i]._fontSize = stream.readUint16BE(); // point size of font
|
||||
_ffAssocEntries[i]._fontStyle = stream.readUint16BE(); // style of font
|
||||
_ffAssocEntries[i]._fontID = stream.readUint16BE(); // font resource ID
|
||||
|
||||
debug(10, " size: %d style: %d id: %d", _ffAssocEntries[i]._fontSize, _ffAssocEntries[i]._fontStyle,
|
||||
_ffAssocEntries[i]._fontID);
|
||||
}
|
||||
|
||||
if (_ffWTabOff || _ffStylOff || _ffKernOff) {
|
||||
_ffNumOffsets = stream.readUint16BE(); // number of entries - 1
|
||||
_ffOffsets = (uint32 *)calloc(_ffNumOffsets + 1, sizeof(uint32));
|
||||
debugN(10, "offset cnt: %d, OFF: ", _ffNumOffsets + 1);
|
||||
for (uint i = 0; i <= _ffNumOffsets; i++) {
|
||||
_ffOffsets[i] = stream.readUint32BE();
|
||||
debugN(10, "%d ", _ffOffsets[i]);
|
||||
}
|
||||
debug(10, "%s", "");
|
||||
|
||||
_ffNumBBoxes = stream.readUint16BE(); // number of entries - 1
|
||||
_ffBBoxes.resize(_ffNumBBoxes + 1);
|
||||
debug(10, "num BBoxes: %d", _ffNumBBoxes + 1);
|
||||
for (uint i = 0; i <= _ffNumBBoxes; i++) {
|
||||
_ffBBoxes[i]._style = stream.readUint16BE();
|
||||
_ffBBoxes[i]._left = stream.readSint16BE();
|
||||
_ffBBoxes[i]._bottom = stream.readSint16BE();
|
||||
_ffBBoxes[i]._right = stream.readSint16BE();
|
||||
_ffBBoxes[i]._top = stream.readSint16BE();
|
||||
|
||||
debug(10, "style: %d left: %g bottom: %g right: %g top: %g", _ffBBoxes[i]._style,
|
||||
_ffBBoxes[i]._left / (double)(1<<12), _ffBBoxes[i]._bottom / (double)(1<<12),
|
||||
_ffBBoxes[i]._right / (double)(1<<12), _ffBBoxes[i]._top / (double)(1<<12));
|
||||
}
|
||||
}
|
||||
|
||||
if (_ffWTabOff) {
|
||||
stream.seek(_ffWTabOff);
|
||||
|
||||
_ffNumStyleWidths = stream.readUint16BE() + 1;
|
||||
_ffStyleWidths.resize(_ffNumStyleWidths);
|
||||
|
||||
debug(10, "style widths entries: %d", _ffNumStyleWidths);
|
||||
|
||||
for (uint i = 0; i < _ffNumStyleWidths; i++) {
|
||||
uint size = _ffLastChar - _ffFirstChar + 3;
|
||||
_ffStyleWidths[i]._style = stream.readUint16BE();
|
||||
_ffStyleWidths[i]._widths.resize(size);
|
||||
|
||||
for (uint j = 0; j < size; j++)
|
||||
_ffStyleWidths[i]._widths[j] = stream.readUint16BE();
|
||||
}
|
||||
}
|
||||
|
||||
if (_ffStylOff) {
|
||||
// looks like this part is not useful for now.
|
||||
// stream.seek(_ffStylOff);
|
||||
|
||||
/*uint16 classFlag =*/ stream.readUint16BE();
|
||||
/*uint8 plainIndex =*/ stream.readSByte();
|
||||
/*uint8 boldIndex =*/ stream.readSByte();
|
||||
/*uint8 italicIndex =*/ stream.readSByte();
|
||||
}
|
||||
|
||||
if (_ffKernOff) {
|
||||
stream.seek(_ffKernOff);
|
||||
|
||||
_ffNumKerns = stream.readUint16BE(); // number of entries - 1
|
||||
_ffKernEntries.resize(_ffNumKerns + 1);
|
||||
|
||||
debug(10, "kern entries: %d", _ffNumKerns + 1);
|
||||
|
||||
for (uint i = 0; i <= _ffNumKerns; i++) {
|
||||
_ffKernEntries[i]._style = stream.readUint16BE();
|
||||
_ffKernEntries[i]._entryLength = stream.readUint16BE();
|
||||
_ffKernEntries[i]._kernPairs.resize(_ffKernEntries[i]._entryLength);
|
||||
|
||||
debug(10, " style: %x kernpairs: %u", _ffKernEntries[i]._style, _ffKernEntries[i]._entryLength);
|
||||
|
||||
for (uint j = 0; j < _ffKernEntries[i]._entryLength; j++) {
|
||||
byte f, s;
|
||||
int16 d;
|
||||
f = _ffKernEntries[i]._kernPairs[j]._firstChar = stream.readByte();
|
||||
s = _ffKernEntries[i]._kernPairs[j]._secondChar = stream.readByte();
|
||||
d = _ffKernEntries[i]._kernPairs[j]._distance = stream.readSint16BE();
|
||||
|
||||
_ffKernEntries[i]._kernTable[(f << 8) | s] = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int MacFontFamily::getGlyphWidth(uint style, uint c) {
|
||||
for (uint i = 0; i < _ffStyleWidths.size(); i++) {
|
||||
if (_ffKernEntries[i]._style == style) {
|
||||
if (c < _ffFirstChar || c > _ffLastChar)
|
||||
return -1;
|
||||
return _ffStyleWidths[i]._widths[c - _ffFirstChar];
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int MacFontFamily::getKerningOffset(uint style, int32 left, uint32 right) const {
|
||||
uint16 idx = ((left & 0xff) << 8) | (right & 0xff);
|
||||
|
||||
for (uint i = 0; i < _ffKernEntries.size(); i++) {
|
||||
if (_ffKernEntries[i]._style == style)
|
||||
if (_ffKernEntries[i]._kernTable.contains(idx))
|
||||
return _ffKernEntries[i]._kernTable[idx];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
MacFONTFont::MacFONTFont() {
|
||||
_data._fontType = 0;
|
||||
_data._firstChar = 0;
|
||||
_data._lastChar = 0;
|
||||
_data._maxWidth = 0;
|
||||
_data._kernMax = 0;
|
||||
_data._nDescent = 0;
|
||||
_data._fRectWidth = 0;
|
||||
_data._fRectHeight = 0;
|
||||
_data._owTLoc = 0;
|
||||
_data._ascent = 0;
|
||||
_data._descent = 0;
|
||||
_data._leading = 0;
|
||||
_data._rowWords = 0;
|
||||
_data._bitImage = nullptr;
|
||||
_data._surfHeight = 0;
|
||||
|
||||
_data._family = nullptr;
|
||||
_data._size = 12;
|
||||
_data._style = 0;
|
||||
}
|
||||
|
||||
MacFONTFont::MacFONTFont(const MacFONTdata &data) {
|
||||
_data = data;
|
||||
}
|
||||
|
||||
MacFONTFont::~MacFONTFont() {
|
||||
delete[] _data._bitImage;
|
||||
}
|
||||
|
||||
bool MacFONTFont::loadFont(Common::SeekableReadStream &stream, MacFontFamily *family, int size, int style) {
|
||||
_data._family = family;
|
||||
_data._size = size;
|
||||
_data._style = style;
|
||||
|
||||
_data._fontType = stream.readUint16BE(); // font type
|
||||
_data._firstChar = stream.readUint16BE(); // character code of first glyph
|
||||
_data._lastChar = stream.readUint16BE(); // character code of last glyph
|
||||
_data._maxWidth = stream.readUint16BE(); // maximum glyph width
|
||||
_data._kernMax = stream.readSint16BE(); // maximum glyph kern
|
||||
_data._nDescent = stream.readSint16BE(); // negative of descent
|
||||
_data._fRectWidth = stream.readUint16BE(); // width of font rectangle
|
||||
_data._fRectHeight = stream.readUint16BE(); // height of font rectangle
|
||||
_data._owTLoc = stream.readUint16BE(); // offset to width/offset table
|
||||
_data._ascent = stream.readUint16BE(); // maximum ascent measurement
|
||||
_data._descent = stream.readUint16BE(); // maximum descent measurement
|
||||
_data._leading = stream.readUint16BE(); // leading measurement
|
||||
_data._rowWords = stream.readUint16BE() * 2; // row width of bit image in 16-bit wds
|
||||
|
||||
_data._surfHeight = _data._fRectHeight;
|
||||
|
||||
// i use this as a flag to indicate whether the font is generated. see more detail on drawChar.
|
||||
_data._slant = 0; // only used in generated font
|
||||
|
||||
if (getDepth(_data._fontType) != 1) {
|
||||
warning("MacFONTFont: %dbpp fonts are not supported", getDepth(_data._fontType));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// If positive, _nDescent holds the high bits of the offset to the
|
||||
// width/offset table.
|
||||
// https://web.archive.org/web/20080724120946/developer.apple.com/documentation/mac/Text/Text-252.html
|
||||
if (_data._nDescent > 0)
|
||||
_data._owTLoc |= _data._nDescent << 16;
|
||||
|
||||
// Alignment is by word
|
||||
_data._owTLoc *= 2;
|
||||
_data._owTLoc += 16;
|
||||
|
||||
uint16 glyphCount = _data._lastChar - _data._firstChar + 1;
|
||||
_data._glyphs.resize(glyphCount);
|
||||
|
||||
// Bit image table
|
||||
uint bitImageSize = _data._rowWords * _data._surfHeight;
|
||||
_data._bitImage = new byte[bitImageSize];
|
||||
stream.read(_data._bitImage, bitImageSize);
|
||||
|
||||
// Bitmap location table
|
||||
// Last glyph is the pic for the missing glyph
|
||||
// One more word for determinig width
|
||||
uint16 *bitmapOffsets = (uint16 *)calloc(glyphCount + 2, sizeof(uint16));
|
||||
|
||||
for (uint16 i = 0; i < glyphCount + 2; i++)
|
||||
bitmapOffsets[i] = stream.readUint16BE();
|
||||
|
||||
for (uint16 i = 0; i < glyphCount + 1; i++) {
|
||||
MacGlyph *glyph = (i == glyphCount) ? &_data._defaultChar : &_data._glyphs[i];
|
||||
glyph->bitmapOffset = bitmapOffsets[i];
|
||||
glyph->bitmapWidth = bitmapOffsets[i + 1] - bitmapOffsets[i];
|
||||
}
|
||||
|
||||
// Width/offset table
|
||||
stream.seek(_data._owTLoc);
|
||||
|
||||
for (uint16 i = 0; i < glyphCount; i++) {
|
||||
byte kerningOffset = stream.readByte();
|
||||
byte width = stream.readByte();
|
||||
|
||||
// 0xFF designates missing glyph
|
||||
if (kerningOffset == 0xFF && width == 0xFF)
|
||||
continue;
|
||||
|
||||
_data._glyphs[i].kerningOffset = _data._kernMax + kerningOffset;
|
||||
_data._glyphs[i].width = width;
|
||||
}
|
||||
|
||||
_data._defaultChar.kerningOffset = _data._kernMax + stream.readByte();
|
||||
_data._defaultChar.width = _data._kernMax + stream.readByte();
|
||||
|
||||
if (_data._fontType & kFontTypeGlyphWidthTable) {
|
||||
warning("Skipping glyph-width table");
|
||||
|
||||
for (uint16 i = 0; i < glyphCount; i++)
|
||||
_data._glyphs[i].width1 = stream.readUint16BE();
|
||||
}
|
||||
|
||||
if (_data._fontType & kFontTypeImageHeightTable) {
|
||||
for (uint16 i = 0; i < glyphCount; i++)
|
||||
_data._glyphs[i].height = stream.readUint16BE();
|
||||
}
|
||||
|
||||
free(bitmapOffsets);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int MacFONTFont::getCharWidth(uint32 chr) const {
|
||||
const MacGlyph *glyph = findGlyph(chr);
|
||||
|
||||
if (!glyph)
|
||||
return _data._maxWidth;
|
||||
|
||||
// this part looks wrong
|
||||
// if (_data._fontType & kFontTypeGlyphWidthTable) {
|
||||
// return glyph->width1;
|
||||
// } else {
|
||||
// if (_data._family) {
|
||||
// int width = _data._family->getGlyphWidth(_data._style, chr);
|
||||
// if (width != -1)
|
||||
// return (width * 1000L + (1 << 11)) >> 12;
|
||||
// }
|
||||
// }
|
||||
return glyph->width;
|
||||
}
|
||||
|
||||
void MacFONTFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const {
|
||||
assert(dst != 0);
|
||||
assert(dst->format.bytesPerPixel == 1 || dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4);
|
||||
|
||||
if (x > dst->w || y > dst->h)
|
||||
return;
|
||||
|
||||
const MacGlyph *glyph = findGlyph(chr);
|
||||
if (!glyph || glyph->width == 0)
|
||||
return;
|
||||
|
||||
if (x + glyph->bitmapWidth < 0 || y + _data._fRectHeight < 0)
|
||||
return;
|
||||
|
||||
// Make sure we do not draw outside the surface
|
||||
uint16 yStart = (y < 0) ? -y : 0;
|
||||
uint16 yStop = _data._fRectHeight;
|
||||
uint16 xStart = (x < 0) ? -x : 0;
|
||||
uint16 xStop = glyph->bitmapWidth;
|
||||
|
||||
// due to the way we are handling the generated fonts. we only add the kerning offset for the original font
|
||||
if (!_data._slant)
|
||||
x += glyph->kerningOffset;
|
||||
|
||||
if (x >= dst->w)
|
||||
return;
|
||||
|
||||
if (y + _data._fRectHeight >= dst->h)
|
||||
yStop = dst->h - y;
|
||||
if (x + glyph->bitmapWidth >= dst->w)
|
||||
xStop = dst->w - x;
|
||||
|
||||
// for the underLine font, we need to draw the line at the whole area, which includes the kerning space.
|
||||
if ((_data._slant & kMacFontUnderline) && glyph->kerningOffset) {
|
||||
int underlineY = y + _data._ascent + 2;
|
||||
|
||||
if (underlineY >= 0 && underlineY < dst->h) {
|
||||
int underlineXStart = x - glyph->kerningOffset;
|
||||
int underlineXEnd = x - 1;
|
||||
|
||||
if (underlineXStart < 0)
|
||||
underlineXStart = 0;
|
||||
if (underlineXEnd >= dst->w)
|
||||
underlineXEnd = dst->w - 1;
|
||||
|
||||
for (int ulx = underlineXStart; ulx <= underlineXEnd; ulx++) {
|
||||
if (dst->format.bytesPerPixel == 1)
|
||||
*((byte *)dst->getBasePtr(ulx, underlineY)) = color;
|
||||
else if (dst->format.bytesPerPixel == 2)
|
||||
*((uint16 *)dst->getBasePtr(ulx, underlineY)) = color;
|
||||
else if (dst->format.bytesPerPixel == 4)
|
||||
*((uint32 *)dst->getBasePtr(ulx, underlineY)) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint16 i = yStart; i < yStop; i++) {
|
||||
byte *srcRow = _data._bitImage + i * _data._rowWords;
|
||||
|
||||
for (uint16 j = xStart; j < xStop; j++) {
|
||||
uint16 bitmapOffset = glyph->bitmapOffset + j;
|
||||
|
||||
if (srcRow[bitmapOffset / 8] & (1 << (7 - (bitmapOffset % 8)))) {
|
||||
if (dst->format.bytesPerPixel == 1)
|
||||
*((byte *)dst->getBasePtr(x + j, y + i)) = color;
|
||||
else if (dst->format.bytesPerPixel == 2)
|
||||
*((uint16 *)dst->getBasePtr(x + j, y + i)) = color;
|
||||
else if (dst->format.bytesPerPixel == 4)
|
||||
*((uint32 *)dst->getBasePtr(x + j, y + i)) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const MacGlyph *MacFONTFont::findGlyph(uint32 c) const {
|
||||
if (_data._glyphs.empty())
|
||||
return 0;
|
||||
|
||||
if (c < _data._firstChar || c > _data._lastChar)
|
||||
return &_data._defaultChar;
|
||||
|
||||
return &_data._glyphs[c - _data._firstChar];
|
||||
}
|
||||
|
||||
int MacFONTFont::getKerningOffset(uint32 left, uint32 right) const {
|
||||
if (_data._family) {
|
||||
int kerning = _data._family->getKerningOffset(_data._style, left, right);
|
||||
kerning *= _data._size;
|
||||
|
||||
return (int)(kerning / (double)(1 << 12));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void makeBold(Surface *src, int *dstGray, MacGlyph *glyph, int height);
|
||||
static void makeOutline(Surface *src, Surface *dst, MacGlyph *glyph, int height);
|
||||
static void makeItalic(Surface *src, Surface *dst, MacGlyph *glyph, int height);
|
||||
static void makeUnderLine(Surface *src, MacGlyph *glyph, int ascent);
|
||||
static void makeShadow(Surface *src, Surface *dst, MacGlyph *glyph, int height);
|
||||
|
||||
MacFONTFont *MacFONTFont::scaleFont(const MacFONTFont *src, int newSize, int slant) {
|
||||
if (!src) {
|
||||
warning("Empty font reference in scale font");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (src->getFontSize() == 0) {
|
||||
warning("Requested to scale 0 size font");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Graphics::Surface srcSurf, tmpSurf;
|
||||
srcSurf.create(MAX(src->getFontSize() * 2, newSize * 2), MAX(src->getFontSize() * 2, newSize * 2),
|
||||
PixelFormat::createFormatCLUT8());
|
||||
int dstGraySize = newSize * 20 * newSize;
|
||||
int *dstGray = (int *)malloc(dstGraySize * sizeof(int));
|
||||
|
||||
tmpSurf.create(MAX(src->getFontSize() * 2, newSize * 2), MAX(src->getFontSize() * 2 + 2, newSize * 2 + 2),
|
||||
PixelFormat::createFormatCLUT8());
|
||||
|
||||
float scale = (float)newSize / (float)src->getFontSize();
|
||||
|
||||
MacFONTdata data;
|
||||
|
||||
data._fontType = src->_data._fontType;
|
||||
data._firstChar = src->_data._firstChar;
|
||||
data._lastChar = src->_data._lastChar;
|
||||
data._maxWidth = (int)((float)src->_data._maxWidth * scale);
|
||||
data._kernMax = (int)((float)src->_data._kernMax * scale);
|
||||
data._nDescent = (int)((float)src->_data._nDescent * scale);
|
||||
data._fRectWidth = (int)((float)src->_data._fRectWidth * scale + data._lastChar * 2);
|
||||
data._fRectHeight = (int)((float)src->_data._fRectHeight * scale);
|
||||
data._owTLoc = src->_data._owTLoc;
|
||||
data._ascent = (int)((float)src->_data._ascent * scale);
|
||||
data._descent = (int)((float)src->_data._descent * scale);
|
||||
data._leading = (int)((float)src->_data._leading * scale);
|
||||
|
||||
data._family = src->_data._family;
|
||||
data._size = src->_data._size;
|
||||
data._style = src->_data._style;
|
||||
|
||||
data._glyphs.resize(src->_data._glyphs.size());
|
||||
|
||||
// when we are generating the slant fonts. e.g. italic font, underLine font. we set this. more detail is in drawChar
|
||||
data._slant = slant;
|
||||
|
||||
// update the height, for shadow and outline font, we are drawing the outline, thus we may have 2 more pixel height
|
||||
// for the underLine, we are drawing the line at ascent + 2, so we shall extend the height when we need.
|
||||
if ((slant & kMacFontShadow) || (slant & kMacFontOutline))
|
||||
data._fRectHeight += 2;
|
||||
else if (slant & kMacFontUnderline) {
|
||||
data._fRectHeight = MAX((int)data._fRectHeight, data._ascent + 2);
|
||||
}
|
||||
|
||||
data._surfHeight = data._fRectHeight;
|
||||
|
||||
// Determine width of the bit image table
|
||||
int newBitmapWidth = 0;
|
||||
|
||||
// add the offset which we may use when we are making fonts
|
||||
int bitmapOffset = 0;
|
||||
|
||||
if (slant & kMacFontBold)
|
||||
bitmapOffset++;
|
||||
if (slant & kMacFontOutline)
|
||||
bitmapOffset += 2;
|
||||
if (slant & kMacFontItalic)
|
||||
bitmapOffset += (data._fRectHeight - 1) / SLANTDEEP;
|
||||
if (slant & kMacFontShadow)
|
||||
bitmapOffset++;
|
||||
|
||||
for (uint i = 0; i < src->_data._glyphs.size() + 1; i++) {
|
||||
MacGlyph *glyph = (i == src->_data._glyphs.size()) ? &data._defaultChar : &data._glyphs[i];
|
||||
const MacGlyph *srcglyph = (i == src->_data._glyphs.size()) ? &src->_data._defaultChar : &src->_data._glyphs[i];
|
||||
|
||||
glyph->width = (int)((float)srcglyph->width * scale);
|
||||
glyph->kerningOffset = (int)((float)srcglyph->kerningOffset * scale);
|
||||
glyph->bitmapWidth = glyph->width; //(int)((float)srcglyph->bitmapWidth * scale);
|
||||
glyph->bitmapOffset = newBitmapWidth;
|
||||
|
||||
// Align width to a byte
|
||||
newBitmapWidth += (glyph->bitmapWidth + 7 + bitmapOffset) & ~0x7;
|
||||
}
|
||||
|
||||
data._rowWords = newBitmapWidth;
|
||||
|
||||
uint bitImageSize = data._rowWords * data._fRectHeight;
|
||||
data._bitImage = new byte[bitImageSize]();
|
||||
|
||||
int dstPitch = data._rowWords;
|
||||
|
||||
for (uint i = 0; i < src->_data._glyphs.size() + 1; i++) {
|
||||
const MacGlyph *srcglyph = (i == src->_data._glyphs.size()) ? &src->_data._defaultChar : &src->_data._glyphs[i];
|
||||
|
||||
int grayLevel = src->_data._fRectHeight * srcglyph->width / 4;
|
||||
|
||||
#if DEBUGSCALING
|
||||
uint ccc = 'c';
|
||||
#endif
|
||||
|
||||
MacGlyph *glyph = (i == src->_data._glyphs.size()) ? &data._defaultChar : &data._glyphs[i];
|
||||
src->scaleSingleGlyph(&srcSurf, dstGray, dstGraySize, glyph->bitmapWidth, data._fRectHeight, 0, 0, grayLevel, i + src->_data._firstChar,
|
||||
src->_data._fRectHeight, srcglyph->width, scale);
|
||||
|
||||
if (slant & kMacFontBold) {
|
||||
memset(dstGray, 0, dstGraySize * sizeof(int));
|
||||
makeBold(&srcSurf, dstGray, glyph, data._fRectHeight);
|
||||
|
||||
for (uint16 y = 0; y < data._fRectHeight; y++) {
|
||||
int *srcPtr = &dstGray[y * glyph->bitmapWidth];
|
||||
byte *dstPtr = (byte *)srcSurf.getBasePtr(0, y);
|
||||
|
||||
for (uint16 x = 0; x < glyph->bitmapWidth; x++, srcPtr++, dstPtr++) {
|
||||
if (*srcPtr)
|
||||
*dstPtr = 1;
|
||||
|
||||
#if DEBUGSCALING
|
||||
if (i == ccc)
|
||||
debugN("%c", *srcPtr ? '@' : '.');
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DEBUGSCALING
|
||||
if (i == ccc)
|
||||
debugN("\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (slant & kMacFontItalic) {
|
||||
tmpSurf.fillRect(Common::Rect(tmpSurf.w, tmpSurf.h), 0);
|
||||
makeItalic(&srcSurf, &tmpSurf, glyph, data._fRectHeight);
|
||||
srcSurf.copyFrom(tmpSurf);
|
||||
}
|
||||
|
||||
if (slant & kMacFontUnderline)
|
||||
makeUnderLine(&srcSurf, glyph, data._ascent);
|
||||
|
||||
if (slant & kMacFontOutline) {
|
||||
tmpSurf.fillRect(Common::Rect(tmpSurf.w, tmpSurf.h), 0);
|
||||
makeOutline(&srcSurf, &tmpSurf, glyph, data._fRectHeight);
|
||||
srcSurf.copyFrom(tmpSurf);
|
||||
}
|
||||
|
||||
if (slant & kMacFontShadow) {
|
||||
tmpSurf.fillRect(Common::Rect(tmpSurf.w, tmpSurf.h), 0);
|
||||
makeShadow(&srcSurf, &tmpSurf, glyph, data._fRectHeight);
|
||||
srcSurf.copyFrom(tmpSurf);
|
||||
}
|
||||
|
||||
if (slant & kMacFontCondense)
|
||||
glyph->width--;
|
||||
|
||||
if (slant & kMacFontExtend)
|
||||
glyph->width++;
|
||||
|
||||
byte *ptr = &data._bitImage[glyph->bitmapOffset / 8];
|
||||
|
||||
for (int y = 0; y < data._fRectHeight; y++) {
|
||||
byte *dst = ptr;
|
||||
byte *srcPtr = (byte *)srcSurf.getBasePtr(0, y);
|
||||
byte b = 0;
|
||||
|
||||
for (int x = 0; x < glyph->bitmapWidth; x++, srcPtr++) {
|
||||
b <<= 1;
|
||||
|
||||
if (*srcPtr == 1)
|
||||
b |= 1;
|
||||
|
||||
if (x % 8 == 7) {
|
||||
*dst++ = b;
|
||||
b = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUGSCALING
|
||||
if (i == ccc) {
|
||||
debugN(1, "--> %d ", grayLevel);
|
||||
|
||||
int *grayPtr = &dstGray[y * glyph->width];
|
||||
for (int x = 0; x < glyph->width; x++, grayPtr++)
|
||||
debugN("%c", *grayPtr > grayLevel ? '#' : '.');
|
||||
}
|
||||
#endif
|
||||
|
||||
if (((glyph->bitmapWidth - 1) % 8)) {
|
||||
#if DEBUGSCALING
|
||||
if (i == ccc)
|
||||
debugN(" --- %02x (w: %d bw: %d << %d)", b, glyph->width, glyph->bitmapWidth, 7 - ((glyph->width - 1) % 8));
|
||||
#endif
|
||||
|
||||
b <<= 7 - ((glyph->bitmapWidth - 1) % 8);
|
||||
*dst = b;
|
||||
|
||||
#if DEBUGSCALING
|
||||
if (i == ccc)
|
||||
debugN(" --- %02x ", b);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DEBUGSCALING
|
||||
if (i == ccc) {
|
||||
byte *srcRow = data._bitImage + y * data._rowWords;
|
||||
|
||||
for (uint16 x = 0; x < glyph->bitmapWidth; x++) {
|
||||
uint16 bitmapOffset = glyph->bitmapOffset + x;
|
||||
|
||||
debugN("%c", srcRow[bitmapOffset / 8] & (1 << (7 - (bitmapOffset % 8))) ? '*' : '.');
|
||||
}
|
||||
|
||||
debugN("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
ptr += dstPitch;
|
||||
}
|
||||
}
|
||||
|
||||
srcSurf.free();
|
||||
tmpSurf.free();
|
||||
free(dstGray);
|
||||
|
||||
return new MacFONTFont(data);
|
||||
}
|
||||
|
||||
static void makeBold(Surface *src, int *dstGray, MacGlyph *glyph, int height) {
|
||||
glyph->width++;
|
||||
glyph->bitmapWidth++;
|
||||
|
||||
for (uint16 y = 0; y < height; y++) {
|
||||
byte *srcPtr = (byte *)src->getBasePtr(0, y);
|
||||
int *dst = &dstGray[y * glyph->bitmapWidth];
|
||||
|
||||
for (uint16 x = 0; x < glyph->bitmapWidth; x++, srcPtr++, dst++) {
|
||||
*dst |= *srcPtr;
|
||||
*(dst + 1) |= *srcPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void makeOutline(Surface *src, Surface *dst, MacGlyph *glyph, int height) {
|
||||
glyph->bitmapWidth += 2;
|
||||
glyph->width++;
|
||||
|
||||
int dx[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
|
||||
int dy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
|
||||
|
||||
for (uint16 y = 0; y < height + 2; y++) {
|
||||
byte *srcPtr = (byte *)src->getBasePtr(0, y);
|
||||
byte *dstPtr = (byte *)dst->getBasePtr(0, y);
|
||||
|
||||
for (uint16 x = 0; x < glyph->bitmapWidth; x++, dstPtr++, srcPtr++) {
|
||||
if (x && *(srcPtr - 1))
|
||||
continue;
|
||||
// for every white pixel, if there is black pixel around it. It means that the white pixel is boundary, then we draw it as black pixel.
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int nx = x + dx[i] - 1;
|
||||
int ny = y + dy[i];
|
||||
if (nx >= src->w || nx < 0 || ny >= src->h || ny < 0)
|
||||
continue;
|
||||
|
||||
if (*((byte *)src->getBasePtr(nx, ny))) {
|
||||
*dstPtr = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void makeItalic(Surface *src, Surface *dst, MacGlyph *glyph, int height) {
|
||||
int dw = (height - 1) / SLANTDEEP;
|
||||
|
||||
for (int16 y = height - 1; y >= 0; y--) {
|
||||
int dx = (height - 1 - y) / SLANTDEEP;
|
||||
byte *srcPtr = (byte *)src->getBasePtr(0, y);
|
||||
byte *dstPtr = (byte *)dst->getBasePtr(dx, y);
|
||||
|
||||
for (uint16 x = 0; x < glyph->width; x++, srcPtr++, dstPtr++) {
|
||||
*dstPtr = *srcPtr;
|
||||
}
|
||||
}
|
||||
glyph->bitmapWidth += dw;
|
||||
glyph->kerningOffset -= dw / 2;
|
||||
}
|
||||
|
||||
static void makeUnderLine(Surface *src, MacGlyph *glyph, int ascent) {
|
||||
// this case is for space, which has the same number of kerning offset and width.
|
||||
// inorder to draw the underLine for space, we need to disable the kerning offset of it.
|
||||
if (glyph->width == glyph->kerningOffset)
|
||||
glyph->kerningOffset = 0;
|
||||
|
||||
for (int x = 0; x < glyph->width; x++)
|
||||
*((byte *) src->getBasePtr(x, ascent + 2)) = 1;
|
||||
}
|
||||
|
||||
static void makeShadow(Surface *src, Surface *dst, MacGlyph *glyph, int height) {
|
||||
// makeShadow looks like just the outLine font with one more shadow at right-most edge and lowest edge
|
||||
makeOutline(src, dst, glyph, height);
|
||||
glyph->bitmapWidth++;
|
||||
glyph->width++;
|
||||
|
||||
// right to left
|
||||
for (uint16 y = 0; y < height + 2; y++) {
|
||||
for (int x = dst->w - 1; x >= 0; x--) {
|
||||
byte *dstPtr = (byte *)dst->getBasePtr(x, y);
|
||||
if (*dstPtr)
|
||||
continue;
|
||||
|
||||
// check the left pixel. if it's black, then we black the current one and break.
|
||||
byte *left = (byte *)dst->getBasePtr(MAX(x - 1, 0), y);
|
||||
if (*left) {
|
||||
*dstPtr = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// down to up
|
||||
for (uint16 x = 0; x < glyph->bitmapWidth; x++) {
|
||||
for (int y = dst->h - 1; y >= 0; y--) {
|
||||
byte *dstPtr = (byte *) dst->getBasePtr(x, y);
|
||||
|
||||
if (*dstPtr)
|
||||
continue;
|
||||
|
||||
byte *up = (byte *)dst->getBasePtr(x, MAX(y - 1, 0));
|
||||
if (*up) {
|
||||
*dstPtr = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MacFONTFont::testBlit(const MacFONTFont *src, ManagedSurface *dst, int color, int x0, int y0, int width) {
|
||||
for (int y = 0; y < src->_data._fRectHeight; y++) {
|
||||
byte *srcRow = src->_data._bitImage + y * src->_data._rowWords;
|
||||
|
||||
for (int x = 0; x < width; x++) {
|
||||
uint16 bitmapOffset = x + 64;
|
||||
|
||||
if (srcRow[bitmapOffset / 8] & (1 << (7 - (bitmapOffset % 8)))) {
|
||||
if (dst->format.bytesPerPixel == 1)
|
||||
*((byte *)dst->getBasePtr(x0 + x, y0 + y)) = color;
|
||||
else if (dst->format.bytesPerPixel == 2)
|
||||
*((uint16 *)dst->getBasePtr(x0 + x, y0 + y)) = color;
|
||||
else if (dst->format.bytesPerPixel == 4)
|
||||
*((uint32 *)dst->getBasePtr(x0 + x, y0 + y)) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Graphics
|
||||
196
graphics/fonts/macfont.h
Normal file
196
graphics/fonts/macfont.h
Normal file
@@ -0,0 +1,196 @@
|
||||
/* 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 GRAPHICS_FONTS_MACFONT_H
|
||||
#define GRAPHICS_FONTS_MACFONT_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/hashmap.h"
|
||||
#include "common/stream.h"
|
||||
#include "graphics/font.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
#define SLANTDEEP 2
|
||||
|
||||
class MacFontFamily {
|
||||
public:
|
||||
MacFontFamily(const Common::String &name);
|
||||
~MacFontFamily();
|
||||
|
||||
bool load(Common::SeekableReadStream &stream);
|
||||
int getKerningOffset(uint style, int32 left, uint32 right) const;
|
||||
int getGlyphWidth(uint style, uint c);
|
||||
|
||||
struct AsscEntry {
|
||||
uint16 _fontSize;
|
||||
uint16 _fontStyle;
|
||||
uint16 _fontID;
|
||||
};
|
||||
|
||||
const Common::String &getName() { return _name; }
|
||||
uint16 getFontFamilyId() { return _ffFamID; }
|
||||
Common::Array<AsscEntry> *getAssocTable() { return &_ffAssocEntries; }
|
||||
|
||||
private:
|
||||
Common::String _name;
|
||||
|
||||
// FOND
|
||||
uint16 _ffFlags;
|
||||
uint16 _ffFamID;
|
||||
uint16 _ffFirstChar;
|
||||
uint16 _ffLastChar;
|
||||
int16 _ffAscent;
|
||||
int16 _ffDescent;
|
||||
int16 _ffLeading;
|
||||
int16 _ffWidMax;
|
||||
uint32 _ffWTabOff;
|
||||
uint32 _ffKernOff;
|
||||
uint32 _ffStylOff;
|
||||
uint16 _ffProperty[9];
|
||||
uint16 _ffIntl[2];
|
||||
uint16 _ffVersion;
|
||||
|
||||
uint16 _ffNumAssoc;
|
||||
Common::Array<AsscEntry> _ffAssocEntries;
|
||||
|
||||
uint16 _ffNumOffsets;
|
||||
uint32 *_ffOffsets;
|
||||
|
||||
struct BBoxEntry {
|
||||
uint16 _style;
|
||||
int16 _left;
|
||||
int16 _bottom;
|
||||
int16 _right;
|
||||
int16 _top;
|
||||
};
|
||||
|
||||
uint16 _ffNumBBoxes;
|
||||
Common::Array<BBoxEntry> _ffBBoxes;
|
||||
|
||||
struct KernPair {
|
||||
byte _firstChar;
|
||||
byte _secondChar;
|
||||
uint16 _distance;
|
||||
};
|
||||
|
||||
struct KernEntry {
|
||||
uint16 _style;
|
||||
uint16 _entryLength;
|
||||
Common::Array<KernPair> _kernPairs;
|
||||
|
||||
Common::HashMap<uint16, int16> _kernTable;
|
||||
};
|
||||
|
||||
uint16 _ffNumKerns;
|
||||
Common::Array<KernEntry> _ffKernEntries;
|
||||
|
||||
struct StyleWidthEntry {
|
||||
uint16 _style;
|
||||
Common::Array<uint16> _widths;
|
||||
};
|
||||
|
||||
uint16 _ffNumStyleWidths;
|
||||
Common::Array<StyleWidthEntry> _ffStyleWidths;
|
||||
};
|
||||
|
||||
struct MacGlyph {
|
||||
void clear() {
|
||||
bitmapOffset = 0;
|
||||
width1 = 0;
|
||||
height = 0;
|
||||
bitmapWidth = 0;
|
||||
kerningOffset = 0;
|
||||
width = 0;
|
||||
}
|
||||
|
||||
uint16 bitmapOffset;
|
||||
uint16 height;
|
||||
uint16 bitmapWidth;
|
||||
uint16 width1; // this width is from glyph-table, which has the higher priority
|
||||
byte width; // this width is from width/offset table
|
||||
int kerningOffset;
|
||||
};
|
||||
|
||||
struct MacFONTdata {
|
||||
uint16 _fontType;
|
||||
uint16 _firstChar;
|
||||
uint16 _lastChar;
|
||||
uint16 _maxWidth;
|
||||
int16 _kernMax;
|
||||
int16 _nDescent;
|
||||
uint16 _fRectWidth;
|
||||
uint16 _fRectHeight;
|
||||
uint32 _owTLoc;
|
||||
uint16 _ascent;
|
||||
uint16 _descent;
|
||||
uint16 _leading;
|
||||
uint16 _rowWords;
|
||||
uint16 _surfHeight;
|
||||
|
||||
byte *_bitImage;
|
||||
|
||||
Common::Array<MacGlyph> _glyphs;
|
||||
MacGlyph _defaultChar;
|
||||
|
||||
MacFontFamily *_family;
|
||||
int _size;
|
||||
int _style;
|
||||
|
||||
// currently only available in generated fonts
|
||||
int _slant;
|
||||
};
|
||||
|
||||
/**
|
||||
* Processing of Mac FONT/NFNT rResources
|
||||
*/
|
||||
class MacFONTFont : public Font {
|
||||
public:
|
||||
MacFONTFont();
|
||||
MacFONTFont(const MacFONTdata &data);
|
||||
virtual ~MacFONTFont();
|
||||
|
||||
virtual int getFontHeight() const { return _data._fRectHeight + getFontLeading(); }
|
||||
virtual int getFontAscent() const { return _data._ascent; }
|
||||
virtual int getFontDescent() const { return _data._descent; }
|
||||
virtual int getFontLeading() const { return _data._leading; }
|
||||
virtual int getMaxCharWidth() const { return _data._maxWidth; }
|
||||
virtual int getCharWidth(uint32 chr) const;
|
||||
virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const;
|
||||
|
||||
bool loadFont(Common::SeekableReadStream &stream, MacFontFamily *family = nullptr, int size = 12, int style = 0);
|
||||
|
||||
virtual int getKerningOffset(uint32 left, uint32 right) const;
|
||||
|
||||
int getFontSize() const { return _data._size; }
|
||||
|
||||
static MacFONTFont *scaleFont(const MacFONTFont *src, int newSize, int slant);
|
||||
static void testBlit(const MacFONTFont *src, ManagedSurface *dst, int color, int x0, int y0, int width);
|
||||
|
||||
private:
|
||||
MacFONTdata _data;
|
||||
|
||||
const MacGlyph *findGlyph(uint32 c) const;
|
||||
};
|
||||
|
||||
} // End of namespace Graphics
|
||||
|
||||
#endif
|
||||
10985
graphics/fonts/newfont.cpp
Normal file
10985
graphics/fonts/newfont.cpp
Normal file
File diff suppressed because it is too large
Load Diff
10137
graphics/fonts/newfont_big.cpp
Normal file
10137
graphics/fonts/newfont_big.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1156
graphics/fonts/ttf.cpp
Normal file
1156
graphics/fonts/ttf.cpp
Normal file
File diff suppressed because it is too large
Load Diff
152
graphics/fonts/ttf.h
Normal file
152
graphics/fonts/ttf.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/* 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 GRAPHICS_FONTS_TTF_H
|
||||
#define GRAPHICS_FONTS_TTF_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
#ifdef USE_FREETYPE2
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/ustr.h"
|
||||
|
||||
namespace Common {
|
||||
class Path;
|
||||
}
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
class Font;
|
||||
|
||||
/**
|
||||
* This specifies the mode in which TTF glyphs are rendered. This, for example,
|
||||
* allows to render glyphs fully monochrome, i.e. without any anti-aliasing.
|
||||
*/
|
||||
enum TTFRenderMode {
|
||||
/**
|
||||
* Standard render mode. Equivalent of FreeType2's FT_RENDER_MODE_NORMAL.
|
||||
*/
|
||||
kTTFRenderModeNormal,
|
||||
|
||||
/**
|
||||
* Use lighter hinting. Equivalent of FreeType2's FT_RENDER_MODE_LIGHT.
|
||||
*/
|
||||
kTTFRenderModeLight,
|
||||
|
||||
/**
|
||||
* Render fully monochrome. This makes glyph pixels either be fully opaque
|
||||
* or fully transparent.
|
||||
*/
|
||||
kTTFRenderModeMonochrome
|
||||
};
|
||||
|
||||
/**
|
||||
* This specifies how the font size is defined.
|
||||
*/
|
||||
enum TTFSizeMode {
|
||||
/**
|
||||
* Character height only.
|
||||
*
|
||||
* This matches rendering obtained when calling
|
||||
* CreateFont in Windows with negative height values.
|
||||
*/
|
||||
kTTFSizeModeCharacter,
|
||||
|
||||
/**
|
||||
* Full cell height.
|
||||
*
|
||||
* This matches rendering obtained when calling
|
||||
* CreateFont in Windows with positive height values.
|
||||
*/
|
||||
kTTFSizeModeCell
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads a TTF font file from a given data stream object.
|
||||
*
|
||||
* @param stream Stream object to load font data from.
|
||||
* @param size The point size to load.
|
||||
* @param sizeMode The point size definition used for the size parameter.
|
||||
* @param dpi The dpi to use for size calculations, by default 72dpi
|
||||
* are used.
|
||||
* @param renderMode FreeType2 mode used to render glyphs. @see TTFRenderMode
|
||||
* @param mapping A mapping from code points 0-255 into UTF-32 code points.
|
||||
* This can be used to support various 8bit character sets.
|
||||
* In case the msb of the UTF-32 code point is set the font
|
||||
* loading fails in case no glyph for it is found. When this
|
||||
* is non-null only characters given in the mapping are
|
||||
* supported.
|
||||
* @return 0 in case loading fails, otherwise a pointer to the Font object.
|
||||
*/
|
||||
Font *loadTTFFont(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, int size, TTFSizeMode sizeMode = kTTFSizeModeCharacter, uint xdpi = 0, uint ydpi = 0, TTFRenderMode renderMode = kTTFRenderModeLight, const uint32 *mapping = 0, bool stemDarkening = false);
|
||||
|
||||
/**
|
||||
* Loads a TTF font file from the common fonts archive.
|
||||
*
|
||||
* @param filename The name of the font to load.
|
||||
* @param size The point size to load.
|
||||
* @param sizeMode The point size definition used for the size parameter.
|
||||
* @param dpi The dpi to use for size calculations, by default 72dpi
|
||||
* are used.
|
||||
* @param renderMode FreeType2 mode used to render glyphs. @see TTFRenderMode
|
||||
* @param mapping A mapping from code points 0-255 into UTF-32 code points.
|
||||
* This can be used to support various 8bit character sets.
|
||||
* In case the msb of the UTF-32 code point is set the font
|
||||
* loading fails in case no glyph for it is found. When this
|
||||
* is non-null only characters given in the mapping are
|
||||
* supported.
|
||||
* @return 0 in case loading fails, otherwise a pointer to the Font object.
|
||||
*/
|
||||
Font *loadTTFFontFromArchive(const Common::String &filename, int size, TTFSizeMode sizeMode = kTTFSizeModeCharacter, uint xdpi = 0, uint ydpi = 0, TTFRenderMode renderMode = kTTFRenderModeLight, const uint32 *mapping = 0);
|
||||
|
||||
/**
|
||||
* Finds the specified face in a collection of TTF/TTC font files.
|
||||
* This functions kinds of mimic CreateFont from Windows API.
|
||||
*
|
||||
* @param files List of files where to find specified face.
|
||||
* @param faceName The face name to search for.
|
||||
* @param bold The weight of the desired face.
|
||||
* @param italic The slant of the desired face.
|
||||
* @param size The point size to load.
|
||||
* @param sizeMode The point size definition used for the size parameter.
|
||||
* @param dpi The dpi to use for size calculations, by default 96dpi
|
||||
* are used. Like in Windows.
|
||||
* @param renderMode FreeType2 mode used to render glyphs. @see TTFRenderMode
|
||||
* @param mapping A mapping from code points 0-255 into UTF-32 code points.
|
||||
* This can be used to support various 8bit character sets.
|
||||
* In case the msb of the UTF-32 code point is set the font
|
||||
* loading fails in case no glyph for it is found. When this
|
||||
* is non-null only characters given in the mapping are
|
||||
* supported.
|
||||
* @return 0 in case loading fails, otherwise a pointer to the Font object.
|
||||
*/
|
||||
Font *findTTFace(const Common::Array<Common::Path> &files, const Common::U32String &faceName, bool bold, bool italic, int size, uint xdpi = 0, uint ydpi = 0,TTFRenderMode renderMode = kTTFRenderModeLight, const uint32 *mapping = 0);
|
||||
|
||||
void shutdownTTF();
|
||||
|
||||
} // End of namespace Graphics
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
438
graphics/fonts/winfont.cpp
Normal file
438
graphics/fonts/winfont.cpp
Normal file
@@ -0,0 +1,438 @@
|
||||
/* 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/file.h"
|
||||
#include "common/str.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "common/formats/winexe_ne.h"
|
||||
#include "common/formats/winexe_pe.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "graphics/fonts/winfont.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
WinFont::WinFont() {
|
||||
_glyphs = nullptr;
|
||||
close();
|
||||
}
|
||||
|
||||
WinFont::~WinFont() {
|
||||
close();
|
||||
}
|
||||
|
||||
void WinFont::close() {
|
||||
_pixHeight = 0;
|
||||
_sizeInPoints = 0;
|
||||
_dpi = 0;
|
||||
_maxWidth = 0;
|
||||
_firstChar = 0;
|
||||
_lastChar = 0;
|
||||
_defaultChar = 0;
|
||||
_glyphCount = 0;
|
||||
delete[] _glyphs;
|
||||
_glyphs = nullptr;
|
||||
}
|
||||
|
||||
// Reads a null-terminated string
|
||||
static Common::String readString(Common::SeekableReadStream &stream) {
|
||||
Common::String string;
|
||||
|
||||
char c = stream.readByte();
|
||||
while (c && stream.pos() < stream.size()) {
|
||||
string += c;
|
||||
c = stream.readByte();
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
static WinFontDirEntry readDirEntry(Common::SeekableReadStream &stream) {
|
||||
WinFontDirEntry entry;
|
||||
|
||||
stream.skip(68); // Useless
|
||||
entry.points = stream.readUint16LE();
|
||||
stream.skip(43); // Useless (for now, maybe not in the future)
|
||||
readString(stream); // Skip Device Name
|
||||
entry.faceName = readString(stream);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
bool WinFont::loadFromFON(const Common::Path &fileName, const WinFontDirEntry &dirEntry) {
|
||||
Common::WinResources *exe = Common::WinResources::createFromEXE(fileName);
|
||||
if (!exe)
|
||||
return false;
|
||||
|
||||
bool ok = loadFromEXE(exe, fileName, dirEntry);
|
||||
delete exe;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool WinFont::loadFromFON(Common::SeekableReadStream &stream, const WinFontDirEntry &dirEntry) {
|
||||
Common::WinResources *exe = Common::WinResources::createFromEXE(&stream);
|
||||
if (!exe)
|
||||
return false;
|
||||
|
||||
bool ok = loadFromEXE(exe, Common::Path("stream"), dirEntry);
|
||||
delete exe;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool WinFont::loadFromEXE(Common::WinResources *exe, const Common::Path &fileName, const WinFontDirEntry &dirEntry) {
|
||||
// Let's pull out the font directory
|
||||
Common::SeekableReadStream *fontDirectory = exe->getResource(Common::kWinFontDir, Common::String("FONTDIR"));
|
||||
if (!fontDirectory) {
|
||||
warning("No font directory in '%s'", fileName.toString(Common::Path::kNativeSeparator).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 fontId = getFontIndex(*fontDirectory, dirEntry);
|
||||
|
||||
delete fontDirectory;
|
||||
|
||||
// Couldn't match the face name
|
||||
if (fontId == 0xffffffff) {
|
||||
warning("Could not find face '%s' in '%s'", dirEntry.faceName.c_str(),
|
||||
fileName.toString(Common::Path::kNativeSeparator).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Actually go get our font now...
|
||||
Common::SeekableReadStream *fontStream = exe->getResource(Common::kWinFont, fontId);
|
||||
if (!fontStream) {
|
||||
warning("Could not find font %d in %s", fontId,
|
||||
fileName.toString(Common::Path::kNativeSeparator).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ok = loadFromFNT(*fontStream);
|
||||
delete fontStream;
|
||||
return ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Size in typographic "points"
|
||||
*
|
||||
* While early Macintosh mapped "points" and "pixels" very closely,
|
||||
* that was not the case on Windows.
|
||||
*
|
||||
* Windows used 96 dpi for font rendering so a 10 point font would
|
||||
*
|
||||
* Macintosh used 72 dpi for fonts while Windows used 96 dpi
|
||||
*/
|
||||
int WinFont::getFontSizeInPointsAtDPI(const int dpi) const {
|
||||
return _sizeInPoints * _dpi / dpi;
|
||||
}
|
||||
|
||||
uint32 WinFont::getFontIndex(Common::SeekableReadStream &stream, const WinFontDirEntry &dirEntry) {
|
||||
uint16 numFonts = stream.readUint16LE();
|
||||
|
||||
// Probably not possible, so this is really a sanity check
|
||||
if (numFonts == 0) {
|
||||
warning("No fonts in exe");
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
// Scour the directory for our matching name
|
||||
for (uint16 i = 0; i < numFonts; i++) {
|
||||
uint16 id = stream.readUint16LE();
|
||||
|
||||
// Use the first name when empty
|
||||
if (dirEntry.faceName.empty()) {
|
||||
_name = getFONFontName(stream);
|
||||
return id;
|
||||
}
|
||||
|
||||
WinFontDirEntry entry = readDirEntry(stream);
|
||||
|
||||
if (dirEntry.faceName.equalsIgnoreCase(entry.faceName) && dirEntry.points == entry.points) // Match!
|
||||
return id;
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
Common::String WinFont::getFONFontName(Common::SeekableReadStream& stream) {
|
||||
// Currently only works when dirEntry.faceName in getFontIndex is empty
|
||||
// But this can be used for each FONTDIR entry
|
||||
stream.seek(117);
|
||||
/* Device Name = */ stream.readString();
|
||||
Common::String fontName = stream.readString();
|
||||
return fontName;
|
||||
}
|
||||
|
||||
bool WinFont::loadFromFNT(const Common::Path &fileName) {
|
||||
Common::File file;
|
||||
|
||||
return file.open(fileName) && loadFromFNT(file);
|
||||
}
|
||||
|
||||
char WinFont::indexToCharacter(uint16 index) const {
|
||||
// Use a space for the sentinel value
|
||||
if (index == _glyphCount - 1)
|
||||
return ' ';
|
||||
|
||||
return index + _firstChar;
|
||||
}
|
||||
|
||||
uint16 WinFont::characterToIndex(uint32 character) const {
|
||||
// Go to the default character if we didn't find a mapping
|
||||
if (character < _firstChar || character > _lastChar)
|
||||
character = _defaultChar;
|
||||
|
||||
return character - _firstChar;
|
||||
}
|
||||
|
||||
int WinFont::getCharWidth(uint32 chr) const {
|
||||
return _glyphs[characterToIndex(chr)].charWidth;
|
||||
}
|
||||
|
||||
bool WinFont::loadFromFNT(Common::SeekableReadStream &stream) {
|
||||
uint16 version = stream.readUint16LE();
|
||||
|
||||
// We'll accept Win1, Win2, and Win3 fonts
|
||||
if (version != 0x100 && version != 0x200 && version != 0x300) {
|
||||
warning("Bad FNT version %04x", version);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* uint32 sizeOfGlyphTableInBytes = */ stream.readUint32LE();
|
||||
stream.skip(60); // Copyright info
|
||||
uint16 fontType = stream.readUint16LE();
|
||||
_sizeInPoints = stream.readUint16LE();
|
||||
uint16 vertRes = stream.readUint16LE(); // usually 96 as in 96dpi
|
||||
uint16 horizRes = stream.readUint16LE(); // usually 96 as in 96dpi
|
||||
|
||||
if (vertRes != horizRes)
|
||||
warning("WinFont::loadFromFNT(): FNT horizontal resolution and vertical resolution differ (%d vs %d)", horizRes, vertRes);
|
||||
|
||||
_dpi = vertRes;
|
||||
|
||||
_ascent = stream.readUint16LE();
|
||||
/* uint16 internalLeading = */ stream.readUint16LE();
|
||||
/* uint16 externalLeading = */ stream.readUint16LE();
|
||||
_italic = stream.readByte();
|
||||
_underline = stream.readByte();
|
||||
_strikethrough = stream.readByte();
|
||||
_weight = stream.readUint16LE();
|
||||
/* byte charSet = */ stream.readByte();
|
||||
uint16 pixWidth = stream.readUint16LE();
|
||||
_pixHeight = stream.readUint16LE();
|
||||
/* byte pitchAndFamily = */ stream.readByte();
|
||||
/* uint16 avgWidth = */ stream.readUint16LE();
|
||||
_maxWidth = stream.readUint16LE();
|
||||
_firstChar = stream.readByte();
|
||||
_lastChar = stream.readByte();
|
||||
_defaultChar = stream.readByte();
|
||||
/* byte breakChar = */ stream.readByte();
|
||||
/* uint16 widthBytes = */ stream.readUint16LE();
|
||||
/* uint32 device = */ stream.readUint32LE();
|
||||
/* uint32 face = */ stream.readUint32LE();
|
||||
/* uint32 bitsPointer = */ stream.readUint32LE();
|
||||
uint32 bitsOffset = stream.readUint32LE();
|
||||
/* byte reserved = */ stream.readByte();
|
||||
|
||||
if (version == 0x100) {
|
||||
// Seems Win1 has an extra byte?
|
||||
stream.readByte();
|
||||
} else if (version == 0x300) {
|
||||
// For Windows 3.0, Microsoft added 6 new fields. All of which are
|
||||
// guaranteed to be 0. Which leads to the question: Why add these at all?
|
||||
|
||||
/* uint32 flags = */ stream.readUint32LE();
|
||||
/* uint16 aSpace = */ stream.readUint16LE();
|
||||
/* uint16 bSpace = */ stream.readUint16LE();
|
||||
/* uint16 cSpace = */ stream.readUint16LE();
|
||||
/* uint32 colorPointer = */ stream.readUint32LE();
|
||||
stream.skip(16); // Reserved
|
||||
}
|
||||
|
||||
// Begin loading in the glyphs
|
||||
_glyphCount = (_lastChar - _firstChar) + 2;
|
||||
delete[] _glyphs;
|
||||
_glyphs = new GlyphEntry[_glyphCount];
|
||||
|
||||
for (uint16 i = 0; i < _glyphCount; i++) {
|
||||
_glyphs[i].charWidth = stream.readUint16LE();
|
||||
|
||||
// Use the default if present
|
||||
if (pixWidth)
|
||||
_glyphs[i].charWidth = pixWidth;
|
||||
|
||||
_glyphs[i].offset = (version == 0x300) ? stream.readUint32LE() : stream.readUint16LE();
|
||||
|
||||
// Seems the offsets in the Win1 font format are based on bitsOffset
|
||||
if (version == 0x100)
|
||||
_glyphs[i].offset += bitsOffset;
|
||||
}
|
||||
|
||||
// TODO: Currently only raster fonts are supported!
|
||||
if (fontType & 1) {
|
||||
warning("Vector FNT files not supported yet");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read in the bitmaps for the raster images
|
||||
for (uint16 i = 0; i < _glyphCount - 1; i++) {
|
||||
stream.seek(_glyphs[i].offset);
|
||||
|
||||
_glyphs[i].bitmap = new byte[_pixHeight * _glyphs[i].charWidth];
|
||||
|
||||
// Calculate the amount of columns
|
||||
byte colCount = (_glyphs[i].charWidth + 7) / 8;
|
||||
|
||||
for (uint16 j = 0; j < colCount; j++) {
|
||||
for (uint16 k = 0; k < _pixHeight; k++) {
|
||||
byte x = stream.readByte();
|
||||
uint offset = j * 8 + k * _glyphs[i].charWidth;
|
||||
|
||||
for (byte l = 0; l < 8 && j * 8 + l < _glyphs[i].charWidth; l++)
|
||||
_glyphs[i].bitmap[offset + l] = (x & (1 << (7 - l))) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Debug print
|
||||
debug("Character %02x '%c' at %08x", indexToCharacter(i), indexToCharacter(i), _glyphs[i].offset);
|
||||
for (uint16 j = 0; j < _pixHeight; j++) {
|
||||
for (uint16 k = 0; k < _glyphs[i].charWidth; k++)
|
||||
debugN("%c", _glyphs[i].bitmap[k + j * _glyphs[i].charWidth] ? 'X' : ' ');
|
||||
|
||||
debugN("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WinFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const {
|
||||
assert(dst);
|
||||
assert(dst->format.bytesPerPixel == 1 || dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4);
|
||||
assert(_glyphs);
|
||||
|
||||
GlyphEntry &glyph = _glyphs[characterToIndex(chr)];
|
||||
|
||||
for (uint16 i = 0; i < _pixHeight; i++) {
|
||||
for (uint16 j = 0; j < glyph.charWidth; j++) {
|
||||
if (glyph.bitmap[j + i * glyph.charWidth]) {
|
||||
if (dst->format.bytesPerPixel == 1)
|
||||
*((byte *)dst->getBasePtr(x + j, y + i)) = color;
|
||||
else if (dst->format.bytesPerPixel == 2)
|
||||
*((uint16 *)dst->getBasePtr(x + j, y + i)) = color;
|
||||
else if (dst->format.bytesPerPixel == 4)
|
||||
*((uint32 *)dst->getBasePtr(x + j, y + i)) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int WinFont::getStyle() const {
|
||||
int style = kFontStyleRegular;
|
||||
|
||||
// This has been taken from Wine Source
|
||||
// https://github.com/wine-mirror/wine/blob/b9a61cde89e5dc6264b4c152f4dc24ecf064f8f6/include/wingdi.h#L728
|
||||
|
||||
if (_weight >= 700)
|
||||
style |= kFontStyleBold;
|
||||
if (_italic)
|
||||
style |= kFontStyleItalic;
|
||||
if (_underline)
|
||||
style |= kFontStyleUnderline;
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
WinFont *WinFont::scaleFont(const WinFont *src, int newSize) {
|
||||
if (!src) {
|
||||
warning("WinFont::scaleFont(): Empty font reference in scale font");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (src->getFontHeight() == 0) {
|
||||
warning("WinFont::scaleFont(): Requested to scale 0 size font");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WinFont *scaledFont = new WinFont();
|
||||
|
||||
Graphics::Surface srcSurf;
|
||||
srcSurf.create(MAX(src->getFontHeight() * 2, newSize * 2), MAX(src->getFontHeight() * 2, newSize * 2), PixelFormat::createFormatCLUT8());
|
||||
int dstGraySize = newSize * 20 * newSize;
|
||||
int *dstGray = (int *)malloc(dstGraySize * sizeof(int));
|
||||
|
||||
float scale = (float)newSize / (float)src->getFontHeight();
|
||||
|
||||
scaledFont->_pixHeight = (int)(roundf((float)src->_pixHeight * scale));
|
||||
scaledFont->_maxWidth = (int)(roundf((float)src->_maxWidth * scale));
|
||||
scaledFont->_ascent = src->_ascent;
|
||||
scaledFont->_firstChar = src->_firstChar;
|
||||
scaledFont->_lastChar = src->_lastChar;
|
||||
scaledFont->_defaultChar = src->_defaultChar;
|
||||
scaledFont->_italic = src->_italic;
|
||||
scaledFont->_strikethrough = src->_strikethrough;
|
||||
scaledFont->_underline = src->_underline;
|
||||
scaledFont->_weight = src->_weight;
|
||||
scaledFont->_name = Common::String(src->_name);
|
||||
|
||||
scaledFont->_glyphCount = src->_glyphCount;
|
||||
|
||||
GlyphEntry *glyphs = new GlyphEntry[src->_glyphCount];
|
||||
for (int i = 0; i < src->_glyphCount; i++) {
|
||||
glyphs[i].charWidth = (int)(roundf((float)src->_glyphs[i].charWidth * scale));
|
||||
glyphs[i].offset = src->_glyphs[i].offset;
|
||||
|
||||
int boxWidth = glyphs[i].charWidth;
|
||||
int boxHeight = scaledFont->_pixHeight;
|
||||
int grayLevel = (boxWidth * boxHeight) / 3;
|
||||
|
||||
byte *bitmap = new byte[boxWidth * boxHeight];
|
||||
memset(bitmap, 0, boxWidth * boxHeight);
|
||||
|
||||
// Scale single character
|
||||
src->scaleSingleGlyph(&srcSurf, dstGray, dstGraySize, boxWidth, boxHeight, 0, 0, grayLevel, i + src->_firstChar,
|
||||
src->_pixHeight, src->_glyphs[i].charWidth, scale);
|
||||
|
||||
// Convert back to bytes representation
|
||||
byte *ptr = bitmap;
|
||||
for (int y = 0; y < boxHeight; y++) {
|
||||
byte *srcd = (byte *)srcSurf.getBasePtr(0, y);
|
||||
byte *dst = ptr;
|
||||
|
||||
for (int x = 0; x < boxWidth; x++, srcd++) {
|
||||
*dst++ = *srcd;
|
||||
}
|
||||
|
||||
ptr += boxWidth;
|
||||
}
|
||||
|
||||
glyphs[i].bitmap = bitmap;
|
||||
}
|
||||
scaledFont->_glyphs = glyphs;
|
||||
|
||||
free(dstGray);
|
||||
srcSurf.free();
|
||||
|
||||
return (WinFont *)scaledFont;
|
||||
}
|
||||
|
||||
} // End of namespace Graphics
|
||||
120
graphics/fonts/winfont.h
Normal file
120
graphics/fonts/winfont.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/* 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 GRAPHICS_WINFONT_H
|
||||
#define GRAPHICS_WINFONT_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "common/path.h"
|
||||
#include "graphics/font.h"
|
||||
|
||||
namespace Common {
|
||||
class SeekableReadStream;
|
||||
class WinResources;
|
||||
}
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
struct WinFontDirEntry {
|
||||
WinFontDirEntry() : points(0) {}
|
||||
WinFontDirEntry(const Common::String &name, uint16 p) : faceName(name), points(p) {}
|
||||
|
||||
// This is really just a simple identifier to match a directory entry with
|
||||
// If need-be, we can add other things to check such as italics and strikethrough, etc.
|
||||
Common::String faceName;
|
||||
uint16 points;
|
||||
};
|
||||
|
||||
class WinFont : public Font {
|
||||
public:
|
||||
WinFont();
|
||||
~WinFont();
|
||||
|
||||
/**
|
||||
* Open a font with a name in an FON file.
|
||||
*
|
||||
* If dirEntry is not given, the first font in the FONTDIR will be loaded
|
||||
*/
|
||||
bool loadFromFON(const Common::Path &fileName, const WinFontDirEntry &dirEntry = WinFontDirEntry());
|
||||
bool loadFromFON(Common::SeekableReadStream &stream, const WinFontDirEntry &dirEntry = WinFontDirEntry());
|
||||
|
||||
/** Open a font from an FNT file */
|
||||
bool loadFromFNT(const Common::Path &fileName);
|
||||
|
||||
/** Close this font */
|
||||
void close();
|
||||
|
||||
// Font API
|
||||
int getFontHeight() const { return _pixHeight; } //< pixels, not points - for points, see getFontSizeInPointsAtDPI()
|
||||
int getFontAscent() const { return _ascent; }
|
||||
int getMaxCharWidth() const { return _maxWidth; }
|
||||
Common::String getName() const { return _name; }
|
||||
int getCharWidth(uint32 chr) const;
|
||||
void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const;
|
||||
int getStyle() const;
|
||||
|
||||
int getFontSizeInPointsAtDPI(const int dpi) const;
|
||||
|
||||
static WinFont *scaleFont(const WinFont *src, int newSize);
|
||||
private:
|
||||
bool loadFromEXE(Common::WinResources *exe, const Common::Path &fileName, const WinFontDirEntry &dirEntry);
|
||||
|
||||
uint32 getFontIndex(Common::SeekableReadStream &stream, const WinFontDirEntry &dirEntry);
|
||||
Common::String getFONFontName(Common::SeekableReadStream &stream);
|
||||
bool loadFromFNT(Common::SeekableReadStream &stream);
|
||||
char indexToCharacter(uint16 index) const;
|
||||
uint16 characterToIndex(uint32 character) const;
|
||||
|
||||
uint16 _pixHeight;
|
||||
uint16 _maxWidth;
|
||||
uint16 _ascent;
|
||||
uint16 _sizeInPoints;
|
||||
uint16 _dpi;
|
||||
byte _firstChar;
|
||||
byte _lastChar;
|
||||
byte _defaultChar;
|
||||
bool _italic;
|
||||
bool _strikethrough;
|
||||
bool _underline;
|
||||
uint16 _weight;
|
||||
Common::String _name;
|
||||
|
||||
enum {
|
||||
kFontStyleRegular,
|
||||
kFontStyleBold = 1,
|
||||
kFontStyleItalic = 2,
|
||||
kFontStyleUnderline = 4,
|
||||
};
|
||||
|
||||
uint16 _glyphCount;
|
||||
struct GlyphEntry {
|
||||
GlyphEntry() { bitmap = 0; charWidth = 0; offset = 0; }
|
||||
~GlyphEntry() { delete[] bitmap; }
|
||||
|
||||
uint16 charWidth;
|
||||
uint32 offset;
|
||||
byte *bitmap;
|
||||
} *_glyphs;
|
||||
};
|
||||
|
||||
} // End of namespace Graphics
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user