// bitmapcode.cpp - Bitmap code helper.
//
// (c) 2012-2017 Xestia Software Development.
//
// This file is part of Xestia Calendar.
//
// Xestia Calendar 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 3 of the license.
//
// Xestia Calendar 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 Xestia Calendar. If not, see
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
void CreateCPPFile(wxString dirfilename, wxString PNGFilename, int* counter)
{
//-------------------------------------------------------------------
// CreateCPPFile: Create a CPP file from the filename given.
//
// dirfilename wxString of the directory name.
// filename wxString of the filename.
// counter Pointer to a integer counter.
//-------------------------------------------------------------------
char pngfile_char;
int pageseek = 0;
wxString outname;
wxString CPPFilename;
CPPFilename = PNGFilename;
CPPFilename.RemoveLast(4);
CPPFilename.Append(wxT(".cpp"));
wxString DirFilenameOnly;
wxString CPPFilenameOnly;
#if defined(__HAIKU__)
#elif defined(__WIN32__)
wxStringTokenizer CPPFilenameTokens(CPPFilename, wxT("\\"));
wxStringTokenizer DirFilenameTokens(dirfilename, wxT("\\"));
#else
wxStringTokenizer CPPFilenameTokens(CPPFilename, wxT("/"));
wxStringTokenizer DirFilenameTokens(dirfilename, wxT("/"));
#endif
while (CPPFilenameTokens.HasMoreTokens()){
CPPFilenameOnly = CPPFilenameTokens.GetNextToken();
}
while (DirFilenameTokens.HasMoreTokens()){
DirFilenameOnly = DirFilenameTokens.GetNextToken();
}
// Setup the PNG file reading and cpp file.
fstream cppfile, pngfile;
#if defined(__WIN32__)
pngfile.open(PNGFilename.wc_str(), ios::in | ios::binary );
cppfile.open(CPPFilename.wc_str(), ios::out | ios::trunc );
# else
pngfile.open(PNGFilename.c_str(), ios::in | ios::binary );
cppfile.open(CPPFilename.c_str(), ios::out | ios::trunc );
#endif
outname.Append(wxString::FromUTF8(DirFilenameOnly.c_str()));
outname.Append(wxT("_"));
outname.Append(wxString::FromUTF8(CPPFilenameOnly.c_str()));
outname.MakeUpper();
outname.RemoveLast(4);
// Setup the inclusion guard.
cppfile << "#include " << endl << endl;
cppfile << "#ifndef " << outname.c_str() << "_CPP" << endl;
cppfile << "#define " << outname.c_str() << "_CPP" << endl << endl;
outname.Clear();
outname.Append(wxString::FromUTF8(DirFilenameOnly.c_str()));
outname.Append(wxT("_"));
outname.Append(wxString::FromUTF8(CPPFilenameOnly.c_str()));
outname.RemoveLast(4);
outname.Append(wxT("_png"));
outname.MakeLower();
// Convert the PNG file into an unsigned char array.
cppfile << "static unsigned char " << outname.c_str() <<
"[] = {" << endl;
while (pngfile){
pngfile.get(pngfile_char);
cppfile << "0x";
if ((unsigned short)pngfile_char > 255){
cppfile << hex << setw(2) << setfill('0') <<
((unsigned short)pngfile_char - 65280);
} else {
cppfile << hex << setw(2) << setfill('0') <<
(unsigned short)pngfile_char;
}
cppfile << ", ";
pageseek++;
if (pageseek == 8){
cppfile << endl;
pageseek = 0;
}
}
// End the file, close it and increment the counter.
cppfile << "};" << endl << endl;
cppfile << "#endif" << endl << endl;
cppfile.close();
cout << "CPP\t" << CPPFilename.c_str() << endl;
++*counter;
}
void CreateHPPFileDir(wxString dirfilename, wxArrayString filelist,
int* counter)
{
//-------------------------------------------------------------------
// CreateHPPFileDir: Create a HPP Directory with the directory
// filename and list of files in the directory
// given.
//
// dirfilename wxString of the directory name.
// filelist wxArrayString of the directory filelist.
// counter Pointer to a integer counter.
//-------------------------------------------------------------------
fstream hppfile;
bool fmatch = FALSE;
wxString finaldirname;
wxString HPPFilename = dirfilename.c_str();
wxString DirFilenameOnly;
wxString HPPFilenameOnly;
wxString CPPFilename;
#if defined(__WIN32__)
wxStringTokenizer HPPFilenameTokens(HPPFilename, wxT("\\"));
wxStringTokenizer DirFilenameTokens(dirfilename, wxT("\\"));
#else
wxStringTokenizer HPPFilenameTokens(HPPFilename, wxT("/"));
wxStringTokenizer DirFilenameTokens(dirfilename, wxT("/"));
#endif
while (HPPFilenameTokens.HasMoreTokens()){
HPPFilenameOnly = HPPFilenameTokens.GetNextToken();
}
while (DirFilenameTokens.HasMoreTokens()){
DirFilenameOnly = DirFilenameTokens.GetNextToken();
}
// Make the directory filename upper case for writing to the
// header file.
wxString CPPFileOnly;
finaldirname.Append(wxString::FromUTF8(DirFilenameOnly.c_str()));
finaldirname.MakeUpper();
// Write out the header file inclusion guard.
HPPFilename.Append(wxT(".h"));
#if defined(__WIN32__)
hppfile.open(HPPFilename.wc_str(), ios::out | ios::trunc );
#else
hppfile.open(HPPFilename.c_str(), ios::out | ios::trunc );
#endif
hppfile << "#include " << endl << endl;
hppfile << "#ifndef " << finaldirname.c_str() << "_H" << endl;
hppfile << "#define " << finaldirname.c_str() << "_H" << endl << endl;
hppfile << "// List all CPP files in the directory." << endl << endl;
// Write each CPP file into the header file.
for (int f = 0; f < filelist.GetCount() ; f++){
CPPFilename = filelist[f];
#if defined(__HAIKU__)
#elif defined(__WIN32__)
wxStringTokenizer CPPFilenameTokenizer(CPPFilename, wxT("\\"));
#else
wxStringTokenizer CPPFilenameTokenizer(CPPFilename, wxT("/"));
#endif
while (CPPFilenameTokenizer.HasMoreTokens()){
CPPFileOnly = CPPFilenameTokenizer.GetNextToken();
}
CPPFileOnly.RemoveLast(4);
CPPFileOnly.Append(wxT(".cpp"));
hppfile << "#include \"" << DirFilenameOnly.c_str() <<
"/" << CPPFileOnly.c_str() << "\"" << endl;
}
// Write the end if and close the file.
hppfile << endl << "#endif" << endl << endl;
hppfile.close();
// Increment the HPP file counter.
cout << "HPPDIR\t" << HPPFilename.c_str() << endl;
++*counter;
}
int main(int argc, char *argv[])
{
int fp = 0;
int cppg = 0;
int hppg = 0;
wxArrayString dirlist;
wxArrayString filelist;
wxString BitmapHeaderFilename;
wxString DirFilenameWxS;
// Check if completed file exists before doing anything
// else and write an error message if it does exist.
if (wxFileExists(wxT("bitmapsdone"))){
std::cout << "Bitmap files have already been generated!" << std::endl << std::endl;
std::cout << "To regenerate the files simply delete the bitmapsdone file where this helper application is run." << std::endl;
return 0;
}
fstream finalhppfile;
if (!argv[1]){
std::cout << "Error: No directory name given!" << std::endl;
return -1;
}
// Look in the subdirectories of the bitmaps directory and
// collect the names of the directories.
std::cout << "Working out directories in bitmaps directory..." <<
std::endl;
const char *dirarg = argv[1];
wxString BitmapDirName = wxString(dirarg, wxConvUTF8);
#if defined(__HAIKU__)
#elif defined(__WIN32__)
BitmapHeaderFilename.Append(BitmapDirName);
BitmapHeaderFilename.Append(wxT("\\..\\bitmaps.h"));
#else
BitmapHeaderFilename.Append(BitmapDirName);
BitmapHeaderFilename.Append(wxT("/../bitmaps.h"));
#endif
if ( wxDirExists(BitmapDirName) ){
wxDir BitmapDir(BitmapDirName);
wxString BitmapSubDir;
wxString BitmapSubDirFull;
bool ContinueProcess = BitmapDir.GetFirst(&BitmapSubDir, wxEmptyString, wxDIR_DEFAULT);
while (ContinueProcess){
#if defined(__HAIKU__)
BitmapSubDirFull.Append(BitmapSubDir);
BitmapSubDirFull.Append();
#elif defined(__WIN32__)
BitmapSubDirFull.Append(BitmapDirName);
BitmapSubDirFull.Append(wxT("\\"));
BitmapSubDirFull.Append(BitmapSubDir);
#else
BitmapSubDirFull.Append(BitmapDirName);
BitmapSubDirFull.Append(wxT("/"));
BitmapSubDirFull.Append(BitmapSubDir);
#endif
if (wxDirExists(BitmapSubDirFull)){
dirlist.Add(BitmapSubDirFull);
}
ContinueProcess = BitmapDir.GetNext(&BitmapSubDir);
BitmapSubDirFull.Clear();
}
} else {
std::cout << "Error: Bitmaps Directory doesn't exist!" << std::endl;
return 1;
}
// Process each directory, generating a .cpp and .hpp file
// for each image and then a final .hpp for the directory
// containing the .hpp's for the directories.
if (dirlist.GetCount() == 0){
cout << "Error: No directories in the bitmaps folder. Unexpected behaviour!" << endl;
return 1;
}
std::cout << "Looking in bitmaps folder for PNGs..." << std::endl;
DirFilenameWxS.Empty();
std::cout << BitmapHeaderFilename.c_str() << std::endl;
#if defined(__WIN32__)
finalhppfile.open(BitmapHeaderFilename.wc_str(), ios::out | ios::trunc);
#else
finalhppfile.open(BitmapHeaderFilename.c_str(), ios::out | ios::trunc);
#endif
finalhppfile << "#include " << endl << endl;
finalhppfile << "#ifndef BITMAPS_H" << endl;
finalhppfile << "#define BITMAPS_H" << endl << endl;
for (int bi = 0; bi < dirlist.GetCount(); bi++)
{
wxString BitmapSubDirName = dirlist[bi];
wxString BitmapFilename;
wxDir BitmapSubDir(BitmapSubDirName);
bool ContinueProcess = BitmapSubDir.GetFirst(&BitmapFilename, wxEmptyString, wxDIR_DEFAULT);
while (ContinueProcess){
if (BitmapFilename.Right(4) == wxT(".PNG") ||
BitmapFilename.Right(4) == wxT(".png")){
#if defined(__HAIKU__)
BitmapSubDirFull.Append(BitmapSubDir);
BitmapSubDirFull.Append();
#elif defined(__WIN32__)
DirFilenameWxS.Append(wxString::FromUTF8(dirlist[bi].c_str()));
DirFilenameWxS.Append(wxT("\\"));
DirFilenameWxS.Append(wxString::FromUTF8(BitmapFilename.c_str()));
#else
DirFilenameWxS.Append(wxString::FromUTF8(dirlist[bi].c_str()));
DirFilenameWxS.Append(wxString::FromUTF8("/"));
DirFilenameWxS.Append(wxString::FromUTF8(BitmapFilename.c_str()));
#endif
filelist.Add(DirFilenameWxS);
}
DirFilenameWxS.Clear();
ContinueProcess = BitmapSubDir.GetNext(&BitmapFilename);
}
for (int fi = 0; fi < filelist.GetCount(); fi++)
{
CreateCPPFile(dirlist[bi].wc_str(), filelist[fi].wc_str(), &cppg);
fp++;
}
if (filelist.GetCount() > 0)
{
CreateHPPFileDir(dirlist[bi].wc_str(), filelist, &hppg);
}
filelist.Clear();
wxString DirNameSplit;
#if defined(__HAIKU__)
#elif defined(__WIN32__)
wxStringTokenizer DirListFile(dirlist[bi], wxT("\\"));
#else
wxStringTokenizer DirListFile(dirlist[bi], wxT("/"));
#endif
while (DirListFile.HasMoreTokens()){
DirNameSplit = DirListFile.GetNextToken();
}
#if defined(__HAIKU__)
#elif defined(__WIN32__)
finalhppfile << "#include \"bitmaps\\" << DirNameSplit.c_str() <<
".h\"" << endl;
#else
finalhppfile << "#include \"bitmaps/" << DirNameSplit.c_str() <<
".h\"" << endl;
#endif
}
finalhppfile << endl << "#endif" << endl;
finalhppfile.close();
++hppg;
// Print out the results.
std::cout << "Finished processing PNGs into code." << std::endl;
std::cout << fp << " files processed." << std::endl;
std::cout << cppg << " .cpp files generated." << std::endl;
std::cout << hppg << " .hpp files generated." << std::endl;
// Write a success flag so that future runs won't take
// place thus speeding up the compilation process as required.
fstream bitmapflag;
bitmapflag.open("bitmapsdone", ios::out | ios::trunc);
bitmapflag << "Bitmaps as code generated. To recreate, simply delete this file and run the bitmap code generation tool again." << endl;
bitmapflag.close();
return 0;
}