Created
January 16, 2021 05:32
-
-
Save andelf/4d2f7d023c92becd1ba2999d82368ab4 to your computer and use it in GitHub Desktop.
CJK Font for Rust embedded-graphics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from PIL import Image, ImageDraw, ImageFont | |
import PIL.features | |
# ! brew install libraqm | |
print('libraqm:', PIL.features.check('raqm')) | |
size = (320, 16) | |
""" | |
FORMAT = "RGB" | |
BG = (255, 255, 255) | |
FG = (0, 0, 0) | |
""" | |
FORMAT = '1' | |
BG = 0 | |
FG = 1 | |
YOFF = 0 # or -1 | |
CHARS = "气温湿度照压卧槽艹牛逼数据设备" | |
im = Image.new(FORMAT, size, BG) | |
# font = ImageFont.truetype("sarasa-mono-sc-nerd-light.ttf", size=16, index=0) | |
# font = ImageFont.truetype("sarasa-mono-sc-nerd-regular.ttf", size=16, index=0) | |
font = ImageFont.truetype("Unibit.ttf", size=16, index=0) | |
# font = ImageFont.truetype("zpix.ttf", size=12, index=0) | |
draw = ImageDraw.Draw(im) | |
# code snippet to show the rendering resuble | |
draw.text((0, YOFF), CHARS, font=font, fill=FG, language='zh-CN') | |
im.save('font.png') | |
im.show() | |
draw.rectangle([(0, 0), size], fill=BG) | |
# NOTE: char 127 is replaced with '°' | |
# all control ascii chars can be used for half width symbols. | |
ASCII = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~°' | |
charmap = [] | |
for i, c in enumerate(ASCII): | |
if c.isprintable(): | |
draw.text((0, YOFF), c, font=font, fill=FG) | |
else: | |
draw.text((0, YOFF), " ", font=font, fill=FG) | |
for y in range(16): | |
v = 0 | |
for x in range(0, 8): | |
b = im.getpixel((x, y)) | |
v = (v << 1) + b | |
charmap.append(v) | |
draw.rectangle([(0, 0), size], fill=BG) | |
for i, c in enumerate(CHARS): | |
draw.text((0, YOFF), c, font=font, fill=FG) | |
for y in range(16): | |
v = 0 | |
for x in range(0, 16): | |
b = im.getpixel((x, y)) | |
v = (v << 1) + b | |
charmap.append(v >> 8) | |
charmap.append(v & 0xFF) | |
draw.rectangle([(0, 0), size], fill=BG) | |
with open('font.raw', 'wb') as fp: | |
fp.write(bytes(charmap)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use embedded_graphics::fonts::Font; | |
use embedded_graphics::geometry::Size; | |
#[derive(Clone, Copy)] | |
pub struct FontCn; | |
impl Font for FontCn { | |
const FONT_IMAGE: &'static [u8] = include_bytes!("../font.raw"); | |
// add 1pixel row spacing | |
const CHARACTER_SIZE: Size = Size::new(16, 16 + 1); | |
const VARIABLE_WIDTH: bool = true; | |
const FONT_IMAGE_WIDTH: u32 = 16; | |
const CHARACTER_SPACING: u32 = 1; | |
fn char_offset(_c: char) -> u32 { | |
unreachable!() | |
} | |
fn char_width(c: char) -> u32 { | |
match c { | |
_ if (c as u16) < 128 => 8, | |
'°' => 8, | |
_ => 16, | |
} | |
} | |
fn character_pixel(c: char, x: u32, y: u32) -> bool { | |
if x >= 16 || y >= 16 { | |
return false; | |
} | |
if c.is_ascii_graphic() { | |
let map = &Self::FONT_IMAGE[16 * (c as usize)..16 + (c as usize) * 16]; | |
return (map[y as usize] & (1 << (7 - x))) != 0; | |
} | |
// chars that are remaped to 0-127 chontrol chars | |
if c == '°' { | |
let map = &Self::FONT_IMAGE[16 * 127..16 + 16 * 128]; | |
return (map[y as usize] & (1 << (7 - x))) != 0; | |
} | |
const start: usize = 128 * 16; | |
const step: usize = 2 * 16; | |
if let Some(index) = "气温湿度照压卧槽艹牛逼数据设备" | |
.chars() | |
.position(|ch| ch == c) | |
{ | |
let bitmap = &Self::FONT_IMAGE[start + index * step..start + (index + 1) * step]; | |
if x >= 8 { | |
(bitmap[y as usize * 2 + 1] & (1 << (15 - x))) != 0 | |
} else { | |
(bitmap[y as usize * 2] & (1 << (7 - x))) != 0 | |
} | |
} else { | |
false | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment