diff --git a/Tools/rc/rclib/font.py b/Tools/rc/rclib/font.py index 26f58d7..dd69f3a 100644 --- a/Tools/rc/rclib/font.py +++ b/Tools/rc/rclib/font.py @@ -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): diff --git a/src/Asset.cpp b/src/Asset.cpp index 6eab540..282044b 100644 --- a/src/Asset.cpp +++ b/src/Asset.cpp @@ -386,27 +386,36 @@ class ResourceGlyph : public GlyphObject assert(y + glyph.height <= typeface.yAdvance); auto bufptr = static_cast(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; } } }