Initial commit
This commit is contained in:
134
graphics/big5.cpp
Normal file
134
graphics/big5.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/* 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/big5.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
Big5Font::Big5Font() : _chineseTraditionalHeight(0) {
|
||||
}
|
||||
|
||||
Big5Font::~Big5Font() {
|
||||
_chineseTraditionalFont.clear();
|
||||
_chineseTraditionalIndex.clear();
|
||||
}
|
||||
|
||||
void Big5Font::ChineseTraditionalGlyph::makeOutline(int height) {
|
||||
outline[0][0] = 0;
|
||||
outline[0][1] = 0;
|
||||
// OR into outline the original bitmap moved by 1 pixel
|
||||
// 1 pixel down
|
||||
for (int y = 0; y < height - 1; y++) {
|
||||
outline[y+1][0] = bitmap[y][0];
|
||||
outline[y+1][1] = bitmap[y][1];
|
||||
}
|
||||
// 1 pixel up
|
||||
for (int y = 0; y < height - 1; y++) {
|
||||
outline[y][0] |= bitmap[y+1][0];
|
||||
outline[y][1] |= bitmap[y+1][1];
|
||||
}
|
||||
for (int y = 0; y < height; y++) {
|
||||
// 1 pixel right
|
||||
outline[y][0] |= bitmap[y][0] >> 1;
|
||||
outline[y][1] |= bitmap[y][0] << 7;
|
||||
outline[y][1] |= bitmap[y][1] >> 1;
|
||||
|
||||
// 1 pixel left
|
||||
outline[y][0] |= bitmap[y][0] << 1;
|
||||
outline[y][0] |= bitmap[y][1] >> 7;
|
||||
outline[y][1] |= bitmap[y][1] << 1;
|
||||
}
|
||||
|
||||
// Then AND-out the original bitmap
|
||||
for (int y = 0; y < height; y++) {
|
||||
outline[y][0] &= ~bitmap[y][0];
|
||||
outline[y][1] &= ~bitmap[y][1];
|
||||
}
|
||||
}
|
||||
|
||||
void Big5Font::loadPrefixedRaw(Common::ReadStream &input, int height) {
|
||||
_chineseTraditionalHeight = height;
|
||||
_chineseTraditionalFont.clear();
|
||||
|
||||
_chineseTraditionalIndex = Common::move(Common::Array<int>(0x8000, -1));
|
||||
// So far the smallest version had 1981 glyphs. Optimize a little bit for this number
|
||||
// but don't rely on it in any way
|
||||
_chineseTraditionalFont.reserve(1981);
|
||||
while(!input.eos()) {
|
||||
// Big-endian because it's not really a u16 but a big5 sequence.
|
||||
uint16 ch = input.readUint16BE();
|
||||
ChineseTraditionalGlyph glyph;
|
||||
if (input.eos())
|
||||
break;
|
||||
if (ch == 0xffff)
|
||||
break;
|
||||
if (!(ch & 0x8000))
|
||||
continue;
|
||||
memset(&glyph.bitmap, 0, sizeof(glyph.bitmap));
|
||||
memset(&glyph.outline, 0, sizeof(glyph.outline));
|
||||
input.read(&glyph.bitmap, (kChineseTraditionalWidth / 8) * _chineseTraditionalHeight);
|
||||
glyph.makeOutline(height);
|
||||
_chineseTraditionalIndex[ch & 0x7fff] = _chineseTraditionalFont.size();
|
||||
_chineseTraditionalFont.push_back(glyph);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T> bool Big5Font::drawReal(byte *dest, uint16 textChar, int maxX, int maxY, uint32 destPitch, byte color, byte outlineColor, bool outline) const {
|
||||
int glyphIdx = _chineseTraditionalIndex[textChar & 0x7fff];
|
||||
if (glyphIdx < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ChineseTraditionalGlyph& glyph = _chineseTraditionalFont[glyphIdx];
|
||||
|
||||
for (int y = 0; y < _chineseTraditionalHeight && y < maxY; y++) {
|
||||
T *cur = (T*) (dest + y * destPitch);
|
||||
T *curMax = cur + maxX;
|
||||
|
||||
for (int byte = 0; byte < 2; byte++)
|
||||
for (int bit = 0; bit < 8 && cur < curMax; bit++, cur++)
|
||||
if ((glyph.bitmap[y][byte] << bit) & 0x80)
|
||||
*cur = color;
|
||||
else if (outline && (((glyph.outline[y][byte] << bit) & 0x80)))
|
||||
*cur = outlineColor;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Big5Font::drawBig5Char(byte *dest, uint16 ch, int maxX, int maxY, uint32 destPitch, byte color, byte outlineColor, bool outline, int bpp) const {
|
||||
switch(bpp) {
|
||||
case 4:
|
||||
return drawReal<uint32>(dest, ch, maxX, maxY, destPitch, color, outlineColor, outline);
|
||||
case 2:
|
||||
return drawReal<uint16>(dest, ch, maxX, maxY, destPitch, color, outlineColor, outline);
|
||||
case 1:
|
||||
return drawReal<uint8>(dest, ch, maxX, maxY, destPitch, color, outlineColor, outline);
|
||||
default:
|
||||
error("Big5 font for bpp=%d is not supported", bpp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Big5Font::drawBig5Char(Graphics::Surface *surf, uint16 ch, const Common::Point &pt, uint32 color, byte outlineColor, bool outline) const {
|
||||
return drawBig5Char((byte*)surf->getBasePtr(pt.x, pt.y), ch, surf->w - pt.x, surf->h - pt.y, surf->pitch, color, outlineColor, outline, surf->format.bytesPerPixel);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user