From ac984dac7a79bc65fb22d2b80a2ec36dae83e019 Mon Sep 17 00:00:00 2001 From: Edouard Dupin Date: Thu, 8 Dec 2011 18:23:30 +0100 Subject: [PATCH] Internal data Fist step : Generate an arbo inside the binary and get data with abstraction of the arboressance od the software --- Makefile | 34 +- Sources/Main.cpp | 9 +- Sources/etk/File.cpp | 375 +++++++++++++++--- Sources/etk/File.h | 61 ++- Sources/ewol/FontBitmap.cpp | 13 +- Sources/ewol/Texture.cpp | 4 +- Sources/ewol/theme/Theme.cpp | 10 +- assets/Font/ebtfont/Monospace.bmp | Bin 1048630 -> 0 bytes assets/Font/ebtfont/Monospace.ebt | 129 ------ assets/ic_luncher_ewoltest.png | Bin 6523 -> 0 bytes assets/theme/exemple.eol | 92 ----- {Font => dataTest/Font}/ebtfont/Monospace.bmp | Bin {Font => dataTest/Font}/ebtfont/Monospace.ebt | 2 +- {Font => dataTest/Font}/freefont/AUTHORS | 0 {Font => dataTest/Font}/freefont/COPYING | 0 {Font => dataTest/Font}/freefont/CREDITS | 0 {Font => dataTest/Font}/freefont/ChangeLog | 0 {Font => dataTest/Font}/freefont/FreeMono.ttf | Bin .../Font}/freefont/FreeMonoBold.ttf | Bin .../Font}/freefont/FreeMonoBoldOblique.ttf | Bin .../Font}/freefont/FreeMonoOblique.ttf | Bin {Font => dataTest/Font}/freefont/FreeSans.ttf | Bin .../Font}/freefont/FreeSansBold.ttf | Bin .../Font}/freefont/FreeSansBoldOblique.ttf | Bin .../Font}/freefont/FreeSansOblique.ttf | Bin .../Font}/freefont/FreeSerif.ttf | Bin .../Font}/freefont/FreeSerifBold.ttf | Bin .../Font}/freefont/FreeSerifBoldItalic.ttf | Bin .../Font}/freefont/FreeSerifItalic.ttf | Bin {Font => dataTest/Font}/freefont/INSTALL | 0 {Font => dataTest/Font}/freefont/README | 0 .../Font}/freefont/date_2010-09-19.txt | 0 tools/fileToCpp.cpp | 219 ++++++++++ 33 files changed, 648 insertions(+), 300 deletions(-) delete mode 100644 assets/Font/ebtfont/Monospace.bmp delete mode 100644 assets/Font/ebtfont/Monospace.ebt delete mode 100644 assets/ic_luncher_ewoltest.png delete mode 100644 assets/theme/exemple.eol rename {Font => dataTest/Font}/ebtfont/Monospace.bmp (100%) rename {Font => dataTest/Font}/ebtfont/Monospace.ebt (99%) rename {Font => dataTest/Font}/freefont/AUTHORS (100%) rename {Font => dataTest/Font}/freefont/COPYING (100%) rename {Font => dataTest/Font}/freefont/CREDITS (100%) rename {Font => dataTest/Font}/freefont/ChangeLog (100%) rename {Font => dataTest/Font}/freefont/FreeMono.ttf (100%) rename {Font => dataTest/Font}/freefont/FreeMonoBold.ttf (100%) rename {Font => dataTest/Font}/freefont/FreeMonoBoldOblique.ttf (100%) rename {Font => dataTest/Font}/freefont/FreeMonoOblique.ttf (100%) rename {Font => dataTest/Font}/freefont/FreeSans.ttf (100%) rename {Font => dataTest/Font}/freefont/FreeSansBold.ttf (100%) rename {Font => dataTest/Font}/freefont/FreeSansBoldOblique.ttf (100%) rename {Font => dataTest/Font}/freefont/FreeSansOblique.ttf (100%) rename {Font => dataTest/Font}/freefont/FreeSerif.ttf (100%) rename {Font => dataTest/Font}/freefont/FreeSerifBold.ttf (100%) rename {Font => dataTest/Font}/freefont/FreeSerifBoldItalic.ttf (100%) rename {Font => dataTest/Font}/freefont/FreeSerifItalic.ttf (100%) rename {Font => dataTest/Font}/freefont/INSTALL (100%) rename {Font => dataTest/Font}/freefont/README (100%) rename {Font => dataTest/Font}/freefont/date_2010-09-19.txt (100%) create mode 100644 tools/fileToCpp.cpp diff --git a/Makefile b/Makefile index 6d1228f2..2eb4e6db 100644 --- a/Makefile +++ b/Makefile @@ -49,18 +49,24 @@ DEFAULT_PLATFORM=X11 # default platform can be overridden PLATFORM?=$(DEFAULT_PLATFORM) +DATA_MODE=MEMORY + ifeq ($(PLATFORM), X11) CXXFILES += base/guiX11.cpp else ifeq ($(PLATFORM), DoubleBuffer) CXXFILES += base/guiDoubleBuffer.cpp else ifeq ($(PLATFORM), IPhone) CXXFILES += base/guiIPhone.cpp + DATA_MODE=MEMORY else ifeq ($(PLATFORM), IPad) CXXFILES += base/guiIPad.cpp + DATA_MODE=MEMORY else ifeq ($(PLATFORM), Android) CXXFILES += base/guiAndroid.cpp + DATA_MODE=MEMORY else ifeq ($(PLATFORM), AndroidTablet) CXXFILES += base/guiAndroidTablet.cpp + DATA_MODE=MEMORY else $(error you must specify a corect platform : make PLATFORM=$(SUPPORTED_PLATFORM)) endif @@ -139,6 +145,10 @@ CXXFLAGS+= -D_REENTRANT CXXFLAGS+= $(DEFINE) # remove warning from the convertion char* CXXFLAGS+= -Wno-write-strings +#set data in memory +ifeq ($(DATA_MODE), MEMORY) +CXXFLAGS+= -DDATA_INTERNAL_BINARY +endif CFLAGS= $(CXXFLAGS) -std=c99 @@ -180,6 +190,12 @@ MAKE_DEPENDENCE=Makefile ### Files Listes ### ############################################################################### +#data File of the program : +ifeq ($(DATA_MODE), MEMORY) +CXXFILES += GeneratedData.cpp +endif + + # tiny XML (extern OPEN Sources) : CXXFILES += tinyXML/tinyxml.cpp \ tinyXML/tinyxmlparser.cpp \ @@ -236,10 +252,13 @@ CXXFILES += ewol/themeManager.cpp \ + # Ewol Test Software : CXXFILES += Main.cpp - +# get all data file in the specific folder +DATA_FOLDER=dataTest +DATA_FILE=$(shell find $(DATA_FOLDER)/*) ############################################################################### ### Liste of folder where .h can be ### @@ -278,6 +297,19 @@ build: .encadrer .versionFile $(OUTPUT_NAME) @mkdir -p $(addprefix $(OBJECT_DIRECTORY)/, $(LISTE_MODULES)) +# Tool used to create a binary version of every element png or other needed by the application +fileToCpp: tools/fileToCpp.cpp + @echo $(F_ROUGE)" (bin) $@"$(F_NORMALE) + @$(CXX) $< -o $@ + @strip -s $@ + +# Generate basic user Data +$(FILE_DIRECTORY)/GeneratedData.cpp: $(DATA_FILE) $(MAKE_DEPENDENCE) fileToCpp + @echo $(F_BLUE)" (.cpp) "$(DATA_FOLDER)" ==> $@"$(F_NORMALE) + @#echo ./pngToCpp $@ $(DATA_FILE) + @./fileToCpp $@ $(DATA_FILE) + + .versionFile: @rm -f $(OBJECT_DIRECTORY)/ewol/ewol.o diff --git a/Sources/Main.cpp b/Sources/Main.cpp index 563a9e1e..0dca7664 100644 --- a/Sources/Main.cpp +++ b/Sources/Main.cpp @@ -100,12 +100,13 @@ void APP_Init(int argc, char *argv[]) //fontID = GetFontIdWithFileName("dataTest/TextMonospace.ebt"); } */ - ewol::SetFontFolder("Font"); + ewol::SetFontFolder("dataTest/Font"); //ewol::SetDefaultFont("freefont/FreeMono", 14); ewol::SetDefaultFont("ebtfont/Monospace", 14); //ewol::theme::LoadDefault("dataTest/exemple.eol"); - ewol::theme::LoadDefault("theme/exemple.eol"); - + etk::File fileTmp("dataTest/exemple.eol", etk::FILE_TYPE_DATA); + ewol::theme::LoadDefault(fileTmp); + /* etk::File tmpFile("/data/data/com.example.EwolActivity.app/assets/theme/exemple.eol"); if (tmpFile.Exist() ) { EWOL_WARNING("file existed : " << tmpFile); @@ -138,7 +139,7 @@ void APP_Init(int argc, char *argv[]) if (tmpFile.Exist() ) { EWOL_WARNING("file existed : " << tmpFile); } - + */ myWindowsExample = new Plop(); diff --git a/Sources/etk/File.cpp b/Sources/etk/File.cpp index e2b7e6db..14bac61d 100644 --- a/Sources/etk/File.cpp +++ b/Sources/etk/File.cpp @@ -28,6 +28,12 @@ #include #include +#ifdef DATA_INTERNAL_BINARY +# include "GeneratedData.h" +#endif + + + #undef __class__ #define __class__ "etk::File" @@ -40,33 +46,40 @@ etk::CCout& etk::operator <<(etk::CCout &os, const etk::File &obj) return os; } -etk::File::File(etk::String &filename, int32_t LineNumber) +etk::File::File(etk::String &filename, etk::FileType_te type, int32_t LineNumber) { m_lineNumberOpen = LineNumber; - SetCompleateName(filename); + m_PointerFile = NULL; + SetCompleateName(filename, type); } -etk::File::File(const char *filename, int32_t LineNumber) +etk::File::File(const char *filename, etk::FileType_te type, int32_t LineNumber) { etk::String tmpString = filename; m_lineNumberOpen = LineNumber; - SetCompleateName(tmpString); + m_PointerFile = NULL; + SetCompleateName(tmpString, type); } -etk::File::File(etk::String &filename, etk::String &folder, int32_t lineNumber) +etk::File::File(etk::String &filename, etk::String &folder, etk::FileType_te type, int32_t lineNumber) { etk::String tmpString = folder; tmpString += '/'; tmpString += filename; - SetCompleateName(tmpString); + m_PointerFile = NULL; + SetCompleateName(tmpString, type); m_lineNumberOpen = lineNumber; } etk::File::~File(void) { // nothing to do ... + if (NULL != m_PointerFile) { + TK_ERROR("Missing close the file : \"" << GetCompleateName() << "\""); + fClose(); + } } @@ -96,6 +109,15 @@ const etk::File& etk::File::operator= (const etk::File &etkF ) m_folder = etkF.m_folder; m_shortFilename = etkF.m_shortFilename; m_lineNumberOpen = etkF.m_lineNumberOpen; + m_type = etkF.m_type; + if (NULL != m_PointerFile) { + TK_ERROR("Missing close the file : \"" << GetCompleateName() << "\""); + fClose(); + } + #ifdef DATA_INTERNAL_BINARY + m_idInternal = etkF.m_idInternal; + m_readingOffset = 0; + #endif } return *this; } @@ -136,20 +158,32 @@ bool etk::File::operator!= (const etk::File &etkF) const } -etk::String baseFolderMobile = "/data/data/com.example.ewolAbstraction/assets/"; +etk::String baseFolderData = "./"; +etk::String baseFolderDataUser = "~/.tmp/userData"; +etk::String baseFolderCache = "~/.tmp/cache"; // for specific device contraint : -void etk::SetBaseFolder(const char * folder) +void etk::SetBaseFolderData(const char * folder) { - //baseFolderMobile = folder; + baseFolderData = folder; +} +void etk::SetBaseFolderDataUser(const char * folder) +{ + baseFolderDataUser = folder; +} +void etk::SetBaseFolderCache(const char * folder) +{ + baseFolderCache = folder; } - -void etk::File::SetCompleateName(etk::String &newFilename) +void etk::File::SetCompleateName(etk::String &newFilename, etk::FileType_te type) { char buf[MAX_FILE_NAME]; memset(buf, 0, MAX_FILE_NAME); char * ok; + #ifdef DATA_INTERNAL_BINARY + m_idInternal = -1; + #endif // Reset ALL DATA : m_folder = ""; m_shortFilename = ""; @@ -162,50 +196,119 @@ void etk::File::SetCompleateName(etk::String &newFilename) destFilename = newFilename; } TK_VERBOSE("2 : Get file Name : " << destFilename ); - if ('/' != *destFilename.c_str()) { - // Get the command came from the running of the program : - char cCurrentPath[FILENAME_MAX]; - #ifdef __PLATFORM__Android - strcpy(cCurrentPath, baseFolderMobile.c_str() ); - #else - if (!getcwd(cCurrentPath, FILENAME_MAX)) { - return; - } - #endif - cCurrentPath[FILENAME_MAX - 1] = '\0'; - etk::String tmpFilename = destFilename; - destFilename = cCurrentPath; - destFilename += '/'; - destFilename += tmpFilename; - } - TK_VERBOSE("3 : Get file Name : " << destFilename ); - - // Get the real Path of the current File - ok = realpath(destFilename.c_str(), buf); - if (!ok) { - int32_t lastPos = destFilename.FindBack('/'); - if (-1 != lastPos) { - // Get the FileName - etk::String tmpFilename = destFilename.Extract(lastPos+1); - destFilename.Remove(lastPos, destFilename.Size() - lastPos); - TK_VERBOSE("try to find :\"" << destFilename << "\" / \"" << tmpFilename << "\" "); - ok = realpath(destFilename.c_str(), buf); - if (!ok) { - TK_VERBOSE("Can not find real Path name of \"" << destFilename << "\""); - m_shortFilename = tmpFilename; - m_folder = destFilename; - } else { - // ALL is OK ... - m_shortFilename = tmpFilename; - m_folder = destFilename; - } - } else { - TK_WARNING("file : \"" << destFilename << "\" ==> No data???"); - // Basic ERROR ... - m_shortFilename = destFilename; + if ('/' == *destFilename.c_str()) { + m_type = etk::FILE_TYPE_DIRECT; + if (type != etk::FILE_TYPE_DIRECT) { + TK_WARNING("Incompatible type with a file=\"" << newFilename << "\" ==> force it in direct mode ..."); + } + } else { + if (type == etk::FILE_TYPE_DIRECT) { + TK_WARNING("Incompatible type with a file=\"" << newFilename << "\" ==> force it in FILE_TYPE_DATA mode ..."); + m_type = etk::FILE_TYPE_DATA; + } else { + m_type = type; + } + } + bool needUnpack = false; + #if ETK_DEBUG_LEVEL > 3 + char *mode = NULL; + #endif + switch (m_type) + { + case etk::FILE_TYPE_DATA: + { + #if ETK_DEBUG_LEVEL > 3 + mode = "FILE_TYPE_DATA"; + #endif + #ifdef DATA_INTERNAL_BINARY + for(int32_t iii=0; iii 3 + mode = "FILE_TYPE_USER_DATA"; + #endif + etk::String tmpFilename = destFilename; + destFilename = baseFolderDataUser; + destFilename += '/'; + destFilename += tmpFilename; + } + needUnpack = true; + break; + case etk::FILE_TYPE_CACHE: + { + #if ETK_DEBUG_LEVEL > 3 + mode = "FILE_TYPE_CACHE"; + #endif + etk::String tmpFilename = destFilename; + destFilename = baseFolderCache; + destFilename += '/'; + destFilename += tmpFilename; + } + needUnpack = true; + break; + default: + // nothing to do ... + #if ETK_DEBUG_LEVEL > 3 + mode = "FILE_TYPE_DIRECT"; + #endif + needUnpack = true; + break; + } + TK_VERBOSE("3 : Get file Name : " << destFilename ); + if (true == needUnpack) { + // Get the real Path of the current File + ok = realpath(destFilename.c_str(), buf); + if (!ok) { + int32_t lastPos = destFilename.FindBack('/'); + if (-1 != lastPos) { + // Get the FileName + etk::String tmpFilename = destFilename.Extract(lastPos+1); + destFilename.Remove(lastPos, destFilename.Size() - lastPos); + TK_VERBOSE("try to find :\"" << destFilename << "\" / \"" << tmpFilename << "\" "); + ok = realpath(destFilename.c_str(), buf); + if (!ok) { + TK_VERBOSE("Can not find real Path name of \"" << destFilename << "\""); + m_shortFilename = tmpFilename; + m_folder = destFilename; + } else { + // ALL is OK ... + m_shortFilename = tmpFilename; + m_folder = destFilename; + } + } else { + TK_WARNING("file : \"" << destFilename << "\" ==> No data???"); + // Basic ERROR ... + m_shortFilename = destFilename; + } + } else { + destFilename = buf; + int32_t lastPos = destFilename.FindBack('/'); + if (-1 != lastPos) { + m_shortFilename = destFilename.Extract(lastPos+1); + m_folder = destFilename.Extract(0, lastPos); + } else { + // Basic ERROR ... + TK_WARNING("file : \"" << destFilename << "\" ==> No data???"); + m_shortFilename = destFilename; + } } } else { - destFilename = buf; int32_t lastPos = destFilename.FindBack('/'); if (-1 != lastPos) { m_shortFilename = destFilename.Extract(lastPos+1); @@ -216,7 +319,7 @@ void etk::File::SetCompleateName(etk::String &newFilename) m_shortFilename = destFilename; } } - TK_VERBOSE("Set FileName :\"" << m_folder << "\" / \"" << m_shortFilename << "\" "); + TK_VERBOSE("Set FileName :\"" << m_folder << "\" / \"" << m_shortFilename << "\" mode=" << mode); } int32_t etk::File::GetLineNumber(void) @@ -261,6 +364,14 @@ etk::String etk::File::GetExtention(void) int32_t etk::File::Size(void) { + #ifdef DATA_INTERNAL_BINARY + if (etk::FILE_TYPE_DATA == m_type) { + if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) { + return internalDataFiles[m_idInternal].fileLenght; + } + return 0; + } + #endif FILE *myFile=NULL; etk::String myCompleateName = GetCompleateName(); myFile=fopen(myCompleateName.c_str(),"rb"); @@ -279,6 +390,14 @@ int32_t etk::File::Size(void) bool etk::File::Exist(void) { + #ifdef DATA_INTERNAL_BINARY + if (etk::FILE_TYPE_DATA == m_type) { + if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) { + return true; + } + return false; + } + #endif FILE *myFile=NULL; etk::String myCompleateName = GetCompleateName(); myFile=fopen(myCompleateName.c_str(),"rb"); @@ -288,3 +407,151 @@ bool etk::File::Exist(void) fclose(myFile); return true; } + + + +bool etk::File::fOpenRead(void) +{ + #ifdef DATA_INTERNAL_BINARY + if (etk::FILE_TYPE_DATA == m_type) { + m_readingOffset = 0; + if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) { + TK_DEBUG("Open file : " << GetCompleateName() << " with size=" << internalDataFilesSize << " Octets"); + return true; + } + return false; + } + #endif + if (NULL != m_PointerFile) { + TK_CRITICAL("File Already open : \"" << GetCompleateName() << "\""); + return true; + } + m_PointerFile=fopen(GetCompleateName().c_str(),"rb"); + if(NULL == m_PointerFile) { + TK_ERROR("Can not find the file name=\"" << GetCompleateName() << "\""); + return false; + } + return true; +} + +bool etk::File::fOpenWrite(void) +{ + #ifdef DATA_INTERNAL_BINARY + if (etk::FILE_TYPE_DATA == m_type) { + m_readingOffset = 0; + return false; + } + #endif + if (NULL != m_PointerFile) { + TK_CRITICAL("File Already open : \"" << GetCompleateName() << "\""); + return true; + } + m_PointerFile=fopen(GetCompleateName().c_str(),"wb"); + if(NULL == m_PointerFile) { + TK_ERROR("Can not find the file name=\"" << GetCompleateName() << "\""); + return false; + } + return true; +} + +bool etk::File::fClose(void) +{ + #ifdef DATA_INTERNAL_BINARY + if (etk::FILE_TYPE_DATA == m_type) { + m_readingOffset = 0; + if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) { + return true; + } + return false; + } + #endif + if (NULL == m_PointerFile) { + TK_CRITICAL("File Already closed : \"" << GetCompleateName() << "\""); + return false; + } + fclose(m_PointerFile); + m_PointerFile = NULL; + return true; +} + +char * etk::File::fGets(char * elementLine, int32_t maxData) +{ + #ifdef DATA_INTERNAL_BINARY + char * element = elementLine; + if (etk::FILE_TYPE_DATA == m_type) { + if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) { + // TODO ... + //char * tmpData = internalDataFiles[iii].data + m_readingOffset; + if (m_readingOffset>internalDataFilesSize) { + element[0] = '\0'; + return NULL; + } + while (internalDataFiles[m_idInternal].data[m_readingOffset] != '\0') { + if( internalDataFiles[m_idInternal].data[m_readingOffset] == '\n' + || internalDataFiles[m_idInternal].data[m_readingOffset] == '\r') + { + *element = internalDataFiles[m_idInternal].data[m_readingOffset]; + element++; + m_readingOffset++; + *element = '\0'; + return elementLine; + } + *element = internalDataFiles[m_idInternal].data[m_readingOffset]; + element++; + m_readingOffset++; + // TODO : Understand why this does not work + /*if (m_readingOffset>internalDataFilesSize) { + *element = '\0'; + return elementLine; + }*/ + } + } + return NULL; + } + #endif + return fgets(elementLine, maxData, m_PointerFile); +} + +int32_t etk::File::fRead(void * data, int32_t blockSize, int32_t nbBlock) +{ + #ifdef DATA_INTERNAL_BINARY + if (etk::FILE_TYPE_DATA == m_type) { + if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) { + int32_t dataToRead = blockSize * nbBlock; + if (dataToRead + m_readingOffset > internalDataFilesSize) { + nbBlock = ((internalDataFilesSize - m_readingOffset) / blockSize); + dataToRead = blockSize * nbBlock; + } + memcpy(data, &internalDataFiles[m_idInternal].data[m_readingOffset], dataToRead); + m_readingOffset +=dataToRead; + return nbBlock; + } + return 0; + } + #endif + return fread(data, blockSize, nbBlock, m_PointerFile); +} + +int32_t etk::File::fWrite(void * data, int32_t blockSize, int32_t nbBlock) +{ + #ifdef DATA_INTERNAL_BINARY + if (etk::FILE_TYPE_DATA == m_type) { + TK_CRITICAL("Can not write on data inside memory : \"" << GetCompleateName() << "\""); + return 0; + } + #endif + return fwrite(data, blockSize, nbBlock, m_PointerFile); +} + + +char * etk::File::GetDirectPointer(void) +{ + #ifdef DATA_INTERNAL_BINARY + if (etk::FILE_TYPE_DATA == m_type) { + if (m_idInternal >= -1 && m_idInternal < internalDataFilesSize) { + return (char*)internalDataFiles[m_idInternal].data; + } + } + #endif + return NULL; +} diff --git a/Sources/etk/File.h b/Sources/etk/File.h index 10caf9f0..b20e0d2a 100644 --- a/Sources/etk/File.h +++ b/Sources/etk/File.h @@ -33,13 +33,36 @@ namespace etk { + typedef enum { + // user might done abstraction ==> acces of the sdcard when possible ... + FILE_TYPE_DIRECT, + + // depend of the case + // - PC : /usr/shared/programName/ + // - Android : Internal at the executable file (pointer on static area) + // - Apple : Internal at the executable file + FILE_TYPE_DATA, + + // depend on case + // - PC : ~/.programName/ + // - Android : /data/data/programName/files/ + // - Apple : ???? + FILE_TYPE_USER_DATA, + + // depend on case + // - PC : ~/.programName/cache/ + // - Android : /data/data/programName/cache/ + // - Apple : ???? + FILE_TYPE_CACHE, + } FileType_te; + class File { public: - File(void) { m_lineNumberOpen=0; } - File(etk::String &filename, int32_t LineNumber = 0); - File(const char *filename, int32_t LineNumber = 0); - File(etk::String &filename, etk::String &folder, int32_t lineNumber = 0); + File(void) { m_lineNumberOpen=0; m_type = etk::FILE_TYPE_DIRECT; m_PointerFile = NULL;} + File(etk::String &filename, etk::FileType_te type = etk::FILE_TYPE_DIRECT, int32_t LineNumber = 0); + File(const char *filename, etk::FileType_te type = etk::FILE_TYPE_DIRECT, int32_t LineNumber = 0); + File(etk::String &filename, etk::String &folder, etk::FileType_te type = etk::FILE_TYPE_DIRECT, int32_t lineNumber = 0); ~File(void); etk::String GetFolder(void) const; etk::String GetShortFilename(void) const; @@ -50,23 +73,41 @@ namespace etk bool Exist(void); int32_t GetLineNumber(void); void SetLineNumber(int32_t newline); - void SetCompleateName(etk::String &newFilename); + void SetCompleateName(etk::String &newFilename, etk::FileType_te type); const etk::File& operator= (const etk::File &etkF ); bool operator== (const etk::File &etkF ) const; bool operator!= (const etk::File &etkF ) const; friend etk::CCout& operator <<( etk::CCout &os,const etk::File &obj); + FileType_te GetTypeAccess(void) { return m_type; }; + char * GetDirectPointer(void); + + // TODO : IO access of the file : + bool fOpenRead(void); + bool fOpenWrite(void); + bool fClose(void); + char * fGets(char * elementLine, int32_t maxData); + int32_t fRead(void * data, int32_t blockSize, int32_t nbBlock); + int32_t fWrite(void * data, int32_t blockSize, int32_t nbBlock); private : - etk::String m_folder; - etk::String m_shortFilename; - int32_t m_lineNumberOpen; + etk::FileType_te m_type; + FILE * m_PointerFile; + #ifdef DATA_INTERNAL_BINARY + int32_t m_idInternal; + int32_t m_readingOffset; + #endif + etk::String m_folder; + etk::String m_shortFilename; + int32_t m_lineNumberOpen; }; etk::CCout& operator <<(etk::CCout &os, const etk::File &obj); - void SetBaseFolder(const char * folder); - + void SetBaseFolderData(const char * folder); + void SetBaseFolderDataUser(const char * folder); + void SetBaseFolderCache(const char * folder); + } #endif diff --git a/Sources/ewol/FontBitmap.cpp b/Sources/ewol/FontBitmap.cpp index 7acd7dfb..a9f98a18 100644 --- a/Sources/ewol/FontBitmap.cpp +++ b/Sources/ewol/FontBitmap.cpp @@ -67,16 +67,16 @@ namespace ewol tmpchar.ratio = 0; m_elements.PushBack(tmpchar); } - FILE* File=fopen(m_filename.GetCompleateName().c_str(),"r"); - if(NULL == File) { + if(false == m_filename.fOpenRead()) { EWOL_ERROR("Can not find the file name=\"" << m_filename << "\""); return; } // load all element of the file ... char elementLine[2048]; int32_t lineID=1; - while (NULL != fgets(elementLine, 2048, File) ) + while (NULL != m_filename.fGets(elementLine, 2048) ) { + EWOL_DEBUG(" Read file Line : " << elementLine); if ( '\n' != elementLine[0] // EOL && '\0' != elementLine[0] // EOF && '#' != elementLine[0] // Comment line @@ -113,11 +113,12 @@ namespace ewol lineID++; } // close the file at end of reading... - fclose(File); + m_filename.fClose(); // Load Bitmap : etk::String bitmapRealFile = m_filename.GetFolder() + "/" + m_bitmapName; EWOL_INFO("load text font image : \"" << bitmapRealFile << "\""); - m_textureId = ewol::LoadTexture(bitmapRealFile); + etk::File tmpFile(bitmapRealFile, m_filename.GetTypeAccess()); + m_textureId = ewol::LoadTexture(tmpFile); m_textureLoaded = true; m_loadedOK = true; }; @@ -270,7 +271,7 @@ int32_t ewol::LoadFont(etk::String fontName, int32_t size) { // check if folder file etk::String tmpFileName = s_currentFolderName + "/" + fontName + ".ebt"; - etk::File fileName(tmpFileName); + etk::File fileName(tmpFileName, etk::FILE_TYPE_DATA); if (false == fileName.Exist()) { EWOL_ERROR("Font does not exist: \"" << fileName.GetCompleateName() << "\""); return -1; diff --git a/Sources/ewol/Texture.cpp b/Sources/ewol/Texture.cpp index acb99688..82ede40e 100644 --- a/Sources/ewol/Texture.cpp +++ b/Sources/ewol/Texture.cpp @@ -88,10 +88,10 @@ class Bitmap FILE *File=NULL; // Get the fileSize ... - if (fileName.Size() < (int32_t)(sizeof(bitmapFileHeader_ts) + sizeof(bitmapInfoHeader_ts) ) ) { + /*if (fileName.Size() < (int32_t)(sizeof(bitmapFileHeader_ts) + sizeof(bitmapInfoHeader_ts) ) ) { EWOL_ERROR("not enought data in the file named=\"" << fileName << "\""); return; - } + }*/ File=fopen(fileName.GetCompleateName().c_str(),"rb"); if(NULL == File) { EWOL_ERROR("Can not find the file name=\"" << fileName << "\""); diff --git a/Sources/ewol/theme/Theme.cpp b/Sources/ewol/theme/Theme.cpp index 2ef7bad7..3e586137 100644 --- a/Sources/ewol/theme/Theme.cpp +++ b/Sources/ewol/theme/Theme.cpp @@ -58,7 +58,15 @@ void ewol::theme::Theme::Load(etk::File & newFile, bool defaultTheme) } else { TiXmlDocument XmlDocument; // open the curent File - XmlDocument.LoadFile(newFile.GetCompleateName().c_str()); + #ifdef DATA_INTERNAL_BINARY + if (etk::FILE_TYPE_DATA == newFile.GetTypeAccess()) { + XmlDocument.Parse(newFile.GetDirectPointer()); + } else { + XmlDocument.LoadFile(newFile.GetCompleateName().c_str()); + } + #else + XmlDocument.LoadFile(newFile.GetCompleateName().c_str()); + #endif TiXmlElement* root = XmlDocument.FirstChildElement( "eol" ); if (NULL == root ) { EWOL_ERROR("(l ?) main node not find: \"eol\" in \"" << newFile << "\""); diff --git a/assets/Font/ebtfont/Monospace.bmp b/assets/Font/ebtfont/Monospace.bmp deleted file mode 100644 index abbde0284a26a1370a55f4a3f36af91997634bf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1048630 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%0AtpcnUeQcNa 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 0x54 (33,45) (33,54) -0x00 (99,453) (33,54) # Error : Unknow the UTF8 element ... -# hexa UTF8 code of the letter and start coordonate and size ==> 0x54 (33,45) (33,54) -# ABCDEFGHIJKLMN -0x20 (0,7) (33,54) # space ... -0x41 (33,7) (33,54) # A -0x42 (66,7) (33,54) # B -0x43 (99,7) (33,54) # C -0x44 (132,7) (33,54) # D -0x45 (165,7) (33,54) # E -0x46 (198,7) (33,54) # F -0x47 (231,7) (33,54) # G -0x48 (264,7) (33,54) # H -0x49 (297,7) (33,54) # I -0x4A (330,7) (33,54) # J -0x4B (363,7) (33,54) # K -0x4C (396,7) (33,54) # L -0x4D (429,7) (33,54) # M -0x4E (462,7) (33,54) # N -#OPQRSTUVWXYZabc -0x4F (0,71) (33,54) # O -0x50 (33,71) (33,54) # P -0x51 (66,71) (33,54) # Q -0x52 (99,71) (33,54) # R -0x53 (132,71) (33,54) # S -0x54 (165,71) (33,54) # T -0x55 (198,71) (33,54) # U -0x56 (231,71) (33,54) # V -0x57 (264,71) (33,54) # W -0x58 (297,71) (33,54) # X -0x59 (330,71) (33,54) # Y -0x5A (363,71) (33,54) # Z -0x61 (396,71) (33,54) # a -0x62 (429,71) (33,54) # b -0x63 (462,71) (33,54) # c -#defghijklmnopqr -0x64 (0,135) (33,54) # d -0x65 (33,135) (33,54) # e -0x66 (66,135) (33,54) # f -0x67 (99,135) (33,54) # g -0x68 (132,135) (33,54) # h -0x69 (165,135) (33,54) # i -0x6A (198,135) (33,54) # j -0x6B (231,135) (33,54) # k -0x6C (264,135) (33,54) # l -0x6D (297,135) (33,54) # m -0x6E (330,135) (33,54) # n -0x6F (363,135) (33,54) # o -0x70 (396,135) (33,54) # p -0x71 (429,135) (33,54) # q -0x72 (462,135) (33,54) # r -#stuvwxyz1234567 -0x73 (0,199) (33,54) # s -0x74 (33,199) (33,54) # t -0x75 (66,199) (33,54) # u -0x76 (99,199) (33,54) # v -0x77 (132,199) (33,54) # w -0x78 (165,199) (33,54) # x -0x79 (198,199) (33,54) # y -0x7A (231,199) (33,54) # z -0x31 (264,199) (33,54) # 1 -0x32 (297,199) (33,54) # 2 -0x33 (330,199) (33,54) # 3 -0x34 (363,199) (33,54) # 4 -0x35 (396,199) (33,54) # 5 -0x36 (429,199) (33,54) # 6 -0x37 (462,199) (33,54) # 7 -#890&é~"#'{([-|è -0x38 (0,263) (33,54) # 8 -0x39 (33,263) (33,54) # 9 -0x30 (66,263) (33,54) # 0 -0x26 (99,263) (33,54) # & -#0x (132,263) (33,54) # é -0x7E (165,263) (33,54) # ~ -0x22 (198,263) (33,54) # " -0x23 (231,263) (33,54) # # -0x27 (264,263) (33,54) # ' -0x7B (297,263) (33,54) # { -0x28 (330,263) (33,54) # ( -0x5B (363,263) (33,54) # [ -0x2D (396,263) (33,54) # - -0x7C (429,263) (33,54) # | -#0x (462,263) (33,54) # è -#`_\ç^à@)]=} -0x60 (0,335) (33,54) # ` -0x5F (33,335) (33,54) # _ -0x5C (66,335) (33,54) # \ -#0x (99,335) (33,54) # ç -0x5E (132,335) (33,54) # ^ -#0x (165,335) (33,54) # à -0x40 (198,335) (33,54) # @ -0x29 (231,335) (33,54) # ) -0x5D (264,335) (33,54) # ] -0x3D (297,335) (33,54) # = -0x7D (330,335) (33,54) # } -#0x (363,335) (33,54) # o chap -#0x (396,335) (33,54) # u chap -#0x (429,335) (33,54) # e chap -#0x (462,335) (33,54) # a chap -#$£*µ%!§:/ -#0x (0,391) (33,54) # i chap -#0x (33,391) (33,54) # o trema -#0x (66,391) (33,54) # u trema -#0x (99,391) (33,54) # e trema -#0x (132,391) (33,54) # a trema -0x24 (165,391) (33,54) # $ -#0x (198,391) (33,54) # £ -0x2A (231,391) (33,54) # * -#0x (264,391) (33,54) # µ -#0x (297,391) (33,54) # ù -0x25 (330,391) (33,54) # % -0x21 (363,391) (33,54) # ! -#0x (396,391) (33,54) # § -0x3A (429,391) (33,54) # : -0x2F (462,391) (33,54) # / -#;.,?<>²!+ -0x3B (0,453) (33,54) # ; -0x2E (33,453) (33,54) # . -0x2C (66,453) (33,54) # , -0x3F (99,453) (33,54) # ? -0x3C (132,453) (33,54) # < -0x3E (165,453) (33,54) # > -#0x (198,453) (33,54) # ² -#0x21 (231,453) (33,54) # ! ==> doublon ... -0x2B (264,453) (33,54) # + diff --git a/assets/ic_luncher_ewoltest.png b/assets/ic_luncher_ewoltest.png deleted file mode 100644 index 14b2a40f6357cd87e98cf1d65c3ee9490f8f7914..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6523 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Font/ebtfont/Monospace.bmp b/dataTest/Font/ebtfont/Monospace.bmp similarity index 100% rename from Font/ebtfont/Monospace.bmp rename to dataTest/Font/ebtfont/Monospace.bmp diff --git a/Font/ebtfont/Monospace.ebt b/dataTest/Font/ebtfont/Monospace.ebt similarity index 99% rename from Font/ebtfont/Monospace.ebt rename to dataTest/Font/ebtfont/Monospace.ebt index 574d98cc..249ba667 100644 --- a/Font/ebtfont/Monospace.ebt +++ b/dataTest/Font/ebtfont/Monospace.ebt @@ -1,6 +1,6 @@ name:Monospace source:Monospace.bmp -# comment line ... +#comment line ... # size 54 largeur 33 space between letter 12 # unknow UTF8 code of the letter and start coordonate and size ==> 0x54 (33,45) (33,54) 0x00 (99,453) (33,54) # Error : Unknow the UTF8 element ... diff --git a/Font/freefont/AUTHORS b/dataTest/Font/freefont/AUTHORS similarity index 100% rename from Font/freefont/AUTHORS rename to dataTest/Font/freefont/AUTHORS diff --git a/Font/freefont/COPYING b/dataTest/Font/freefont/COPYING similarity index 100% rename from Font/freefont/COPYING rename to dataTest/Font/freefont/COPYING diff --git a/Font/freefont/CREDITS b/dataTest/Font/freefont/CREDITS similarity index 100% rename from Font/freefont/CREDITS rename to dataTest/Font/freefont/CREDITS diff --git a/Font/freefont/ChangeLog b/dataTest/Font/freefont/ChangeLog similarity index 100% rename from Font/freefont/ChangeLog rename to dataTest/Font/freefont/ChangeLog diff --git a/Font/freefont/FreeMono.ttf b/dataTest/Font/freefont/FreeMono.ttf similarity index 100% rename from Font/freefont/FreeMono.ttf rename to dataTest/Font/freefont/FreeMono.ttf diff --git a/Font/freefont/FreeMonoBold.ttf b/dataTest/Font/freefont/FreeMonoBold.ttf similarity index 100% rename from Font/freefont/FreeMonoBold.ttf rename to dataTest/Font/freefont/FreeMonoBold.ttf diff --git a/Font/freefont/FreeMonoBoldOblique.ttf b/dataTest/Font/freefont/FreeMonoBoldOblique.ttf similarity index 100% rename from Font/freefont/FreeMonoBoldOblique.ttf rename to dataTest/Font/freefont/FreeMonoBoldOblique.ttf diff --git a/Font/freefont/FreeMonoOblique.ttf b/dataTest/Font/freefont/FreeMonoOblique.ttf similarity index 100% rename from Font/freefont/FreeMonoOblique.ttf rename to dataTest/Font/freefont/FreeMonoOblique.ttf diff --git a/Font/freefont/FreeSans.ttf b/dataTest/Font/freefont/FreeSans.ttf similarity index 100% rename from Font/freefont/FreeSans.ttf rename to dataTest/Font/freefont/FreeSans.ttf diff --git a/Font/freefont/FreeSansBold.ttf b/dataTest/Font/freefont/FreeSansBold.ttf similarity index 100% rename from Font/freefont/FreeSansBold.ttf rename to dataTest/Font/freefont/FreeSansBold.ttf diff --git a/Font/freefont/FreeSansBoldOblique.ttf b/dataTest/Font/freefont/FreeSansBoldOblique.ttf similarity index 100% rename from Font/freefont/FreeSansBoldOblique.ttf rename to dataTest/Font/freefont/FreeSansBoldOblique.ttf diff --git a/Font/freefont/FreeSansOblique.ttf b/dataTest/Font/freefont/FreeSansOblique.ttf similarity index 100% rename from Font/freefont/FreeSansOblique.ttf rename to dataTest/Font/freefont/FreeSansOblique.ttf diff --git a/Font/freefont/FreeSerif.ttf b/dataTest/Font/freefont/FreeSerif.ttf similarity index 100% rename from Font/freefont/FreeSerif.ttf rename to dataTest/Font/freefont/FreeSerif.ttf diff --git a/Font/freefont/FreeSerifBold.ttf b/dataTest/Font/freefont/FreeSerifBold.ttf similarity index 100% rename from Font/freefont/FreeSerifBold.ttf rename to dataTest/Font/freefont/FreeSerifBold.ttf diff --git a/Font/freefont/FreeSerifBoldItalic.ttf b/dataTest/Font/freefont/FreeSerifBoldItalic.ttf similarity index 100% rename from Font/freefont/FreeSerifBoldItalic.ttf rename to dataTest/Font/freefont/FreeSerifBoldItalic.ttf diff --git a/Font/freefont/FreeSerifItalic.ttf b/dataTest/Font/freefont/FreeSerifItalic.ttf similarity index 100% rename from Font/freefont/FreeSerifItalic.ttf rename to dataTest/Font/freefont/FreeSerifItalic.ttf diff --git a/Font/freefont/INSTALL b/dataTest/Font/freefont/INSTALL similarity index 100% rename from Font/freefont/INSTALL rename to dataTest/Font/freefont/INSTALL diff --git a/Font/freefont/README b/dataTest/Font/freefont/README similarity index 100% rename from Font/freefont/README rename to dataTest/Font/freefont/README diff --git a/Font/freefont/date_2010-09-19.txt b/dataTest/Font/freefont/date_2010-09-19.txt similarity index 100% rename from Font/freefont/date_2010-09-19.txt rename to dataTest/Font/freefont/date_2010-09-19.txt diff --git a/tools/fileToCpp.cpp b/tools/fileToCpp.cpp new file mode 100644 index 00000000..d1a65606 --- /dev/null +++ b/tools/fileToCpp.cpp @@ -0,0 +1,219 @@ +/** + ******************************************************************************* + * @file pngToCpp.cpp + * @brief convert a binary file into a C source vector + * @author Sandro Sigala + * @date 26/01/2011 + * @par Project + * --- + * + * @version $Id$ + * + * @par Copyright + * THE "BEER-WARE LICENSE" (Revision 3.1415): + * sandro AT sigala DOT it wrote this file. As long as you retain this notice you can do + * whatever you want with this stuff. If we meet some day, and you think this stuff is + * worth it, you can buy me a beer in return. Sandro Sigala + * + * @compilation g++ pngToCpp -o pngToCpp + * + ******************************************************************************* + */ + +#include +#include +#include +#include + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +bool zeroTerminated = false; + +int myfgetc(FILE *f) +{ + int c = fgetc(f); + if (c == EOF && zeroTerminated) + { + zeroTerminated = 0; + return 0; + } + return c; +} + +void generateHeader(FILE *file) +{ + fprintf(file, "/**\n"); + fprintf(file, " ******************************************************************************* \n"); + fprintf(file, " * \n"); + fprintf(file, " * @par Project\n"); + fprintf(file, " * Edn\n"); + fprintf(file, " * \n"); + fprintf(file, " * Automatic generated file for Edn Software\n"); + fprintf(file, " * Please do not save this file on File configuration server\n"); + fprintf(file, " * \n"); + fprintf(file, " * @par Copyright\n"); + fprintf(file, " * The copyright of the data depend on the source file but generated file is on GPL v3\n"); + fprintf(file, " * \n"); + fprintf(file, " * Copyright 2010 Edouard DUPIN, all right reserved\n"); + fprintf(file, " * \n"); + fprintf(file, " * This is free software; you can redistribute it and/or modify it under the\n"); + fprintf(file, " * terms of the GNU General Public License as published by the Free Software\n"); + fprintf(file, " * Foundation; either version 3 of the License, or (at your option) any later\n"); + fprintf(file, " * version.\n"); + fprintf(file, " * \n"); + fprintf(file, " * This software is distributed in the hope that it will be useful, but WITHOUT\n"); + fprintf(file, " * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n"); + fprintf(file, " * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n"); + fprintf(file, " * for more details.\n"); + fprintf(file, " * \n"); + fprintf(file, " ******************************************************************************* \n"); + fprintf(file, " */\n\n"); +} + +char endTable[256000] = ""; + +FILE *ofile=NULL; +FILE *ofileH=NULL; + +void process(const char *ifname) +{ + printf(" Import File : \"%s\"\n", ifname); + FILE *ifile=NULL; + ifile = fopen(ifname, "rb"); + if (ifile == NULL) + { + fprintf(stderr, "cannot open %s for reading\n", ifname); + exit(1); + } + char buf[PATH_MAX], *p; + const char *cp; + if ((cp = strrchr(ifname, '/')) != NULL) + { + ++cp; + } else { + if ((cp = strrchr(ifname, '\\')) != NULL) + ++cp; + else + cp = ifname; + } + strcpy(buf, cp); + for (p = buf; *p != '\0'; ++p) + { + if (!isalnum(*p)) + *p = '_'; + } + fprintf(ofile, "unsigned char %s[] = {", buf); + int n = 0; + unsigned char c = 0; + while(fread(&c, 1, 1, ifile) == 1) + { + if(n%100 == 0) { + fprintf(ofile, "\n\t\t"); + } + fprintf(ofile, "0x%02x,", c); + n++; + } + fprintf(ofile, "\n};\n"); + fprintf(ofile, "long int %s_size = sizeof(%s);\n", buf, buf); + + //fprintf(ofileH, "extern unsigned char %s[];\n", buf); + //fprintf(ofileH, "extern unsigned long int %s_size;\n", buf); + char tmpVar[4096]; + sprintf(tmpVar, " {\"%s\", %s_size , %s},\n", ifname, buf, buf); + strcat (endTable, tmpVar); + + fclose(ifile); +} + +void usage(void) +{ + fprintf(stderr, "usage: pngToCpp .xxx \n"); + exit(1); +} + +int main(int argc, char **argv) +{ + //zeroTerminated = true; + if (argc < 3) { + usage(); + } + // dynamic output name : + char tmpOutput[PATH_MAX*2] = ""; + strcpy(tmpOutput, argv[1]); + int32_t sizeName = strlen(tmpOutput); + if (6>=sizeName) { + usage(); + } + if (tmpOutput[sizeName-1] == '.') { + tmpOutput[sizeName-1] = '\0'; + } else if (tmpOutput[sizeName-2] == '.') { + tmpOutput[sizeName-2] = '\0'; + } else if (tmpOutput[sizeName-3] == '.') { + tmpOutput[sizeName-3] = '\0'; + } else if (tmpOutput[sizeName-4] == '.') { + tmpOutput[sizeName-4] = '\0'; + } else if (tmpOutput[sizeName-5] == '.') { + tmpOutput[sizeName-5] = '\0'; + } else if (tmpOutput[sizeName-6] == '.') { + tmpOutput[sizeName-6] = '\0'; + } + //fprintf(stderr, "writing to %s\n", tmpOutput); + + char tmpOutputCPP[PATH_MAX*2] = ""; + char tmpOutputH[PATH_MAX*2] = ""; + // Generate the output filename + sprintf(tmpOutputCPP,"%s.cpp", tmpOutput); + sprintf(tmpOutputH,"%s.h", tmpOutput); + // open destination name : + ofile = fopen(tmpOutputCPP, "wb"); + if (ofile == NULL) + { + fprintf(stderr, "cannot open %s for writing\n", tmpOutputCPP); + exit(1); + } + generateHeader(ofile); + ofileH = fopen(tmpOutputH, "wb"); + if (ofileH == NULL) + { + fprintf(stderr, "cannot open %s for writing\n", tmpOutputH); + exit(1); + } + generateHeader(ofileH); + fprintf(ofileH, "#ifndef __INPUT_PNG_FILE_GENERATED_H__\n"); + fprintf(ofileH, "#define __INPUT_PNG_FILE_GENERATED_H__\n\n"); + fprintf(ofileH, "extern \"C\" {\n"); + fprintf(ofileH, " typedef struct {\n"); + fprintf(ofileH, " char filename[1024];\n"); + fprintf(ofileH, " long int fileLenght;\n"); + fprintf(ofileH, " unsigned char * data;\n"); + fprintf(ofileH, " } internalData_ts;\n\n\n"); + + + // Generate the output + int32_t i; + for(i=2; i