Skip to content

Commit

Permalink
Support L2, L4
Browse files Browse the repository at this point in the history
  • Loading branch information
mikee47 committed Dec 23, 2024
1 parent 22ed9be commit 78614c0
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 41 deletions.
49 changes: 22 additions & 27 deletions Tools/rc/rclib/font.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,39 +71,34 @@ def set_bitmap(self, img: Image):
self.width = w
self.height = h
stride = w # All modes 1 byte per pixel
self.alpha = 1 if img.mode == '1' else self.typeface.font.alpha
pixels_per_byte = 8 // self.alpha
alpha = 1 if img.mode == '1' else self.typeface.font.alpha
self.alpha = alpha
pixels_per_byte = 8 // alpha
dstsize = (w * h + pixels_per_byte - 1) // pixels_per_byte

# Pack source bits so resulting data is as compact as possible
imgdata = img.tobytes('raw', ('L'))
imgdata = img.tobytes('raw', ('L', 0, 1))

# print(f'Bitmap {w} x {h}, bpp {bpp}, src {len(imgdata)} bytes, dst {dstsize}')
# print(f'{self.typeface.font.name} bitmap {w} x {h}, alpha {alpha}, src {len(imgdata)} bytes, dst {dstsize}')

if self.alpha == 8:
if pixels_per_byte == 1:
self.bitmap = imgdata
return

dstbuf = bytearray(dstsize)
srcoff = 0
dstoff = 0
dstbits = 0
dstbitlen = 0
mask = 1 << 8
for bit in imgdata:
mask >>= 1
if bit:
dstbits |= mask
dstbitlen += 1
if dstbitlen == 8:
dstbuf[dstoff] = dstbits
dstoff += 1
dstbits = 0
dstbitlen = 0
mask = 1 << 8
if dstbitlen:
dstbuf[dstoff] = dstbits
self.bitmap = dstbuf
else:
dstbuf = bytearray(dstsize)
dstoff = 0
dstbyte = 0
shift = 8
for pixel in imgdata:
shift -= alpha
dstbyte |= (pixel >> (8 - alpha)) << shift
if shift == 0:
dstbuf[dstoff] = dstbyte
dstoff += 1
dstbyte = 0
shift = 8
if shift != 8:
dstbuf[dstoff] = dstbyte
self.bitmap = dstbuf


class Typeface(Resource):
Expand Down
5 changes: 3 additions & 2 deletions Tools/rc/rclib/vlw.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@

import struct
from .font import Glyph
from PIL import Image

def parse_typeface(typeface):
with open(typeface.source, "rb") as f:
Expand All @@ -87,8 +88,8 @@ def parse_typeface(typeface):
descent = max(descent, g.height - topExtent)
ascent = max(ascent, topExtent)
g.yOffset = -topExtent
g.alpha = 8
g.bitmap = data[bmOffset:bmOffset+bmSize]
img = Image.frombuffer('L', (g.width, g.height), data[bmOffset:bmOffset+bmSize], 'raw', ('L', 0, 1))
g.set_bitmap(img)
typeface.glyphs.append(g)
offset += GLYPH_HEADER_SIZE
bmOffset += bmSize
Expand Down
33 changes: 21 additions & 12 deletions src/Asset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,27 +386,36 @@ class ResourceGlyph : public GlyphObject
assert(y + glyph.height <= typeface.yAdvance);
auto bufptr = static_cast<uint8_t*>(buffer) + off;

if(glyph.alpha) {
using Alpha = Resource::GlyphResource::Alpha;
if(glyph.alpha == Alpha::L8) {
for(unsigned y = 0; y < glyph.height; ++y, offset += glyph.width, bufptr += stride) {
resourceStream->read(offset, bufptr, glyph.width);
}
} else {
uint8_t raw{0};
uint8_t mask{0};
uint8_t bitsPerPixel = 1;
switch(glyph.alpha) {
case Alpha::L4:
bitsPerPixel = 4;
break;
case Alpha::L2:
bitsPerPixel = 2;
break;
}
uint8_t srcbyte = 0;
uint8_t srcShift = 0;
const uint8_t mask = (1 << bitsPerPixel) - 1;
const uint8_t dstShift = 8 - bitsPerPixel;
auto rowptr = bufptr;
for(unsigned y = 0; y < glyph.height; ++y) {
auto rowptr = bufptr;
for(unsigned x = 0; x < glyph.width; ++x) {
if(mask == 0) {
raw = resourceStream->read(offset++);
mask = 0x80;
}
if(raw & mask) {
bufptr[x] = 0xff;
if(srcShift == 0) {
srcbyte = resourceStream->read(offset++);
srcShift = 8;
}
mask >>= 1;
srcShift -= bitsPerPixel;
rowptr[x] = ((srcbyte >> srcShift) & mask) << dstShift;
}
rowptr += stride;
bufptr = rowptr;
}
}
}
Expand Down

0 comments on commit 78614c0

Please sign in to comment.