Add blocks/gaps to the font format
This commit is contained in:
parent
9d927cbd6f
commit
b8c5e94a41
16
data/font.h
16
data/font.h
@ -260,9 +260,10 @@ unsigned char font_data[] = {
|
||||
0x06, 0x00, 0x00, 0x00, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x00, 0x00, 0x00, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x00, 0x00, 0x00, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x74, 0x00, 0xD0, 0x1F, 0x40, 0x8B, 0x07, 0x3D, 0xF3, 0xF1, 0x3F, 0x3F, 0xFD, 0xF8, 0x41, 0xFF, 0x07, 0xD0, 0x1C, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
short font_ptrs[] = {
|
||||
unsigned short font_ptrs[] = {
|
||||
0x0000, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050, 0x0060, 0x0070,
|
||||
0x0080, 0x0090, 0x00A0, 0x00B0, 0x00C0, 0x00D0, 0x00E0, 0x00F0,
|
||||
0x0100, 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0160, 0x0170,
|
||||
@ -295,14 +296,23 @@ short font_ptrs[] = {
|
||||
0x1396, 0x13A9, 0x13BC, 0x13CF, 0x13E2, 0x13F5, 0x1408, 0x141B,
|
||||
0x142E, 0x1441, 0x1454, 0x1467, 0x147A, 0x148D, 0x14A0, 0x14B3,
|
||||
0x14C6, 0x14D9, 0x14EC, 0x14FF, 0x1512, 0x1525, 0x1538, 0x154B,
|
||||
|
||||
0x155E,
|
||||
};
|
||||
unsigned int font_ranges[][2] = {
|
||||
{ 0x000000, 0x0000FF },
|
||||
{ 0x00FFFD, 0x00FFFD },
|
||||
{ 0, 0 },
|
||||
};
|
||||
#else
|
||||
extern unsigned char font_data[];
|
||||
extern short font_ptrs[];
|
||||
extern unsigned short font_ptrs[];
|
||||
extern unsigned int font_ranges[][2];
|
||||
#endif
|
||||
#else
|
||||
extern unsigned char *font_data;
|
||||
extern short *font_ptrs;
|
||||
extern unsigned short *font_ptrs;
|
||||
extern unsigned int (*font_ranges)[2];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -17,9 +17,25 @@ class FontReader
|
||||
data(0)
|
||||
{}
|
||||
|
||||
static inline unsigned char *lookupChar(String::value_type ch)
|
||||
{
|
||||
size_t offset = 0;
|
||||
for(int i = 0; font_ranges[i][1]; i++)
|
||||
if(font_ranges[i][0] > ch)
|
||||
break;
|
||||
else if(font_ranges[i][1] >= ch)
|
||||
return &font_data[font_ptrs[offset + (ch - font_ranges[i][0])]];
|
||||
else
|
||||
offset += font_ranges[i][1] - font_ranges[i][0] + 1;
|
||||
if(ch == 0xFFFD)
|
||||
return &font_data[0];
|
||||
else
|
||||
return lookupChar(0xFFFD);
|
||||
}
|
||||
|
||||
public:
|
||||
inline FontReader(String::value_type ch):
|
||||
FontReader(ch <= 0xFF ? &font_data[font_ptrs[ch]] : &font_data[0])
|
||||
FontReader(lookupChar(ch))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,8 @@
|
||||
|
||||
#ifdef FONTEDITOR
|
||||
unsigned char *font_data;
|
||||
short *font_ptrs;
|
||||
unsigned short *font_ptrs;
|
||||
unsigned int (*font_ranges)[2];
|
||||
|
||||
void FontEditor::ReadHeader(ByteString header)
|
||||
{
|
||||
@ -47,15 +48,15 @@ void FontEditor::ReadHeader(ByteString header)
|
||||
}
|
||||
while(!file.fail());
|
||||
file.clear();
|
||||
|
||||
|
||||
size_t endFontData = file.tellg();
|
||||
|
||||
|
||||
while(word != "font_ptrs[]")
|
||||
file >> word;
|
||||
file >> word >> word;
|
||||
|
||||
|
||||
size_t startFontPtrs = file.tellg();
|
||||
|
||||
|
||||
fontPtrs.clear();
|
||||
do
|
||||
{
|
||||
@ -69,9 +70,30 @@ void FontEditor::ReadHeader(ByteString header)
|
||||
}
|
||||
while(!file.fail());
|
||||
file.clear();
|
||||
|
||||
|
||||
size_t endFontPtrs = file.tellg();
|
||||
|
||||
while(word != "font_ranges[][2]")
|
||||
file >> word;
|
||||
file >> word >> word;
|
||||
|
||||
size_t startFontRanges = file.tellg();
|
||||
|
||||
fontRanges.clear();
|
||||
while(true)
|
||||
{
|
||||
unsigned int value1, value2;
|
||||
file >> word >> std::hex >> value1 >> word >> std::hex >> value2 >> word;
|
||||
if(file.fail())
|
||||
break;
|
||||
fontRanges.push_back({value1, value2});
|
||||
if(!value2)
|
||||
break;
|
||||
}
|
||||
file.clear();
|
||||
|
||||
size_t endFontRanges = file.tellg();
|
||||
|
||||
do
|
||||
{
|
||||
file >> word;
|
||||
@ -88,17 +110,17 @@ void FontEditor::ReadHeader(ByteString header)
|
||||
afterFontData = ByteString(startFontPtrs - endFontData, 0);
|
||||
file.read(&afterFontData[0], startFontPtrs - endFontData);
|
||||
|
||||
file.seekg(endFontData);
|
||||
afterFontData = ByteString(startFontPtrs - endFontData, 0);
|
||||
file.read(&afterFontData[0], startFontPtrs - endFontData);
|
||||
|
||||
file.seekg(endFontPtrs);
|
||||
afterFontPtrs = ByteString(eof - endFontPtrs, 0);
|
||||
file.read(&afterFontPtrs[0], eof - endFontPtrs);
|
||||
afterFontPtrs = ByteString(startFontRanges - endFontPtrs, 0);
|
||||
file.read(&afterFontPtrs[0], startFontRanges - endFontPtrs);
|
||||
|
||||
file.seekg(endFontRanges);
|
||||
afterFontRanges = ByteString(eof - endFontRanges, 0);
|
||||
file.read(&afterFontRanges[0], eof - endFontRanges);
|
||||
file.close();
|
||||
}
|
||||
|
||||
void FontEditor::WriteHeader(ByteString header, std::vector<unsigned char> const &fontData, std::vector<short> const &fontPtrs)
|
||||
void FontEditor::WriteHeader(ByteString header, std::vector<unsigned char> const &fontData, std::vector<unsigned short> const &fontPtrs, std::vector<std::array<unsigned int, 2> > const &fontRanges)
|
||||
{
|
||||
std::fstream file;
|
||||
file.open(header, std::ios_base::out | std::ios_base::trunc);
|
||||
@ -107,84 +129,128 @@ void FontEditor::WriteHeader(ByteString header, std::vector<unsigned char> const
|
||||
|
||||
file << std::setfill('0') << std::hex << std::uppercase;
|
||||
file << beforeFontData << std::endl;
|
||||
for(int ch = 0; ch < 256; ch++)
|
||||
|
||||
size_t pos = 0;
|
||||
size_t ptrpos = 0;
|
||||
while(pos < fontData.size())
|
||||
{
|
||||
file << " " << "0x" << std::setw(2) << (unsigned int)fontData[fontPtrs[ch]] << ", ";
|
||||
for(int i = fontPtrs[ch] + 1; i < (int)(ch == (int)fontPtrs.size() - 1 ? fontData.size() : fontPtrs[ch + 1]); i++)
|
||||
file << " " << "0x" << std::setw(2) << (unsigned int)fontData[i] << ",";
|
||||
file << " " << "0x" << std::setw(2) << (unsigned int)fontData[pos] << ", ";
|
||||
for(pos++; pos < fontData.size() && (ptrpos == fontPtrs.size() - 1 || pos < (size_t)fontPtrs[ptrpos + 1]); pos++)
|
||||
file << " " << "0x" << std::setw(2) << (unsigned int)fontData[pos] << ",";
|
||||
file << std::endl;
|
||||
ptrpos++;
|
||||
}
|
||||
file << afterFontData;
|
||||
for(int ch = 0; ch < 256; ch++)
|
||||
|
||||
pos = 0;
|
||||
for(size_t i = 0; pos < fontPtrs.size() && fontRanges[i][1]; i++)
|
||||
{
|
||||
if(!(ch & 7))
|
||||
file << std::endl << " ";
|
||||
else
|
||||
file << " ";
|
||||
file << "0x" << std::setw(4) << (unsigned int)fontPtrs[ch] << ",";
|
||||
bool first = true;
|
||||
for(String::value_type ch = fontRanges[i][0]; ch <= fontRanges[i][1]; ch++)
|
||||
{
|
||||
if(!(ch & 0x7) || first)
|
||||
file << std::endl << " ";
|
||||
else
|
||||
file << " ";
|
||||
first = false;
|
||||
file << "0x" << std::setw(4) << (unsigned int)fontPtrs[pos++] << ",";
|
||||
}
|
||||
file << std::endl;
|
||||
}
|
||||
file << std::endl << afterFontPtrs;
|
||||
file << afterFontPtrs << std::endl;
|
||||
for(size_t i = 0; i < fontRanges.size() - 1; i++)
|
||||
file << " { 0x" << std::setw(6) << (unsigned int)fontRanges[i][0] << ", 0x" << std::setw(6) << (unsigned int)fontRanges[i][1] << " }," << std::endl;
|
||||
file << " { 0, 0 },";
|
||||
file << afterFontRanges;
|
||||
file.close();
|
||||
}
|
||||
|
||||
void FontEditor::UnpackData(
|
||||
std::array<char, 256> &fontWidths,
|
||||
std::array<std::array<std::array<char, MAX_WIDTH>, FONT_H>, 256> &fontPixels,
|
||||
std::map<String::value_type, unsigned char> &fontWidths,
|
||||
std::map<String::value_type, std::array<std::array<char, MAX_WIDTH>, FONT_H> > &fontPixels,
|
||||
std::vector<unsigned char> const &fontData,
|
||||
std::vector<short> const &fontPtrs)
|
||||
std::vector<unsigned short> const &fontPtrs,
|
||||
std::vector<std::array<unsigned int, 2> > const &fontRanges)
|
||||
{
|
||||
for(int ch = 0; ch < 256; ch++)
|
||||
{
|
||||
unsigned char const *data = &fontData[fontPtrs[ch]];
|
||||
int bits = 0;
|
||||
int pixels = 0;
|
||||
int width = fontWidths[ch] = *(data++);
|
||||
for(int j = 0; j < FONT_H; j++)
|
||||
for(int i = 0; i < width; i++)
|
||||
{
|
||||
if(!bits)
|
||||
fontWidths.clear();
|
||||
fontPixels.clear();
|
||||
size_t pos = 0;
|
||||
for(size_t range = 0; fontRanges[range][1]; range++)
|
||||
for(String::value_type ch = fontRanges[range][0]; ch <= fontRanges[range][1]; ch++)
|
||||
{
|
||||
unsigned char const *pointer = &fontData[fontPtrs[pos]];
|
||||
int width = fontWidths[ch] = *(pointer++);
|
||||
int pixels = 0;
|
||||
int data = 0;
|
||||
for(int j = 0; j < FONT_H; j++)
|
||||
for(int i = 0; i < width; i++)
|
||||
{
|
||||
pixels = *(data++);
|
||||
bits = 8;
|
||||
if(!pixels)
|
||||
{
|
||||
data = *(pointer++);
|
||||
pixels = 4;
|
||||
}
|
||||
fontPixels[ch][j][i] = data & 3;
|
||||
data >>= 2;
|
||||
pixels--;
|
||||
}
|
||||
fontPixels[ch][j][i] = pixels & 3;
|
||||
pixels >>= 2;
|
||||
bits -= 2;
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
void FontEditor::PackData(
|
||||
std::array<char, 256> const &fontWidths,
|
||||
std::array<std::array<std::array<char, MAX_WIDTH>, FONT_H>, 256> const &fontPixels,
|
||||
std::map<String::value_type, unsigned char> const &fontWidths,
|
||||
std::map<String::value_type, std::array<std::array<char, MAX_WIDTH>, FONT_H> > const &fontPixels,
|
||||
std::vector<unsigned char> &fontData,
|
||||
std::vector<short> &fontPtrs)
|
||||
std::vector<unsigned short> &fontPtrs,
|
||||
std::vector<std::array<unsigned int, 2> > &fontRanges)
|
||||
{
|
||||
fontPtrs.clear();
|
||||
fontData.clear();
|
||||
for(int ch = 0; ch < 256; ch++)
|
||||
fontPtrs.clear();
|
||||
fontRanges.clear();
|
||||
bool first = true;
|
||||
String::value_type rangeStart;
|
||||
String::value_type prev;
|
||||
for(std::map<String::value_type, unsigned char>::const_iterator it = fontWidths.begin(); it != fontWidths.end(); it++)
|
||||
{
|
||||
fontPtrs.push_back(fontData.size());
|
||||
fontData.push_back(fontWidths[ch]);
|
||||
|
||||
int bits = 0;
|
||||
int pixels = 0;
|
||||
for(int j = 0; j < FONT_H; j++)
|
||||
for(int i = 0; i < fontWidths[ch]; i++)
|
||||
String::value_type ch = it->first;
|
||||
if(first)
|
||||
{
|
||||
rangeStart = ch;
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
if(ch != prev + 1)
|
||||
{
|
||||
if(bits == 8)
|
||||
{
|
||||
fontData.push_back(pixels);
|
||||
bits = 0;
|
||||
pixels = 0;
|
||||
}
|
||||
pixels >>= 2;
|
||||
pixels |= fontPixels[ch][j][i] << 6;
|
||||
bits += 2;
|
||||
fontRanges.push_back({rangeStart, prev});
|
||||
rangeStart = ch;
|
||||
}
|
||||
if(bits)
|
||||
fontData.push_back(pixels);
|
||||
|
||||
fontPtrs.push_back(fontData.size());
|
||||
fontData.push_back(it->second);
|
||||
|
||||
int pixels = 0;
|
||||
int data = 0;
|
||||
for(int j = 0; j < FONT_H; j++)
|
||||
for(int i = 0; i < it->second; i++)
|
||||
{
|
||||
if(pixels == 4)
|
||||
{
|
||||
fontData.push_back(data);
|
||||
pixels = 0;
|
||||
data = 0;
|
||||
}
|
||||
data >>= 2;
|
||||
data |= fontPixels.at(ch)[j][i] << 6;
|
||||
pixels++;
|
||||
}
|
||||
if(pixels)
|
||||
fontData.push_back(data);
|
||||
|
||||
prev = ch;
|
||||
}
|
||||
fontRanges.push_back({rangeStart, prev});
|
||||
fontRanges.push_back({0, 0});
|
||||
}
|
||||
|
||||
#define FONT_SCALE 16
|
||||
@ -197,9 +263,10 @@ FontEditor::FontEditor(ByteString _header):
|
||||
rulers(1)
|
||||
{
|
||||
ReadHeader(header);
|
||||
UnpackData(fontWidths, fontPixels, fontData, fontPtrs);
|
||||
UnpackData(fontWidths, fontPixels, fontData, fontPtrs, fontRanges);
|
||||
font_data = fontData.data();
|
||||
font_ptrs = fontPtrs.data();
|
||||
font_ranges = (unsigned int (*)[2])fontRanges.data();
|
||||
|
||||
int baseline = 8 + FONT_H * FONT_SCALE + 4 + FONT_H + 4 + 1;
|
||||
int currentX = 1;
|
||||
@ -227,9 +294,9 @@ FontEditor::FontEditor(ByteString _header):
|
||||
void TextChangedCallback(ui::Textbox *)
|
||||
{
|
||||
unsigned int number;
|
||||
String::Stream ss(v->currentCharTextbox->GetText());
|
||||
ByteString::Stream ss(v->currentCharTextbox->GetText().ToUtf8());
|
||||
ss >> std::hex >> number;
|
||||
if(number < 256)
|
||||
if(number <= 0x10FFFF)
|
||||
v->currentChar = number;
|
||||
}
|
||||
};
|
||||
@ -284,6 +351,45 @@ FontEditor::FontEditor(ByteString _header):
|
||||
grow->SetActionCallback(new GrowCharAction(this));
|
||||
AddComponent(grow);
|
||||
|
||||
class AddCharAction : public ui::ButtonAction
|
||||
{
|
||||
FontEditor *v;
|
||||
public:
|
||||
AddCharAction(FontEditor *_v): v(_v) {}
|
||||
void ActionCallback(ui::Button *)
|
||||
{
|
||||
if(v->fontWidths.find(v->currentChar) == v->fontWidths.end())
|
||||
{
|
||||
v->savedButton->SetToggleState(false);
|
||||
v->fontWidths[v->currentChar] = 5;
|
||||
v->fontPixels[v->currentChar];
|
||||
}
|
||||
}
|
||||
};
|
||||
ui::Button *add = new ui::Button(ui::Point(currentX, baseline), ui::Point(36, 17), "Add");
|
||||
currentX += 37;
|
||||
add->SetActionCallback(new AddCharAction(this));
|
||||
AddComponent(add);
|
||||
|
||||
class RemoveCharAction : public ui::ButtonAction
|
||||
{
|
||||
FontEditor *v;
|
||||
public:
|
||||
RemoveCharAction(FontEditor *_v): v(_v) {}
|
||||
void ActionCallback(ui::Button *)
|
||||
{
|
||||
if(v->fontWidths.find(v->currentChar) != v->fontWidths.end())
|
||||
{
|
||||
v->savedButton->SetToggleState(false);
|
||||
v->fontWidths.erase(v->currentChar);
|
||||
v->fontPixels.erase(v->currentChar);
|
||||
}
|
||||
}
|
||||
};
|
||||
ui::Button *remove = new ui::Button(ui::Point(currentX, baseline), ui::Point(36, 17), "Remove");
|
||||
currentX += 37;
|
||||
remove->SetActionCallback(new RemoveCharAction(this));
|
||||
AddComponent(remove);
|
||||
|
||||
class ToggleAction : public ui::ButtonAction
|
||||
{
|
||||
@ -295,6 +401,7 @@ FontEditor::FontEditor(ByteString _header):
|
||||
toggle = button->GetToggleState();
|
||||
}
|
||||
};
|
||||
|
||||
ui::Button *showGrid = new ui::Button(ui::Point(currentX, baseline), ui::Point(32, 17), "Grid");
|
||||
currentX += 33;
|
||||
showGrid->SetTogglable(true);
|
||||
@ -319,7 +426,7 @@ FontEditor::FontEditor(ByteString _header):
|
||||
ColorComponentAction(int &_color): color(_color) {}
|
||||
void TextChangedCallback(ui::Textbox *box)
|
||||
{
|
||||
String::Stream ss(box->GetText());
|
||||
ByteString::Stream ss(box->GetText().ToUtf8());
|
||||
ss >> color;
|
||||
}
|
||||
};
|
||||
@ -384,7 +491,7 @@ FontEditor::FontEditor(ByteString _header):
|
||||
PreviewAction(FontEditor *_v): v(_v) {}
|
||||
void TextChangedCallback(ui::Textbox *box)
|
||||
{
|
||||
String::Stream ss(box->GetText());
|
||||
ByteString::Stream ss(box->GetText().ToUtf8()); // ByteString::Stream for now
|
||||
String text;
|
||||
while(!ss.eof())
|
||||
{
|
||||
@ -431,41 +538,54 @@ void FontEditor::OnDraw()
|
||||
{
|
||||
Graphics *g = GetGraphics();
|
||||
|
||||
int areaWidth = 8 + fontWidths[currentChar] * FONT_SCALE + 8;
|
||||
g->fillrect(0, 0, areaWidth, 8 + FONT_H * FONT_SCALE + 4 + FONT_H + 4, bgR, bgG, bgB, 255);
|
||||
for(int j = 0; j < FONT_H; j++)
|
||||
for(int i = 0; i < fontWidths[currentChar]; i++)
|
||||
g->fillrect(8 + i * FONT_SCALE, 8 + j * FONT_SCALE, FONT_SCALE - grid, FONT_SCALE - grid, fgR, fgG, fgB, fontPixels[currentChar][j][i] * 255 / 3);
|
||||
|
||||
for(int j = 0; j < FONT_H; j++)
|
||||
for(int i = 0; i < fontWidths[currentChar]; i++)
|
||||
g->blendpixel(8 + i, 8 + FONT_H * FONT_SCALE + 4 + j, fgR, fgG, fgB, fontPixels[currentChar][j][i] * 255 / 3);
|
||||
|
||||
|
||||
if(rulers)
|
||||
if(fontWidths.find(currentChar) != fontWidths.end())
|
||||
{
|
||||
g->draw_line(0, 7 + 0 * FONT_SCALE , areaWidth - 1, 7 + 0 * FONT_SCALE, 128, 128, 128, 255);
|
||||
g->draw_line(0, 7 + 2 * FONT_SCALE , areaWidth - 1, 7 + 2 * FONT_SCALE, 128, 128, 128, 255);
|
||||
g->draw_line(0, 7 + 4 * FONT_SCALE , areaWidth - 1, 7 + 4 * FONT_SCALE, 128, 128, 128, 255);
|
||||
g->draw_line(0, 7 + 9 * FONT_SCALE , areaWidth - 1, 7 + 9 * FONT_SCALE, 128, 128, 128, 255);
|
||||
g->draw_line(0, 7 + 12 * FONT_SCALE , areaWidth - 1, 7 + 12 * FONT_SCALE, 128, 128, 128, 255);
|
||||
int width = fontWidths[currentChar];
|
||||
std::array<std::array<char, MAX_WIDTH>, FONT_H> const &pixels = fontPixels[currentChar];
|
||||
|
||||
g->draw_line(7, 8, 7, 7 + FONT_H * FONT_SCALE, 128, 128, 128, 255);
|
||||
g->draw_line(7 + fontWidths[currentChar] * FONT_SCALE, 8, 7 + fontWidths[currentChar] * FONT_SCALE, 7 + FONT_H * FONT_SCALE, 128, 128, 128, 255);
|
||||
int areaWidth = 8 + width * FONT_SCALE + 8;
|
||||
g->fillrect(0, 0, areaWidth, 8 + FONT_H * FONT_SCALE + 4 + FONT_H + 4, bgR, bgG, bgB, 255);
|
||||
for(int j = 0; j < FONT_H; j++)
|
||||
for(int i = 0; i < width; i++)
|
||||
g->fillrect(8 + i * FONT_SCALE, 8 + j * FONT_SCALE, FONT_SCALE - grid, FONT_SCALE - grid, fgR, fgG, fgB, pixels[j][i] * 255 / 3);
|
||||
|
||||
for(int j = 0; j < FONT_H; j++)
|
||||
for(int i = 0; i < width; i++)
|
||||
g->blendpixel(8 + i, 8 + FONT_H * FONT_SCALE + 4 + j, fgR, fgG, fgB, pixels[j][i] * 255 / 3);
|
||||
|
||||
|
||||
if(rulers)
|
||||
{
|
||||
g->draw_line(0, 7 + 0 * FONT_SCALE , areaWidth - 1, 7 + 0 * FONT_SCALE, 128, 128, 128, 255);
|
||||
g->draw_line(0, 7 + 2 * FONT_SCALE , areaWidth - 1, 7 + 2 * FONT_SCALE, 128, 128, 128, 255);
|
||||
g->draw_line(0, 7 + 4 * FONT_SCALE , areaWidth - 1, 7 + 4 * FONT_SCALE, 128, 128, 128, 255);
|
||||
g->draw_line(0, 7 + 9 * FONT_SCALE , areaWidth - 1, 7 + 9 * FONT_SCALE, 128, 128, 128, 255);
|
||||
g->draw_line(0, 7 + 12 * FONT_SCALE , areaWidth - 1, 7 + 12 * FONT_SCALE, 128, 128, 128, 255);
|
||||
|
||||
g->draw_line(7, 8, 7, 7 + FONT_H * FONT_SCALE, 128, 128, 128, 255);
|
||||
g->draw_line(7 + width * FONT_SCALE, 8, 7 + width * FONT_SCALE, 7 + FONT_H * FONT_SCALE, 128, 128, 128, 255);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g->drawtext(8, 8, "No character", 255, 0, 0, 255);
|
||||
}
|
||||
}
|
||||
|
||||
void FontEditor::OnMouseDown(int x, int y, unsigned button)
|
||||
{
|
||||
x = (x - 8) / FONT_SCALE;
|
||||
y = (y - 8) / FONT_SCALE;
|
||||
if(x >= 0 && y >= 0 && x < fontWidths[currentChar] && y < FONT_H)
|
||||
if(fontWidths.find(currentChar) != fontWidths.end())
|
||||
{
|
||||
if(button == SDL_BUTTON_LEFT)
|
||||
fontPixels[currentChar][y][x] = (fontPixels[currentChar][y][x] + 1) % 4;
|
||||
else
|
||||
fontPixels[currentChar][y][x] = (fontPixels[currentChar][y][x] + 3) % 4;
|
||||
savedButton->SetToggleState(false);
|
||||
x = (x - 8) / FONT_SCALE;
|
||||
y = (y - 8) / FONT_SCALE;
|
||||
if(x >= 0 && y >= 0 && x < fontWidths[currentChar] && y < FONT_H)
|
||||
{
|
||||
if(button == SDL_BUTTON_LEFT)
|
||||
fontPixels[currentChar][y][x] = (fontPixels[currentChar][y][x] + 1) % 4;
|
||||
else
|
||||
fontPixels[currentChar][y][x] = (fontPixels[currentChar][y][x] + 3) % 4;
|
||||
savedButton->SetToggleState(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -492,9 +612,9 @@ void FontEditor::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bo
|
||||
|
||||
void FontEditor::UpdateCharNumber()
|
||||
{
|
||||
String::Stream ss;
|
||||
ByteString::Stream ss;
|
||||
ss << std::hex << currentChar;
|
||||
currentCharTextbox->SetText(ss.str());
|
||||
currentCharTextbox->SetText(ByteString(ss.str()).FromUtf8());
|
||||
}
|
||||
|
||||
void FontEditor::PrevChar()
|
||||
@ -506,7 +626,7 @@ void FontEditor::PrevChar()
|
||||
|
||||
void FontEditor::NextChar()
|
||||
{
|
||||
if(currentChar < 255)
|
||||
if(currentChar <= 0x10FFFF)
|
||||
currentChar++;
|
||||
UpdateCharNumber();
|
||||
}
|
||||
@ -527,17 +647,19 @@ void FontEditor::GrowChar()
|
||||
|
||||
void FontEditor::Render()
|
||||
{
|
||||
PackData(fontWidths, fontPixels, fontData, fontPtrs);
|
||||
PackData(fontWidths, fontPixels, fontData, fontPtrs, fontRanges);
|
||||
font_data = fontData.data();
|
||||
font_ptrs = fontPtrs.data();
|
||||
font_ranges = (unsigned int (*)[2])fontRanges.data();
|
||||
}
|
||||
|
||||
void FontEditor::Save()
|
||||
{
|
||||
std::vector<unsigned char> tmpFontData;
|
||||
std::vector<short> tmpFontPtrs;
|
||||
PackData(fontWidths, fontPixels, tmpFontData, tmpFontPtrs);
|
||||
WriteHeader(header, tmpFontData, tmpFontPtrs);
|
||||
std::vector<unsigned short> tmpFontPtrs;
|
||||
std::vector<std::array<unsigned int, 2> > tmpFontRanges;
|
||||
PackData(fontWidths, fontPixels, tmpFontData, tmpFontPtrs, tmpFontRanges);
|
||||
WriteHeader(header, tmpFontData, tmpFontPtrs, tmpFontRanges);
|
||||
savedButton->SetToggleState(true);
|
||||
}
|
||||
#endif
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <map>
|
||||
|
||||
#include "font.h"
|
||||
|
||||
@ -14,34 +15,38 @@ class FontEditor: public ui::Window
|
||||
{
|
||||
private:
|
||||
ByteString header;
|
||||
std::array<char, 256> fontWidths;
|
||||
std::array<std::array<std::array<char, MAX_WIDTH>, FONT_H>, 256> fontPixels;
|
||||
std::map<String::value_type, unsigned char> fontWidths;
|
||||
std::map<String::value_type, std::array<std::array<char, MAX_WIDTH>, FONT_H> > fontPixels;
|
||||
|
||||
std::vector<unsigned char> fontData;
|
||||
std::vector<short> fontPtrs;
|
||||
std::vector<unsigned short> fontPtrs;
|
||||
std::vector<std::array<unsigned int, 2> > fontRanges;
|
||||
|
||||
ByteString beforeFontData;
|
||||
ByteString afterFontData;
|
||||
ByteString afterFontPtrs;
|
||||
ByteString afterFontRanges;
|
||||
|
||||
void ReadHeader(ByteString header);
|
||||
void WriteHeader(ByteString header, std::vector<unsigned char> const &fontData, std::vector<short> const &fontPtrs);
|
||||
void WriteHeader(ByteString header, std::vector<unsigned char> const &fontData, std::vector<unsigned short> const &fontPtrs, std::vector<std::array<unsigned int, 2> > const &fontRanges);
|
||||
static void PackData(
|
||||
std::array<char, 256> const &fontWidths,
|
||||
std::array<std::array<std::array<char, MAX_WIDTH>, FONT_H>, 256> const &fontPixels,
|
||||
std::map<String::value_type, unsigned char> const &fontWidths,
|
||||
std::map<String::value_type, std::array<std::array<char, MAX_WIDTH>, FONT_H> > const &fontPixels,
|
||||
std::vector<unsigned char> &fontData,
|
||||
std::vector<short> &fontPtrs);
|
||||
std::vector<unsigned short> &fontPtrs,
|
||||
std::vector<std::array<unsigned int, 2> > &fontRanges);
|
||||
static void UnpackData(
|
||||
std::array<char, 256> &fontWidths,
|
||||
std::array<std::array<std::array<char, MAX_WIDTH>, FONT_H>, 256> &fontPixels,
|
||||
std::map<String::value_type, unsigned char> &fontWidths,
|
||||
std::map<String::value_type, std::array<std::array<char, MAX_WIDTH>, FONT_H> > &fontPixels,
|
||||
std::vector<unsigned char> const &fontData,
|
||||
std::vector<short> const &fontPtrs);
|
||||
std::vector<unsigned short> const &fontPtrs,
|
||||
std::vector<std::array<unsigned int, 2> > const &fontRanges);
|
||||
|
||||
ui::Textbox *currentCharTextbox;
|
||||
ui::Button *savedButton;
|
||||
ui::Label *outputPreview;
|
||||
|
||||
int currentChar;
|
||||
String::value_type currentChar;
|
||||
int fgR, fgG, fgB;
|
||||
int bgR, bgG, bgB;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user