mirror of
https://github.com/EdgeTX/edgetx.git
synced 2025-07-24 16:55:15 +03:00
Fonts optimization
This commit is contained in:
parent
d5e2f1472e
commit
6228110a48
9 changed files with 81 additions and 57 deletions
|
@ -41,7 +41,7 @@ macro(add_truetype_font_target name size subset effect)
|
||||||
endif()
|
endif()
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${target}.png ${target}.specs ${target}.lbm
|
OUTPUT ${target}.png ${target}.specs ${target}.lbm
|
||||||
COMMAND ${PYTHON_EXECUTABLE} ${TOOLS_DIR}/build-font-bitmap.py --subset ${subset} --size ${size} --font ${font}:${FONT_OFFSET} --cjk-font ${cjk_font}:${CJK_FONT_OFFSET} --output ${target}
|
COMMAND ${PYTHON_EXECUTABLE} ${TOOLS_DIR}/build-font-bitmap.py --subset ${subset} --size ${size} --font ${font} --cjk-font ${cjk_font} --output ${target}
|
||||||
COMMAND ${PYTHON_EXECUTABLE} ${LIBOPENUI_TOOLS_DIR}/encode-bitmap.py --format 8bits --rle --size-format 2 ${target}.png ${target}.lbm
|
COMMAND ${PYTHON_EXECUTABLE} ${LIBOPENUI_TOOLS_DIR}/encode-bitmap.py --format 8bits --rle --size-format 2 ${target}.png ${target}.lbm
|
||||||
DEPENDS ${TOOLS_DIR}/build-font-bitmap.py ${TOOLS_DIR}/charset.py ${LIBOPENUI_TOOLS_DIR}/encode-bitmap.py ${RADIO_SRC_DIR}/translations/cn.h.txt
|
DEPENDS ${TOOLS_DIR}/build-font-bitmap.py ${TOOLS_DIR}/charset.py ${LIBOPENUI_TOOLS_DIR}/encode-bitmap.py ${RADIO_SRC_DIR}/translations/cn.h.txt
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
set(FONT "Roboto/Roboto-Regular")
|
set(FONT "Roboto/Roboto-Regular")
|
||||||
set(FONT_BOLD "Roboto/Roboto-Bold")
|
set(FONT_BOLD "Roboto/Roboto-Bold")
|
||||||
set(FONT_OFFSET 1)
|
|
||||||
set(CJK_FONT "Noto/NotoSansCJKsc-Regular")
|
set(CJK_FONT "Noto/NotoSansCJKsc-Regular")
|
||||||
set(CJK_FONT_BOLD "Noto/NotoSansCJKsc-Bold")
|
set(CJK_FONT_BOLD "Noto/NotoSansCJKsc-Bold")
|
||||||
set(CJK_FONT_OFFSET -3)
|
|
||||||
|
|
||||||
#set(FONT "Kanit/Kanit-Regular")
|
#set(FONT "Kanit/Kanit-Regular")
|
||||||
#set(FONT_BOLD "Kanit/Kanit-Bold")
|
#set(FONT_BOLD "Kanit/Kanit-Bold")
|
||||||
#set(FONT_OFFSET -2)
|
|
||||||
|
|
||||||
#set(FONT "Ubuntu/Ubuntu-Regular")
|
#set(FONT "Ubuntu/Ubuntu-Regular")
|
||||||
#set(FONT_BOLD "Ubuntu/Ubuntu-Bold")
|
#set(FONT_BOLD "Ubuntu/Ubuntu-Bold")
|
||||||
#set(FONT_OFFSET 1)
|
|
||||||
|
|
||||||
if(TRANSLATIONS STREQUAL CN)
|
if(TRANSLATIONS STREQUAL CN)
|
||||||
set(subset all)
|
set(subset all)
|
||||||
|
|
|
@ -115,9 +115,12 @@ void FullScreenDialog::checkEvents()
|
||||||
|
|
||||||
void FullScreenDialog::deleteLater()
|
void FullScreenDialog::deleteLater()
|
||||||
{
|
{
|
||||||
|
#if !defined(HARDWARE_TOUCH)
|
||||||
if (previousFocus) {
|
if (previousFocus) {
|
||||||
previousFocus->setFocus();
|
previousFocus->setFocus();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (running) {
|
if (running) {
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,10 +113,10 @@ int getTextWidth(const char * s, int len, LcdFlags flags)
|
||||||
if (c >= 0x101)
|
if (c >= 0x101)
|
||||||
c -= 1;
|
c -= 1;
|
||||||
c += CJK_FIRST_LETTER_INDEX;
|
c += CJK_FIRST_LETTER_INDEX;
|
||||||
result += getFontPatternWidth(specs, c);
|
result += getFontPatternWidth(specs, c) + 1;
|
||||||
}
|
}
|
||||||
else if (c >= 0x20) {
|
else if (c >= 0x20) {
|
||||||
result += getCharWidth(c, specs);
|
result += getCharWidth(c, specs) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
++s;
|
++s;
|
||||||
|
|
|
@ -55,7 +55,7 @@ constexpr uint32_t FH = PAGE_LINE_HEIGHT;
|
||||||
constexpr uint32_t NUM_BODY_LINES = MENU_BODY_HEIGHT / PAGE_LINE_HEIGHT;
|
constexpr uint32_t NUM_BODY_LINES = MENU_BODY_HEIGHT / PAGE_LINE_HEIGHT;
|
||||||
|
|
||||||
constexpr uint32_t FIELD_PADDING_LEFT = 3;
|
constexpr uint32_t FIELD_PADDING_LEFT = 3;
|
||||||
constexpr uint32_t FIELD_PADDING_TOP = 0;
|
constexpr uint32_t FIELD_PADDING_TOP = 2;
|
||||||
|
|
||||||
constexpr uint32_t CURVE_SIDE_WIDTH = 100;
|
constexpr uint32_t CURVE_SIDE_WIDTH = 100;
|
||||||
constexpr uint32_t CURVE_CENTER_X = LCD_W - CURVE_SIDE_WIDTH - 7;
|
constexpr uint32_t CURVE_CENTER_X = LCD_W - CURVE_SIDE_WIDTH - 7;
|
||||||
|
|
|
@ -123,7 +123,7 @@ DRESULT __disk_write(BYTE drv, const BYTE * buff, DWORD sector, UINT count);
|
||||||
#define FLASH_PAGESIZE 256
|
#define FLASH_PAGESIZE 256
|
||||||
void unlockFlash();
|
void unlockFlash();
|
||||||
void lockFlash();
|
void lockFlash();
|
||||||
void flashWrite(uint32_t * address, uint32_t * buffer);
|
void flashWrite(uint32_t * address, const uint32_t * buffer);
|
||||||
uint32_t isFirmwareStart(const uint8_t * buffer);
|
uint32_t isFirmwareStart(const uint8_t * buffer);
|
||||||
uint32_t isBootloaderStart(const uint8_t * buffer);
|
uint32_t isBootloaderStart(const uint8_t * buffer);
|
||||||
|
|
||||||
|
@ -252,21 +252,20 @@ extern uint32_t powerupReason;
|
||||||
#define DIRTY_SHUTDOWN 0xCAFEDEAD
|
#define DIRTY_SHUTDOWN 0xCAFEDEAD
|
||||||
#define NORMAL_POWER_OFF ~DIRTY_SHUTDOWN
|
#define NORMAL_POWER_OFF ~DIRTY_SHUTDOWN
|
||||||
|
|
||||||
#define wdt_disable()
|
|
||||||
void watchdogInit(unsigned int duration);
|
void watchdogInit(unsigned int duration);
|
||||||
#if defined(SIMU)
|
#if defined(SIMU)
|
||||||
#define WAS_RESET_BY_WATCHDOG() (false)
|
#define WAS_RESET_BY_WATCHDOG() (false)
|
||||||
#define WAS_RESET_BY_SOFTWARE() (false)
|
#define WAS_RESET_BY_SOFTWARE() (false)
|
||||||
#define WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() (false)
|
#define WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() (false)
|
||||||
#define wdt_enable(x)
|
#define WDG_ENABLE(x)
|
||||||
#define wdt_reset()
|
#define WDG_RESET()
|
||||||
#else
|
#else
|
||||||
#if defined(WATCHDOG_DISABLED)
|
#if defined(WATCHDOG)
|
||||||
#define wdt_enable(x)
|
#define WDG_ENABLE(x) watchdogInit(x)
|
||||||
#define wdt_reset()
|
#define WDG_RESET() IWDG->KR = 0xAAAA
|
||||||
#else
|
#else
|
||||||
#define wdt_enable(x) watchdogInit(x)
|
#define WDG_ENABLE(x)
|
||||||
#define wdt_reset() IWDG->KR = 0xAAAA
|
#define WDG_RESET()
|
||||||
#endif
|
#endif
|
||||||
#define WAS_RESET_BY_WATCHDOG() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF))
|
#define WAS_RESET_BY_WATCHDOG() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF))
|
||||||
#define WAS_RESET_BY_SOFTWARE() (RCC->CSR & RCC_CSR_SFTRSTF)
|
#define WAS_RESET_BY_SOFTWARE() (RCC->CSR & RCC_CSR_SFTRSTF)
|
||||||
|
|
|
@ -55,7 +55,7 @@ constexpr uint32_t FH = PAGE_LINE_HEIGHT;
|
||||||
constexpr uint32_t NUM_BODY_LINES = MENU_BODY_HEIGHT / PAGE_LINE_HEIGHT;
|
constexpr uint32_t NUM_BODY_LINES = MENU_BODY_HEIGHT / PAGE_LINE_HEIGHT;
|
||||||
|
|
||||||
constexpr uint32_t FIELD_PADDING_LEFT = 3;
|
constexpr uint32_t FIELD_PADDING_LEFT = 3;
|
||||||
constexpr uint32_t FIELD_PADDING_TOP = 2;
|
constexpr uint32_t FIELD_PADDING_TOP = 3;
|
||||||
|
|
||||||
constexpr uint32_t CURVE_SIDE_WIDTH = 100;
|
constexpr uint32_t CURVE_SIDE_WIDTH = 100;
|
||||||
constexpr uint32_t CURVE_CENTER_X = LCD_W - CURVE_SIDE_WIDTH - 7;
|
constexpr uint32_t CURVE_CENTER_X = LCD_W - CURVE_SIDE_WIDTH - 7;
|
||||||
|
|
2
radio/src/thirdparty/libopenui
vendored
2
radio/src/thirdparty/libopenui
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit a86c68741a49f0cefb098d02add8dbe55b17837f
|
Subproject commit 8a17965620675f5726ade0dc8ca75927c68fb1d8
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
from PIL import Image, ImageDraw, ImageFont
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
from charset import get_chars, special_chars, extra_chars
|
from charset import get_chars, special_chars, extra_chars
|
||||||
|
|
||||||
|
@ -13,8 +14,8 @@ class FontBitmap:
|
||||||
self.font_size = font_size
|
self.font_size = font_size
|
||||||
self.foreground = foreground
|
self.foreground = foreground
|
||||||
self.background = background
|
self.background = background
|
||||||
self.font, self.font_offset = self.load_font(font_name)
|
self.font = self.load_font(font_name)
|
||||||
self.cjk_font, self.cjk_font_offset = self.load_font(cjk_font_name)
|
self.cjk_font = self.load_font(cjk_font_name)
|
||||||
self.extra_bitmap = self.load_extra_bitmap()
|
self.extra_bitmap = self.load_extra_bitmap()
|
||||||
|
|
||||||
def load_extra_bitmap(self):
|
def load_extra_bitmap(self):
|
||||||
|
@ -28,44 +29,66 @@ class FontBitmap:
|
||||||
|
|
||||||
def load_font(self, font_name):
|
def load_font(self, font_name):
|
||||||
# print(font_name)
|
# print(font_name)
|
||||||
font_name, font_offset = font_name.split(":")
|
|
||||||
for ext in (".ttf", ".otf"):
|
for ext in (".ttf", ".otf"):
|
||||||
tools_path = os.path.dirname(os.path.realpath(__file__))
|
tools_path = os.path.dirname(os.path.realpath(__file__))
|
||||||
path = os.path.join(tools_path, "../radio/src/fonts", font_name + ext)
|
path = os.path.join(tools_path, "../radio/src/fonts", font_name + ext)
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
return ImageFont.truetype(path, self.font_size), int(font_offset)
|
return ImageFont.truetype(path, self.font_size)
|
||||||
print("Font file %s not found" % font_name)
|
print("Font file %s not found" % font_name)
|
||||||
|
|
||||||
def get_char_width(self, c):
|
@staticmethod
|
||||||
if c in extra_chars:
|
def is_row_needed(px, y, width):
|
||||||
if self.extra_bitmap:
|
for x in range(width):
|
||||||
# Extra characters 16px
|
if px[x, y] != (255, 255, 255):
|
||||||
# if fontsize == 16:
|
return True
|
||||||
if extra_chars.index(c) < 9:
|
return False
|
||||||
return 13
|
|
||||||
else:
|
|
||||||
return 15
|
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
elif c == " ":
|
|
||||||
return 4
|
|
||||||
elif c in special_chars["cn"]:
|
|
||||||
w, h = self.cjk_font.getsize(c)
|
|
||||||
return w + 1
|
|
||||||
else:
|
|
||||||
w, h = self.font.getsize(c)
|
|
||||||
return w + 1
|
|
||||||
|
|
||||||
def get_width(self):
|
@staticmethod
|
||||||
width = 0
|
def is_column_needed(px, x, height):
|
||||||
for c in self.chars:
|
for y in range(height):
|
||||||
width += self.get_char_width(c)
|
if px[x, y] != (255, 255, 255):
|
||||||
return width
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_real_size(self, image):
|
||||||
|
px = image.load()
|
||||||
|
left = 0
|
||||||
|
while left < image.width:
|
||||||
|
if self.is_column_needed(px, left, image.height):
|
||||||
|
break
|
||||||
|
left += 1
|
||||||
|
right = image.width - 1
|
||||||
|
while right > left:
|
||||||
|
if self.is_column_needed(px, right, image.height):
|
||||||
|
break
|
||||||
|
right -= 1
|
||||||
|
top = 0
|
||||||
|
while top < image.height:
|
||||||
|
if self.is_row_needed(px, top, image.width):
|
||||||
|
break
|
||||||
|
top += 1
|
||||||
|
bottom = image.height - 1
|
||||||
|
while bottom > top:
|
||||||
|
if self.is_row_needed(px, bottom, image.width):
|
||||||
|
break
|
||||||
|
bottom -= 1
|
||||||
|
return left, top, right, bottom
|
||||||
|
|
||||||
|
def draw_char(self, image, x, c, font):
|
||||||
|
size = font.font.getsize(c)
|
||||||
|
width = size[0][0]
|
||||||
|
offset = size[1][0]
|
||||||
|
char_image = Image.new("RGB", (width, image.height), self.background)
|
||||||
|
draw = ImageDraw.Draw(char_image)
|
||||||
|
draw.text((-offset, 0), c, fill=self.foreground, font=font)
|
||||||
|
left, _, right, _ = self.get_real_size(char_image)
|
||||||
|
if image:
|
||||||
|
image.paste(char_image.crop((left, 0, right + 1, image.height)), (x, 0))
|
||||||
|
return right - left + 1
|
||||||
|
|
||||||
def generate(self, filename, generate_coords_file=True):
|
def generate(self, filename, generate_coords_file=True):
|
||||||
coords = [self.font_size + 4]
|
coords = []
|
||||||
width = self.get_width()
|
image = Image.new("RGB", (len(self.chars) * self.font_size, self.font_size + 10), self.background)
|
||||||
image = Image.new('RGB', (width, self.font_size + 4), self.background)
|
|
||||||
draw = ImageDraw.Draw(image)
|
draw = ImageDraw.Draw(image)
|
||||||
|
|
||||||
width = 0
|
width = 0
|
||||||
|
@ -82,16 +105,15 @@ class FontBitmap:
|
||||||
elif c == " ":
|
elif c == " ":
|
||||||
pass
|
pass
|
||||||
elif c in special_chars["cn"]:
|
elif c in special_chars["cn"]:
|
||||||
offset = self.cjk_font.getoffset(c)[0]
|
width += self.draw_char(image, width, c, self.cjk_font)
|
||||||
draw.text((width - offset, self.cjk_font_offset), c, fill=self.foreground, font=self.cjk_font)
|
|
||||||
else:
|
else:
|
||||||
offset = self.font.getoffset(c)[0]
|
width += self.draw_char(image, width, c, self.font)
|
||||||
draw.text((width - offset, self.font_offset), c, fill=self.foreground, font=self.font)
|
|
||||||
|
|
||||||
width += self.get_char_width(c)
|
|
||||||
|
|
||||||
coords.append(width)
|
coords.append(width)
|
||||||
|
|
||||||
|
_, top, _, bottom = self.get_real_size(image)
|
||||||
|
image = image.crop((0, top, width, bottom))
|
||||||
|
coords.insert(0, bottom - top)
|
||||||
|
|
||||||
image.save(filename + ".png")
|
image.save(filename + ".png")
|
||||||
if generate_coords_file:
|
if generate_coords_file:
|
||||||
with open(filename + ".specs", "w") as f:
|
with open(filename + ".specs", "w") as f:
|
||||||
|
@ -99,6 +121,10 @@ class FontBitmap:
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
if sys.version_info < (3, 0, 0):
|
||||||
|
print("%s requires Python 3. Terminating." % __file__)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Builder for OpenTX font files")
|
parser = argparse.ArgumentParser(description="Builder for OpenTX font files")
|
||||||
parser.add_argument('--output', help="Output file name")
|
parser.add_argument('--output', help="Output file name")
|
||||||
parser.add_argument('--subset', help="Subset", default="all")
|
parser.add_argument('--subset', help="Subset", default="all")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue