Fix semi-opaque glyph shading with scales > 2

- Also add defensive coding in debug builds
This commit is contained in:
Aaron Culliney 2016-01-05 22:25:55 -08:00
parent 3089b98a30
commit 4436b9b7ca
3 changed files with 41 additions and 10 deletions

View File

@ -559,6 +559,7 @@ static inline void _plot_char40(uint8_t **d, uint8_t **s) {
}
static inline void _plot_char80(uint8_t **d, uint8_t **s, const unsigned int fb_width) {
// FIXME : this is implicitly scaling at FONT_GLYPH_SCALE_Y ... make it explicit
*((uint32_t *)(*d)) = *((uint32_t *)(*s));
*d += 4, *s += 4;
*((uint16_t *)(*d)) = *((uint16_t *)(*s));

View File

@ -25,6 +25,19 @@ typedef struct EightPatchArgs_s {
unsigned int dstIdx;
} EightPatchArgs_s;
#ifndef NDEBUG
# define SET_TEX_PIXEL(OFF) \
do { \
assert((OFF) > 0 && (OFF) < lastPoint); \
*((PIXEL_TYPE*)(texPixels + (OFF))) |= SEMI_OPAQUE; \
} while (0);
#else
# define SET_TEX_PIXEL(OFF) \
do { \
*((PIXEL_TYPE*)(texPixels + (OFF))) |= SEMI_OPAQUE; \
} while (0);
#endif
// Generates a semi-opaque halo effect around each glyph
static void _eightpatch_opaquePixelHaloFilter(const EightPatchArgs_s args) {
@ -43,8 +56,8 @@ static void _eightpatch_opaquePixelHaloFilter(const EightPatchArgs_s args) {
const unsigned int lastCol = (fb_w-1);
const unsigned int dstPointStride = pixelSize * glyphScale;
const unsigned int dstRowStride = fb_w * dstPointStride;
const unsigned int texRowStride = ((fb_w * glyphScale) * (glyphScale/*1 row*/ * glyphScale) * pixelSize);
const unsigned int lastPoint = ((fb_w * glyphScale) * (fb_h * glyphScale) * pixelSize);
const unsigned int texRowStride = ((fb_w * glyphScale) * (FONT_GLYPH_SCALE_Y * glyphScale) * pixelSize);
const unsigned int lastPoint = ((fb_w * glyphScale) * (fb_h * glyphScale) * pixelSize);
uint8_t *texPixels = args.parent->texPixels;
const int dstIdx0 = (int)args.dstIdx;
@ -59,11 +72,11 @@ static void _eightpatch_opaquePixelHaloFilter(const EightPatchArgs_s args) {
for (unsigned int k=0; k<glyphScale; k++, dstPre+=dstRowStride) {
for (unsigned int l=0; l<glyphScale; l++, dstPre+=pixelSize) {
if (srcCol != 0) {
*((PIXEL_TYPE*)(texPixels + dstPre - dstPointStride)) |= SEMI_OPAQUE;
SET_TEX_PIXEL(dstPre - dstPointStride);
}
*((PIXEL_TYPE*)(texPixels + dstPre)) |= SEMI_OPAQUE;
SET_TEX_PIXEL(dstPre);
if (srcCol < lastCol) {
*((PIXEL_TYPE*)(texPixels + dstPre + dstPointStride)) |= SEMI_OPAQUE;
SET_TEX_PIXEL(dstPre + dstPointStride);
}
}
dstPre -= dstPointStride;
@ -75,7 +88,7 @@ static void _eightpatch_opaquePixelHaloFilter(const EightPatchArgs_s args) {
int dstIdx = dstIdx0;
for (unsigned int k=0; k<glyphScale; k++, dstIdx+=dstRowStride) {
for (unsigned int l=0; l<glyphScale; l++, dstIdx+=pixelSize) {
*((PIXEL_TYPE*)(texPixels + dstIdx - dstPointStride)) |= SEMI_OPAQUE;
SET_TEX_PIXEL(dstIdx - dstPointStride);
}
dstIdx -= dstPointStride;
}
@ -86,7 +99,7 @@ static void _eightpatch_opaquePixelHaloFilter(const EightPatchArgs_s args) {
int dstIdx = dstIdx0;
for (unsigned int k=0; k<glyphScale; k++, dstIdx+=dstRowStride) {
for (unsigned int l=0; l<glyphScale; l++, dstIdx+=pixelSize) {
*((PIXEL_TYPE*)(texPixels + dstIdx + dstPointStride)) |= SEMI_OPAQUE;
SET_TEX_PIXEL(dstIdx + dstPointStride);
}
dstIdx -= dstPointStride;
}
@ -98,11 +111,11 @@ static void _eightpatch_opaquePixelHaloFilter(const EightPatchArgs_s args) {
for (unsigned int k=0; k<glyphScale; k++, dstPost+=dstRowStride) {
for (unsigned int l=0; l<glyphScale; l++, dstPost+=pixelSize) {
if (srcCol != 0) {
*((PIXEL_TYPE*)(texPixels + dstPost - dstPointStride)) |= SEMI_OPAQUE;
SET_TEX_PIXEL(dstPost - dstPointStride);
}
*((PIXEL_TYPE*)(texPixels + dstPost)) |= SEMI_OPAQUE;
SET_TEX_PIXEL(dstPost);
if (srcCol < lastCol) {
*((PIXEL_TYPE*)(texPixels + dstPost + dstPointStride)) |= SEMI_OPAQUE;
SET_TEX_PIXEL(dstPost + dstPointStride);
}
}
dstPost -= dstPointStride;
@ -151,6 +164,10 @@ void glhud_setupDefault(GLModel *parent) {
do {
unsigned int srcIdx = 0;
unsigned int texIdx = 0;
#ifndef NDEBUG
const unsigned int srcLastPoint = fb_w * fb_h;
const unsigned int texLastPoint = ((fb_w * glyphScale) * (fb_h * glyphScale) * pixelSize);
#endif
for (unsigned int i=0; i<fb_h; i++, texIdx+=texSubRowStride) {
for (unsigned int j=0; j<fb_w; j++, srcIdx++, texIdx+=dstPointStride) {
uint8_t value = *(fb + srcIdx);
@ -173,11 +190,19 @@ void glhud_setupDefault(GLModel *parent) {
}
}
}
#ifndef NDEBUG
assert(srcIdx == srcLastPoint);
assert(texIdx == texLastPoint);
#endif
} while (0);
if (hudElement->opaquePixelHalo) {
unsigned int srcIdx = 0;
unsigned int texIdx = 0;
#ifndef NDEBUG
const unsigned int srcLastPoint = fb_w * fb_h;
const unsigned int texLastPoint = ((fb_w * glyphScale) * (fb_h * glyphScale) * pixelSize);
#endif
for (unsigned int i=0; i<fb_h; i++, texIdx+=texSubRowStride) {
for (unsigned int j=0; j<fb_w; j++, srcIdx++, texIdx+=dstPointStride) {
uint8_t value = *(fb + srcIdx);
@ -202,6 +227,10 @@ void glhud_setupDefault(GLModel *parent) {
}
}
}
#ifndef NDEBUG
assert(srcIdx == srcLastPoint);
assert(texIdx == texLastPoint);
#endif
}
parent->texDirty = true;

View File

@ -190,6 +190,7 @@ uint8_t floating_bus_hibit(const bool hibit);
#define FONT_GLYPH_X (7+/*unused*/1) // generated font.c uses a single byte (8bits) per font glyph line
#define FONT_GLYPH_Y (FONT_HEIGHT_PIXELS>>1) // ... 8 bytes total for whole glyph
#define FONT_GLYPH_SCALE_Y (FONT_HEIGHT_PIXELS/FONT_GLYPH_Y) // FIXME NOTE : implicit 2x scaling in display.c ...
#define MOUSETEXT_BEGIN 0x80 // offset + 0x20 length
#define MOUSETEXT_RETURN (MOUSETEXT_BEGIN+0x0d)