├── .github └── FUNDING.yml ├── doc ├── input.jpg ├── addin_font.jpg ├── choose.font.jpg ├── addin_bitmap.jpg ├── generate_font.jpg ├── import_bitmap.jpg ├── generate_bitmap.jpg └── font-to-pixel.txt ├── GuiLiteToolkit ├── curl.exe ├── stdafx.h ├── resource.h ├── stdafx.cpp ├── targetver.h ├── GuiLiteToolkit.h ├── GuiLiteToolkit.cpp ├── GuiLiteToolkit.rc ├── GuiLiteToolkitDlg.h ├── GuiLiteToolkitDlg.cpp ├── res │ ├── GuiLiteToolkit.ico │ └── GuiLiteToolkit.rc2 ├── GuiLiteToolkit.vcxproj.user ├── BitmapDlg.h ├── FontDlg.h ├── GuiLiteToolkit.vcxproj.filters ├── BitmapDlg.cpp ├── FontDlg.cpp └── GuiLiteToolkit.vcxproj ├── .gitignore ├── GuiLiteToolkit.sln ├── README.md ├── sync_build.bat └── LICENSE /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: https://idea4good.github.io/ 2 | -------------------------------------------------------------------------------- /doc/input.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/doc/input.jpg -------------------------------------------------------------------------------- /doc/addin_font.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/doc/addin_font.jpg -------------------------------------------------------------------------------- /doc/choose.font.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/doc/choose.font.jpg -------------------------------------------------------------------------------- /doc/addin_bitmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/doc/addin_bitmap.jpg -------------------------------------------------------------------------------- /doc/generate_font.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/doc/generate_font.jpg -------------------------------------------------------------------------------- /doc/import_bitmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/doc/import_bitmap.jpg -------------------------------------------------------------------------------- /GuiLiteToolkit/curl.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/GuiLiteToolkit/curl.exe -------------------------------------------------------------------------------- /GuiLiteToolkit/stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/GuiLiteToolkit/stdafx.h -------------------------------------------------------------------------------- /doc/generate_bitmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/doc/generate_bitmap.jpg -------------------------------------------------------------------------------- /GuiLiteToolkit/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/GuiLiteToolkit/resource.h -------------------------------------------------------------------------------- /GuiLiteToolkit/stdafx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/GuiLiteToolkit/stdafx.cpp -------------------------------------------------------------------------------- /GuiLiteToolkit/targetver.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/GuiLiteToolkit/targetver.h -------------------------------------------------------------------------------- /GuiLiteToolkit/GuiLiteToolkit.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/GuiLiteToolkit/GuiLiteToolkit.h -------------------------------------------------------------------------------- /GuiLiteToolkit/GuiLiteToolkit.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/GuiLiteToolkit/GuiLiteToolkit.cpp -------------------------------------------------------------------------------- /GuiLiteToolkit/GuiLiteToolkit.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/GuiLiteToolkit/GuiLiteToolkit.rc -------------------------------------------------------------------------------- /GuiLiteToolkit/GuiLiteToolkitDlg.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/GuiLiteToolkit/GuiLiteToolkitDlg.h -------------------------------------------------------------------------------- /GuiLiteToolkit/GuiLiteToolkitDlg.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/GuiLiteToolkit/GuiLiteToolkitDlg.cpp -------------------------------------------------------------------------------- /GuiLiteToolkit/res/GuiLiteToolkit.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/GuiLiteToolkit/res/GuiLiteToolkit.ico -------------------------------------------------------------------------------- /GuiLiteToolkit/res/GuiLiteToolkit.rc2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idea4good/GuiLiteToolkit/HEAD/GuiLiteToolkit/res/GuiLiteToolkit.rc2 -------------------------------------------------------------------------------- /GuiLiteToolkit/GuiLiteToolkit.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | GuiLiteToolkit.rc 5 | 6 | -------------------------------------------------------------------------------- /doc/font-to-pixel.txt: -------------------------------------------------------------------------------- 1 | |Arial Font size | Pixel height | 2 | | --- | --- | 3 | | 3 | 10 | 4 | | 3B | 10 | 5 | | 4 | 14 | 6 | | 4B | 14 | 7 | | 5 | 16 | 8 | | 5B | 16 | 9 | | 6 | 18 | 10 | | 6B | 19 | 11 | | 7 | 22 | 12 | | 7B | 22 | 13 | | 8 | 24 | 14 | | 8B | 24 | 15 | | 9 | 27 | 16 | | 9B | 29 | 17 | | 10 | 32 | 18 | | 10B | 32 | 19 | | 14B | 44 | 20 | | 15B | 46 | 21 | | 16B | 51 | 22 | | 18B | 56 | 23 | | 20B | 62 | -------------------------------------------------------------------------------- /GuiLiteToolkit/BitmapDlg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | class BitmapDlg : 4 | public CDialog 5 | { 6 | public: 7 | afx_msg void OnBnClickedImport(); 8 | afx_msg void OnBnClickedGenerate(); 9 | DECLARE_MESSAGE_MAP() 10 | private: 11 | bool saveFile(char* pixel_data); 12 | CString m_fileName; 13 | CString m_filePath; 14 | BITMAPFILEHEADER m_bm_file_header; 15 | BITMAPINFOHEADER m_bm_info_header; 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | GuiLiteToolkit.exe 31 | *.out 32 | *.app 33 | 34 | # Visual studio 35 | Debug 36 | Release 37 | .vs 38 | /GuiLiteToolkit/GuiLiteToolkit.aps 39 | -------------------------------------------------------------------------------- /GuiLiteToolkit/FontDlg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class CFontLattice 9 | { 10 | public: 11 | CFontLattice(); 12 | ~CFontLattice(); 13 | 14 | unsigned int utf_8_code; 15 | unsigned char width; 16 | unsigned char* p_data; 17 | 18 | unsigned char* p_compressed_data; 19 | int p_compressed_data_length; 20 | }; 21 | 22 | class CFontDlg : public CDialog 23 | { 24 | public: 25 | virtual BOOL OnInitDialog(); 26 | afx_msg void OnBnClickedFont(); 27 | afx_msg void OnBnClickedGenerate(); 28 | DECLARE_MESSAGE_MAP() 29 | int GetCharInfo(CClientDC& dc, wchar_t character, LOGFONT& logFont); 30 | int GetStringInfo(wchar_t* str, LOGFONT& logFont); 31 | private: 32 | int WriteLatticeDataInCppFile(std::fstream& file); 33 | unsigned char* CompressFontLattice(unsigned char* p_data, int length, int& out_length); 34 | int GetCompressionRatio(); 35 | std::map mCurrentFontLatticeMap; 36 | std::string mCurrentFontName; 37 | int mCurrentFontHeight; 38 | wchar_t mInput[65536]; 39 | }; 40 | -------------------------------------------------------------------------------- /GuiLiteToolkit.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2000 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GuiLiteToolkit", "GuiLiteToolkit\GuiLiteToolkit.vcxproj", "{A2718D2D-82A1-4381-B336-B2642889F09D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {A2718D2D-82A1-4381-B336-B2642889F09D}.Debug|x64.ActiveCfg = Debug|x64 17 | {A2718D2D-82A1-4381-B336-B2642889F09D}.Debug|x64.Build.0 = Debug|x64 18 | {A2718D2D-82A1-4381-B336-B2642889F09D}.Debug|x86.ActiveCfg = Debug|Win32 19 | {A2718D2D-82A1-4381-B336-B2642889F09D}.Debug|x86.Build.0 = Debug|Win32 20 | {A2718D2D-82A1-4381-B336-B2642889F09D}.Release|x64.ActiveCfg = Release|x64 21 | {A2718D2D-82A1-4381-B336-B2642889F09D}.Release|x64.Build.0 = Release|x64 22 | {A2718D2D-82A1-4381-B336-B2642889F09D}.Release|x86.ActiveCfg = Release|Win32 23 | {A2718D2D-82A1-4381-B336-B2642889F09D}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {699F39B4-DB80-4E42-9491-438D90A33C7A} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GuiLite Toolkit - Build Font/Bitmap resource 2 | GuiLiteToolkit is 200 lines code for building font lattice & bitmap of [GuiLite](https://github.com/idea4good/GuiLite). 3 | 4 | ## How to build font lattice? 5 | Step 1: Input the charaters you need. 6 | 7 | ![input](doc/input.jpg) 8 | 9 | Step 2: Choose font type you want. 10 | 11 | ![choose.font](doc/choose.font.jpg) 12 | 13 | Step 3: Generate CPP files. 14 | 15 | ![generate](doc/generate_font.jpg) 16 | 17 | Step 4: Add CPP files to your APP project. 18 | 19 | ![addin](doc/addin_font.jpg) 20 | 21 | ## How to input charaters in your APP? 22 | It works with unicode(UTF-8), will help your APP support all languages and symbols all over the world. 23 | ### For Linux Gcc - input unicode charaters directly 24 | e.g: char* my_string = "abc你好" 25 | ### For Windows Visual studio 26 | - For ascii code: input directly. 27 | - For 2 bytes code or above, input charaters in code(e.g: char* my_string = "abc你好" => char* my_string = "abc **\xE4\xBD\xA0\xE5\xA5\xBD**") 28 | - How to get utf-8 code of chinese? Visit the websites below: 29 | - [Chinese website](http://www.mytju.com/classcode/tools/encode_utf8.asp) 30 | - [English website](https://www.browserling.com/tools/utf8-encode) 31 | 32 | ### Sample Code 33 | [Link to HelloFont](https://github.com/idea4good/GuiLiteSamples/blob/master/HelloFont/UIcode/UIcode.cpp) 34 | 35 | ## How to build bitmap? 36 | Step 1: Import 24 bits bitmap. 37 | 38 | ![import bitmap](doc/import_bitmap.jpg) 39 | 40 | Step 2: Generate CPP files. 41 | 42 | ![generate](doc/generate_bitmap.jpg) 43 | 44 | Step 3: Add CPP files to your APP project. 45 | 46 | ![addin](doc/addin_bitmap.jpg) 47 | 48 | ## Know issue 49 | 1. Letter lattice is all black. 50 | - Because of DC error, the letter could not be display correctly, so the lattice would be wrong. The workaround is running GuiLiteToolkit in Visual Studio debug mode. 51 | -------------------------------------------------------------------------------- /GuiLiteToolkit/GuiLiteToolkit.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | 58 | 59 | Resource Files 60 | 61 | 62 | 63 | 64 | Resource Files 65 | 66 | 67 | 68 | 69 | Resource Files 70 | 71 | 72 | -------------------------------------------------------------------------------- /sync_build.bat: -------------------------------------------------------------------------------- 1 | echo off 2 | setlocal 3 | 4 | set argC=0 5 | for %%x in (%*) do set /A argC+=1 6 | if NOT "1" == "%argC%" ( 7 | echo "Invalidate arguments" 8 | goto :eof 9 | ) 10 | 11 | set url="https://api.powerbi.com/beta/72f988bf-86f1-41af-91ab-2d7cd011db47/datasets/2ff1e8a8-2f6f-4d73-a75d-86829e3f4574/rows?key=8f5xLp1gP8%%2FzSee4vCUBcyjR65I9zZ6nb%%2B%%2F7bbzex%%2FSctLX3ntIlAR0sxWpDdguuYyDtLdHK%%2Fxbxj%%2FrSBkX7eQ%%3D%%3D" 12 | 13 | ::analyze date time 14 | for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do ( 15 | set %%x 16 | ) 17 | 18 | set Second=0%Second% 19 | set Second=%Second:~-2% 20 | set Minute=0%Minute% 21 | set Minute=%Minute:~-2% 22 | set Hour=0%Hour% 23 | set Hour=%Hour:~-2% 24 | set Day=0%Day% 25 | set Day=%Day:~-2% 26 | set Month=0%Month% 27 | set Month=%Month:~-2% 28 | set datetime=%Year%-%Month%-%Day%T%Hour%:%Minute%:%Second%.000+0000 29 | 30 | ::----------------- for GEO info ----------------- 31 | set tmpPath=%userprofile%\AppData\Local\Temp\ 32 | if not exist "%tmpPath%ip_info.tmp" ( 33 | curl.exe ipinfo.io > %tmpPath%ip_info.tmp 34 | ) 35 | 36 | if not exist "%tmpPath%ip_country.tmp" ( 37 | findstr.exe country %tmpPath%ip_info.tmp > %tmpPath%ip_country.tmp 38 | powershell -Command "(gc %tmpPath%ip_country.tmp) -replace '\"country\":', '' | Out-File -encoding ASCII %tmpPath%ip_country.tmp" 39 | powershell -Command "(gc %tmpPath%ip_country.tmp) -replace '""' , '' | Out-File -encoding ASCII %tmpPath%ip_country.tmp" 40 | powershell -Command "(gc %tmpPath%ip_country.tmp) -replace ',' , '' | Out-File -encoding ASCII %tmpPath%ip_country.tmp" 41 | ) 42 | 43 | if not exist "%tmpPath%ip_city.tmp" ( 44 | findstr.exe city %tmpPath%ip_info.tmp > %tmpPath%ip_city.tmp 45 | powershell -Command "(gc %tmpPath%ip_city.tmp) -replace '\"city\":', '' | Out-File -encoding ASCII %tmpPath%ip_city.tmp" 46 | powershell -Command "(gc %tmpPath%ip_city.tmp) -replace '""' , '' | Out-File -encoding ASCII %tmpPath%ip_city.tmp" 47 | powershell -Command "(gc %tmpPath%ip_city.tmp) -replace ',' , '' | Out-File -encoding ASCII %tmpPath%ip_city.tmp" 48 | ) 49 | 50 | if not exist "%tmpPath%ip_org.tmp" ( 51 | findstr.exe org %tmpPath%ip_info.tmp > %tmpPath%ip_org.tmp 52 | powershell -Command "(gc %tmpPath%ip_org.tmp) -replace '\"org\":', '' | Out-File -encoding ASCII %tmpPath%ip_org.tmp" 53 | powershell -Command "(gc %tmpPath%ip_org.tmp) -replace '""' , '' | Out-File -encoding ASCII %tmpPath%ip_org.tmp" 54 | powershell -Command "(gc %tmpPath%ip_org.tmp) -replace ',' , '' | Out-File -encoding ASCII %tmpPath%ip_org.tmp" 55 | ) 56 | 57 | set /p country=<%tmpPath%ip_country.tmp 58 | set /p city=<%tmpPath%ip_city.tmp 59 | set /p org=<%tmpPath%ip_org.tmp 60 | set raw_data=[{^ 61 | \"device_info\" :\"Win-%USERNAME%\",^ 62 | \"project_info\" :\"%1\",^ 63 | \"time\" :\"%datetime%\",^ 64 | \"weight\" : 1,^ 65 | \"country\" :\"%country%\",^ 66 | \"city\" :\"%city%\",^ 67 | \"org\" :\"%org%\",^ 68 | \"log\" :\"%datetime%\",^ 69 | \"version\" :\"v2.2\"^ 70 | }] 71 | 72 | curl.exe --include --request POST --header "Content-Type: application/json" --data-binary "%raw_data%" "%url%" 73 | 74 | exit /B 0 75 | -------------------------------------------------------------------------------- /GuiLiteToolkit/BitmapDlg.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "BitmapDlg.h" 3 | #include "resource.h" 4 | #include 5 | #include 6 | #include 7 | 8 | BEGIN_MESSAGE_MAP(BitmapDlg, CDialog) 9 | ON_BN_CLICKED(IDC_BUTTON1, &BitmapDlg::OnBnClickedGenerate) 10 | ON_BN_CLICKED(IDC_BUTTON2, &BitmapDlg::OnBnClickedImport) 11 | END_MESSAGE_MAP() 12 | 13 | void BitmapDlg::OnBnClickedImport() 14 | { 15 | CFileDialog fileDlg(TRUE); 16 | fileDlg.DoModal(); 17 | m_fileName = fileDlg.GetFileName(); 18 | m_filePath = fileDlg.GetPathName(); 19 | 20 | HBITMAP hb = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), m_filePath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 21 | if (NULL == hb) 22 | { 23 | MessageBox(L"24 bits bitmap file only", L"✖✖✖"); 24 | m_fileName.Empty(); 25 | m_filePath.Empty(); 26 | return; 27 | } 28 | 29 | CStatic* p_picture = (CStatic*)GetDlgItem(IDC_STATIC); 30 | p_picture->ModifyStyle(0xF, SS_BITMAP, SWP_NOSIZE); 31 | p_picture->SetBitmap(hb); 32 | } 33 | 34 | void BitmapDlg::OnBnClickedGenerate() 35 | { 36 | if (m_fileName.IsEmpty() || m_filePath.IsEmpty()) 37 | { 38 | return; 39 | } 40 | 41 | std::ifstream file(m_filePath, std::ios::in | std::ios::binary | std::ios::ate); 42 | if (!file.is_open()) 43 | { 44 | return; 45 | } 46 | 47 | file.seekg(0, std::ios::beg); 48 | file.read((char*)&m_bm_file_header, sizeof(m_bm_file_header)); 49 | file.read((char*)&m_bm_info_header, sizeof(m_bm_info_header)); 50 | 51 | char* pixel_data = new char[m_bm_info_header.biSizeImage]; 52 | file.read(pixel_data, m_bm_info_header.biSizeImage); 53 | if (saveFile(pixel_data)) 54 | { 55 | MessageBox(L"Generate bitmap cpp file success✌", L"\\^o^/"); 56 | } 57 | 58 | file.close(); 59 | delete[] pixel_data; 60 | } 61 | 62 | static char* include = "#include \"GuiLite.h\"\n\n"; 63 | bool BitmapDlg::saveFile(char* pixel_data) 64 | { 65 | int width = m_bm_info_header.biWidth; 66 | int height = m_bm_info_header.biHeight; 67 | int byteCount = m_bm_info_header.biBitCount / 8; 68 | if (byteCount != 3) 69 | { 70 | MessageBox(L"24 bits bitmap file only", L"✖✖✖"); 71 | return FALSE; 72 | } 73 | 74 | std::string strFileName = CT2A(m_fileName); 75 | std::replace(strFileName.begin(), strFileName.end(), '.', '_'); //replace '.' with '_' 76 | std::replace(strFileName.begin(), strFileName.end(), ' ', '_'); //replace ' ' with '_' 77 | std::fstream file(std::string("./") + strFileName + ".cpp", std::ios::trunc | std::ios::out | std::ios::binary); 78 | file.write(include, strlen(include)); 79 | 80 | std::string data_type = "static const unsigned short "; 81 | std::string data_name = "raw_data"; 82 | std::string define_bitmap_data = data_type + data_name + "[] = {\n"; 83 | 84 | unsigned int bytesPerLine = ((width * byteCount + 3) & (~3)); 85 | for (int y = (height - 1); y >= 0; y--) 86 | { 87 | define_bitmap_data += " "; 88 | char* data = pixel_data + (y * bytesPerLine); 89 | for (int x = 0; x < width; x++) 90 | { 91 | unsigned int rgb = *(unsigned int*)data; 92 | define_bitmap_data += std::to_string((((((unsigned int)(rgb)) & 0xFF) >> 3) | ((((unsigned int)(rgb)) & 0xFC00) >> 5) | ((((unsigned int)(rgb)) & 0xF80000) >> 8))); 93 | define_bitmap_data += ", "; 94 | data += byteCount; 95 | } 96 | define_bitmap_data += "\n"; 97 | } 98 | define_bitmap_data += "};\n"; 99 | file.write(define_bitmap_data.c_str(), define_bitmap_data.length()); 100 | 101 | data_type = "const BITMAP_INFO "; 102 | std::string define_font_info = "extern " + data_type + strFileName + ";\n"; 103 | define_font_info += data_type + strFileName + " ={\n"; 104 | define_font_info += " " + std::to_string(width) + ",\n"; 105 | define_font_info += " " + std::to_string(height) + ",\n"; 106 | define_font_info += " " + std::to_string(16) + ",\n"; 107 | define_font_info += " (unsigned short*)raw_data\n};\n"; 108 | file.write(define_font_info.c_str(), define_font_info.length()); 109 | 110 | file.close(); 111 | return TRUE; 112 | } 113 | -------------------------------------------------------------------------------- /GuiLiteToolkit/FontDlg.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "FontDlg.h" 3 | #include "resource.h" 4 | 5 | CFontLattice::CFontLattice() 6 | { 7 | utf_8_code = width = 0; 8 | p_data = 0; 9 | } 10 | 11 | CFontLattice::~CFontLattice() 12 | { 13 | if (p_data) 14 | { 15 | free(p_data); 16 | } 17 | if (p_compressed_data) 18 | { 19 | free(p_compressed_data); 20 | } 21 | } 22 | 23 | BEGIN_MESSAGE_MAP(CFontDlg, CDialog) 24 | ON_BN_CLICKED(IDC_BUTTON1, &CFontDlg::OnBnClickedFont) 25 | ON_BN_CLICKED(IDC_BUTTON2, &CFontDlg::OnBnClickedGenerate) 26 | END_MESSAGE_MAP() 27 | 28 | static wchar_t default_input[] = L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789(_+=./-\:;@%!#',?)<>▲▼"; 29 | BOOL CFontDlg::OnInitDialog() 30 | { 31 | CDialog::OnInitDialog(); 32 | CWnd* p_edit = GetDlgItem(IDC_EDIT1); 33 | p_edit->SetWindowTextW(default_input); 34 | return TRUE; 35 | } 36 | 37 | void CFontDlg::OnBnClickedFont() 38 | { 39 | // TODO: Add your control notification handler code here 40 | memset(mInput, 0, sizeof(mInput)); 41 | GetDlgItemText(IDC_EDIT1, mInput, sizeof(mInput) / sizeof(wchar_t)); 42 | if (0 == wcslen(mInput) || ((sizeof(mInput) / sizeof(wchar_t)) == wcslen(mInput))) 43 | { 44 | MessageBox(L"Input no character✍ or input too much⌛️", L"o(╯□╰)o"); 45 | return; 46 | } 47 | 48 | CWnd* generate_bt = GetDlgItem(IDC_BUTTON2); 49 | CWnd* font_bt = GetDlgItem(IDC_BUTTON1); 50 | generate_bt->EnableWindow(false); 51 | font_bt->EnableWindow(false); 52 | 53 | LOGFONT logFont; 54 | CFontDialog fdlg; 55 | if (IDOK == fdlg.DoModal()) 56 | { 57 | fdlg.GetCurrentFont(&logFont); 58 | if (0 != wcslen(logFont.lfFaceName)) 59 | { 60 | mCurrentFontLatticeMap.clear(); 61 | mCurrentFontName.clear(); 62 | mCurrentFontHeight = 0; 63 | GetStringInfo(mInput, logFont); 64 | } 65 | } 66 | generate_bt->EnableWindow(true); 67 | font_bt->EnableWindow(true); 68 | } 69 | 70 | int CFontDlg::GetStringInfo(wchar_t* str, LOGFONT& logFont) 71 | { 72 | CClientDC dc(this); 73 | int length = wcslen(str); 74 | for (int i = 0; i < length; i++) 75 | { 76 | GetCharInfo(dc, str[i], logFont); 77 | } 78 | return 0; 79 | } 80 | 81 | int CFontDlg::GetCharInfo(CClientDC& dc, wchar_t character, LOGFONT& logFont) 82 | { 83 | wchar_t characterBuffer[2] = { character, 0 }; 84 | CFont font; 85 | font.CreateFontIndirectW(&logFont); 86 | dc.SelectObject(&font); 87 | 88 | dc.FillRect(&CRect{ 0, 0, mCurrentFontHeight, mCurrentFontHeight }, &CBrush(RGB(255, 255, 255))); 89 | dc.TextOut(0, 0, characterBuffer, 1); 90 | 91 | SIZE size; 92 | GetTextExtentPoint(dc, characterBuffer, 1, &size); 93 | unsigned char* pixel_buffer = (unsigned char*)malloc(size.cx * size.cy); 94 | if (NULL == pixel_buffer) 95 | { 96 | return -1; 97 | } 98 | 99 | for (size_t y = 0; y < size.cy; y++) 100 | { 101 | for (size_t x = 0; x < size.cx; x++) 102 | { 103 | int value = 0xff - (GetPixel(dc, x, y) & 0xff); 104 | pixel_buffer[y * size.cx + x] = value; 105 | } 106 | } 107 | 108 | unsigned char utf8_buffer[32]; 109 | memset(utf8_buffer, 0, sizeof(utf8_buffer)); 110 | int len = WideCharToMultiByte(CP_UTF8, 0, characterBuffer, -1, (char*)utf8_buffer, sizeof(utf8_buffer), NULL, NULL); 111 | 112 | unsigned int utf8_code = 0; 113 | switch (len) 114 | { 115 | case 0: 116 | case 1: 117 | MessageBox(L"WideCharToMultiByte error!", L"✖✖✖"); 118 | return -1; 119 | case 2: 120 | utf8_code = utf8_buffer[0]; 121 | break; 122 | case 3: 123 | utf8_code = (utf8_buffer[0] << 8) | (utf8_buffer[1]); 124 | break; 125 | case 4: 126 | utf8_code = (utf8_buffer[0] << 16) | (utf8_buffer[1] << 8) | utf8_buffer[2]; 127 | break; 128 | case 5: 129 | utf8_code = (utf8_buffer[0] << 24) | (utf8_buffer[1] << 16) | (utf8_buffer[2] << 8) | utf8_buffer[3]; 130 | break; 131 | default: 132 | MessageBox(L"GuiLite could not support unicode over 4 bytes", L"✖✖✖"); 133 | return -1; 134 | } 135 | 136 | mCurrentFontLatticeMap[utf8_code].utf_8_code = utf8_code; 137 | mCurrentFontLatticeMap[utf8_code].width = size.cx; 138 | mCurrentFontLatticeMap[utf8_code].p_data = pixel_buffer; 139 | mCurrentFontLatticeMap[utf8_code].p_compressed_data = CompressFontLattice(pixel_buffer, size.cx * size.cy, mCurrentFontLatticeMap[utf8_code].p_compressed_data_length); 140 | 141 | char name[64]; 142 | sprintf_s(name, "%ws_%d", logFont.lfFaceName, size.cy); 143 | mCurrentFontName = name; 144 | mCurrentFontName += (logFont.lfWeight > 400) ? "B" : ""; 145 | 146 | std::replace(mCurrentFontName.begin(), mCurrentFontName.end(), '@', '_'); //replace '@' with '_' 147 | std::replace(mCurrentFontName.begin(), mCurrentFontName.end(), ' ', '_'); //replace ' ' with '_' 148 | 149 | mCurrentFontHeight = size.cy; 150 | TRACE(_T("font name = %s, utf8 = 0x%x, width = %d, height = %d\n"), logFont.lfFaceName, utf8_code, size.cx, size.cy); 151 | return 0; 152 | } 153 | 154 | static char* include = "#include \"GuiLite.h\"\n\n"; 155 | void CFontDlg::OnBnClickedGenerate() 156 | { 157 | // TODO: Add your control notification handler code here 158 | if (0 == mCurrentFontLatticeMap.size()) 159 | { 160 | return; 161 | } 162 | 163 | CWnd* generate_bt = GetDlgItem(IDC_BUTTON2); 164 | generate_bt->EnableWindow(false); 165 | 166 | char font_major_name[LF_FACESIZE]; 167 | memset(font_major_name, 0, sizeof(font_major_name)); 168 | 169 | std::fstream file(std::string("./") + mCurrentFontName + ".cpp", std::ios::trunc | std::ios::out | std::ios::binary); 170 | file.write(include, strlen(include)); 171 | WriteLatticeDataInCppFile(file); 172 | file.close(); 173 | 174 | generate_bt->EnableWindow(true); 175 | std::wstring result = L"Generate lattice cpp file success✌\n" + std::to_wstring(GetCompressionRatio()) + L"% of lattice size"; 176 | MessageBox(result.c_str(), L"\\^o^/"); 177 | } 178 | 179 | int CFontDlg::WriteLatticeDataInCppFile(std::fstream& file) 180 | { 181 | if (0 == mCurrentFontLatticeMap.size()) 182 | { 183 | return -1; 184 | } 185 | 186 | for (auto& elem : mCurrentFontLatticeMap) 187 | { 188 | std::string data_type = "static const unsigned char "; 189 | std::string data_name = "_" + (std::to_string(elem.second.utf_8_code)); 190 | 191 | std::string define_lattice_data = data_type + data_name + "[] = {\n"; 192 | for (int i = 0; i < elem.second.p_compressed_data_length; i++) 193 | { 194 | define_lattice_data += std::to_string(elem.second.p_compressed_data[i]); 195 | define_lattice_data += ", "; 196 | } 197 | define_lattice_data += "};\n"; 198 | file.write(define_lattice_data.c_str(), define_lattice_data.length()); 199 | } 200 | 201 | std::string define_lattice_array = "static LATTICE lattice_array[] = {\n"; 202 | for (auto& elem : mCurrentFontLatticeMap) 203 | { 204 | define_lattice_array += " {" + std::to_string(elem.second.utf_8_code) + ", " + 205 | std::to_string(elem.second.width) + ", " + 206 | "_" + (std::to_string(elem.second.utf_8_code)) + "},\n"; 207 | } 208 | define_lattice_array += "};\n"; 209 | file.write(define_lattice_array.c_str(), define_lattice_array.length()); 210 | 211 | std::string data_type = "const LATTICE_FONT_INFO "; 212 | std::string define_font_info = "extern " + data_type + mCurrentFontName + ";\n"; 213 | define_font_info += data_type + mCurrentFontName + " ={\n"; 214 | define_font_info += " " + std::to_string(mCurrentFontHeight) + ",\n"; 215 | define_font_info += " " + std::to_string(mCurrentFontLatticeMap.size()) + ",\n"; 216 | define_font_info += " lattice_array\n};\n"; 217 | 218 | file.write(define_font_info.c_str(), define_font_info.length()); 219 | return 0; 220 | } 221 | 222 | unsigned char* CFontDlg::CompressFontLattice(unsigned char* p_data, int length, int& out_length) 223 | { 224 | class CLatticeBlock 225 | { 226 | public: 227 | CLatticeBlock() 228 | { 229 | m_value = m_count = 0; 230 | } 231 | unsigned char m_value; 232 | unsigned char m_count; 233 | }; 234 | 235 | std::vector blocks; 236 | CLatticeBlock cur_blk; 237 | cur_blk.m_value = p_data[0]; 238 | for (int i = 0; i < length; i++) 239 | { 240 | if (cur_blk.m_value == p_data[i]) 241 | { 242 | cur_blk.m_count++; 243 | if (0xFF == cur_blk.m_count && ((i + 1) < length) && (cur_blk.m_value == p_data[i + 1])) 244 | {//avoiding cur_blk.m_count overflow, add new block 245 | blocks.push_back(cur_blk);//truncate current block 246 | cur_blk.m_count = 0;//new block 247 | } 248 | } 249 | else 250 | { 251 | blocks.push_back(cur_blk); 252 | cur_blk.m_value = p_data[i]; 253 | cur_blk.m_count = 1; 254 | } 255 | } 256 | if (cur_blk.m_count) 257 | { 258 | blocks.push_back(cur_blk); 259 | } 260 | 261 | out_length = blocks.size() * 2; 262 | unsigned char* ret = (unsigned char*)malloc(out_length); 263 | int index = 0; 264 | for (auto& elem : blocks) 265 | { 266 | ret[index++] = elem.m_value; 267 | ret[index++] = elem.m_count; 268 | } 269 | return ret; 270 | } 271 | 272 | int CFontDlg::GetCompressionRatio() 273 | { 274 | if (0 == mCurrentFontLatticeMap.size()) 275 | { 276 | return 0; 277 | } 278 | 279 | int raw_data_cnt = 0; 280 | int compressed_data_cnt = 0; 281 | for (auto& elem : mCurrentFontLatticeMap) 282 | { 283 | raw_data_cnt += elem.second.width * mCurrentFontHeight; 284 | compressed_data_cnt += elem.second.p_compressed_data_length; 285 | } 286 | TRACE(_T("raw_data_cnt = %d, compressed_data_cnt = %d\n"), raw_data_cnt, compressed_data_cnt); 287 | return (100 * compressed_data_cnt / raw_data_cnt); 288 | } -------------------------------------------------------------------------------- /GuiLiteToolkit/GuiLiteToolkit.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {A2718D2D-82A1-4381-B336-B2642889F09D} 24 | MFCProj 25 | GuiLiteToolkit 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | Dynamic 35 | 36 | 37 | Application 38 | false 39 | v142 40 | true 41 | Unicode 42 | Dynamic 43 | 44 | 45 | Application 46 | true 47 | v142 48 | Unicode 49 | Static 50 | 51 | 52 | Application 53 | false 54 | v142 55 | true 56 | Unicode 57 | Dynamic 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | true 79 | 80 | 81 | true 82 | 83 | 84 | false 85 | 86 | 87 | false 88 | 89 | 90 | 91 | Use 92 | Level3 93 | Disabled 94 | true 95 | WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) 96 | 97 | 98 | Windows 99 | Kernel32.lib 100 | 101 | 102 | false 103 | true 104 | _DEBUG;%(PreprocessorDefinitions) 105 | 106 | 107 | 0x0409 108 | _DEBUG;%(PreprocessorDefinitions) 109 | $(IntDir);%(AdditionalIncludeDirectories) 110 | 111 | 112 | call "$(SolutionDir)sync_build.bat" "GuiLiteToolkit" 113 | 114 | 115 | 116 | 117 | Use 118 | Level3 119 | Disabled 120 | true 121 | _WINDOWS;_DEBUG;%(PreprocessorDefinitions) 122 | 123 | 124 | Windows 125 | 126 | 127 | false 128 | true 129 | _DEBUG;%(PreprocessorDefinitions) 130 | 131 | 132 | 0x0409 133 | _DEBUG;%(PreprocessorDefinitions) 134 | $(IntDir);%(AdditionalIncludeDirectories) 135 | 136 | 137 | call "$(SolutionDir)sync_build.bat" "GuiLiteToolkit" 138 | 139 | 140 | 141 | 142 | Use 143 | Level3 144 | MaxSpeed 145 | true 146 | true 147 | true 148 | WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) 149 | 150 | 151 | Windows 152 | true 153 | true 154 | 155 | 156 | false 157 | true 158 | NDEBUG;%(PreprocessorDefinitions) 159 | 160 | 161 | 0x0409 162 | NDEBUG;%(PreprocessorDefinitions) 163 | $(IntDir);%(AdditionalIncludeDirectories) 164 | 165 | 166 | call "$(SolutionDir)sync_build.bat" "GuiLiteToolkit" 167 | 168 | 169 | 170 | 171 | Use 172 | Level3 173 | MaxSpeed 174 | true 175 | true 176 | true 177 | _WINDOWS;NDEBUG;%(PreprocessorDefinitions) 178 | 179 | 180 | Windows 181 | true 182 | true 183 | 184 | 185 | false 186 | true 187 | NDEBUG;%(PreprocessorDefinitions) 188 | 189 | 190 | 0x0409 191 | NDEBUG;%(PreprocessorDefinitions) 192 | $(IntDir);%(AdditionalIncludeDirectories) 193 | 194 | 195 | call "$(SolutionDir)sync_build.bat" "GuiLiteToolkit" 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | Create 214 | Create 215 | Create 216 | Create 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------