ppsspp/Core/Font/PGF.h
2016-01-23 15:37:19 -08:00

310 lines
6.9 KiB
C++

// Copyright (c) 2012- PPSSPP Project.
// 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, version 2.0 or later versions.
// 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 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
// Thanks to the JPCSP project! This sceFont implementation is basically a C++ take on JPCSP's font code.
#pragma once
#include <string>
#include <vector>
#include "Common/Log.h"
#include "Common/CommonTypes.h"
class PointerWrap;
enum {
FONT_FILETYPE_PGF = 0x00,
FONT_FILETYPE_BWFON = 0x01,
};
enum {
FONT_PGF_BMP_H_ROWS = 0x01,
FONT_PGF_BMP_V_ROWS = 0x02,
FONT_PGF_BMP_OVERLAY = 0x03,
// Metric names according to JPCSP findings
FONT_PGF_METRIC_DIMENSION_INDEX = 0x04,
FONT_PGF_METRIC_BEARING_X_INDEX = 0x08,
FONT_PGF_METRIC_BEARING_Y_INDEX = 0x10,
FONT_PGF_METRIC_ADVANCE_INDEX = 0x20,
FONT_PGF_CHARGLYPH = 0x20,
FONT_PGF_SHADOWGLYPH = 0x40,
};
enum Family {
FONT_FAMILY_SANS_SERIF = 1,
FONT_FAMILY_SERIF = 2,
};
enum Style {
FONT_STYLE_REGULAR = 1,
FONT_STYLE_ITALIC = 2,
FONT_STYLE_BOLD = 5,
FONT_STYLE_BOLD_ITALIC = 6,
FONT_STYLE_DB = 103, // Demi-Bold / semi-bold
};
enum Language {
FONT_LANGUAGE_JAPANESE = 1,
FONT_LANGUAGE_LATIN = 2,
FONT_LANGUAGE_KOREAN = 3,
FONT_LANGUAGE_CHINESE = 4,
};
enum FontPixelFormat {
PSP_FONT_PIXELFORMAT_4 = 0, // 2 pixels packed in 1 byte (natural order)
PSP_FONT_PIXELFORMAT_4_REV = 1, // 2 pixels packed in 1 byte (reversed order)
PSP_FONT_PIXELFORMAT_8 = 2, // 1 pixel in 1 byte
PSP_FONT_PIXELFORMAT_24 = 3, // 1 pixel in 3 bytes (RGB)
PSP_FONT_PIXELFORMAT_32 = 4, // 1 pixel in 4 bytes (RGBA)
};
struct PGFFontStyle {
float_le fontH;
float_le fontV;
float_le fontHRes;
float_le fontVRes;
float_le fontWeight;
u16_le fontFamily;
u16_le fontStyle;
// Check.
u16_le fontStyleSub;
u16_le fontLanguage;
u16_le fontRegion;
u16_le fontCountry;
char fontName[64];
char fontFileName[64];
u32_le fontAttributes;
u32_le fontExpire;
};
struct Glyph {
int w;
int h;
int left;
int top;
int flags;
int shadowFlags;
int shadowID;
int advanceH;
int advanceV;
int dimensionWidth, dimensionHeight;
int xAdjustH, xAdjustV;
int yAdjustH, yAdjustV;
u32 ptr;
};
#if COMMON_LITTLE_ENDIAN
typedef FontPixelFormat FontPixelFormat_le;
#else
typedef swap_struct_t<FontPixelFormat, swap_32_t<FontPixelFormat> > FontPixelFormat_le;
#endif
struct GlyphImage {
FontPixelFormat_le pixelFormat;
s32_le xPos64;
s32_le yPos64;
u16_le bufWidth;
u16_le bufHeight;
u16_le bytesPerLine;
u16_le pad;
u32_le bufferPtr;
};
#pragma pack(push,1)
struct PGFHeader
{
u16_le headerOffset;
u16_le headerSize;
char PGFMagic[4];
s32_le revision;
s32_le version;
s32_le charMapLength;
s32_le charPointerLength;
s32_le charMapBpe;
s32_le charPointerBpe;
// TODO: This has values in it (0404)...
u8 pad1[2];
u8 bpp;
u8 pad2[1];
s32_le hSize;
s32_le vSize;
s32_le hResolution;
s32_le vResolution;
u8 pad3[1];
char fontName[64];
char fontType[64];
u8 pad4[1];
u16_le firstGlyph;
u16_le lastGlyph;
// TODO: This has a few 01s in it in the official fonts.
u8 pad5[26];
s32_le maxAscender;
s32_le maxDescender;
s32_le maxLeftXAdjust;
s32_le maxBaseYAdjust;
s32_le minCenterXAdjust;
s32_le maxTopYAdjust;
s32_le maxAdvance[2];
s32_le maxSize[2];
u16_le maxGlyphWidth;
u16_le maxGlyphHeight;
u8 pad6[2];
u8 dimTableLength;
u8 xAdjustTableLength;
u8 yAdjustTableLength;
u8 advanceTableLength;
u8 pad7[102];
s32_le shadowMapLength;
s32_le shadowMapBpe;
float_le unknown1;
s32_le shadowScale[2];
u8 pad8[8];
};
struct PGFHeaderRev3Extra {
s32_le compCharMapBpe1;
s32_le compCharMapLength1;
s32_le compCharMapBpe2;
s32_le compCharMapLength2;
u32_le unknown;
};
struct PGFCharInfo {
u32_le bitmapWidth;
u32_le bitmapHeight;
u32_le bitmapLeft;
u32_le bitmapTop;
// Glyph metrics (in 26.6 signed fixed-point).
u32_le sfp26Width;
u32_le sfp26Height;
s32_le sfp26Ascender;
s32_le sfp26Descender;
s32_le sfp26BearingHX;
s32_le sfp26BearingHY;
s32_le sfp26BearingVX;
s32_le sfp26BearingVY;
s32_le sfp26AdvanceH;
s32_le sfp26AdvanceV;
s16_le shadowFlags;
s16_le shadowId;
};
struct PGFFontInfo {
// Glyph metrics (in 26.6 signed fixed-point).
s32_le maxGlyphWidthI;
s32_le maxGlyphHeightI;
s32_le maxGlyphAscenderI;
s32_le maxGlyphDescenderI;
s32_le maxGlyphLeftXI;
s32_le maxGlyphBaseYI;
s32_le minGlyphCenterXI;
s32_le maxGlyphTopYI;
s32_le maxGlyphAdvanceXI;
s32_le maxGlyphAdvanceYI;
// Glyph metrics (replicated as float).
float_le maxGlyphWidthF;
float_le maxGlyphHeightF;
float_le maxGlyphAscenderF;
float_le maxGlyphDescenderF;
float_le maxGlyphLeftXF;
float_le maxGlyphBaseYF;
float_le minGlyphCenterXF;
float_le maxGlyphTopYF;
float_le maxGlyphAdvanceXF;
float_le maxGlyphAdvanceYF;
// Bitmap dimensions.
s16_le maxGlyphWidth;
s16_le maxGlyphHeight;
s32_le numGlyphs;
s32_le shadowMapLength; // Number of elements in the font's shadow charmap.
// Font style (used by font comparison functions).
PGFFontStyle fontStyle;
u8 BPP; // Font's BPP.
u8 pad[3];
};
#pragma pack(pop)
class PGF {
public:
PGF();
~PGF();
bool ReadPtr(const u8 *ptr, size_t dataSize);
bool GetCharInfo(int charCode, PGFCharInfo *ci, int altCharCode, int glyphType = FONT_PGF_CHARGLYPH) const;
void GetFontInfo(PGFFontInfo *fi) const;
void DrawCharacter(const GlyphImage *image, int clipX, int clipY, int clipWidth, int clipHeight, int charCode, int altCharCode, int glyphType) const;
void DoState(PointerWrap &p);
PGFHeader header;
private:
bool ReadCharGlyph(const u8 *fontdata, size_t charPtr, Glyph &glyph);
bool ReadShadowGlyph(const u8 *fontdata, size_t charPtr, Glyph &glyph);
bool GetCharGlyph(int charCode, int glyphType, Glyph &glyph) const;
// Unused
int GetCharIndex(int charCode, const std::vector<int> &charmapCompressed);
void SetFontPixel(u32 base, int bpl, int bufWidth, int bufHeight, int x, int y, u8 pixelColor, FontPixelFormat pixelformat) const;
PGFHeaderRev3Extra rev3extra;
// Font character image data
u8 *fontData;
size_t fontDataSize;
std::string fileName;
std::vector<int> dimensionTable[2];
std::vector<int> xAdjustTable[2];
std::vector<int> yAdjustTable[2];
std::vector<int> advanceTable[2];
// Unused
std::vector<int> charmapCompressionTable1[2];
std::vector<int> charmapCompressionTable2[2];
std::vector<int> charmap_compr;
std::vector<int> charmap;
std::vector<Glyph> glyphs;
std::vector<Glyph> shadowGlyphs;
int firstGlyph;
};