├── Screenshots
├── 01.png
├── 02.png
├── 01-thumb.png
└── 02-thumb.png
├── Docs
├── Example Fonts
│ ├── ionicons 20pt.zi
│ ├── ionicons 24pt.zi
│ ├── ionicons 32pt.zi
│ ├── ionicons 48pt.zi
│ ├── ionicons 64pt.zi
│ └── Readme.md
└── Nextion Font Format Specification ZI version 3.md
├── NextionHMITest
└── NextionHMITest.HMI
├── NextionFontEditor
├── NextionFontEditor
│ ├── ZiLib.dll
│ ├── icons8-text-box.ico
│ ├── Icons
│ │ ├── icons8-grid-16.png
│ │ ├── icons8-pen-16.png
│ │ ├── icons8-pen-30.png
│ │ ├── icons8-save-16.png
│ │ ├── icons8-erase-16.png
│ │ ├── icons8-search-16.png
│ │ ├── icons8-search-30.png
│ │ ├── icons8-text-box.ico
│ │ ├── icons8-sort-down-16.png
│ │ ├── icons8-sort-left-16.png
│ │ ├── icons8-sort-up-16.png
│ │ ├── icons8-text-box-16.png
│ │ ├── icons8-text-box-30.png
│ │ ├── icons8-text-box-40.png
│ │ ├── icons8-text-box-80.png
│ │ ├── icons8-edit-image-16.png
│ │ ├── icons8-edit-image-30.png
│ │ ├── icons8-sort-right-16.png
│ │ ├── icons8-increase-font-16.png
│ │ ├── icons8-increase-font-30.png
│ │ ├── icons8-opened-folder-16.png
│ │ ├── icons8-opened-folder-30.png
│ │ ├── icons8-preview-pane-16.png
│ │ ├── icons8_search_16_lF9_icon.ico
│ │ ├── icons8_edit_image_16_23V_icon.ico
│ │ ├── icons8_preview_pane_16_Vww_icon.ico
│ │ └── icons8_increase_font_16_mb5_icon.ico
│ ├── Test Files
│ │ ├── Arial_16_ascii.zi
│ │ ├── Arial_40_ascii.zi
│ │ ├── Arial_40_gb2312.zi
│ │ ├── Arial_16_ASCII_v5.zi
│ │ ├── Arial_32_ASCII_v5.zi
│ │ ├── Arial_16_ASCII_AA_v5.zi
│ │ ├── Arial_32_ASCII_AA_v5.zi
│ │ ├── Arial_32_iso-8859-1.zi
│ │ ├── Arial_40_iso-8859-1.zi
│ │ └── Code Page Test
│ │ │ ├── ascii.zi
│ │ │ ├── big5.zi
│ │ │ ├── gb2312.zi
│ │ │ ├── koi8-r.zi
│ │ │ ├── iso-8859-1.zi
│ │ │ ├── iso-8859-2.zi
│ │ │ ├── iso-8859-3.zi
│ │ │ ├── iso-8859-4.zi
│ │ │ ├── iso-8859-5.zi
│ │ │ ├── iso-8859-6.zi
│ │ │ ├── iso-8859-7.zi
│ │ │ ├── iso-8859-8.zi
│ │ │ ├── iso-8859-9.zi
│ │ │ ├── iso-8859-11.zi
│ │ │ ├── iso-8859-13.zi
│ │ │ ├── iso-8859-15.zi
│ │ │ ├── windows-1255.zi
│ │ │ ├── windows-1256.zi
│ │ │ ├── windows-1257.zi
│ │ │ ├── windows-1258.zi
│ │ │ ├── windows-874.zi
│ │ │ ├── ks_c_5601-1987.zi
│ │ │ └── iso-8859-11-duplicate.zi
│ ├── NextionFontEditor_TemporaryKey.pfx
│ ├── App.config
│ ├── Properties
│ │ ├── Settings.settings
│ │ ├── Settings.Designer.cs
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ └── Resources.resx
│ ├── Program.cs
│ ├── FormFontSuite.cs
│ ├── Controls
│ │ ├── FontListBox.cs
│ │ └── CharEditor.cs
│ ├── Extensions
│ │ └── FormExtensions.cs
│ ├── FormCharacterWidth.cs
│ ├── FormFontPreview.cs
│ ├── FormFontGenerator.cs
│ ├── FormAddCharacters.cs
│ ├── FormCharacterWidth.Designer.cs
│ ├── FormFontPreview.resx
│ ├── FormAddCharacters.resx
│ ├── FormFontGenerator.resx
│ └── FormFontSuite.Designer.cs
├── ZiLib
│ ├── FileVersion
│ │ ├── Common
│ │ │ ├── CodePageMode.cs
│ │ │ ├── FontOrientation.cs
│ │ │ ├── ZiFont.cs
│ │ │ ├── ZiCharacter.cs
│ │ │ ├── CodePageIdentifier.cs
│ │ │ ├── CodePages.cs
│ │ │ ├── ZiClipboard.cs
│ │ │ └── CodePage.cs
│ │ ├── V5
│ │ │ ├── CharMapEntry.cs
│ │ │ └── BinaryTools.cs
│ │ └── V3
│ │ │ ├── ZiFontV3.cs
│ │ │ └── ZiCharacterV3.cs
│ ├── Interfaces
│ │ ├── IZiFont.cs
│ │ └── IZiCharacter.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── ZiLib.csproj
│ ├── Extensions
│ │ └── BitmapExtensions.cs
│ └── BinaryTools.cs
└── NextionFontEditor.sln
├── .github
└── FUNDING.yml
├── test2.linq
├── test1.linq
├── .gitattributes
├── README.md
└── .gitignore
/Screenshots/01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/Screenshots/01.png
--------------------------------------------------------------------------------
/Screenshots/02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/Screenshots/02.png
--------------------------------------------------------------------------------
/Screenshots/01-thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/Screenshots/01-thumb.png
--------------------------------------------------------------------------------
/Screenshots/02-thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/Screenshots/02-thumb.png
--------------------------------------------------------------------------------
/Docs/Example Fonts/ionicons 20pt.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/Docs/Example Fonts/ionicons 20pt.zi
--------------------------------------------------------------------------------
/Docs/Example Fonts/ionicons 24pt.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/Docs/Example Fonts/ionicons 24pt.zi
--------------------------------------------------------------------------------
/Docs/Example Fonts/ionicons 32pt.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/Docs/Example Fonts/ionicons 32pt.zi
--------------------------------------------------------------------------------
/Docs/Example Fonts/ionicons 48pt.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/Docs/Example Fonts/ionicons 48pt.zi
--------------------------------------------------------------------------------
/Docs/Example Fonts/ionicons 64pt.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/Docs/Example Fonts/ionicons 64pt.zi
--------------------------------------------------------------------------------
/NextionHMITest/NextionHMITest.HMI:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionHMITest/NextionHMITest.HMI
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/ZiLib.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/ZiLib.dll
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/icons8-text-box.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/icons8-text-box.ico
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-grid-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-grid-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-pen-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-pen-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-pen-30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-pen-30.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-save-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-save-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-erase-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-erase-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-search-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-search-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-search-30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-search-30.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-text-box.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-text-box.ico
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-sort-down-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-sort-down-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-sort-left-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-sort-left-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-sort-up-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-sort-up-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-text-box-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-text-box-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-text-box-30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-text-box-30.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-text-box-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-text-box-40.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-text-box-80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-text-box-80.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Arial_16_ascii.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Arial_16_ascii.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Arial_40_ascii.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Arial_40_ascii.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Arial_40_gb2312.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Arial_40_gb2312.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-edit-image-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-edit-image-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-edit-image-30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-edit-image-30.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-sort-right-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-sort-right-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Arial_16_ASCII_v5.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Arial_16_ASCII_v5.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Arial_32_ASCII_v5.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Arial_32_ASCII_v5.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-increase-font-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-increase-font-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-increase-font-30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-increase-font-30.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-opened-folder-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-opened-folder-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-opened-folder-30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-opened-folder-30.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8-preview-pane-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8-preview-pane-16.png
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/NextionFontEditor_TemporaryKey.pfx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/NextionFontEditor_TemporaryKey.pfx
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Arial_16_ASCII_AA_v5.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Arial_16_ASCII_AA_v5.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Arial_32_ASCII_AA_v5.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Arial_32_ASCII_AA_v5.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Arial_32_iso-8859-1.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Arial_32_iso-8859-1.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Arial_40_iso-8859-1.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Arial_40_iso-8859-1.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/ascii.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/ascii.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/big5.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/big5.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8_search_16_lF9_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8_search_16_lF9_icon.ico
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/gb2312.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/gb2312.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/koi8-r.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/koi8-r.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8_edit_image_16_23V_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8_edit_image_16_23V_icon.ico
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-1.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-1.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-2.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-2.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-3.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-3.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-4.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-4.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-5.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-5.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-6.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-6.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-7.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-7.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-8.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-8.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-9.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-9.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8_preview_pane_16_Vww_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8_preview_pane_16_Vww_icon.ico
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-11.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-11.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-13.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-13.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-15.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-15.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/windows-1255.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/windows-1255.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/windows-1256.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/windows-1256.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/windows-1257.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/windows-1257.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/windows-1258.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/windows-1258.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/windows-874.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/windows-874.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Icons/icons8_increase_font_16_mb5_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Icons/icons8_increase_font_16_mb5_icon.ico
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/ks_c_5601-1987.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/ks_c_5601-1987.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-11-duplicate.zi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hagronnestad/nextion-font-editor/HEAD/NextionFontEditor/NextionFontEditor/Test Files/Code Page Test/iso-8859-11-duplicate.zi
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/FileVersion/Common/CodePageMode.cs:
--------------------------------------------------------------------------------
1 | namespace ZiLib
2 | {
3 | public enum CodePageMode : byte
4 | {
5 | SINGLE_BYTE_FULL_CHARSET = 0x00,
6 | DOUBLE_BYTE_FULL_CHARSET = 0x01,
7 | CHARACTER_SUBSET = 0x02
8 | }
9 | }
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/FileVersion/Common/FontOrientation.cs:
--------------------------------------------------------------------------------
1 | namespace ZiLib.FileVersion.Common
2 | {
3 |
4 | public enum FontOrientation : byte
5 | {
6 | Vertical = 0x0a,
7 | Horizontal = 0x0b,
8 | VerticalRotated = 0x0c,
9 | HorizontalRotated = 0x0d
10 | }
11 |
12 | }
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/FileVersion/V5/CharMapEntry.cs:
--------------------------------------------------------------------------------
1 | namespace ZiLib.FileVersion.V5 {
2 |
3 | public struct CharMapEntry {
4 | public ushort Code;
5 | public byte Width;
6 | public byte KerningLeft;
7 | public byte KerningRight;
8 | public uint DataAddressOffset; // Offset from start of entry
9 | public ushort Length;
10 |
11 | public int TotalWidth => Width + KerningLeft + KerningRight;
12 | }
13 |
14 | }
--------------------------------------------------------------------------------
/Docs/Example Fonts/Readme.md:
--------------------------------------------------------------------------------
1 | # Example Fonts
2 |
3 | This is a test of the ZI v5 font specification for TJC/Nextion HMI displays. Use these files at your own risk!
4 | The characterset starts with a space (`0x20`) as the first character and ends with character `0x02D7` using the GB2312 encoding.
5 |
6 | The files contain the [ionicons-designerpack](https://github.com/ionic-team/ionicons) in a ZI v5 format.
7 | The original icon files are created by [iconic-team](https://github.com/ionic-team) and licensed under the MIT license.
8 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [ hagronnestad ]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 | using ZiLib.FileVersion.V5;
4 |
5 | namespace NextionFontEditor {
6 |
7 | internal static class Program {
8 |
9 | ///
10 | /// The main entry point for the application.
11 | ///
12 | [STAThread]
13 | private static void Main() {
14 | //ZiFont f;
15 | //var f = ZiLib.FileVersion.Common.ZiFont.FromFile(@"Test Files\Arial_32_ASCII_AA_v5.zi");
16 |
17 | Application.EnableVisualStyles();
18 | Application.SetCompatibleTextRenderingDefault(false);
19 | Application.Run(new FormFontSuite());
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/Interfaces/IZiFont.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 | using ZiLib.FileVersion.Common;
4 |
5 | namespace ZiLib {
6 |
7 | public interface IZiFont {
8 | string Name { get; set; }
9 | CodePage CodePage { get; set; }
10 |
11 | byte Version { get; set; }
12 |
13 | byte CharacterWidth { get; set; }
14 | byte CharacterHeight { get; set; }
15 | int CharacterCount { get; }
16 |
17 | long FileSize { get; set; }
18 |
19 | //List CharBitmaps { get; set; }
20 | List Characters { get; set; }
21 | void Save(string fileName, CodePage codepage);
22 | //void AddCharacter(uint codepoint, byte[] bytes, byte width, byte kerningL = 0, byte kerningR = 0);
23 | void AddCharacter(uint codepoint, IZiCharacter character);
24 | void RemoveCharacter(int index);
25 | }
26 | }
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/FileVersion/Common/ZiFont.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using ZiLib.FileVersion.V3;
4 | using ZiLib.FileVersion.V5;
5 |
6 | namespace ZiLib.FileVersion.Common {
7 |
8 | public class ZiFont {
9 | private const long FILE_VERSION_OFFSET = 0x10;
10 |
11 | public static IZiFont FromFile(string fileName) {
12 | var version = 0;
13 |
14 | using (var fs = File.OpenRead(fileName)) {
15 | fs.Seek(FILE_VERSION_OFFSET, SeekOrigin.Begin);
16 | version = fs.ReadByte();
17 | fs.Close();
18 | }
19 |
20 | switch (version) {
21 | case 3:
22 | return ZiFontV3.FromFile(fileName);
23 |
24 | case 5:
25 | case 6:
26 | return ZiFontV5.FromFile(fileName);
27 | default:
28 | return null;
29 | }
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/Interfaces/IZiCharacter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 | using ZiLib.FileVersion.Common;
4 |
5 | namespace ZiLib {
6 |
7 | public interface IZiCharacter {
8 |
9 | uint CodePoint { get; set; }
10 |
11 | string Txt { get; set; }
12 |
13 | Font Font { get; set; }
14 |
15 | PointF TxtPosition { get; set; }
16 |
17 | byte KerningLeft { get; set; }
18 | byte KerningRight { get; set; }
19 |
20 | byte Width { get; set; }
21 |
22 | IZiFont Parent { get; set; }
23 |
24 | Bitmap ToBitmap();
25 |
26 | byte[] ToBytes();
27 |
28 | byte[] GetCharacterData();
29 |
30 | bool CanRevert();
31 |
32 | Bitmap RevertBitmap();
33 |
34 | void SetBitmap(Bitmap bmp);
35 |
36 | void SetPixel(int x, int y, Color pixel);
37 |
38 | void SetString(Font font, PointF location, string txt);
39 |
40 | string GetString();
41 | }
42 | }
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace NextionFontEditor.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/FormFontSuite.cs:
--------------------------------------------------------------------------------
1 | using NextionFontEditor.Extensions;
2 | using System;
3 | using System.Windows.Forms;
4 |
5 | namespace NextionFontEditor {
6 |
7 | public partial class FormFontSuite : Form {
8 |
9 | public FormFontSuite() {
10 | InitializeComponent();
11 | }
12 |
13 | private void mnuFileExit_Click(object sender, EventArgs e) {
14 | Close();
15 | }
16 |
17 | private void btnNewFontGenerator_Click(object sender, EventArgs e) {
18 | var form = new FormFontGenerator {
19 | MdiParent = this,
20 | //WindowState = FormWindowState.Maximized
21 | };
22 | form.Show();
23 | }
24 |
25 | private void btnNewFontEditor_Click(object sender, EventArgs e) {
26 | var form = new FormFontEditor {
27 | MdiParent = this,
28 | //WindowState = FormWindowState.Maximized
29 | };
30 | form.Show();
31 | }
32 |
33 | private void btnNewFontPreview_Click(object sender, EventArgs e) {
34 | var form = new FormFontPreview {
35 | MdiParent = this,
36 | //WindowState = FormWindowState.Maximized
37 | };
38 | form.Show();
39 | }
40 |
41 | private void FormFontSuite_Load(object sender, EventArgs e) {
42 | this.SetBevel(false);
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("ZiLib")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("ZiLib")]
13 | [assembly: AssemblyCopyright("Copyright © 2018")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("656212b8-63ab-4c9d-a654-59f54ab10ea5")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/test2.linq:
--------------------------------------------------------------------------------
1 |
2 | <RuntimeDirectory>\System.Windows.Forms.dll
3 | <RuntimeDirectory>\System.Security.dll
4 | <RuntimeDirectory>\System.Configuration.dll
5 | <RuntimeDirectory>\Accessibility.dll
6 | <RuntimeDirectory>\System.Deployment.dll
7 | <RuntimeDirectory>\System.Runtime.Serialization.Formatters.Soap.dll
8 | System.Windows.Forms
9 | System.Drawing
10 |
11 |
12 | var f = new Form();
13 | f.Width = 500;
14 | f.Show();
15 |
16 | var p1 = new PictureBox()
17 | {
18 | Location = new Point(10, 10),
19 | //BackColor = Color.Red,
20 | Size = new Size(200, 200),
21 | //SizeMode = PictureBoxSizeMode.StretchImage
22 | };
23 | f.Controls.Add(p1);
24 |
25 | var c = "w";
26 |
27 | var font1 = new Font("Arial Black", 48, GraphicsUnit.Pixel);
28 | var b1 = new Bitmap(200, 200);
29 | var p1g = Graphics.FromImage(b1);
30 |
31 | var size = p1g.MeasureString(c, font1, default(PointF), StringFormat.GenericTypographic);
32 | //var size = TextRenderer.MeasureText(c, font1, new Size(1, 1), TextFormatFlags.Default);
33 |
34 | p1g.DrawRectangle(new Pen(Color.DarkRed), new Rectangle(0, 0, (int)size.Width + 2, (int)size.Height + 2));
35 |
36 | p1g.DrawString(
37 | c,
38 | font1,
39 | new SolidBrush(Color.Black), 1, 1, StringFormat.GenericTypographic);
40 |
41 | f.Text = size.ToString();
42 |
43 | p1.Image = b1;
44 |
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("Nextion Font Suite")]
8 | [assembly: AssemblyDescription("A collection of tools to view, edit and generate Nextion .zi fonts.")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("https://github.com/hagronnestad")]
11 | [assembly: AssemblyProduct("Nextion Font Suite")]
12 | [assembly: AssemblyCopyright("Copyright © 2019")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("ddc95925-4b4a-4fd4-9a57-d1b5b206d8d9")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.1.0.0")]
35 | [assembly: AssemblyFileVersion("1.1.0.0")]
36 |
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28010.2041
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NextionFontEditor", "NextionFontEditor\NextionFontEditor.csproj", "{DDC95925-4B4A-4FD4-9A57-D1B5B206D8D9}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZiLib", "ZiLib\ZiLib.csproj", "{656212B8-63AB-4C9D-A654-59F54AB10EA5}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {DDC95925-4B4A-4FD4-9A57-D1B5B206D8D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {DDC95925-4B4A-4FD4-9A57-D1B5B206D8D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {DDC95925-4B4A-4FD4-9A57-D1B5B206D8D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {DDC95925-4B4A-4FD4-9A57-D1B5B206D8D9}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {656212B8-63AB-4C9D-A654-59F54AB10EA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {656212B8-63AB-4C9D-A654-59F54AB10EA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {656212B8-63AB-4C9D-A654-59F54AB10EA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {656212B8-63AB-4C9D-A654-59F54AB10EA5}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {C93CFD0E-325B-47FD-B72A-E50C55BB4EEC}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/FileVersion/Common/ZiCharacter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using ZiLib.FileVersion.V3;
4 | using ZiLib.FileVersion.V5;
5 |
6 | namespace ZiLib.FileVersion.Common {
7 |
8 | public class ZiCharacter {
9 | public static IZiCharacter FromBitmap(IZiFont parent, uint codepoint, Bitmap bmp, byte kerningL, byte kerningR) {
10 | switch (parent.Version) {
11 | case 3:
12 | return new ZiCharacterV3(parent, codepoint, bmp, kerningL, kerningR);
13 | case 5:
14 | return new ZiCharacterV5(parent, codepoint, bmp, kerningL, kerningR);
15 | default:
16 | return null;
17 | }
18 | }
19 |
20 | public static IZiCharacter FromBytes(IZiFont parent, uint codepoint, byte[] bytes, byte width, byte kerningL, byte kerningR) {
21 | switch (parent.Version) {
22 | case 3:
23 | return new ZiCharacterV3(parent, codepoint, bytes, width, kerningL, kerningR);
24 | case 5:
25 | return new ZiCharacterV5(parent, codepoint, bytes, width, kerningL, kerningR);
26 | default:
27 | return null;
28 | }
29 | }
30 |
31 | public static IZiCharacter FromString(IZiFont parent, uint codepoint, Font font, PointF location, String txt) {
32 | switch (parent.Version) {
33 | case 3:
34 | return new ZiCharacterV3(parent, codepoint, font, location, txt);
35 | case 5:
36 | return new ZiCharacterV5(parent, codepoint, font, location, txt);
37 | default:
38 | return null;
39 | }
40 | }
41 |
42 | }
43 | }
--------------------------------------------------------------------------------
/test1.linq:
--------------------------------------------------------------------------------
1 |
2 | <RuntimeDirectory>\System.Configuration.dll
3 | <RuntimeDirectory>\System.Design.dll
4 | <RuntimeDirectory>\System.Drawing.Design.dll
5 | <RuntimeDirectory>\System.Web.dll
6 | <RuntimeDirectory>\System.Web.Mobile.dll
7 | <RuntimeDirectory>\System.Web.RegularExpressions.dll
8 | <RuntimeDirectory>\System.Windows.Forms.dll
9 | System.Windows.Forms
10 | System.Drawing
11 | System.Drawing.Text
12 |
13 |
14 | var f = new Form();
15 | f.Show();
16 |
17 | var p1 = new PictureBox()
18 | {
19 | Location = new Point(0, 0),
20 | BackColor = Color.Red
21 | };
22 | f.Controls.Add(p1);
23 |
24 | var p2 = new PictureBox()
25 | {
26 | Location = new Point(0, 100),
27 | BackColor = Color.Red
28 | };
29 | f.Controls.Add(p2);
30 |
31 | var font1 = new Font("Arial", 24, GraphicsUnit.Pixel);
32 | var b1 = new Bitmap(24, 24);
33 | var p1g = Graphics.FromImage(b1);
34 | p1g.DrawString(
35 | "a",
36 | font1,
37 | new SolidBrush(Color.Black), 0, 0);
38 | p1.Image = b1;
39 |
40 | var font2 = new Font("Arial", 96, GraphicsUnit.Pixel);
41 | var b2 = new Bitmap(96, 96);
42 |
43 | var p2g = Graphics.FromImage(b2);
44 | p2g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None;
45 | p2g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
46 |
47 | p2g.DrawString(
48 | "a",
49 | font2,
50 | new SolidBrush(Color.Black), 0, 0);
51 |
52 |
53 |
54 | var b3 = new Bitmap(24, 24);
55 | var p3g = Graphics.FromImage(b3);
56 | p3g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
57 | p3g.DrawImage(b2, 0, 0, 24, 24);
58 |
59 | p2.Image = b3;
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Controls/FontListBox.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Drawing.Text;
4 | using System.Linq;
5 | using System.Windows.Forms;
6 |
7 | namespace NextionFontEditor.Controls {
8 | public class FontListBox : ListBox {
9 | private int _padding = 3;
10 |
11 | private int _fontPreviewSize = 20;
12 | public int FontPreviewSize {
13 | get => _fontPreviewSize;
14 | set {
15 | _fontPreviewSize = value;
16 | Invalidate();
17 | Update();
18 | }
19 | }
20 |
21 |
22 | public FontListBox() {
23 | DrawMode = DrawMode.OwnerDrawVariable;
24 | LoadFontList();
25 | }
26 |
27 | private void LoadFontList() {
28 | using (InstalledFontCollection col = new InstalledFontCollection()) {
29 | Items.AddRange(col.Families
30 | .OrderBy(x => x.Name)
31 | .Select(x => string.IsNullOrWhiteSpace(x.Name) ? "[No name]" : x.Name)
32 | .ToArray()
33 | );
34 | }
35 | }
36 |
37 |
38 | protected override void OnMeasureItem(MeasureItemEventArgs e) {
39 | var fontName = Items[e.Index].ToString();
40 | var font = new Font(fontName, _fontPreviewSize, GraphicsUnit.Pixel);
41 | var size = e.Graphics.MeasureString(fontName, font);
42 |
43 | e.ItemWidth = (int)Math.Ceiling(size.Width);
44 | e.ItemHeight = (int)Math.Ceiling(size.Height) + _padding * 2;
45 | }
46 |
47 | protected override void OnDrawItem(DrawItemEventArgs e) {
48 | e.DrawBackground();
49 |
50 | var fontName = Items[e.Index].ToString();
51 | var font = new Font(fontName, _fontPreviewSize, GraphicsUnit.Pixel);
52 |
53 | if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
54 | e.Graphics.DrawString(fontName, font, SystemBrushes.HighlightText, e.Bounds.Left, e.Bounds.Top + _padding);
55 | } else {
56 | using (SolidBrush br = new SolidBrush(e.ForeColor)) {
57 | e.Graphics.DrawString(fontName, font, br, e.Bounds.Left, e.Bounds.Top + _padding);
58 | }
59 | }
60 |
61 | e.DrawFocusRectangle();
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Extensions/FormExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Windows.Forms;
4 |
5 | namespace NextionFontEditor.Extensions {
6 |
7 | public static class FormExtensions {
8 |
9 | [DllImport("user32.dll")]
10 | private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
11 |
12 | [DllImport("user32.dll")]
13 | private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
14 |
15 | [DllImport("user32.dll", ExactSpelling = true)]
16 | private static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
17 |
18 | private const int GWL_EXSTYLE = -20;
19 | private const int WS_EX_CLIENTEDGE = 0x200;
20 | private const uint SWP_NOSIZE = 0x0001;
21 | private const uint SWP_NOMOVE = 0x0002;
22 | private const uint SWP_NOZORDER = 0x0004;
23 | private const uint SWP_NOREDRAW = 0x0008;
24 | private const uint SWP_NOACTIVATE = 0x0010;
25 | private const uint SWP_FRAMECHANGED = 0x0020;
26 | private const uint SWP_SHOWWINDOW = 0x0040;
27 | private const uint SWP_HIDEWINDOW = 0x0080;
28 | private const uint SWP_NOCOPYBITS = 0x0100;
29 | private const uint SWP_NOOWNERZORDER = 0x0200;
30 | private const uint SWP_NOSENDCHANGING = 0x0400;
31 |
32 | public static bool SetBevel(this Form form, bool show) {
33 | foreach (Control c in form.Controls) {
34 | MdiClient client = c as MdiClient;
35 | if (client != null) {
36 | int windowLong = GetWindowLong(c.Handle, GWL_EXSTYLE);
37 |
38 | if (show) {
39 | windowLong |= WS_EX_CLIENTEDGE;
40 | } else {
41 | windowLong &= ~WS_EX_CLIENTEDGE;
42 | }
43 |
44 | SetWindowLong(c.Handle, GWL_EXSTYLE, windowLong);
45 |
46 | // Update the non-client area.
47 | SetWindowPos(client.Handle, IntPtr.Zero, 0, 0, 0, 0,
48 | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
49 | SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
50 |
51 | return true;
52 | }
53 | }
54 | return false;
55 | }
56 |
57 | }
58 | }
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/FormCharacterWidth.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | namespace NextionFontEditor {
12 | public partial class FormCharacterWidth : Form {
13 | public FormCharacterWidth() {
14 | InitializeComponent();
15 | }
16 |
17 | private void btnCancel_Click(object sender, EventArgs e) {
18 | this.DialogResult = DialogResult.Cancel;
19 | this.Close();
20 | }
21 |
22 | private void btnOK_Click(object sender, EventArgs e) {
23 | this.DialogResult = DialogResult.OK;
24 | this.Close();
25 | }
26 |
27 | private void txtWidth_TextChanged(object sender, EventArgs e) {
28 |
29 | }
30 |
31 | private void numWidth_ValueChanged(object sender, EventArgs e) {
32 | numKerningL.Maximum = numWidth.Value - numKerningR.Value - 1;
33 | if (numKerningL.Value > (numWidth.Value - numKerningR.Value - 1))
34 | numKerningL.Value = numWidth.Value - numKerningR.Value - 1;
35 |
36 | numKerningR.Maximum = numWidth.Value - numKerningL.Value - 1;
37 | if (numKerningR.Value > (numWidth.Value - numKerningL.Value - 1))
38 | numKerningR.Value = numWidth.Value - numKerningL.Value - 1;
39 | }
40 |
41 | private void numKerningL_ValueChanged(object sender, EventArgs e) {
42 | numWidth.Minimum = numKerningL.Value + numKerningR.Value + 1;
43 | numKerningR.Maximum = numWidth.Value - numKerningL.Value - 1;
44 | if (numWidth.Value < (numKerningL.Value + numKerningR.Value + 1))
45 | numWidth.Value = numKerningL.Value + numKerningR.Value + 1;
46 | }
47 |
48 | private void numKerningR_ValueChanged(object sender, EventArgs e) {
49 | numWidth.Minimum = numKerningL.Value + numKerningR.Value + 1;
50 | numKerningL.Maximum = numWidth.Value - numKerningR.Value - 1;
51 | if (numWidth.Value < (numKerningL.Value + numKerningR.Value + 1))
52 | numWidth.Value = numKerningL.Value + numKerningR.Value + 1;
53 | }
54 |
55 | private void lblKerningL_Click(object sender, EventArgs e) {
56 |
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/FileVersion/Common/CodePageIdentifier.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using System.ComponentModel;
5 |
6 | namespace ZiLib
7 | {
8 |
9 | public enum CodePageIdentifier : byte
10 | {
11 | [Description("ascii")]
12 | ASCII = 0x01,
13 | [Description("gb2312")]
14 | GB2312 = 0x02,
15 | [Description("iso-8859-1")]
16 | ISO_8859_1 = 0x03,
17 | [Description("iso-8859-2")]
18 | ISO_8859_2 = 0x04,
19 | [Description("iso-8859-3")]
20 | ISO_8859_3 = 0x05,
21 | [Description("iso-8859-4")]
22 | ISO_8859_4 = 0x06,
23 | [Description("iso-8859-5")]
24 | ISO_8859_5 = 0x07,
25 | [Description("iso-8859-6")]
26 | ISO_8859_6 = 0x08,
27 | [Description("iso-8859-7")]
28 | ISO_8859_7 = 0x09,
29 | [Description("iso-8859-8")]
30 | ISO_8859_8 = 0x0A,
31 | [Description("iso-8859-9")]
32 | ISO_8859_9 = 0x0B,
33 | [Description("iso-8859-13")]
34 | ISO_8859_13 = 0x0C,
35 | [Description("iso-8859-15")]
36 | ISO_8859_15 = 0x0D,
37 | [Description("iso-8859-11")]
38 | ISO_8859_11 = 0x0E,
39 | [Description("ks_c_5601-1987")]
40 | KS_C_5601_1987 = 0x0F,
41 | [Description("big5")]
42 | BIG5 = 0x10,
43 | [Description("windows-1255")]
44 | WINDOWS_1255 = 0x11,
45 | [Description("windows-1256")]
46 | WINDOWS_1256 = 0x12,
47 | [Description("windows-1257")]
48 | WINDOWS_1257 = 0x13,
49 | [Description("windows-1258")]
50 | WINDOWS_1258 = 0x14,
51 | [Description("windows-874")]
52 | WINDOWS_874 = 0x15,
53 | [Description("koi8-r")]
54 | KOI8_R = 0x16,
55 | [Description("shift-jis")]
56 | SHIFT_JIS = 0x17,
57 | [Description("utf-8")]
58 | UTF_8 = 0x18
59 | }
60 |
61 | }
62 |
63 | public static class Extensions
64 | {
65 | public static string GetDescription(this Enum e)
66 | {
67 | var attribute =
68 | e.GetType()
69 | .GetTypeInfo()
70 | .GetMember(e.ToString())
71 | .FirstOrDefault(member => member.MemberType == MemberTypes.Field)
72 | .GetCustomAttributes(typeof(DescriptionAttribute), false)
73 | .SingleOrDefault()
74 | as DescriptionAttribute;
75 |
76 | return attribute?.Description ?? e.ToString();
77 | }
78 | }
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Nextion Font Suite
2 |
3 | A collection of tools to work with Nextion Fonts.
4 |
5 | ### Builds
6 | | Branch | Status |
7 | |--------|--------|
8 | | master | [](https://ci.appveyor.com/project/hagronnestad/nextion-font-editor) |
9 |
10 | ### Binaries
11 | | Version | Link |
12 | |---------|------|
13 | | Stable | https://github.com/hagronnestad/nextion-font-editor/releases |
14 | | Latest | https://ci.appveyor.com/project/hagronnestad/nextion-font-editor/build/artifacts |
15 |
16 | ### Contributors
17 | | User | Feature | Pull request |
18 | |--------|--------|--------|
19 | | [@jyberg](https://github.com/jyberg) | Font generator | [#2](https://github.com/hagronnestad/nextion-font-editor/pull/2) |
20 | | [@fvanroie](https://github.com/fvanroie) | .ZI v5/v6 support | [#7](https://github.com/hagronnestad/nextion-font-editor/pull/7) |
21 |
22 | ## Roadmap
23 |
24 | #### Prioritized tasks
25 | - [x] Reverse engineering of the new Nextion font format (v5/v6)
26 | - [x] Support for anti-aliased and variable width fonts (v5/v6)
27 |
28 | #### Less prioritized tasks
29 | - [x] Reverse engineering of the Nextion font format version 3 for Nextion Editor V0.53
30 | - [x] Font Viewer
31 | - [x] Font Editor
32 | - [x] Font generator
33 | - [x] Support for most code pages supported by Nextion Editor
34 | - [x] ASCII
35 | - [x] ISO-8859-1
36 | - [x] Others
37 |
38 | > Sample screenshot of the "Font Editor"-tool previewing the `$` character from the `Arial_40_ascii.zi` file.
39 |
40 | 
41 |
42 | > Sample screenshot of the "Font Preview"-tool previewing the `Arial_40_ascii.zi` file.
43 |
44 | 
45 |
46 | ## Nextion .ZI Font Format Specification
47 |
48 | ### ZI version 3 specification
49 |
50 | A mostly complete reverse engineered specification of the Nextion font format (ZI version 3), can be found here:
51 |
52 | [ZI version 3 specification](Docs/Nextion%20Font%20Format%20Specification%20ZI%20version%203.md)
53 |
54 | ### ZI version 5 specification
55 |
56 | I recently started reverse engineering the new ZI file format version 5 used in TJCs USART HMI editor version `0.55`. ZI version 5 supports variable width fonts and antialiasing. This specification is very much a work in progress. Feel free to contribute.
57 |
58 | [ZI version 5 specification (❗ Work in progress ❗)](Docs/Nextion%20Font%20Format%20Specification%20ZI%20version%205.md)
59 |
60 | ### TJCs USART HMI English Patch
61 | If you want to try the new font features and have a TJC panel, you can use this patch to run USART HMI in english.
62 |
63 | [TJCs USART HMI English Patch](https://github.com/hagronnestad/tjc-usart-hmi-english-patch)
64 |
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace NextionFontEditor.Properties
12 | {
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources
26 | {
27 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// Returns the cached ResourceManager instance used by this class.
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NextionFontEditor.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// Overrides the current thread's CurrentUICulture property for all
56 | /// resource lookups using this strongly typed resource class.
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/ZiLib.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {656212B8-63AB-4C9D-A654-59F54AB10EA5}
8 | Library
9 | Properties
10 | ZiLib
11 | ZiLib
12 | v4.6.1
13 | 512
14 | true
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/FileVersion/Common/CodePages.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Text;
4 |
5 | namespace ZiLib.FileVersion.Common {
6 | ///*
7 | //public class CodePages {
8 |
9 | // public static CodePage CreateAscii() {
10 | // var start = 32;
11 | // var count = 95;
12 | // var bytes = Enumerable.Range(start, count).Select(x => (byte) x).ToArray();
13 | // var characters = Encoding.ASCII.GetChars(bytes);
14 |
15 | // return new CodePage(CodePageIdentifier.ASCII);
16 |
17 | // /*
18 | // return new CodePage {
19 | // CodePageIdentifier = CodePageIdentifier.ASCII,
20 | // FirstByteStart = (byte)start,
21 | // FirstByteEnd = (byte)(start + count),
22 | // CharacterCount = count,
23 | // Characters = characters
24 | // };
25 | // */
26 | // }
27 |
28 | // public static CodePage CreateIso_8859_1() {
29 | // var start = 32;
30 | // var count = 224;
31 | // var bytes = Enumerable.Range(start, count).Select(x => (byte) x).ToArray();
32 | // var encoding = Encoding.GetEncoding("ISO-8859-1");
33 | // var characters = encoding.GetChars(bytes);
34 |
35 | // return new CodePage(CodePageIdentifier.ISO_8859_1);
36 |
37 | // /*
38 | // return new CodePage {
39 | // CodePageIdentifier = CodePageIdentifier.ISO_8859_1,
40 | // FirstByteStart = (byte)start,
41 | // FirstByteEnd = (byte)(start + count),
42 | // CharacterCount = count,
43 | // Characters = characters
44 | // };
45 | // */
46 | // }
47 |
48 | // // This one is not working correctly, characters doesn't match the Font Generator in Nextion Editor
49 | // public static CodePage CreateBig5() {
50 | // var firstByteStart = (byte)0xA0;
51 | // var firstByteEnd = (byte)0xF9;
52 | // var secondByteStart = (byte)0x40;
53 | // var secondByteEnd = (byte)0xFE;
54 |
55 | // var bytes = new List();
56 |
57 | // for (int i = firstByteStart; i <= firstByteEnd; i++) {
58 | // for (int j = secondByteStart; j <= secondByteEnd; j++) {
59 | // bytes.Add((byte) i);
60 | // bytes.Add((byte) j);
61 | // }
62 | // }
63 |
64 | // var encoding = Encoding.GetEncoding("big5");
65 | // var characters = encoding.GetChars(bytes.ToArray());
66 |
67 | // return new CodePage(CodePageIdentifier.BIG5);
68 |
69 | // /*
70 | // return new CodePage {
71 | // CodePageIdentifier = CodePageIdentifier.BIG5,
72 | // FirstByteStart = firstByteStart,
73 | // FirstByteEnd = firstByteEnd,
74 | // SecondByteStart = secondByteStart,
75 | // SecondByteEnd = secondByteEnd,
76 | // CharacterCount = 0,
77 | // Characters = characters
78 | // };
79 | // */
80 | // }
81 |
82 | // public static CodePage GetCodePage(CodePageIdentifier codePage) {
83 | // switch (codePage) {
84 | // case CodePageIdentifier.ASCII:
85 | // return CreateAscii();
86 |
87 | // case CodePageIdentifier.ISO_8859_1:
88 | // return CreateIso_8859_1();
89 |
90 | // case CodePageIdentifier.BIG5:
91 | // return CreateBig5();
92 | // }
93 |
94 | // return null;
95 | // }
96 | //}*/
97 | }
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/FileVersion/Common/ZiClipboard.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Forms;
2 | using System.Drawing;
3 | using System.IO;
4 |
5 | namespace ZiLib.FileVersion.Common
6 | {
7 | public static class ZiClipboard
8 | {
9 | public static void CopyToClipboard(IZiCharacter character) {
10 | var bmp = character.ToBitmap();
11 | if (bmp == null) {
12 | return;
13 | }
14 | // Remove transparency
15 | var clip = new Bitmap(bmp.Width, bmp.Height);
16 | Color color;
17 |
18 | using (var graphics = Graphics.FromImage(clip)) {
19 | graphics.FillRectangle(Brushes.White, 0, 0, clip.Width, clip.Height);
20 | //graphics.DrawImage(bmp, 0, 0);
21 | }
22 |
23 | // Remove ForegroundColor, replace with black
24 | for (int y = 0; y < bmp.Height; y++) {
25 | for (int x = 0; x < bmp.Width; x++) {
26 | color = Color.FromArgb(bmp.GetPixel(x, y).A, Color.Black);
27 | clip.SetPixel(x, y, color);
28 | }
29 | }
30 |
31 | var clip2 = new Bitmap(bmp.Width, bmp.Height);
32 |
33 | using (var graphics = Graphics.FromImage(clip2)) {
34 | graphics.FillRectangle(Brushes.White, 0, 0, clip.Width, clip.Height);
35 | graphics.DrawImage(clip, 0, 0);
36 | }
37 |
38 | Clipboard.SetImage(clip2);
39 | clip.Dispose();
40 | clip2.Dispose();
41 | }
42 |
43 | public static bool PasteFromClipboard(IZiCharacter character) {
44 | try
45 | {
46 | if (Clipboard.ContainsData("PNG"))
47 | {
48 | object png = Clipboard.GetData("PNG");
49 | if (png is MemoryStream)
50 | {
51 | MemoryStream pngstream = png as MemoryStream;
52 | var clip = Image.FromStream(pngstream);
53 | var newbmp = Convert(new Bitmap(clip));
54 | character.SetBitmap(newbmp);
55 | clip.Dispose();
56 | return true;
57 | }
58 |
59 | }
60 | }
61 | catch {
62 | }
63 |
64 | if (Clipboard.ContainsImage()) {
65 | var clip = Clipboard.GetImage();
66 | if (clip.Height > character.Parent.CharacterHeight)
67 | {
68 | var newbmp = Convert(new Bitmap(clip));
69 | character.SetBitmap(newbmp);
70 | clip.Dispose();
71 | return true;
72 | }
73 | else {
74 | var newbmp = Convert(new Bitmap(clip));
75 | character.SetBitmap(newbmp);
76 | clip.Dispose();
77 | return true;
78 | }
79 | }
80 |
81 | return false;
82 | }
83 |
84 | private static Color GetAlphaColor(Color pixel) {
85 | var curColor = (byte)(255 - (pixel.R + 2 * pixel.G + pixel.B) / 4); // Weighted Color2Grayscale;
86 | return Color.FromArgb(curColor, Color.Black);
87 | }
88 |
89 | private static Bitmap Convert(Bitmap clip) {
90 | var bmp = new Bitmap(clip.Width, clip.Height);
91 | Color color;
92 | for (int y = 0; y < bmp.Height; y++) {
93 | for (int x = 0; x < bmp.Width; x++) {
94 | color = GetAlphaColor(clip.GetPixel(x,y));
95 | bmp.SetPixel(x, y, color);
96 | }
97 | }
98 | return bmp;
99 | }
100 |
101 | public static bool ContainsImage() {
102 | return Clipboard.ContainsImage() || Clipboard.ContainsData("PNG");
103 | }
104 |
105 | }
106 | }
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/FormFontPreview.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.IO;
4 | using System.Windows.Forms;
5 | using ZiLib;
6 | using ZiLib.FileVersion.Common;
7 |
8 | namespace NextionFontEditor {
9 |
10 | public partial class FormFontPreview : Form {
11 |
12 | public FormFontPreview() {
13 | InitializeComponent();
14 | }
15 |
16 | private void FormFontPreview_Load(object sender, EventArgs e) {
17 | var p = new PictureBox() {
18 | Width = 16,
19 | Height = 32,
20 | BorderStyle = BorderStyle.FixedSingle,
21 | BackColor = Color.White
22 | };
23 |
24 | flowPanel.Controls.Add(p);
25 | }
26 |
27 | private void CreateCharacterPreview(IZiFont font) {
28 | flowPanel.Controls.Clear();
29 | this.SuspendLayout();
30 |
31 | for (int i = 0; i < font.Characters.Count; i++) {
32 | var b = font.Characters[i].ToBitmap();
33 | if (b != null && b.PixelFormat != System.Drawing.Imaging.PixelFormat.Undefined) {
34 | var p = new PictureBox() {
35 | Width = b.Width + 2,
36 | Height = font.CharacterHeight + 2,
37 | Image = b,
38 | BorderStyle = BorderStyle.FixedSingle,
39 | BackColor = Color.White
40 | };
41 | flowPanel.Controls.Add(p);
42 | } else {
43 | var img = new Bitmap(font.CharacterHeight + 2, 2);
44 | var p = new PictureBox() {
45 | Width = 2,
46 | Height = font.CharacterHeight + 2,
47 | Image = img,
48 | BorderStyle = BorderStyle.FixedSingle,
49 | BackColor = Color.White
50 | };
51 |
52 | flowPanel.Controls.Add(p);
53 | }
54 | if (i >= 1024) { break; }
55 | }
56 | this.ResumeLayout();
57 | }
58 |
59 | private void CreateCharacterPreview2(IZiFont font) {
60 | flowPanel.Controls.Clear();
61 | this.SuspendLayout();
62 |
63 | var preview = new Bitmap(flowPanel.Width - 15, flowPanel.Height - 15);
64 | var x = 0;
65 | var y = 0;
66 |
67 | using (var graphics = Graphics.FromImage(preview)) {
68 | graphics.FillRectangle(Brushes.Transparent, 0, 0, preview.Width, preview.Height);
69 |
70 | foreach (var ch in font.Characters) {
71 | var b = ch.ToBitmap();
72 |
73 | if ((x + b.Width) > preview.Width) {
74 | x = 0;
75 | y += b.Height;
76 | }
77 |
78 | if (y >= preview.Height) { break; }
79 |
80 | graphics.DrawImage(b, x, y);
81 | x += b.Width;
82 | }
83 |
84 | }
85 |
86 | var p = new PictureBox() {
87 | Width = preview.Width,
88 | Height = preview.Height,
89 | Image = preview,
90 | BorderStyle = BorderStyle.FixedSingle,
91 | BackColor = Color.Black
92 | };
93 |
94 | flowPanel.Controls.Add(p);
95 |
96 | this.ResumeLayout();
97 | }
98 |
99 |
100 | private void btnOpen_Click(object sender, EventArgs e) {
101 | var res = ofd.ShowDialog();
102 |
103 | if (res == DialogResult.OK) {
104 | var zifont = ZiFont.FromFile(ofd.FileName);
105 | CreateCharacterPreview2(zifont);
106 |
107 | lblFile.Text = Path.GetFileName(ofd.FileName);
108 | lblFontName.Text = zifont.Name;
109 | lblCodePage.Text = zifont.CodePage.CodePageIdentifier.ToString();
110 |
111 | lblWidth.Text = zifont.CharacterWidth.ToString();
112 | lblHeight.Text = zifont.CharacterHeight.ToString();
113 | lblCharacters.Text = zifont.CodePage.CharacterCount.ToString();
114 |
115 | lblFileSize.Text = zifont.FileSize.ToString();
116 | lblFileVersion.Text = zifont.Version.ToString();
117 | //lblBytesPerChar.Text = zifont.BytesPerChar.ToString();
118 | }
119 | }
120 | }
121 | }
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/Extensions/BitmapExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Drawing;
4 | using System.IO;
5 |
6 | namespace ZiLib.Extensions {
7 |
8 | public static class BitmapExtensions {
9 |
10 | public static void SetPixelNumber(this Bitmap b, int number, Color color) {
11 | if (number >= b.Width * b.Height) {
12 | Debug.WriteLine($"!!! pixelNumber >= {b.Width * b.Height} !!!");
13 | return;
14 | }
15 |
16 | var l = NumberToPoint(number, b.Width);
17 | b.SetPixel(l.X, l.Y, color);
18 | }
19 |
20 | public static Point NumberToPoint(int number, int width) {
21 | var p = new Point {
22 | Y = (int) Math.Floor((double) number / width),
23 | X = number % width
24 | };
25 | return p;
26 | }
27 |
28 | public static Bitmap DrawString(string txt, string fontname, byte height, FontStyle style = FontStyle.Regular, byte x = 0, byte y = 0, byte contrast = 0)
29 | {
30 | var fontsize = (float)height;
31 |
32 | var strFormat = (StringFormat)StringFormat.GenericTypographic.Clone();
33 | strFormat.FormatFlags = strFormat.FormatFlags | StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.NoFontFallback;
34 |
35 | var tmp = new Bitmap(1, 1);
36 | var grphtmp = Graphics.FromImage(tmp);
37 |
38 | var font = new Font("Arial", 12);
39 |
40 | // Check if it is a otf/ttf file
41 | if (((Path.GetExtension(fontname) == ".ttf") || (Path.GetExtension(fontname) == ".otf")) && (File.Exists(fontname)))
42 | {
43 |
44 | var pfc = new System.Drawing.Text.PrivateFontCollection();
45 | pfc.AddFontFile(fontname);
46 |
47 | var i = 0;
48 |
49 | font = new Font(pfc.Families[0], fontsize, style, GraphicsUnit.Pixel);
50 | while (Math.Abs(font.Height - height) > 0.1 && i++<10)
51 | {
52 | fontsize += (float)(height - font.Height) / 2;
53 | font = new Font(pfc.Families[0], fontsize, style, GraphicsUnit.Pixel);
54 | }
55 |
56 | /*while (font.Height > height)
57 | {
58 | fontsize -= (float)0.02;
59 | font.Dispose();
60 | font = new Font(pfc.Families[0], fontsize, style, GraphicsUnit.Pixel);
61 | }*/
62 |
63 | // System Font
64 | }
65 | else
66 | {
67 | font = new Font(fontname, fontsize, style, GraphicsUnit.Pixel);
68 | while (Math.Abs(font.Height - height) > 0.1)
69 | {
70 | fontsize += (float)(height - font.Height) / 2;
71 | font = new Font(fontname, fontsize, style, GraphicsUnit.Pixel);
72 | }
73 |
74 | }
75 | var width = (int)Math.Round((grphtmp.MeasureString(txt, font, new PointF(0, 0), strFormat)).Width);
76 | width = width > 255 ? 255 : width;
77 |
78 | if (width > 0)
79 | {
80 | var b = new Bitmap(width, height);
81 | var graphics = Graphics.FromImage(b);
82 |
83 | //Adjust for high quality
84 | graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
85 | graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
86 | graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
87 | graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; // AntiAlias // HighQuality
88 | graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; //AntiAliasGridFit; // (B/W = SingleBitPerPixelGridFit)
89 |
90 | var brushBg = Brushes.White;
91 | var brushFg = Brushes.Black;
92 |
93 | graphics.FillRectangle(brushBg, 0, 0, b.Width, b.Height);
94 | graphics.TextContrast = contrast;
95 | graphics.DrawString(txt, font, brushFg, x, y, strFormat); // experimental
96 | //TextRenderer.DrawText(graphics, txt, font, new Point(x, y), Color.Black, Color.White);
97 | graphics.Dispose();
98 | return b;
99 |
100 | }
101 | else
102 | {
103 | // Nextion requires a minimum width of 1 pixel. It doesn't like zero length chardata as it crashes the Application when rotating the font.
104 | var b = new Bitmap(1, height);
105 | //b.Dispose();
106 | return b;
107 | }
108 |
109 | }
110 |
111 | }
112 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
262 |
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/FormFontGenerator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data;
4 | using System.Drawing;
5 | using System.Drawing.Text;
6 | using System.Linq;
7 | using System.Windows.Forms;
8 | using ZiLib.FileVersion.Common;
9 | using ZiLib.FileVersion.V3;
10 |
11 | namespace NextionFontEditor {
12 |
13 | public partial class FormFontGenerator : Form {
14 |
15 | public FormFontGenerator() {
16 | InitializeComponent();
17 | }
18 |
19 | private ZiFontV3 ziFont = new ZiFontV3();
20 |
21 | private void FormFontGenerator_Load(object sender, EventArgs e) {
22 | InitializeNextionFontSizesList();
23 |
24 | //new FormFontPreview().Show();
25 | }
26 |
27 | private void InitializeNextionFontSizesList() {
28 | for (int i = 8; i <= 255; i += 8) {
29 | cmbNextionFontSize.Items.Add(i);
30 | }
31 |
32 | cmbNextionFontSize.Text = "16";
33 | numFontSize.Value = 16;
34 | }
35 |
36 | public Graphics CreateGraphics(Bitmap bitmap = null) {
37 | var b = bitmap ?? new Bitmap(1, 1);
38 | var g = Graphics.FromImage(b);
39 |
40 | g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
41 | g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None;
42 | g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
43 | g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
44 |
45 | return g;
46 | }
47 |
48 | private void CreatePreview() {
49 | var codePage = new CodePage(ZiLib.CodePageIdentifier.ISO_8859_1);
50 |
51 | var fontName = lstFonts.SelectedItem?.ToString() ?? "";
52 | var fontSize = (int)numFontSize.Value;
53 |
54 | var size = int.Parse(cmbNextionFontSize.Text);
55 | var width = size / 2;
56 | var height = size;
57 |
58 | var font = new Font(fontName, fontSize, GraphicsUnit.Pixel);
59 |
60 | var pPreviews = new List();
61 |
62 | var bLightCoral = new SolidBrush(Color.LightCoral);
63 | var bLightGreen = new SolidBrush(Color.LightGreen);
64 | var bWhite = new SolidBrush(Color.White);
65 | var bBlack = new SolidBrush(Color.Black);
66 |
67 | foreach (var cp in codePage.CodePoints) {
68 | var bPreview = new Bitmap(width, height);
69 | var txt = codePage.Encoding.GetString(BitConverter.GetBytes(cp));
70 |
71 | using (var gPreview = CreateGraphics(bPreview)) {
72 |
73 | var sChar = gPreview.MeasureString(txt, font, new PointF(0, 0), StringFormat.GenericTypographic).ToSize();
74 | if (sChar.Width == 0) sChar.Width = 1;
75 |
76 | var bChar = new Bitmap(sChar.Width, sChar.Height);
77 |
78 | using (var gChar = CreateGraphics(bChar)) {
79 | var sb = PreviewTest.Checked ?
80 | bChar.Width > bPreview.Width ? bLightCoral : bLightGreen :
81 | PreviewBW.Checked ? bWhite : bBlack;
82 |
83 | gChar.FillRectangle(sb, 0, 0, sChar.Width, sChar.Height);
84 |
85 | gChar.DrawString(txt, font,
86 | PreviewWB.Checked ? bWhite : bBlack,
87 | (float)numCharOffsetX.Value, (float)numCharOffsetY.Value, StringFormat.GenericTypographic
88 | );
89 | }
90 |
91 | gPreview.FillRectangle(PreviewTest.Checked ?
92 | bChar.Width > bPreview.Width ? bLightCoral : bLightGreen :
93 | PreviewBW.Checked ? bWhite : bBlack,
94 | 0, 0, width, height);
95 |
96 | if (bChar.Width > bPreview.Width) {
97 | gPreview.DrawImage(bChar, 0, 0, width, height);
98 |
99 | } else {
100 | gPreview.DrawImage(bChar, (width / 2) - (bChar.Width / 2), 0, bChar.Width, height);
101 | }
102 | }
103 |
104 | pPreviews.Add(bPreview);
105 | }
106 |
107 | panelPreview.SuspendLayout();
108 | panelPreview.Controls.Clear();
109 | panelPreview.BackColor = PreviewTest.Checked ? Color.Transparent : PreviewBW.Checked ? Color.White : Color.Black;
110 | panelPreview.Controls.AddRange(
111 | pPreviews.Select(x => new PictureBox() {
112 | Width = width,
113 | Height = height,
114 | Image = x,
115 | Margin = new Padding(3)
116 | }).ToArray());
117 | panelPreview.ResumeLayout();
118 |
119 | ziFont = ZiFontV3.FromCharacterBitmaps(fontName + " " + cmbNextionFontSize.Text, (byte)width, (byte)height, codePage, pPreviews, PreviewWB.Checked);
120 | }
121 |
122 | private int GetMaxFontSizeForRect(string text, String fontName, int fontSize, SizeF rect) {
123 |
124 | var g = Graphics.FromImage(new Bitmap(10, 10));
125 |
126 | for (int i = fontSize; i > 0; i--) {
127 |
128 | var font = new Font(fontName, i, GraphicsUnit.Pixel);
129 |
130 | var ss = g.MeasureString(text, font, 0, StringFormat.GenericTypographic);
131 |
132 | if (ss.Width < rect.Width && ss.Height < rect.Height) return i;
133 | }
134 |
135 | return fontSize;
136 | }
137 |
138 | private void lstFonts_SelectedIndexChanged(object sender, EventArgs e) {
139 | CreatePreview();
140 | }
141 |
142 | private void numCharOffsetX_ValueChanged(object sender, EventArgs e) {
143 | CreatePreview();
144 | }
145 |
146 | private void numCharOffsetY_ValueChanged(object sender, EventArgs e) {
147 | CreatePreview();
148 | }
149 |
150 | private void cmbFontSize_SelectedIndexChanged(object sender, EventArgs e) {
151 | CreatePreview();
152 | }
153 |
154 | private void cmbNextionFontSize_SelectedIndexChanged(object sender, EventArgs e) {
155 | CreatePreview();
156 | }
157 |
158 | private void numFontSize_ValueChanged(object sender, EventArgs e) {
159 | CreatePreview();
160 | }
161 |
162 | private void rbManualFontSize_CheckedChanged(object sender, EventArgs e) {
163 | CreatePreview();
164 | }
165 |
166 | private void rbUseAllCharactersMaxSize_CheckedChanged(object sender, EventArgs e) {
167 | CreatePreview();
168 | }
169 |
170 | private void rbUseSingleCharacterMaxSize_CheckedChanged(object sender, EventArgs e) {
171 | CreatePreview();
172 | }
173 |
174 | private void numDbs_ValueChanged(object sender, EventArgs e) {
175 | CreatePreview();
176 | }
177 |
178 | private void btnSave_Click(object sender, EventArgs e) {
179 | sfd.FileName = ziFont.Name;
180 | var res = sfd.ShowDialog();
181 | if (res == DialogResult.OK) {
182 | ziFont.Save(sfd.FileName);
183 | }
184 | }
185 |
186 | private void PreviewTest_CheckedChanged(object sender, EventArgs e) {
187 | CreatePreview();
188 | }
189 | }
190 | }
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/FormAddCharacters.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data;
4 | using System.Drawing;
5 | using System.Drawing.Text;
6 | using System.Linq;
7 | using System.Windows.Forms;
8 | using ZiLib.FileVersion.Common;
9 | using ZiLib.FileVersion.V3;
10 |
11 | namespace NextionFontEditor {
12 |
13 | public partial class FormAddCharacters : Form {
14 |
15 | public FormAddCharacters() {
16 | InitializeComponent();
17 | }
18 |
19 | private ZiFontV3 ziFont = new ZiFontV3();
20 |
21 | private void FormAddCharacters_Load(object sender, EventArgs e) {
22 | InitializeNextionFontSizesList();
23 |
24 | //new FormFontPreview().Show();
25 | }
26 |
27 | private void InitializeNextionFontSizesList() {
28 | for (int i = 8; i <= 255; i++) {
29 | cmbNextionFontSize.Items.Add(i);
30 | }
31 |
32 | cmbNextionFontSize.Text = "16";
33 | numFontSize.Value = 16;
34 | }
35 |
36 | public Graphics CreateGraphics(Bitmap bitmap = null) {
37 | var b = bitmap ?? new Bitmap(1, 1);
38 | var g = Graphics.FromImage(b);
39 |
40 | g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
41 | g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None;
42 | g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
43 | g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
44 |
45 | return g;
46 | }
47 |
48 | private void CreatePreview() {
49 | var codePage = new CodePage(ZiLib.CodePageIdentifier.ISO_8859_1);
50 |
51 | var fontName = lstFonts.SelectedItem?.ToString() ?? "";
52 | var fontSize = (int)numFontSize.Value;
53 |
54 | var size = int.Parse(cmbNextionFontSize.Text);
55 | var width = size / 2;
56 | var height = size;
57 |
58 | var font = new Font(fontName, fontSize, GraphicsUnit.Pixel);
59 |
60 | var pPreviews = new List();
61 |
62 | var bLightCoral = new SolidBrush(Color.LightCoral);
63 | var bLightGreen = new SolidBrush(Color.LightGreen);
64 | var bWhite = new SolidBrush(Color.White);
65 | var bBlack = new SolidBrush(Color.Black);
66 |
67 | foreach (var cp in codePage.CodePoints) {
68 | var bPreview = new Bitmap(width, height);
69 | var txt = codePage.Encoding.GetString(BitConverter.GetBytes(cp));
70 |
71 | using (var gPreview = CreateGraphics(bPreview)) {
72 |
73 | var sChar = gPreview.MeasureString(txt, font, new PointF(0, 0), StringFormat.GenericTypographic).ToSize();
74 | if (sChar.Width == 0) sChar.Width = 1;
75 |
76 | var bChar = new Bitmap(sChar.Width, sChar.Height);
77 |
78 | using (var gChar = CreateGraphics(bChar)) {
79 | var sb = PreviewTest.Checked ?
80 | bChar.Width > bPreview.Width ? bLightCoral : bLightGreen :
81 | PreviewBW.Checked ? bWhite : bBlack;
82 |
83 | gChar.FillRectangle(sb, 0, 0, sChar.Width, sChar.Height);
84 |
85 | gChar.DrawString(txt, font,
86 | PreviewWB.Checked ? bWhite : bBlack,
87 | (float)numCharOffsetX.Value, (float)numCharOffsetY.Value, StringFormat.GenericTypographic
88 | );
89 | }
90 |
91 | gPreview.FillRectangle(PreviewTest.Checked ?
92 | bChar.Width > bPreview.Width ? bLightCoral : bLightGreen :
93 | PreviewBW.Checked ? bWhite : bBlack,
94 | 0, 0, width, height);
95 |
96 | if (bChar.Width > bPreview.Width) {
97 | gPreview.DrawImage(bChar, 0, 0, width, height);
98 |
99 | } else {
100 | gPreview.DrawImage(bChar, (width / 2) - (bChar.Width / 2), 0, bChar.Width, height);
101 | }
102 | }
103 |
104 | pPreviews.Add(bPreview);
105 | }
106 |
107 | panelPreview.SuspendLayout();
108 | panelPreview.Controls.Clear();
109 | panelPreview.BackColor = PreviewTest.Checked ? Color.Transparent : PreviewBW.Checked ? Color.White : Color.Black;
110 | panelPreview.Controls.AddRange(
111 | pPreviews.Select(x => new PictureBox() {
112 | Width = width,
113 | Height = height,
114 | Image = x,
115 | Margin = new Padding(3)
116 | }).ToArray());
117 | panelPreview.ResumeLayout();
118 |
119 | ziFont = ZiFontV3.FromCharacterBitmaps(fontName + " " + cmbNextionFontSize.Text, (byte)width, (byte)height, codePage, pPreviews, PreviewWB.Checked);
120 | }
121 |
122 | private int GetMaxFontSizeForRect(string text, String fontName, int fontSize, SizeF rect) {
123 |
124 | var g = Graphics.FromImage(new Bitmap(10, 10));
125 |
126 | for (int i = fontSize; i > 0; i--) {
127 |
128 | var font = new Font(fontName, i, GraphicsUnit.Pixel);
129 |
130 | var ss = g.MeasureString(text, font, 0, StringFormat.GenericTypographic);
131 |
132 | if (ss.Width < rect.Width && ss.Height < rect.Height) return i;
133 | }
134 |
135 | return fontSize;
136 | }
137 |
138 | private void lstFonts_SelectedIndexChanged(object sender, EventArgs e) {
139 | CreatePreview();
140 | }
141 |
142 | private void numCharOffsetX_ValueChanged(object sender, EventArgs e) {
143 | CreatePreview();
144 | }
145 |
146 | private void numCharOffsetY_ValueChanged(object sender, EventArgs e) {
147 | CreatePreview();
148 | }
149 |
150 | private void cmbFontSize_SelectedIndexChanged(object sender, EventArgs e) {
151 | CreatePreview();
152 | }
153 |
154 | private void cmbNextionFontSize_SelectedIndexChanged(object sender, EventArgs e) {
155 | CreatePreview();
156 | }
157 |
158 | private void numFontSize_ValueChanged(object sender, EventArgs e) {
159 | CreatePreview();
160 | }
161 |
162 | private void rbManualFontSize_CheckedChanged(object sender, EventArgs e) {
163 | CreatePreview();
164 | }
165 |
166 | private void rbUseAllCharactersMaxSize_CheckedChanged(object sender, EventArgs e) {
167 | CreatePreview();
168 | }
169 |
170 | private void rbUseSingleCharacterMaxSize_CheckedChanged(object sender, EventArgs e) {
171 | CreatePreview();
172 | }
173 |
174 | private void numDbs_ValueChanged(object sender, EventArgs e) {
175 | CreatePreview();
176 | }
177 |
178 | private void btnSave_Click(object sender, EventArgs e) {
179 | this.DialogResult = DialogResult.OK;
180 | this.Close();
181 | }
182 |
183 | private void PreviewTest_CheckedChanged(object sender, EventArgs e) {
184 | CreatePreview();
185 | }
186 |
187 | private void Label1_Click(object sender, EventArgs e) {
188 |
189 | }
190 |
191 | private void LblFont_Click(object sender, EventArgs e) {
192 |
193 | }
194 |
195 | private void FontDialog1_Apply(object sender, EventArgs e) {
196 |
197 | }
198 | }
199 | }
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/FormCharacterWidth.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace NextionFontEditor {
2 | partial class FormCharacterWidth {
3 | ///
4 | /// Required designer variable.
5 | ///
6 | private System.ComponentModel.IContainer components = null;
7 |
8 | ///
9 | /// Clean up any resources being used.
10 | ///
11 | /// true if managed resources should be disposed; otherwise, false.
12 | protected override void Dispose(bool disposing) {
13 | if (disposing && (components != null)) {
14 | components.Dispose();
15 | }
16 | base.Dispose(disposing);
17 | }
18 |
19 | #region Windows Form Designer generated code
20 |
21 | ///
22 | /// Required method for Designer support - do not modify
23 | /// the contents of this method with the code editor.
24 | ///
25 | private void InitializeComponent() {
26 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormCharacterWidth));
27 | this.lblWidth = new System.Windows.Forms.Label();
28 | this.lblKerningL = new System.Windows.Forms.Label();
29 | this.lblKerningR = new System.Windows.Forms.Label();
30 | this.btnOK = new System.Windows.Forms.Button();
31 | this.btnCancel = new System.Windows.Forms.Button();
32 | this.numWidth = new System.Windows.Forms.NumericUpDown();
33 | this.numKerningL = new System.Windows.Forms.NumericUpDown();
34 | this.numKerningR = new System.Windows.Forms.NumericUpDown();
35 | ((System.ComponentModel.ISupportInitialize)(this.numWidth)).BeginInit();
36 | ((System.ComponentModel.ISupportInitialize)(this.numKerningL)).BeginInit();
37 | ((System.ComponentModel.ISupportInitialize)(this.numKerningR)).BeginInit();
38 | this.SuspendLayout();
39 | //
40 | // lblWidth
41 | //
42 | this.lblWidth.AutoSize = true;
43 | this.lblWidth.Location = new System.Drawing.Point(47, 14);
44 | this.lblWidth.Name = "lblWidth";
45 | this.lblWidth.Size = new System.Drawing.Size(87, 13);
46 | this.lblWidth.TabIndex = 0;
47 | this.lblWidth.Text = "Character Width:";
48 | this.lblWidth.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
49 | //
50 | // lblKerningL
51 | //
52 | this.lblKerningL.AutoSize = true;
53 | this.lblKerningL.Location = new System.Drawing.Point(67, 42);
54 | this.lblKerningL.Name = "lblKerningL";
55 | this.lblKerningL.Size = new System.Drawing.Size(67, 13);
56 | this.lblKerningL.TabIndex = 2;
57 | this.lblKerningL.Text = "Kerning Left:";
58 | this.lblKerningL.TextAlign = System.Drawing.ContentAlignment.TopRight;
59 | this.lblKerningL.Click += new System.EventHandler(this.lblKerningL_Click);
60 | //
61 | // lblKerningR
62 | //
63 | this.lblKerningR.AutoSize = true;
64 | this.lblKerningR.Location = new System.Drawing.Point(60, 70);
65 | this.lblKerningR.Name = "lblKerningR";
66 | this.lblKerningR.Size = new System.Drawing.Size(74, 13);
67 | this.lblKerningR.TabIndex = 4;
68 | this.lblKerningR.Text = "Kerning Right:";
69 | this.lblKerningR.TextAlign = System.Drawing.ContentAlignment.TopRight;
70 | //
71 | // btnOK
72 | //
73 | this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
74 | this.btnOK.Location = new System.Drawing.Point(235, 65);
75 | this.btnOK.Name = "btnOK";
76 | this.btnOK.Size = new System.Drawing.Size(75, 23);
77 | this.btnOK.TabIndex = 6;
78 | this.btnOK.Text = "OK";
79 | this.btnOK.UseVisualStyleBackColor = true;
80 | this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
81 | //
82 | // btnCancel
83 | //
84 | this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
85 | this.btnCancel.Location = new System.Drawing.Point(235, 31);
86 | this.btnCancel.Name = "btnCancel";
87 | this.btnCancel.Size = new System.Drawing.Size(75, 23);
88 | this.btnCancel.TabIndex = 7;
89 | this.btnCancel.Text = "Cancel";
90 | this.btnCancel.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
91 | this.btnCancel.UseVisualStyleBackColor = true;
92 | this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
93 | //
94 | // numWidth
95 | //
96 | this.numWidth.Location = new System.Drawing.Point(140, 12);
97 | this.numWidth.Maximum = new decimal(new int[] {
98 | 255,
99 | 0,
100 | 0,
101 | 0});
102 | this.numWidth.Minimum = new decimal(new int[] {
103 | 1,
104 | 0,
105 | 0,
106 | 0});
107 | this.numWidth.Name = "numWidth";
108 | this.numWidth.Size = new System.Drawing.Size(60, 20);
109 | this.numWidth.TabIndex = 8;
110 | this.numWidth.Value = new decimal(new int[] {
111 | 1,
112 | 0,
113 | 0,
114 | 0});
115 | this.numWidth.ValueChanged += new System.EventHandler(this.numWidth_ValueChanged);
116 | //
117 | // numKerningL
118 | //
119 | this.numKerningL.Location = new System.Drawing.Point(140, 40);
120 | this.numKerningL.Maximum = new decimal(new int[] {
121 | 254,
122 | 0,
123 | 0,
124 | 0});
125 | this.numKerningL.Name = "numKerningL";
126 | this.numKerningL.Size = new System.Drawing.Size(60, 20);
127 | this.numKerningL.TabIndex = 9;
128 | this.numKerningL.Value = new decimal(new int[] {
129 | 1,
130 | 0,
131 | 0,
132 | 0});
133 | this.numKerningL.ValueChanged += new System.EventHandler(this.numKerningL_ValueChanged);
134 | //
135 | // numKerningR
136 | //
137 | this.numKerningR.Location = new System.Drawing.Point(140, 68);
138 | this.numKerningR.Maximum = new decimal(new int[] {
139 | 254,
140 | 0,
141 | 0,
142 | 0});
143 | this.numKerningR.Name = "numKerningR";
144 | this.numKerningR.Size = new System.Drawing.Size(60, 20);
145 | this.numKerningR.TabIndex = 10;
146 | //
147 | // FormCharacterWidth
148 | //
149 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
150 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
151 | this.ClientSize = new System.Drawing.Size(332, 101);
152 | this.Controls.Add(this.numKerningR);
153 | this.Controls.Add(this.numKerningL);
154 | this.Controls.Add(this.numWidth);
155 | this.Controls.Add(this.btnCancel);
156 | this.Controls.Add(this.btnOK);
157 | this.Controls.Add(this.lblKerningR);
158 | this.Controls.Add(this.lblKerningL);
159 | this.Controls.Add(this.lblWidth);
160 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
161 | this.Name = "FormCharacterWidth";
162 | this.Text = "Character Width";
163 | ((System.ComponentModel.ISupportInitialize)(this.numWidth)).EndInit();
164 | ((System.ComponentModel.ISupportInitialize)(this.numKerningL)).EndInit();
165 | ((System.ComponentModel.ISupportInitialize)(this.numKerningR)).EndInit();
166 | this.ResumeLayout(false);
167 | this.PerformLayout();
168 |
169 | }
170 |
171 | #endregion
172 |
173 | private System.Windows.Forms.Label lblWidth;
174 | private System.Windows.Forms.Label lblKerningL;
175 | private System.Windows.Forms.Label lblKerningR;
176 | private System.Windows.Forms.Button btnOK;
177 | private System.Windows.Forms.Button btnCancel;
178 | public System.Windows.Forms.NumericUpDown numWidth;
179 | public System.Windows.Forms.NumericUpDown numKerningL;
180 | public System.Windows.Forms.NumericUpDown numKerningR;
181 | }
182 | }
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/FileVersion/V3/ZiFontV3.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 | using ZiLib.FileVersion.Common;
8 |
9 | namespace ZiLib.FileVersion.V3 {
10 |
11 | public class ZiFontV3 : IZiFont {
12 | private static readonly byte[] MagicNumbers = new byte[] { 0x04, 0xFF, 0x00, 0x0A };
13 | private static readonly byte[] MagicNumbersBig5 = new byte[] { 0x04, 0x7E, 0x22, 0x0A }; // The two middle bytes might not be static
14 |
15 | private const int HEADER_LENGTH = 0x1C; // 28
16 |
17 | private byte[] _header { get; set; }
18 | private byte[] _charData { get; set; }
19 |
20 | public byte CharacterWidth { get; set; }
21 | public byte CharacterHeight { get; set; }
22 | public int CharacterCount => Characters.Count;
23 |
24 | public CodePage CodePage { get; set; }
25 |
26 | public byte Version { get; set; } = 3;
27 | public byte NameLength { get; set; }
28 | public string Name { get; set; }
29 | public long FileSize { get; set; }
30 |
31 | public uint VariableDataLength { get; set; }
32 | public uint CharDataLength { get; set; }
33 | public int BytesPerChar { get; set; }
34 |
35 | public List Characters { get; set; } = new List();
36 |
37 | //public List CharBitmaps { get; set; } = new List();
38 |
39 | //public ZiFont(byte width, byte height, CodePage codePage) {
40 | // CharacterWidth = width;
41 | // CharacterHeight = height;
42 | // CodePage = codePage;
43 | //}
44 | public void Save(string fileName, CodePage codePage) {
45 | CodePage = codePage;
46 | //_charData = CreateCharData(CharBitmaps);
47 | Save(fileName);
48 | }
49 |
50 | public void Save(string fileName) {
51 | // _charData = CreateCharData(CharBitmaps);
52 |
53 | var file = new List();
54 |
55 | file.AddRange(MagicNumbers);
56 | file.AddRange(BitConverter.GetBytes((ushort)CodePage.CodePageIdentifier));
57 | file.Add(CharacterWidth);
58 | file.Add(CharacterHeight);
59 | file.Add((byte)(CodePage.IsMultibyte ? CodePage.FirstByteStart : 0));
60 | file.Add((byte)(CodePage.IsMultibyte ? CodePage.FirstByteEnd : 0));
61 | file.Add((byte)(CodePage.IsMultibyte ? CodePage.SecondByteStart : CodePage.FirstByteStart));
62 | file.Add((byte)(CodePage.IsMultibyte ? CodePage.SecondByteEnd : CodePage.FirstByteEnd));
63 | file.AddRange(BitConverter.GetBytes(CodePage.CharacterCount));
64 | file.Add(Version);
65 | file.Add(NameLength);
66 | file.Add(NameLength);
67 | file.Add(0x00); // Reserved
68 | file.AddRange(BitConverter.GetBytes(VariableDataLength));
69 | file.Add(0x00); // Reserved
70 | file.Add(0x00); // Reserved
71 | file.Add(0x00); // Reserved
72 | file.Add(0x00); // Reserved
73 | file.AddRange(Encoding.ASCII.GetBytes(Name));
74 | file.AddRange(_charData);
75 |
76 | File.WriteAllBytes(fileName, file.ToArray());
77 | }
78 |
79 | public static IZiFont FromFile(string fileName) {
80 | return FromBytes(File.ReadAllBytes(fileName));
81 | }
82 |
83 | public static IZiFont FromBytes(byte[] bytes) {
84 | if (!VerifyHeader(bytes)) return null;
85 |
86 | var ziFont = new ZiFontV3();
87 | //var ziFont = new ZiFontV5();
88 |
89 | byte[] _header = bytes.Take(HEADER_LENGTH).ToArray();
90 | int NameLength = _header[0x11];
91 | ziFont.Name = Encoding.ASCII.GetString(bytes.Skip(HEADER_LENGTH).Take(NameLength).ToArray());
92 | ziFont.FileSize = bytes.Length;
93 |
94 | ziFont.CharacterWidth = _header[0x6];
95 | ziFont.CharacterHeight = _header[0x7];
96 |
97 | ziFont.VariableDataLength = BitConverter.ToUInt32(_header.Skip(0x14).Take(4).ToArray(), 0);
98 | ziFont.CharDataLength = ziFont.VariableDataLength - (uint)NameLength;
99 |
100 | byte[] _charData = bytes.Skip(HEADER_LENGTH + NameLength).ToArray();
101 | //ziFont.BytesPerChar = (ziFont.CharacterWidth * ziFont.CharacterHeight) / 8;
102 | int BytesPerChar = (ziFont.CharacterWidth * ziFont.CharacterHeight) / 8;
103 |
104 | var codePageId = BitConverter.ToUInt16(_header.Skip(0x4).Take(2).ToArray(), 0);
105 | var characterCount = BitConverter.ToUInt32(_header.Skip(0x0C).Take(4).ToArray(), 0);
106 | var calculatedCharCount = ziFont.CharDataLength / BytesPerChar;
107 |
108 | ziFont.CodePage = new CodePage((CodePageIdentifier)codePageId);
109 |
110 | if (characterCount != calculatedCharCount) throw new Exception($"{nameof(characterCount)} and {nameof(calculatedCharCount)} doesn't match.");
111 |
112 | var bb = new SolidBrush(Color.Black);
113 | var pr = new Pen(Color.DarkCyan);
114 | for (int charIndex = 0; charIndex < ziFont.CodePage.CharacterCount; charIndex++) {
115 | var charBitmap = new Bitmap(ziFont.CharacterWidth, ziFont.CharacterHeight);
116 | var g = Graphics.FromImage(charBitmap);
117 |
118 | var charData = _charData.Skip(charIndex * BytesPerChar).Take(BytesPerChar).ToArray();
119 | var pixels = BinaryTools.BytesToBits(charData);
120 |
121 | var pixel = 0;
122 |
123 | for (int y = 0; y < ziFont.CharacterHeight; y++) {
124 | for (int x = 0; x < ziFont.CharacterWidth; x++) {
125 | if (pixels[pixel]) g.FillRectangle(bb, x, y, 1, 1);
126 |
127 | pixel++;
128 | }
129 | }
130 |
131 | /* var ch = new ZiCharacterV3
132 | (
133 | ziFont,
134 | ziFont.CodePage.CodePoints[charIndex],
135 | charBitmap
136 | );*/
137 | var ch = new ZiCharacterV3
138 | (
139 | ziFont,
140 | ziFont.CodePage.CodePoints[charIndex],
141 | charData
142 | );
143 | ziFont.Characters.Add(ch);
144 | }
145 |
146 | return ziFont;
147 | }
148 |
149 |
150 | private byte[] CreateCharData(List characters, bool invertColour = false) {
151 | var charData = new List();
152 |
153 | foreach (var cb in characters) {
154 | charData.AddRange(BinaryTools.BitmapTo1BppData(cb, invertColour));
155 | }
156 |
157 | return charData.ToArray();
158 | }
159 |
160 | public static ZiFontV3 FromCharacterBitmaps(string fontName, byte width, byte height, CodePage codePage, List characters, bool invertColour = false) {
161 | var bytesPerChar = width * height / 8;
162 | var charDataLength = (uint)(bytesPerChar * characters.Count());
163 |
164 | var ziFont = new ZiFontV3 {
165 | Name = fontName,
166 | NameLength = (byte)fontName.Length,
167 | CharacterWidth = width,
168 | CharacterHeight = height,
169 | CodePage = codePage,
170 | CharDataLength = charDataLength,
171 | VariableDataLength = (uint)fontName.Length + charDataLength,
172 | BytesPerChar = bytesPerChar,
173 | };
174 |
175 | ziFont._charData = ziFont.CreateCharData(characters, invertColour);
176 |
177 | //var charData = new List();
178 | //foreach (var cb in characters) {
179 | // charData.AddRange(BinaryTools.BitmapTo1BppData(cb));
180 | //}
181 | //ziFont._charData = charData.ToArray();
182 |
183 | return ziFont;
184 | }
185 |
186 | public static bool VerifyHeader(byte[] header) {
187 | if (header.Length < 4) return false;
188 | if (header.Length > 5) header = header.Take(4).ToArray();
189 |
190 | if (header.SequenceEqual(MagicNumbers)) return true;
191 | if (header.SequenceEqual(MagicNumbersBig5)) return true;
192 |
193 | return false;
194 | }
195 | public void AddCharacter(uint codepoint, IZiCharacter character) {
196 | Characters.Add(character);
197 | }
198 |
199 | public void RemoveCharacter(int index) {
200 | Characters.RemoveAt(index);
201 | }
202 | }
203 | }
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/FileVersion/V5/BinaryTools.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Collections.Generic;
3 |
4 | namespace ZiLib.FileVersion.V5
5 | {
6 |
7 | public class BinaryTools
8 | {
9 | public static byte Get3bppColor(Color pixel, bool invertColour) {
10 | var curColor = (byte)0u;
11 | if (invertColour)
12 | {
13 | // curColor = (byte)((pixel.R + 2 * pixel.G + pixel.B) / 4); // Weighted Color2Grayscale;
14 | curColor = (byte)(255 - pixel.A);
15 | } else
16 | {
17 | // curColor = (byte)(255 - (pixel.R + 2 * pixel.G + pixel.B) / 4); // Weighted Color2Grayscale;
18 | curColor = (byte)pixel.A;
19 | }
20 | // curColor = (byte)(curColor * pixel.A / 255);
21 | // convert to 3 bits
22 | return (byte)(curColor >> 5);
23 | }
24 |
25 | /* A faster 3-bit encoder and compresser combined into one loop instead of consecutive nested loops */
26 | public static byte[] BitmapTo3BppData(Bitmap b, bool invertColour = false)
27 | {
28 | var data = new List();
29 |
30 | byte curColor;
31 | var prevColor = (byte)0u;
32 | var prevCount = 0u;
33 |
34 | var antialias = false;
35 |
36 |
37 | if (b == null)
38 | {
39 | //return data.ToArray();
40 | }
41 |
42 | if (b.PixelFormat == System.Drawing.Imaging.PixelFormat.Undefined) {
43 | return data.ToArray();
44 | }
45 | data.Add(0x03);
46 |
47 | for (int y = 0; y < b.Height; y++)
48 | {
49 | for (int x = 0; x < b.Width; x++)
50 | {
51 | curColor = Get3bppColor(b.GetPixel(x, y), invertColour);
52 |
53 | if (curColor == prevColor)
54 | {
55 | prevCount++;
56 | continue; // to next pixel
57 | }
58 |
59 | if (prevCount == 0) // No previous data to encode
60 | {
61 | prevColor = curColor;
62 | prevCount = 1;
63 | continue; // to next pixel
64 | }
65 |
66 | if (prevColor == 0)
67 | {
68 | while (prevCount >= 31)
69 | {
70 | data.Add(CompressedByte.RepeatedWhites(31));
71 | prevCount -= 31;
72 | }
73 |
74 | if (prevCount == 0)
75 | {
76 | // start with fresh color count
77 | prevColor = curColor;
78 | prevCount = 1;
79 | continue; // to next pixel
80 | }
81 |
82 | /* also check for second black pixel */
83 | if (curColor == 7)
84 | {
85 | var blacks = 1u;
86 | var j = (x + 1) >= b.Width ? y + 1 : y;
87 | var i = (x + 1) >= b.Width ? 0 : x + 1;
88 | while (blacks<2 && j= b.Width ? y + 1 : y;
99 | i = (x + 1) >= b.Width ? 0 : x + 1;
100 | }
101 | data.Add(CompressedByte.RepeatedWhites(prevCount, blacks));
102 | // start with fresh color count
103 | prevColor = curColor;
104 | prevCount = 0;
105 | continue; // to next pixel
106 | }
107 |
108 | if (prevCount >= 8)
109 | {
110 | data.Add(CompressedByte.RepeatedWhites(prevCount));
111 | // start with fresh color count
112 | prevColor = curColor;
113 | prevCount = 1;
114 | }
115 | else
116 | {
117 | data.Add(CompressedByte.RepeatedWhites(prevCount, curColor));
118 | prevColor = curColor;
119 | prevCount = 0;
120 | }
121 |
122 | continue; // to next pixel
123 | }
124 |
125 | if (prevColor == 7)
126 | {
127 | while (prevCount >= 31)
128 | {
129 | data.Add(CompressedByte.RepeatedBlacks(31));
130 | prevCount -= 31;
131 | }
132 |
133 | switch (prevCount)
134 | {
135 | case 0: // start with fresh color count
136 | prevColor = curColor;
137 | prevCount = 1;
138 | break;
139 | case 1:
140 | data.Add(CompressedByte.AlphaColors(prevColor, curColor)); // one black + one color
141 | prevCount = 0;
142 | prevColor = curColor;
143 | break;
144 | default:
145 | data.Add(CompressedByte.RepeatedBlacks(prevCount)); // remaining blacks
146 | prevColor = curColor;
147 | prevCount = 1;
148 | break;
149 | }
150 |
151 | continue; // to next pixel
152 | }
153 |
154 | // a grayscale
155 | antialias = true;
156 |
157 | while (prevCount >= 2)
158 | {
159 | data.Add(CompressedByte.AlphaColors(prevColor, prevColor));
160 | prevCount -= 2;
161 | }
162 |
163 | if (prevCount == 0)
164 | {
165 | prevColor = curColor;
166 | prevCount = 1;
167 | }
168 | else
169 | {
170 | data.Add(CompressedByte.AlphaColors(prevColor, curColor)); // one black + one color
171 | prevColor = curColor;
172 | prevCount = 0;
173 | }
174 | continue; // to next pixel
175 |
176 | }
177 | }
178 |
179 | /* Handle remainder stored in PrevColor and PreCount */
180 |
181 | if (prevCount > 0) // more previous data to encode
182 | {
183 | // remaining whites
184 | if (prevColor == 0)
185 | {
186 | while (prevCount >= 31)
187 | {
188 | data.Add(CompressedByte.RepeatedWhites(31));
189 | prevCount -= 31;
190 | }
191 |
192 | if (prevCount > 0)
193 | {
194 | data.Add(CompressedByte.RepeatedWhites(prevCount));
195 | }
196 |
197 | return data.ToArray();
198 | }
199 |
200 | // remaining blacks
201 | if (prevColor == 7)
202 | {
203 | while (prevCount >= 31)
204 | {
205 | data.Add(CompressedByte.RepeatedBlacks(31));
206 | prevCount -= 31;
207 | }
208 |
209 | if (prevCount > 0)
210 | {
211 | data.Add(CompressedByte.RepeatedBlacks(prevCount));
212 | }
213 |
214 | return data.ToArray();
215 | }
216 |
217 | // remaining grayscales
218 | while (prevCount >= 2)
219 | {
220 | data.Add(CompressedByte.AlphaColors(prevColor, prevColor));
221 | prevCount -= 2;
222 | }
223 |
224 | if (prevCount > 0)
225 | {
226 | data.Add(CompressedByte.RepeatedWhites((byte)0, prevColor)); // zero whites + one color
227 | }
228 | }
229 |
230 | return data.ToArray();
231 | }
232 | }
233 | }
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/FormFontPreview.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
124 |
125 |
126 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
127 | YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADzSURBVDhPY6AYTKty+Y+OZ9S41kKlCQOQhtsbUuH4yqqk
128 | /3Pq3b7NrHWrgyrBD9ANQDYE2VXYME4DiMG0N+DMkrj/q7v9UZyMiZ2+gA3Ahhc2e/8/vzbr/+czLf+/
129 | nmvFwE8PVP2fXeP6GGzAsnY/rIrw4Vvbiv7Prnc/ATZg46QwrIrw4fNrsv/PqXNfCjZg39wErIrw4SOL
130 | k/9Pr3ZuYJhZ4/b/1MoMrIrw4W3To/5PrXRKZpjT4PH/2uYCrIrw4ZXdQf+nVri6Mcyp9/j/aF8FVkX4
131 | 8IIm7//TK520GGZUu2KNRmLwxHoPPnBiIh8wMAAAq106cVRsxHIAAAAASUVORK5CYII=
132 |
133 |
134 |
135 | 122, 17
136 |
137 |
138 |
139 | AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAANcNAADXDQAAAAAAAAAA
140 | AACejnzAno1765qKejAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
141 | AAAAAAAAno1766+fjP2ejnvvm4l2KQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
142 | AAAAAAAAAAAAAJ2LeTmejXryqZqG/Z+NeeebiXYcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
143 | AAAAAAAAAAAAAAAAAAAAAAAAnY13L5+Ne++klIH9oI564ZeLdBYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
144 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACajXkmno566qGRfv2fjXvZoouAFp6NeWmikX3YnYx5+52M
145 | efuikX3XnYx4aJmZZgUAAAAAAAAAAAAAAAAAAAAAAAAAAJ2JdhqfjnrhnIt4/6KQffm5p5Hz59W8//zq
146 | zv/86s7/59W7/7emkfKhkX3ZnYl2GgAAAAAAAAAAAAAAAAAAAAAAAAAAn494IKGQfPvNuqT//+3R///t
147 | 0f//7dH//+3R///t0f//7dH/zLqk/KGRfNqqgIAGAAAAAAAAAAAAAAAAAAAAAJ6NeW62pY/2/+3R///t
148 | 0f//7dH//+3R///t0f//7dH//+3R///t0f+2pY/0no54bAAAAAAAAAAAAAAAAAAAAACjkn7Z59W7///t
149 | 0f//7dH//+3R///t0f//7dH//+3R///t0f//7dH/5tW7/6ORftYAAAAAAAAAAAAAAAAAAAAAno16+fvp
150 | zf//7dH//+3R///t0f//7dH//+3R///t0f//7dH//+3R//rozP+ejXr4AAAAAAAAAAAAAAAAAAAAAJ6N
151 | evn76c3//+3R///t0f//7dH//+3R///t0f//7dH//+3R///t0f/66Mz/no16+AAAAAAAAAAAAAAAAAAA
152 | AACikn/Z59W7///t0f//7dH//+3R///t0f//7dH//+3R///t0f//7dH/5tW7/6KRftYAAAAAAAAAAAAA
153 | AAAAAAAAno95dLelkPX/7dH//+3R///t0f//7dH//+3R///t0f//7dH//+3R/7alj/Sfj3lyAAAAAAAA
154 | AAAAAAAAAAAAAJ+AgAiikHvd0b+o/P/t0f//7dH//+3R///t0f//7dH//+3R/9C+qPyhkXzakpJtBwAA
155 | AAAAAAAAAAAAAAAAAAAAAAAAoY57G6GQfdq5qJL059W8//jmy//45sv/59W7/7mnkfShkX3ZnYl2GgAA
156 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACqgIAGoZB9bKKSftmfj3v1n4979aORfdigj3xrmZlmBQAA
157 | AAAAAAAAH/8AAA//AAAH/wAAg/8AAMADAADgAQAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAA
158 | AAD4AQAA/AMAAA==
159 |
160 |
161 |
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/FormAddCharacters.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 48
122 |
123 |
124 | 130, 48
125 |
126 |
127 |
128 |
129 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
130 | YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAClSURBVDhPY6AK6C5d+B8ZF9dN/59W2Y+BS2pn/O+vXFID
131 | 1YYAIE13rn4C42O7noEVP3z9CQODxKfWr/7WX724DqoVAggZUNE9B27A1bOv/0+rX/ulr3JpG1Q7aQaA
132 | 1Fw58wrsVah2VANOH3j5v657CVgxOm6euByuDqcBxGLaGUAI0MeAQy+wYxAgygB8gCgDsNkOwiBAlAH4
133 | AE4DyMFQ7ZQABgYA8IyChn1Fh6IAAAAASUVORK5CYII=
134 |
135 |
136 |
137 | 76
138 |
139 |
140 |
141 | AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAANcNAADXDQAAAAAAAAAA
142 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
143 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
144 | AAAAAAAAAAAAAI95ZtSPeWb/j3pmwQAAAAAAAAAAAAAAAAAAAAAAAAAAj3pmwY95Zv+OeWbVAAAAAAAA
145 | AAAAAAAAAAAAAAAAAACQeWV+j3lm/495ZvqSgG0OAAAAAAAAAAAAAAAAiHdmD495ZvqPeWb/j3pmgAAA
146 | AAAAAAAAAAAAAAAAAAAAAAAAj3ZkKY95Zv+PeWb/j3lm/495Zv+PeWb/j3lm/495Zv+PeWb/j3lm/5F6
147 | aCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPeWbhj3lm/494Zv+PeWb/j3lm/495Zv+PeWb/j3lm/494
148 | ZdsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj3hme495Zv+PeWbl/wAAAQAAAAD/AAABj3lm5Y95
149 | Zv+PemaCAAAAAAAAAAAAAAAAj3lm/wAAAAAAAAAAAAAAAJF8ZyWPeWb/j3lm/414aDEAAAAAj3pmMo95
150 | Zv+PeWb/kHpkLgAAAAAAAAAAAAAAAI95Zv8AAAAAAAAAAAAAAAAAAAAAj3lmzY95Zv+PeGZ7AAAAAJB5
151 | Z3yPeWb/j3lm2QAAAAAAAAAAj3lm/495Zv+PeWb/j3lm/495Zv8AAAAAAAAAAJB4Z3ePeWb/j3llxAAA
152 | AACOeGbFj3lm/496ZoQAAAAAAAAAAAAAAAAAAAAAj3lm/wAAAAAAAAAAAAAAAAAAAACSfGYjj3lm/495
153 | ZvuPeGkij3lm+495Zv+PemUwAAAAAAAAAAAAAAAAAAAAAI95Zv8AAAAAAAAAAAAAAAAAAAAAAAAAAI95
154 | ZsaPeWb/j3hmto95Zv+PeGbYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
155 | AACOemZzj3lm/495Zv+PeWb/kHlmhwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
156 | AAAAAAAAknZkHI95Zv2PeWb/j3lm/496ZTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
157 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
158 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
159 | AAAAAAAA//8AAP//AAAfHwAADh8AAAAfAACAPwAAhDsAAIQ7AADEYAAAxHsAAMB7AADg/wAA4P8AAOD/
160 | AAD//wAA//8AAA==
161 |
162 |
163 |
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/FormFontGenerator.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 48
122 |
123 |
124 | 130, 48
125 |
126 |
127 |
128 |
129 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
130 | YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAClSURBVDhPY6AK6C5d+B8ZF9dN/59W2Y+BS2pn/O+vXFID
131 | 1YYAIE13rn4C42O7noEVP3z9CQODxKfWr/7WX724DqoVAggZUNE9B27A1bOv/0+rX/ulr3JpG1Q7aQaA
132 | 1Fw58wrsVah2VANOH3j5v657CVgxOm6euByuDqcBxGLaGUAI0MeAQy+wYxAgygB8gCgDsNkOwiBAlAH4
133 | AE4DyMFQ7ZQABgYA8IyChn1Fh6IAAAAASUVORK5CYII=
134 |
135 |
136 |
137 | 76
138 |
139 |
140 |
141 | AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAANcNAADXDQAAAAAAAAAA
142 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
143 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
144 | AAAAAAAAAAAAAI95ZtSPeWb/j3pmwQAAAAAAAAAAAAAAAAAAAAAAAAAAj3pmwY95Zv+OeWbVAAAAAAAA
145 | AAAAAAAAAAAAAAAAAACQeWV+j3lm/495ZvqSgG0OAAAAAAAAAAAAAAAAiHdmD495ZvqPeWb/j3pmgAAA
146 | AAAAAAAAAAAAAAAAAAAAAAAAj3ZkKY95Zv+PeWb/j3lm/495Zv+PeWb/j3lm/495Zv+PeWb/j3lm/5F6
147 | aCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPeWbhj3lm/494Zv+PeWb/j3lm/495Zv+PeWb/j3lm/494
148 | ZdsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj3hme495Zv+PeWbl/wAAAQAAAAD/AAABj3lm5Y95
149 | Zv+PemaCAAAAAAAAAAAAAAAAj3lm/wAAAAAAAAAAAAAAAJF8ZyWPeWb/j3lm/414aDEAAAAAj3pmMo95
150 | Zv+PeWb/kHpkLgAAAAAAAAAAAAAAAI95Zv8AAAAAAAAAAAAAAAAAAAAAj3lmzY95Zv+PeGZ7AAAAAJB5
151 | Z3yPeWb/j3lm2QAAAAAAAAAAj3lm/495Zv+PeWb/j3lm/495Zv8AAAAAAAAAAJB4Z3ePeWb/j3llxAAA
152 | AACOeGbFj3lm/496ZoQAAAAAAAAAAAAAAAAAAAAAj3lm/wAAAAAAAAAAAAAAAAAAAACSfGYjj3lm/495
153 | ZvuPeGkij3lm+495Zv+PemUwAAAAAAAAAAAAAAAAAAAAAI95Zv8AAAAAAAAAAAAAAAAAAAAAAAAAAI95
154 | ZsaPeWb/j3hmto95Zv+PeGbYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
155 | AACOemZzj3lm/495Zv+PeWb/kHlmhwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
156 | AAAAAAAAknZkHI95Zv2PeWb/j3lm/496ZTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
157 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
158 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
159 | AAAAAAAA//8AAP//AAAfHwAADh8AAAAfAACAPwAAhDsAAIQ7AADEYAAAxHsAAMB7AADg/wAA4P8AAOD/
160 | AAD//wAA//8AAA==
161 |
162 |
163 |
--------------------------------------------------------------------------------
/Docs/Nextion Font Format Specification ZI version 3.md:
--------------------------------------------------------------------------------
1 | # Nextion Font Format Specification
2 | This is a reverse engineered specification of the Nextion font format. Use at own risk.
3 |
4 | ## General information
5 |
6 | The Nextion Font Format is a proprietary font format used by the Nextion Editor HMI software. Nextion Editor has a built in "Font Generator"-tool which converts standard fonts into .zi files that is compatible with the Nextion HMI displays.
7 |
8 | | Information | |
9 | |-------------------------|-----------------------|
10 | | **Software** | Nextion Editor V0.53 |
11 | | **File extension** | .zi |
12 | | **File format version** | ZI version 3 |
13 | | **Example file** | Arial_40_ascii.zi |
14 |
15 | ## Code pages / character encoding reference
16 |
17 | | Code page / encoding | Value | Number of characters |
18 | |-----------------------|-----------------------|-----------------------|
19 | | ASCII | 0x01 | 95 |
20 | | GB2312 | 0x02 | 8273 |
21 | | ISO-8859-1 | 0x03 | 224 |
22 | | ISO-8859-2 | 0x04 | 224 |
23 | | ISO-8859-3 | 0x05 | 224 |
24 | | ISO-8859-4 | 0x06 | 224 |
25 | | ISO-8859-5 | 0x07 | 224 |
26 | | ISO-8859-6 | 0x08 | 224 |
27 | | ISO-8859-7 | 0x09 | 224 |
28 | | BIG5 | 0x1001 | 14225 |
29 | | ISO-8859-8 | 0x0A | 224 |
30 | | ISO-8859-9 | 0x0B | 224 |
31 | | ISO-8859-13 | 0x0C | 224 |
32 | | ISO-8859-15 | 0x0D | 224 |
33 | | ISO-8859-11 | 0x0E | 224 |
34 | | KS_C_5601-1987 | 0x0F | 3855 |
35 | | WINDOWS-1255 | 0x11 | 224 |
36 | | WINDOWS-1256 | 0x12 | 224 |
37 | | WINDOWS-1257 | 0x13 | 224 |
38 | | WINDOWS-1258 | 0x14 | 224 |
39 | | WINDOWS-874 | 0x15 | 224 |
40 | | KOI8-R | 0x16 | 224 |
41 |
42 |
43 | ## File format structure
44 |
45 | ### Fixed header
46 |
47 | **Length:** 0x1C (28)
48 |
49 | ```
50 | 0x00000000: 04 FF 00 0A 01 00 14 28 00 00 20 7E 5F 00 00 00
51 | 0x00000010: 03 0E 0E 00 2A 25 00 00 00 00 00 00
52 | ```
53 |
54 | | Offset | Length | Data | Type | Value | Description |
55 | |------------|-------:|--------------------------------------------------|--------|--------------------:|---------------------------------------------------------------------------------------|
56 | | 0x00000000 | 4 | `04 FF 00 0A` * | byte[] | | File signature / magic numbers |
57 | | 0x00000004 | 2 | `01 00` | uint16 | 1 | Code page / character encoding (possible values listed in the reference table) |
58 | | 0x00000006 | 1 | `14` | byte | 20 | Character width |
59 | | 0x00000007 | 1 | `28` | byte | 40 | Character height |
60 | | 0x00000008 | 1 | `00` | byte | 0 | Code page multibyte - first byte start |
61 | | 0x00000009 | 1 | `00` | byte | 0 | Code page multibyte - first byte end |
62 | | 0x0000000A | 1 | `20` | byte | 32, ' ' (ASCII) | Code page start / multibyte second byte start |
63 | | 0x0000000B | 1 | `7E` | byte | 126, '~' (ASCII) | Code page end / multibyte second byte end |
64 | | 0x0000000C | 4 | `5F 00 00 00` | uint32 | 95 | Number of characters in file |
65 | | 0x00000010 | 1 | `03` | byte | 3 | File Format Version |
66 | | 0x00000011 | 1 | `0E` | byte | 14 | Length of font name |
67 | | 0x00000012 | 1 | `0E` | byte | 14 | Also length of font name? Always the same value as 0x11 |
68 | | 0x00000013 | 1 | `00` | byte | 0 | Reserved |
69 | | 0x00000014 | 4 | `2A 25 00 00` | uint32 | 9514 | Total length of font name and character data |
70 | | 0x00000018 | 4 | `00 00 00 00` | uint32 | 0 | Reserved |
71 |
72 | > **\* The file signature/magic bytes for a .zi file containing the `BIG5` code page is different from all other files. For `BIG5` the magic bytes are `04 7E 22 0A`. Which means that the second and third byte might be variable and have some meaning beyond being magic numbers.**
73 |
74 | ### Font name
75 | Variable length font name. In this case the font name is `0x0E (14)` bytes long as seen in offset `0x00000011`.
76 |
77 | ```
78 | 0x00000010: 03 0E 0E 00 2A 25 00 00 00 00 00 00 41 72 69 61
79 | 0x00000020: 6C 5F 34 30 5F 61 73 63 69 69 00 00 00 00 00 00
80 | ```
81 |
82 | | Offset | Length | Data | Type | Value | Description |
83 | |------------|-------:|--------------------------------------------------|--------|--------------------:|------------------------------------------------------------------|
84 | | 0x0000001C | 14 | `41 72 69 61 6C 5F 34 30 5F 61 73 63 69 69` | string | Arial_40_ascii | Font name |
85 |
86 | ### Character data
87 |
88 | The rest of the file contains the actual character data. The length of each character is calculated like this: `character width * character height / 8`. In our example we get; `20 * 40 / 8` which gives us `100` bytes per character. Characters are monochrome, which means that each bit in the `100` bytes gives us one pixel. `20 * 40 = 800 pixels`.
89 |
90 | Example data for one character. This is the exclamation mark character (`!`), which is the second character in the file. I skipped the first one, beacuse that is the space character which is blank.
91 |
92 | ```
93 | 0x00000080: 00 00
94 | 0x00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
95 | 0x000000a0: 00 00 00 00 01 E0 00 1E 00 01 E0 00 1E 00 01 E0
96 | 0x000000b0: 00 1E 00 00 E0 00 0E 00 00 E0 00 0E 00 00 E0 00
97 | 0x000000c0: 0E 00 00 E0 00 0E 00 00 E0 00 0E 00 00 00 00 00
98 | 0x000000d0: 00 01 E0 00 1E 00 01 E0 00 00 00 00 00 00 00 00
99 | 0x000000e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
100 | 0x000000f0: 00 00
101 | ```
102 |
103 | The rest of the file contains the remaining characters supported by the font.
104 |
105 | ### Character data example for a 16 pixels tall exclamation mark (`!`) character
106 |
107 | This example shows how to read the pixel data for a character. The height of character is `16` pixels, which means it is `8` pixels wide. This gives us a total of `128` pixels. This also means that each of the `16` bytes contains the data for one line of pixels.
108 |
109 | ```
110 | 0x00000030: 00 00 00 00 60 60
111 | 0x00000040: 60 60 60 60 00 60 00 00 00 00
112 | ```
113 |
114 | Let's look at the bits of each byte:
115 |
116 | ```
117 | 00: 0 0 0 0 0 0 0 0
118 | 00: 0 0 0 0 0 0 0 0
119 | 00: 0 0 0 0 0 0 0 0
120 | 00: 0 0 0 0 0 0 0 0
121 | 60: 0 1 1 0 0 0 0 0
122 | 60: 0 1 1 0 0 0 0 0
123 | 60: 0 1 1 0 0 0 0 0
124 | 60: 0 1 1 0 0 0 0 0
125 | 60: 0 1 1 0 0 0 0 0
126 | 60: 0 1 1 0 0 0 0 0
127 | 00: 0 0 0 0 0 0 0 0
128 | 60: 0 1 1 0 0 0 0 0
129 | 00: 0 0 0 0 0 0 0 0
130 | 00: 0 0 0 0 0 0 0 0
131 | 00: 0 0 0 0 0 0 0 0
132 | 00: 0 0 0 0 0 0 0 0
133 | ```
134 |
135 | Now let's remove the zeroes (blank pixel) and replace the ones with an X:
136 |
137 | ```
138 | 00:
139 | 00:
140 | 00:
141 | 00:
142 | 60: X X
143 | 60: X X
144 | 60: X X
145 | 60: X X
146 | 60: X X
147 | 60: X X
148 | 00:
149 | 60: X X
150 | 00:
151 | 00:
152 | 00:
153 | 00:
154 | ```
155 |
156 | ❗️ There's our exclamation mark ❗️
157 |
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/BinaryTools.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Collections.Generic;
3 | using ZiLib.FileVersion.V5;
4 |
5 | namespace ZiLib {
6 |
7 | public class BinaryTools {
8 |
9 | public static bool[] BytesToBits(byte[] bytes) {
10 | bool[] bits = new bool[bytes.Length * 8];
11 |
12 | for (int i = 0; i < bytes.Length; i++) {
13 | for (int j = 0; j < 8; j++) {
14 | var index = i * 8 + j;
15 | bits[index] = (bytes[i] & (1 << (7 - j))) != 0;
16 | }
17 | }
18 |
19 | return bits;
20 | }
21 |
22 | public static byte[] BitmapTo1BppData(Bitmap b, bool invertColour=false) {
23 | var pixels = new bool[b.Width * b.Height];
24 |
25 | var A = invertColour ? Color.White.A : Color.Black.A;
26 | var B = invertColour ? Color.White.B : Color.Black.B;
27 | var G = invertColour ? Color.White.G : Color.Black.G;
28 | var R = invertColour ? Color.White.R : Color.Black.R;
29 | for (int y = 0; y < b.Height; y++) {
30 |
31 | for (int x = 0; x < b.Width; x++) {
32 | var pixel = b.GetPixel(x, y);
33 | pixels[(y * b.Width) + x] = (pixel.A == A && pixel.R == R && pixel.G == G && pixel.B == B);
34 | }
35 |
36 | }
37 |
38 | var data = new byte[b.Width * b.Height / 8];
39 |
40 | for (int i = 0; i < data.Length; i++) {
41 |
42 | for (int j = 0; j < 8; j++) {
43 |
44 | var bit = pixels[(i * 8) + j] ? 1 : 0;
45 | data[i] |= (byte) (bit << (7 - j));
46 |
47 | }
48 |
49 | }
50 |
51 | return data;
52 | }
53 |
54 | /*
55 | public static byte[] BitmapTo3BppData(Bitmap b, bool invertColour = false)
56 | {
57 | var pixels = new byte[b.Width * b.Height];
58 |
59 | for (int y = 0; y < b.Height; y++)
60 | {
61 |
62 | for (int x = 0; x < b.Width; x++)
63 | {
64 |
65 | var pixel = b.GetPixel(x, y);
66 | pixels[(y * b.Width) + x] = (byte)((pixel.R + 2 * pixel.G + pixel.B) / 4 * pixel.A / 255); // Weighted Color2Grayscale;
67 |
68 | if (!invertColour)
69 | {
70 | pixels[(y * b.Width) + x] = (byte)(255 - pixels[(y * b.Width) + x]);
71 | }
72 |
73 | // convert to 3 bits
74 | pixels[(y * b.Width) + x] = (byte)(pixels[(y * b.Width) + x] >> 5);
75 |
76 | }
77 |
78 | }
79 |
80 | return pixels;
81 | }
82 | */
83 |
84 | /* A faster 3-bit encoder and compresser combined into one loop instead of consecutive nested loops */
85 | public static byte[] BitmapTo3BppData(Bitmap b, bool invertColour = false)
86 | {
87 | var data = new List();
88 |
89 | var curColor = (byte)0u;
90 | var prevColor = (byte)0u;
91 | var prevCount = 0u;
92 |
93 | var antialias = false;
94 |
95 | data.Add(0x03);
96 |
97 | for (int y = 0; y < b.Height; y++)
98 | {
99 | for (int x = 0; x < b.Width; x++)
100 | {
101 | var pixel = b.GetPixel(x, y);
102 |
103 | if (invertColour)
104 | {
105 | curColor = (byte)((pixel.R + 2 * pixel.G + pixel.B) / 4); // Weighted Color2Grayscale;
106 | }
107 | else
108 | {
109 | curColor = (byte)(255 - (pixel.R + 2 * pixel.G + pixel.B) / 4); // Weighted Color2Grayscale;
110 | }
111 | curColor = (byte)(curColor * pixel.A / 255);
112 | // convert to 3 bits
113 | curColor = (byte)(curColor >> 5);
114 |
115 | if (curColor == prevColor) {
116 | prevCount++;
117 | continue; // to next pixel
118 | }
119 |
120 | if (prevCount == 0) // No previous data to encode
121 | {
122 | prevColor = curColor;
123 | prevCount = 1;
124 | continue; // to next pixel
125 | }
126 |
127 | if (prevColor == 0)
128 | {
129 | while (prevCount >= 31) {
130 | data.Add(CompressedByte.RepeatedWhites(31));
131 | prevCount -= 31;
132 | }
133 |
134 | if (prevCount == 0)
135 | {
136 | // start with fresh color count
137 | prevColor = curColor;
138 | prevCount = 1;
139 | continue; // to next pixel
140 | }
141 |
142 | if (curColor == 7)
143 | {
144 | data.Add(CompressedByte.RepeatedWhites(prevCount, 1u));
145 | // start with fresh color count
146 | prevColor = curColor;
147 | prevCount = 0;
148 | continue; // to next pixel
149 | }
150 |
151 | if (prevCount >= 8)
152 | {
153 | data.Add(CompressedByte.RepeatedWhites(prevCount));
154 | // start with fresh color count
155 | prevColor = curColor;
156 | prevCount = 1;
157 | }
158 | else
159 | {
160 | data.Add(CompressedByte.RepeatedWhites(prevCount, curColor));
161 | prevColor = curColor;
162 | prevCount = 0;
163 | }
164 |
165 | continue; // to next pixel
166 | }
167 |
168 | if (prevColor == 7)
169 | {
170 | while (prevCount >= 31)
171 | {
172 | data.Add(CompressedByte.RepeatedBlacks(31));
173 | prevCount -= 31;
174 | }
175 |
176 | if (prevCount > 1)
177 | {
178 | data.Add(CompressedByte.RepeatedBlacks(prevCount)); // remaining blacks
179 | prevCount = 1;
180 | }
181 | else
182 | {
183 | data.Add(CompressedByte.AlphaColors(prevColor, curColor)); // one black + one color
184 | prevCount = 0;
185 | }
186 | prevColor = curColor;
187 | continue; // to next pixel
188 | }
189 |
190 | // a grayscale
191 | antialias = true;
192 |
193 | while (prevCount >= 2)
194 | {
195 | data.Add(CompressedByte.AlphaColors(prevColor, prevColor));
196 | prevCount -= 2;
197 | }
198 |
199 | if (prevCount == 0)
200 | {
201 | prevCount = 1;
202 | }
203 | else
204 | {
205 | data.Add(CompressedByte.AlphaColors(prevColor, curColor)); // one black + one color
206 | prevCount = 0;
207 | }
208 | prevColor = curColor;
209 | continue; // to next pixel
210 |
211 | }
212 | }
213 |
214 | /* Handle remainder stored in PrevColor and PreCount */
215 |
216 | if (prevCount == 0) // no more previous data to encode
217 | {
218 | return data.ToArray();
219 | }
220 |
221 | if (prevColor == 0)
222 | {
223 | while (prevCount >= 31)
224 | {
225 | data.Add(CompressedByte.RepeatedWhites(31));
226 | prevCount -= 31;
227 | }
228 |
229 | if (prevCount > 0)
230 | {
231 | data.Add(CompressedByte.RepeatedWhites(prevCount));
232 | }
233 |
234 | return data.ToArray();
235 | }
236 |
237 | if (prevColor == 7)
238 | {
239 | while (prevCount >= 31)
240 | {
241 | data.Add(CompressedByte.RepeatedBlacks(31));
242 | prevCount -= 31;
243 | }
244 |
245 | if (prevCount > 0)
246 | {
247 | data.Add(CompressedByte.RepeatedBlacks(prevCount));
248 | }
249 |
250 | return data.ToArray();
251 | }
252 |
253 | // a grayscale
254 | while (prevCount >= 2)
255 | {
256 | data.Add(CompressedByte.AlphaColors(prevColor, prevColor));
257 | prevCount -= 2;
258 | }
259 |
260 | if (prevCount > 0)
261 | {
262 | data.Add(CompressedByte.RepeatedWhites((byte)0, prevColor)); // zero whites + one color
263 | }
264 |
265 | return data.ToArray();
266 | }
267 | }
268 | }
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/FormFontSuite.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace NextionFontEditor {
2 | partial class FormFontSuite {
3 | ///
4 | /// Required designer variable.
5 | ///
6 | private System.ComponentModel.IContainer components = null;
7 |
8 | ///
9 | /// Clean up any resources being used.
10 | ///
11 | /// true if managed resources should be disposed; otherwise, false.
12 | protected override void Dispose(bool disposing) {
13 | if (disposing && (components != null)) {
14 | components.Dispose();
15 | }
16 | base.Dispose(disposing);
17 | }
18 |
19 | #region Windows Form Designer generated code
20 |
21 | ///
22 | /// Required method for Designer support - do not modify
23 | /// the contents of this method with the code editor.
24 | ///
25 | private void InitializeComponent() {
26 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormFontSuite));
27 | this.statusStrip = new System.Windows.Forms.StatusStrip();
28 | this.lblStatusStatic = new System.Windows.Forms.ToolStripStatusLabel();
29 | this.toolStrip1 = new System.Windows.Forms.ToolStrip();
30 | this.btnNewFontGenerator = new System.Windows.Forms.ToolStripButton();
31 | this.btnNewFontEditor = new System.Windows.Forms.ToolStripButton();
32 | this.btnNewFontPreview = new System.Windows.Forms.ToolStripButton();
33 | this.menuStrip1 = new System.Windows.Forms.MenuStrip();
34 | this.mnuFile = new System.Windows.Forms.ToolStripMenuItem();
35 | this.mnuFileExit = new System.Windows.Forms.ToolStripMenuItem();
36 | this.mnuAbout = new System.Windows.Forms.ToolStripMenuItem();
37 | this.mnuAboutCredit = new System.Windows.Forms.ToolStripMenuItem();
38 | this.mnuAboutIcons = new System.Windows.Forms.ToolStripMenuItem();
39 | this.statusStrip.SuspendLayout();
40 | this.toolStrip1.SuspendLayout();
41 | this.menuStrip1.SuspendLayout();
42 | this.SuspendLayout();
43 | //
44 | // statusStrip
45 | //
46 | this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
47 | this.lblStatusStatic});
48 | this.statusStrip.Location = new System.Drawing.Point(0, 527);
49 | this.statusStrip.Name = "statusStrip";
50 | this.statusStrip.Size = new System.Drawing.Size(961, 22);
51 | this.statusStrip.TabIndex = 1;
52 | this.statusStrip.Text = "statusStrip1";
53 | //
54 | // lblStatusStatic
55 | //
56 | this.lblStatusStatic.Name = "lblStatusStatic";
57 | this.lblStatusStatic.Size = new System.Drawing.Size(207, 17);
58 | this.lblStatusStatic.Text = "Nextion Font Suite by @hagronnestad";
59 | //
60 | // toolStrip1
61 | //
62 | this.toolStrip1.ImageScalingSize = new System.Drawing.Size(30, 30);
63 | this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
64 | this.btnNewFontGenerator,
65 | this.btnNewFontEditor,
66 | this.btnNewFontPreview});
67 | this.toolStrip1.Location = new System.Drawing.Point(0, 24);
68 | this.toolStrip1.Name = "toolStrip1";
69 | this.toolStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;
70 | this.toolStrip1.Size = new System.Drawing.Size(961, 37);
71 | this.toolStrip1.TabIndex = 2;
72 | this.toolStrip1.Text = "toolStrip1";
73 | //
74 | // btnNewFontGenerator
75 | //
76 | this.btnNewFontGenerator.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
77 | this.btnNewFontGenerator.Image = ((System.Drawing.Image)(resources.GetObject("btnNewFontGenerator.Image")));
78 | this.btnNewFontGenerator.ImageTransparentColor = System.Drawing.Color.Magenta;
79 | this.btnNewFontGenerator.Name = "btnNewFontGenerator";
80 | this.btnNewFontGenerator.Size = new System.Drawing.Size(34, 34);
81 | this.btnNewFontGenerator.Text = "Font Generator";
82 | this.btnNewFontGenerator.Click += new System.EventHandler(this.btnNewFontGenerator_Click);
83 | //
84 | // btnNewFontEditor
85 | //
86 | this.btnNewFontEditor.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
87 | this.btnNewFontEditor.Image = ((System.Drawing.Image)(resources.GetObject("btnNewFontEditor.Image")));
88 | this.btnNewFontEditor.ImageTransparentColor = System.Drawing.Color.Magenta;
89 | this.btnNewFontEditor.Name = "btnNewFontEditor";
90 | this.btnNewFontEditor.Size = new System.Drawing.Size(34, 34);
91 | this.btnNewFontEditor.Text = "Font Editor";
92 | this.btnNewFontEditor.Click += new System.EventHandler(this.btnNewFontEditor_Click);
93 | //
94 | // btnNewFontPreview
95 | //
96 | this.btnNewFontPreview.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
97 | this.btnNewFontPreview.Image = ((System.Drawing.Image)(resources.GetObject("btnNewFontPreview.Image")));
98 | this.btnNewFontPreview.ImageTransparentColor = System.Drawing.Color.Magenta;
99 | this.btnNewFontPreview.Name = "btnNewFontPreview";
100 | this.btnNewFontPreview.Size = new System.Drawing.Size(34, 34);
101 | this.btnNewFontPreview.Text = "Font Preview";
102 | this.btnNewFontPreview.Click += new System.EventHandler(this.btnNewFontPreview_Click);
103 | //
104 | // menuStrip1
105 | //
106 | this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
107 | this.mnuFile,
108 | this.mnuAbout});
109 | this.menuStrip1.Location = new System.Drawing.Point(0, 0);
110 | this.menuStrip1.Name = "menuStrip1";
111 | this.menuStrip1.Size = new System.Drawing.Size(961, 24);
112 | this.menuStrip1.TabIndex = 3;
113 | this.menuStrip1.Text = "menuStrip1";
114 | //
115 | // mnuFile
116 | //
117 | this.mnuFile.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
118 | this.mnuFileExit});
119 | this.mnuFile.Name = "mnuFile";
120 | this.mnuFile.Size = new System.Drawing.Size(37, 20);
121 | this.mnuFile.Text = "File";
122 | //
123 | // mnuFileExit
124 | //
125 | this.mnuFileExit.Name = "mnuFileExit";
126 | this.mnuFileExit.Size = new System.Drawing.Size(92, 22);
127 | this.mnuFileExit.Text = "Exit";
128 | this.mnuFileExit.Click += new System.EventHandler(this.mnuFileExit_Click);
129 | //
130 | // mnuAbout
131 | //
132 | this.mnuAbout.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
133 | this.mnuAboutCredit,
134 | this.mnuAboutIcons});
135 | this.mnuAbout.Name = "mnuAbout";
136 | this.mnuAbout.Size = new System.Drawing.Size(52, 20);
137 | this.mnuAbout.Text = "About";
138 | //
139 | // mnuAboutCredit
140 | //
141 | this.mnuAboutCredit.Enabled = false;
142 | this.mnuAboutCredit.Name = "mnuAboutCredit";
143 | this.mnuAboutCredit.Size = new System.Drawing.Size(274, 22);
144 | this.mnuAboutCredit.Text = "Nextion Font Suite by @hagronnestad";
145 | //
146 | // mnuAboutIcons
147 | //
148 | this.mnuAboutIcons.Enabled = false;
149 | this.mnuAboutIcons.Name = "mnuAboutIcons";
150 | this.mnuAboutIcons.Size = new System.Drawing.Size(274, 22);
151 | this.mnuAboutIcons.Text = "Icons by Icons8.com";
152 | //
153 | // FormFontSuite
154 | //
155 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
156 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
157 | this.ClientSize = new System.Drawing.Size(961, 549);
158 | this.Controls.Add(this.toolStrip1);
159 | this.Controls.Add(this.statusStrip);
160 | this.Controls.Add(this.menuStrip1);
161 | this.DoubleBuffered = true;
162 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
163 | this.IsMdiContainer = true;
164 | this.MainMenuStrip = this.menuStrip1;
165 | this.Name = "FormFontSuite";
166 | this.Text = "Nextion Font Suite";
167 | this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
168 | this.Load += new System.EventHandler(this.FormFontSuite_Load);
169 | this.statusStrip.ResumeLayout(false);
170 | this.statusStrip.PerformLayout();
171 | this.toolStrip1.ResumeLayout(false);
172 | this.toolStrip1.PerformLayout();
173 | this.menuStrip1.ResumeLayout(false);
174 | this.menuStrip1.PerformLayout();
175 | this.ResumeLayout(false);
176 | this.PerformLayout();
177 |
178 | }
179 |
180 | #endregion
181 |
182 | private System.Windows.Forms.StatusStrip statusStrip;
183 | private System.Windows.Forms.ToolStrip toolStrip1;
184 | private System.Windows.Forms.MenuStrip menuStrip1;
185 | private System.Windows.Forms.ToolStripMenuItem mnuFile;
186 | private System.Windows.Forms.ToolStripMenuItem mnuFileExit;
187 | private System.Windows.Forms.ToolStripMenuItem mnuAbout;
188 | private System.Windows.Forms.ToolStripMenuItem mnuAboutCredit;
189 | private System.Windows.Forms.ToolStripButton btnNewFontGenerator;
190 | private System.Windows.Forms.ToolStripButton btnNewFontEditor;
191 | private System.Windows.Forms.ToolStripButton btnNewFontPreview;
192 | private System.Windows.Forms.ToolStripStatusLabel lblStatusStatic;
193 | private System.Windows.Forms.ToolStripMenuItem mnuAboutIcons;
194 | }
195 | }
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/FileVersion/Common/CodePage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace ZiLib.FileVersion.Common
7 | {
8 |
9 | public class CodePage
10 | {
11 | public CodePageIdentifier CodePageIdentifier { get; set; }
12 |
13 | public byte FirstByteStart { get; set; }
14 | public byte FirstByteEnd { get; set; }
15 | public byte SecondByteStart { get; set; }
16 | public byte SecondByteEnd { get; set; }
17 |
18 | public byte FirstByteSkipAfter { get; set; }
19 | public byte FirstByteSkipCount { get; set; }
20 | public byte SecondByteSkipAfter { get; set; }
21 | public byte SecondByteSkipCount { get; set; }
22 |
23 | public int CharacterCount { get; set; }
24 | public ushort[] CodePoints { get; set; }
25 |
26 | public bool IsMultibyte => !Encoding.IsSingleByte; // SecondByteStart.HasValue && SecondByteEnd.HasValue;
27 |
28 | public Encoding Encoding { get; }
29 | // public byte MultiByteMode { get; } // Use Encoding.IsSingleByte
30 |
31 | public CodePage(CodePageIdentifier codePageid)
32 | {
33 | switch (codePageid)
34 | {
35 | case CodePageIdentifier.ASCII:
36 | CreateSingleByte(32, 95, codePageid);
37 | break;
38 |
39 | case CodePageIdentifier.ISO_8859_1:
40 | case CodePageIdentifier.ISO_8859_2:
41 | case CodePageIdentifier.ISO_8859_3:
42 | case CodePageIdentifier.ISO_8859_4:
43 | case CodePageIdentifier.ISO_8859_5:
44 | case CodePageIdentifier.ISO_8859_6:
45 | case CodePageIdentifier.ISO_8859_7:
46 | case CodePageIdentifier.ISO_8859_8:
47 | case CodePageIdentifier.ISO_8859_9:
48 | case CodePageIdentifier.ISO_8859_11:
49 | case CodePageIdentifier.ISO_8859_13:
50 | case CodePageIdentifier.ISO_8859_15:
51 | case CodePageIdentifier.WINDOWS_1255:
52 | case CodePageIdentifier.WINDOWS_1256:
53 | case CodePageIdentifier.WINDOWS_1257:
54 | case CodePageIdentifier.WINDOWS_1258:
55 | case CodePageIdentifier.WINDOWS_874:
56 | case CodePageIdentifier.KOI8_R:
57 | CreateSingleByte(32, 224, codePageid);
58 | break;
59 |
60 | // A1 C8 A1 FE = Swapped order
61 | case CodePageIdentifier.KS_C_5601_1987:
62 | CreateDoubleByte(0xA1, 0xC8, 0xA1, 0xFE, 0xFF, 0x00, 0xFF, 0x00, codePageid);
63 | break;
64 |
65 | // 81 EF 40 FC = Swapped order
66 | case CodePageIdentifier.SHIFT_JIS:
67 | CreateDoubleByte(0x81, 0xEF, 0x40, 0xFC, 0x9F, 0x40, 0x7E, 0x01, codePageid);
68 | break;
69 |
70 | // A1 F7 A1 FE = Swapped order
71 | case CodePageIdentifier.GB2312:
72 | CreateDoubleByte(0xA1, 0xF7, 0xA1, 0xFE, 0xff, 0x00, 0xff, 0x00, codePageid);
73 | break;
74 |
75 | // A0 F9 40 FE = Swapped order
76 | case CodePageIdentifier.BIG5:
77 | CreateDoubleByte(0xA0, 0xF9, 0x40, 0xFE, 0xFF, 0x00, 0x7E, 0x22, codePageid);
78 | break;
79 |
80 | // FF FF 00 FF = Swapped order
81 | case CodePageIdentifier.UTF_8:
82 | CreateUnicode(codePageid);
83 | break;
84 |
85 | default:
86 | break;
87 | }
88 |
89 | if (codePageid == CodePageIdentifier.UTF_8)
90 | {
91 | Encoding = Encoding.Unicode;
92 | }
93 | else
94 | {
95 | Encoding = Encoding.GetEncoding(codePageid.GetDescription());
96 | }
97 | // MultiByteMode = (byte)(Encoding.IsSingleByte ? 0 : 1);
98 | }
99 |
100 |
101 | public String GetString(int codepoint) {
102 | switch (CodePageIdentifier) {
103 | case CodePageIdentifier.ASCII:
104 | case CodePageIdentifier.ISO_8859_1:
105 | case CodePageIdentifier.ISO_8859_2:
106 | case CodePageIdentifier.ISO_8859_3:
107 | case CodePageIdentifier.ISO_8859_4:
108 | case CodePageIdentifier.ISO_8859_5:
109 | case CodePageIdentifier.ISO_8859_6:
110 | case CodePageIdentifier.ISO_8859_7:
111 | case CodePageIdentifier.ISO_8859_8:
112 | case CodePageIdentifier.ISO_8859_9:
113 | case CodePageIdentifier.ISO_8859_11:
114 | case CodePageIdentifier.ISO_8859_13:
115 | case CodePageIdentifier.ISO_8859_15:
116 | case CodePageIdentifier.WINDOWS_1255:
117 | case CodePageIdentifier.WINDOWS_1256:
118 | case CodePageIdentifier.WINDOWS_1257:
119 | case CodePageIdentifier.WINDOWS_1258:
120 | case CodePageIdentifier.WINDOWS_874:
121 | case CodePageIdentifier.KOI8_R:
122 | if ((codepoint >= 0) & (codepoint <= 255)) {
123 | var bytes = new byte[1];
124 | bytes[0] = (byte)codepoint;
125 | return Encoding.GetString(bytes);
126 | } else {
127 | return "?";
128 | }
129 |
130 | case CodePageIdentifier.KS_C_5601_1987:
131 | case CodePageIdentifier.SHIFT_JIS:
132 | case CodePageIdentifier.GB2312:
133 | case CodePageIdentifier.BIG5:
134 | if ((codepoint >= 0) & (codepoint <= 255)) {
135 | var bytes = new byte[1];
136 | bytes[0] = (byte)codepoint;
137 | return Encoding.GetString(bytes);
138 | } else if ((codepoint >= 256) & (codepoint <= 65535)) {
139 | var bytes = BitConverter.GetBytes((ushort)codepoint);
140 | return Encoding.GetString(bytes);
141 | } else {
142 | return "?";
143 | }
144 |
145 | case CodePageIdentifier.UTF_8:
146 | if (codepoint < 0x00d800 | codepoint > 0x00dfff) {
147 | return Char.ConvertFromUtf32(codepoint);
148 | } else {
149 | return "?";
150 | }
151 |
152 | default:
153 | return "?";
154 | }
155 | }
156 |
157 | private void CreateSingleByte(byte start, byte count, CodePageIdentifier codepageid)
158 | {
159 | var characters = Enumerable.Range(start, count).Select(x => (ushort)x).ToArray();
160 |
161 | FirstByteStart = start;
162 | FirstByteEnd = (byte)(start + count);
163 | SecondByteStart = SecondByteEnd = 0;
164 |
165 | // No skipped bytes
166 | FirstByteSkipAfter = SecondByteSkipAfter = 0xff;
167 | FirstByteSkipCount = SecondByteSkipCount = 0x00;
168 |
169 | CodePageIdentifier = codepageid;
170 | CodePoints = characters.ToArray();
171 | CharacterCount = CodePoints.Length;
172 | }
173 |
174 | private void CreateDoubleByte(byte outerStart, byte outerEnd, byte innerStart, byte innerEnd,
175 | byte outerSkip, byte outerCount, byte innerSkip, byte innerCount,
176 | CodePageIdentifier codepageid)
177 | {
178 | var characters = new List();
179 |
180 | // Outer Loop
181 | for (int i = outerStart; i <= outerEnd; i++)
182 | {
183 | if ((i > outerSkip) && (i <= outerSkip + outerCount))
184 | {
185 | continue; // i is in exclusion range
186 | }
187 |
188 | // Inner Loop
189 | for (int j = innerStart; j <= innerEnd; j++)
190 | {
191 | if ((j > innerSkip) && (j <= innerSkip + innerCount))
192 | {
193 | continue; // j is in exclusion range
194 | }
195 |
196 | //bytes.Add((byte) i);
197 | //bytes.Add((byte) j);
198 | characters.Add((char)(j * 256 + i));
199 | //characters.Add((uint)(i * 256 + j));
200 | }
201 | }
202 |
203 | // End with ascii standard set
204 | for (int i = 32; i <= 126; i++)
205 | {
206 | characters.Add((char)i);
207 | }
208 |
209 | SecondByteStart = outerStart;
210 | SecondByteEnd = outerEnd;
211 | FirstByteStart = innerStart;
212 | FirstByteEnd = innerEnd;
213 |
214 | SecondByteSkipAfter = outerSkip;
215 | SecondByteSkipCount = outerCount;
216 | FirstByteSkipAfter = innerSkip;
217 | FirstByteSkipCount = innerCount;
218 |
219 | CodePageIdentifier = codepageid;
220 | CodePoints = characters.ToArray();
221 | CharacterCount = CodePoints.Length;
222 | }
223 |
224 | // The TJC/Nextion UTF-8 is actually Unicode encoding
225 | private void CreateUnicode(CodePageIdentifier codepageid)
226 | {
227 | var characters = new List();
228 |
229 | SecondByteStart = FirstByteStart = SecondByteSkipCount = FirstByteSkipCount = 0;
230 | SecondByteEnd = FirstByteEnd = SecondByteSkipAfter = FirstByteSkipAfter = 255;
231 |
232 | // Outer Loop
233 | for (int i = SecondByteStart; i <= SecondByteEnd; i++)
234 | {
235 | // Inner Loop
236 | for (int j = FirstByteStart; j <= FirstByteEnd; j++)
237 | {
238 | //bytes.Add((byte) j);
239 | //bytes.Add((byte) i);
240 | characters.Add((char)(i * 256 + j));
241 | }
242 | }
243 |
244 | SecondByteStart = 255;
245 | CodePageIdentifier = codepageid;
246 | CodePoints = characters.ToArray();
247 | CharacterCount = CodePoints.Length;
248 | }
249 | }
250 | }
--------------------------------------------------------------------------------
/NextionFontEditor/NextionFontEditor/Controls/CharEditor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Drawing.Drawing2D;
4 | using System.Windows.Forms;
5 | using ZiLib;
6 |
7 | namespace NextionFontEditor.Controls {
8 |
9 | public class CharEditor : Control {
10 | private IZiCharacter _character;
11 | private Graphics _charGraphics;
12 | private int _zoom = 10;
13 | private bool _showGrid = true;
14 | private bool _showKerning = true;
15 |
16 | private Bitmap _bBuffer;
17 | private Graphics _gBuffer;
18 |
19 | private const int GUIDE_SIZE = 5;
20 |
21 | public CharEditor() : base() {
22 | BackColor = Color.WhiteSmoke;
23 | }
24 |
25 | protected override bool DoubleBuffered => true;
26 |
27 | protected override void OnCreateControl() {
28 | base.OnCreateControl();
29 |
30 | //CharImage = new Bitmap(16, 32);
31 | }
32 |
33 | protected override void OnResize(EventArgs e) {
34 | base.OnResize(e);
35 | SetSize();
36 | }
37 |
38 | protected override void OnPaintBackground(PaintEventArgs pevent) {
39 | base.OnPaintBackground(pevent);
40 | }
41 |
42 | protected override void OnPaint(PaintEventArgs e) {
43 | base.OnPaint(e);
44 | var _charImage = _character?.ToBitmap();
45 |
46 | if (_charImage != null && _bBuffer != null && _gBuffer != null) {
47 | _gBuffer.Clear(Color.Transparent);
48 | _gBuffer.DrawImage(_charImage, 0, 0, _charImage.Width * Zoom, _charImage.Height * Zoom);
49 |
50 | if (_showGrid) DrawGrid();
51 |
52 | /* Kerning updates */
53 | if (_showKerning) DrawKerning();
54 |
55 | SolidBrush bgBrush = new SolidBrush(SystemColors.ControlDark);
56 | e.Graphics.FillRectangle(bgBrush, 0, 0, _charImage.Width * Zoom, GUIDE_SIZE);
57 | e.Graphics.FillRectangle(bgBrush, 0, _charImage.Height * Zoom + GUIDE_SIZE, _charImage.Width * Zoom, GUIDE_SIZE);
58 |
59 | SolidBrush fgBrush = new SolidBrush(Color.Red);
60 | Rectangle rect = new Rectangle(2 * Zoom - GUIDE_SIZE, -GUIDE_SIZE, 2 * GUIDE_SIZE, 2 * GUIDE_SIZE);
61 | e.Graphics.FillPie(fgBrush, rect, 90, 90);
62 | fgBrush = new SolidBrush(Color.Red);
63 | rect = new Rectangle(2 * Zoom - GUIDE_SIZE, -GUIDE_SIZE, 2 * GUIDE_SIZE, 2 * GUIDE_SIZE);
64 | e.Graphics.FillPie(fgBrush, rect, 90, -90);
65 | rect = new Rectangle(2 * Zoom - GUIDE_SIZE, _charImage.Height * Zoom - GUIDE_SIZE, 2 * GUIDE_SIZE, 2 * GUIDE_SIZE);
66 | e.Graphics.FillPie(fgBrush, rect, 90, -90);
67 |
68 | fgBrush = new SolidBrush(Color.Red);
69 | rect = new Rectangle(2 * Zoom - GUIDE_SIZE, 0, 2 * GUIDE_SIZE, GUIDE_SIZE);
70 | e.Graphics.FillPie(fgBrush, rect, 270, 90);
71 | rect = new Rectangle(2 * Zoom - GUIDE_SIZE, _charImage.Height * Zoom + GUIDE_SIZE, 2 * GUIDE_SIZE, GUIDE_SIZE);
72 | e.Graphics.FillPie(fgBrush, rect, 270, 90);
73 |
74 | e.Graphics.DrawImage(_bBuffer, 0, GUIDE_SIZE, _bBuffer.Width, _bBuffer.Height);
75 | }
76 |
77 | }
78 |
79 | protected override void OnMouseClick(MouseEventArgs e) {
80 | base.OnMouseClick(e);
81 | if (e.Button != MouseButtons.Left) return;
82 | var _charImage = _character?.ToBitmap();
83 |
84 | var x = e.X / Zoom;
85 | var y = (e.Y - GUIDE_SIZE) / Zoom;
86 |
87 | if (x < 0 || x > _character?.Width - 1 || y < 0 || y > _character?.Parent.CharacterHeight - 1) return;
88 |
89 | TogglePixel(_charImage, x, y);
90 |
91 | Invalidate();
92 | Refresh();
93 | }
94 |
95 | private int lastX = -1;
96 | private int lastY = -1;
97 |
98 | protected override void OnMouseDown(MouseEventArgs e) {
99 | base.OnMouseDown(e);
100 | if (e.Button != MouseButtons.Left) return;
101 | var _charImage = _character?.ToBitmap();
102 |
103 | var x = e.X / Zoom;
104 | var y = (e.Y - GUIDE_SIZE) / Zoom;
105 |
106 | if (x < 0 || x > _charImage?.Width - 1 || y < 0 || y > _charImage?.Height - 1) return;
107 |
108 | lastX = x;
109 | lastY = y;
110 | }
111 |
112 | protected override void OnMouseMove(MouseEventArgs e) {
113 | base.OnMouseMove(e);
114 | var _charImage = _character?.ToBitmap();
115 |
116 | var x = e.X / Zoom;
117 | var y = (e.Y - GUIDE_SIZE) / Zoom;
118 |
119 | if (x < 0) x = 0;
120 | if (y < 0) y = 0;
121 | if (y > _charImage?.Height - 1) y = _charImage.Height - 1;
122 | if (x > _charImage?.Width - 1) x = _charImage.Width - 1;
123 |
124 | if (e.Button == MouseButtons.Left) {
125 | if (x != lastX || y != lastY) {
126 | TogglePixel(_charImage, lastX, lastY);
127 |
128 | Invalidate();
129 | Refresh();
130 | }
131 |
132 | lastX = x;
133 | lastY = y;
134 | }
135 | }
136 |
137 | public void Clear() {
138 | if (_charGraphics == null) return;
139 | var _charImage = _character.ToBitmap();
140 |
141 | _charGraphics.Clear(Color.Transparent);
142 | Character.SetBitmap(_charImage);
143 | var ts = (ToolStrip)this.Parent.Parent.Controls["tsCharEditor"];
144 | ts.Items["btnRevertCharacter"].Enabled = true;
145 |
146 | Invalidate();
147 | Refresh();
148 | }
149 |
150 | public void MoveCharacterX(int pixels) {
151 | if (_charGraphics == null) return;
152 | var _charImage = _character.ToBitmap();
153 |
154 | using (var b = new Bitmap(_charImage)) {
155 | _charGraphics.Clear(Color.White);
156 | _charGraphics.DrawImage(b, pixels, 0);
157 | }
158 | _charImage.Tag = true; // Bitmap is dirty or has changed
159 | var ts = (ToolStrip)this.Parent.Parent.Controls["tsCharEditor"];
160 | ts.Items["btnRevertCharacter"].Enabled = true;
161 |
162 | Invalidate();
163 | Refresh();
164 | }
165 |
166 | public void MoveCharacterY(int pixels) {
167 | if (_charGraphics == null) return;
168 | var _charImage = _character.ToBitmap();
169 |
170 | using (var b = new Bitmap(_charImage)) {
171 | _charGraphics.Clear(Color.White);
172 | _charGraphics.DrawImage(b, 0, pixels);
173 | }
174 | _charImage.Tag = true; // Bitmap is dirty or has changed
175 | var ts = (ToolStrip)this.Parent.Parent.Controls["tsCharEditor"];
176 | ts.Items["btnRevertCharacter"].Enabled = true;
177 |
178 | Invalidate();
179 | Refresh();
180 | }
181 |
182 | private void CreateBuffer() {
183 | if (_character == null) return;
184 | var _charImage = _character.ToBitmap();
185 |
186 | _bBuffer = new Bitmap(_charImage.Width * Zoom, _charImage.Height * Zoom);
187 | _gBuffer = Graphics.FromImage(_bBuffer);
188 |
189 | _gBuffer.PixelOffsetMode = PixelOffsetMode.Half;
190 | _gBuffer.InterpolationMode = InterpolationMode.NearestNeighbor;
191 | _gBuffer.SmoothingMode = SmoothingMode.None;
192 | }
193 |
194 | private void TogglePixel(Bitmap b, int x, int y) {
195 | if (x < 0 || y < 0) { return; }
196 | b = _character?.ToBitmap();
197 |
198 | if (b != null) {
199 | var p = b.GetPixel(x, y);
200 | b.SetPixel(x, y, p.A == 255 && p.R == 0 && p.G == 0 && p.B == 0 ? Color.FromArgb(0, 255, 255, 255) : Color.FromArgb(255, 0, 0, 0));
201 | Character.SetPixel(x, y, b.GetPixel(x, y));
202 | //_charImage.Tag = true; // Bitmap is dirty or has changed
203 | var ts = (ToolStrip)this.Parent.Parent.Controls["tsCharEditor"];
204 | ts.Items["btnRevertCharacter"].Enabled = true;
205 | }
206 | }
207 |
208 | private void SetSize() {
209 | if (_character == null) return;
210 |
211 | Width = _character.Width * Zoom;
212 | Height = _character.Parent.CharacterHeight * Zoom + 10;
213 | }
214 |
215 | private void DrawGrid() {
216 | if (_character == null) return;
217 | if (_gBuffer == null) return;
218 | var _charImage = _character.ToBitmap();
219 |
220 | for (int x = 0; x < _charImage.Width; x++) {
221 | _gBuffer.DrawLine(Pens.LightGray, x * Zoom, 0, x * Zoom, _charImage.Height * Zoom);
222 | }
223 |
224 | for (int y = 0; y < _charImage.Height; y++) {
225 | _gBuffer.DrawLine(Pens.LightGray, 0, y * Zoom, _charImage.Width * Zoom, y * Zoom);
226 | }
227 |
228 |
229 | _gBuffer.DrawRectangle(Pens.LightGray, 1, 1, _charImage.Width * Zoom - 1, _charImage.Height * Zoom - 1);
230 | }
231 |
232 | private void DrawKerning() {
233 | if (_character == null) return;
234 | if (_gBuffer == null) return;
235 | var _charImage = _character.ToBitmap();
236 |
237 | if (_character.KerningLeft > 0) {
238 | _gBuffer.DrawLine(Pens.Red, _character.KerningLeft * Zoom, 0, _character.KerningLeft * Zoom, _charImage.Height * Zoom);
239 | }
240 |
241 | if (_character.KerningRight > 0) {
242 | _gBuffer.DrawLine(Pens.Red, (_charImage.Width - _character.KerningRight) * Zoom, 0, (_charImage.Width - _character.KerningRight) * Zoom, _charImage.Height * Zoom);
243 | }
244 |
245 | }
246 |
247 | public IZiCharacter Character {
248 | get => _character;
249 | set {
250 | Bitmap b;
251 | _character = value;
252 | if (_character == null) {
253 | b = new Bitmap(8, 16);
254 | } else {
255 | b = _character.ToBitmap();
256 | }
257 | _charGraphics = Graphics.FromImage(b);
258 |
259 | CreateBuffer();
260 | SetSize();
261 | Invalidate();
262 | }
263 |
264 | }
265 |
266 | public int Zoom {
267 | get => _zoom;
268 | set {
269 | _zoom = value;
270 | ShowGrid = _zoom > 3;
271 | CreateBuffer();
272 | SetSize();
273 | Invalidate();
274 | }
275 | }
276 |
277 | public bool ShowGrid {
278 | get => _showGrid;
279 | set {
280 | _showGrid = value;
281 | Invalidate();
282 | }
283 | }
284 | }
285 | }
--------------------------------------------------------------------------------
/NextionFontEditor/ZiLib/FileVersion/V3/ZiCharacterV3.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Drawing;
4 | using System.Collections.Generic;
5 |
6 | namespace ZiLib.FileVersion.V3 {
7 | internal enum ValidData : byte {
8 | UNKNOWN = 0x0,
9 | TEXT = 0x01,
10 | BITMAP = 0x02,
11 | TEXT_BITMAP = 0x03,
12 | CHARDATA = 0x04,
13 | CHARDATA_BITMAP = 0x06,
14 | TEXT_CHARDATA_BITMAP = 0x07
15 | }
16 |
17 | public class ZiCharacterV3 : IZiCharacter {
18 | byte ColorMode { get; set; }
19 | private ValidData DataState { get; set; }
20 |
21 | /* Common Properties */
22 | public IZiFont Parent { get; set; }
23 | public uint CodePoint { get; set; }
24 | public byte Width { get; set; }
25 | public byte KerningLeft { get; set; }
26 | public byte KerningRight { get; set; }
27 | public Color ForegroundColor { get; set; }
28 |
29 | /* FromString Constructor */
30 | public String Txt { get; set; }
31 | public PointF TxtPosition { get; set; }
32 | public Font Font { get; set; }
33 |
34 | /* FromBitmap Constructor and after rendering with DrawString or Decode from bytes */
35 | private Bitmap _Bitmap { get; set; }
36 |
37 | /* FromBytes constructor and after encoding the bitmap */
38 | private byte[] _CharacterData { get; set; }
39 |
40 | /* Helpers */
41 | byte TotalWidth => (byte)(Parent.CharacterWidth);
42 | public byte[] ToBytes() => GetCharacterData();
43 |
44 | private ValidData OriginalFormat;
45 |
46 | /* Constructors */
47 | public ZiCharacterV3(IZiFont parent, uint codepoint, Bitmap bmp, byte kerningL = 0, byte kerningR = 0) {
48 | Parent = parent;
49 | CodePoint = codepoint;
50 | _Bitmap = new Bitmap(Parent.CharacterWidth, Parent.CharacterHeight);
51 | using (var graphics = Graphics.FromImage(_Bitmap)) {
52 | graphics.DrawImage(bmp, 0, 0);
53 | }
54 | if (_CharacterData != null) {
55 | _CharacterData = null;
56 | }
57 | KerningRight = KerningLeft = 0; // Kerning is not supported in V3
58 | Width = Parent.CharacterWidth; // Fixed Width set by Parent Font
59 | DataState = ValidData.BITMAP;
60 | OriginalFormat = DataState;
61 | ForegroundColor = Color.Green;
62 | }
63 | public ZiCharacterV3(IZiFont parent, uint codepoint, byte[] bytes, byte width=0, byte kerningL = 0, byte kerningR = 0) {
64 | Parent = parent;
65 | CodePoint = codepoint;
66 | if (_Bitmap != null && _Bitmap.PixelFormat != System.Drawing.Imaging.PixelFormat.Undefined) {
67 | _Bitmap.Dispose();
68 | }
69 | _CharacterData = bytes;
70 | KerningRight = KerningLeft = 0; // Kerning is not supported in V3
71 | DataState = ValidData.CHARDATA;
72 | OriginalFormat = DataState;
73 | Width = Parent.CharacterWidth; // Fixed Width set by Parent Font
74 | ForegroundColor = Color.Aqua;
75 | }
76 |
77 | public ZiCharacterV3(IZiFont parent, uint codepoint, Font font, PointF location, String txt = null) {
78 | Parent = parent;
79 | CodePoint = codepoint;
80 | SetString(font, location, txt);
81 | if (_Bitmap != null && _Bitmap.PixelFormat != System.Drawing.Imaging.PixelFormat.Undefined) {
82 | _Bitmap.Dispose();
83 | }
84 | if (_CharacterData != null) {
85 | _CharacterData = null;
86 | }
87 | ForegroundColor = Color.Chocolate;
88 | }
89 |
90 | /* Bitmap Operations */
91 | public void SetPixel(int x, int y, System.Drawing.Color pixel) {
92 | DataState = ValidData.BITMAP;
93 | _Bitmap.SetPixel(x, y, pixel);
94 | }
95 |
96 | public Color GetPixel(int x, int y) {
97 | var bmp = ToBitmap();
98 | return bmp.GetPixel(x, y);
99 | }
100 |
101 | public void SetPixelNumber(int number, Color color) {
102 | if (number >= _Bitmap.Width * _Bitmap.Height) {
103 | Debug.WriteLine($"!!! pixelNumber >= {_Bitmap.Width * _Bitmap.Height} !!!");
104 | return;
105 | }
106 |
107 | var l = ZiLib.Extensions.BitmapExtensions.NumberToPoint(number, _Bitmap.Width);
108 | _Bitmap.SetPixel(l.X, l.Y, color);
109 | }
110 |
111 | public Bitmap ToBitmap() {
112 | /* Check if Bitmap bit is 0 in the DataState */
113 | if ((DataState & ValidData.BITMAP) == 0) {
114 | if ((DataState & ValidData.CHARDATA) != 0) {
115 | Decode();
116 | } else {
117 | DrawString(Txt, Font, Parent.CharacterHeight, TxtPosition);
118 | Width = 0; // (byte)_Bitmap.Width;
119 | }
120 | DataState = DataState | ValidData.BITMAP;
121 | }
122 | return _Bitmap;
123 | }
124 |
125 | public void SetBitmap(Bitmap bmp) {
126 | if (_Bitmap != null && _Bitmap.PixelFormat != System.Drawing.Imaging.PixelFormat.Undefined) {
127 | using (var graphics = Graphics.FromImage(_Bitmap)) {
128 | graphics.FillRectangle(Brushes.Transparent, 0, 0, _Bitmap.Width, _Bitmap.Height);
129 | graphics.DrawImage(bmp, 0, 0);
130 | }
131 | DataState = ValidData.BITMAP;
132 | }
133 | }
134 |
135 | public String GetString() {
136 | return Parent.CodePage.GetString((int)CodePoint);
137 | }
138 |
139 | public void SetString(Font font, PointF location, String txt = null) {
140 | DataState = ValidData.TEXT;
141 | OriginalFormat = DataState;
142 |
143 | Txt = txt;
144 | TxtPosition = location;
145 | Font = font;
146 |
147 | ForegroundColor = Color.Crimson;
148 | }
149 |
150 | public Bitmap RevertBitmap() {
151 | DataState = OriginalFormat;
152 | return ToBitmap();
153 | }
154 | public bool CanRevert() {
155 | return (DataState == ValidData.BITMAP);
156 | }
157 |
158 | /* Byte Array Operations */
159 | public byte[] GetCharacterData() {
160 | /* Check if CharData bit is 0 in the DataState */
161 | if ((DataState & ValidData.CHARDATA) == 0) {
162 | if ((DataState & ValidData.BITMAP) == 0) {
163 | var b = ToBitmap();
164 | }
165 | _CharacterData = Encode(_Bitmap, false);
166 | DataState = DataState | ValidData.CHARDATA;
167 | }
168 | return _CharacterData;
169 | }
170 |
171 | private void DrawString(string txt, Font font, byte height, PointF location, byte contrast = 0) {
172 | var fontsize = (float)height;
173 |
174 | var strFormat = (StringFormat)StringFormat.GenericTypographic.Clone();
175 | strFormat.FormatFlags = strFormat.FormatFlags | StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.NoFontFallback;
176 |
177 | var tmp = new Bitmap(1, 1);
178 | var grphtmp = Graphics.FromImage(tmp);
179 |
180 | var width = Parent.CharacterWidth;
181 | //width = width > 255 ? 255 : width;
182 |
183 | if (width <= 0) {
184 | // Nextion requires a minimum width of 1 pixel. It doesn't like zero length chardata as it crashes the Application when rotating the font.
185 | _Bitmap = new Bitmap(1, height);
186 | return;
187 | }
188 |
189 | var b = new Bitmap(width + KerningLeft + KerningRight, height);
190 | location.X += KerningLeft;
191 |
192 | using (var graphics = Graphics.FromImage(b)) {
193 |
194 | //Adjust for high quality
195 | graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
196 | graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
197 | graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
198 | graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; // AntiAlias // HighQuality
199 | graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; //AntiAliasGridFit; // (B/W = SingleBitPerPixelGridFit)
200 | graphics.TextContrast = contrast;
201 |
202 | // Make sure the background is Transparent as the encoder only looks at the Alpha channel, not Text color
203 | graphics.FillRectangle(Brushes.Transparent, 0, 0, b.Width, b.Height);
204 | graphics.DrawString(txt, font, Brushes.Black, location, strFormat); // experimental
205 |
206 | //TextRenderer.DrawText(graphics, txt, font, new Point(x, y), Color.Black, Color.White);
207 | }
208 |
209 | _Bitmap = new Bitmap(b.Width, b.Height);
210 | for (var y = 0; y < b.Height; y++) {
211 | for (var x = 0; x < b.Width; x++) {
212 | var alpha = Get1bppColor(b.GetPixel(x, y), false);
213 | SetPixelNumber(y * b.Width + x, Color.FromArgb((255 / 7) * alpha, ForegroundColor));
214 | }
215 | }
216 |
217 | b.Dispose();
218 | }
219 |
220 | private byte Get1bppColor(Color pixel, bool invertColour) {
221 | var curColor = (byte)0u;
222 | if (invertColour) {
223 | curColor = (byte)(255 - pixel.A);
224 | } else {
225 | curColor = (byte)pixel.A;
226 | }
227 | // convert to 1 bits
228 | return (byte)(curColor >> 7);
229 | }
230 |
231 | private byte[] Encode(Bitmap b, bool invertColour = false) {
232 | var data = new List();
233 |
234 | return data.ToArray();
235 | }
236 |
237 | private void Decode() {
238 |
239 | var charData = _CharacterData;
240 | if (Parent.CharacterWidth > 0 && Parent.CharacterHeight > 0) {
241 | _Bitmap = new Bitmap(Parent.CharacterWidth, Parent.CharacterHeight);
242 | } else {
243 | if (_Bitmap != null && _Bitmap.PixelFormat != System.Drawing.Imaging.PixelFormat.Undefined) {
244 | _Bitmap.Dispose();
245 | }
246 | return;
247 | }
248 |
249 | var g = Graphics.FromImage(_Bitmap);
250 | var bb = new SolidBrush(Color.Black);
251 | var pr = new Pen(Color.DarkCyan);
252 |
253 | var pixels = BinaryTools.BytesToBits(_CharacterData);
254 | var pixel = 0;
255 |
256 | for (int y = 0; y < Parent.CharacterHeight; y++) {
257 | for (int x = 0; x < Parent.CharacterWidth; x++) {
258 | if (pixels[pixel]) SetPixelNumber(pixel, Color.Black); // g.FillRectangle(bb, x, y, 1, 1);
259 |
260 | pixel++;
261 | }
262 | }
263 |
264 | }
265 |
266 | }
267 | }
--------------------------------------------------------------------------------