From 39d9e40b689408ab16deb0027e434ceab6f0c056 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 29 Nov 2018 00:11:16 +1100 Subject: [PATCH] Port some drawing functions from launcher --- src/Bitmap.h | 4 +- src/Drawer2D.c | 175 ++++++++++++++++++++++++++++++++++++++-- src/Drawer2D.h | 23 +++++- src/Options.h | 4 +- src/Platform.c | 1 - src/freetype/ftconfig.h | 8 +- src/freetype/ftheader.h | 3 - src/freetype/ftobjs.c | 111 ------------------------- 8 files changed, 202 insertions(+), 127 deletions(-) diff --git a/src/Bitmap.h b/src/Bitmap.h index a1983ba16..98606857e 100644 --- a/src/Bitmap.h +++ b/src/Bitmap.h @@ -21,8 +21,8 @@ typedef struct Bitmap_ { uint8_t* Scan0; int Width, Height; } Bitmap; #define BITMAP_SIZEOF_PIXEL 4 /* 32 bit ARGB */ #define Bitmap_DataSize(width, height) ((uint32_t)(width) * (uint32_t)(height) * (uint32_t)BITMAP_SIZEOF_PIXEL) -#define Bitmap_RawRow(bmp, y) ((uint32_t*)((bmp)->Scan0 + ((y) * ((bmp)->Width << 2)))) -#define Bitmap_GetRow(bmp, y) ((BitmapCol*)((bmp)->Scan0 + ((y) * ((bmp)->Width << 2)))) +#define Bitmap_RawRow(bmp, y) ((uint32_t*)(bmp)->Scan0 + (y) * (bmp)->Width) +#define Bitmap_GetRow(bmp, y) ((BitmapCol*)(bmp)->Scan0 + (y) * (bmp)->Width) #define Bitmap_GetPixel(bmp, x, y) (Bitmap_GetRow(bmp, y)[x]) BitmapCol BitmapCol_Scale(BitmapCol value, float t); diff --git a/src/Drawer2D.c b/src/Drawer2D.c index 0fcdc087c..0d5b7945f 100644 --- a/src/Drawer2D.c +++ b/src/Drawer2D.c @@ -82,23 +82,186 @@ void Drawer2D_SetFontBitmap(Bitmap* bmp) { } -/* Draws a 2D flat rectangle. */ -void Drawer2D_Rect(Bitmap* bmp, BitmapCol col, int x, int y, int width, int height); +bool Drawer2D_Clamp(Bitmap* bmp, int* x, int* y, int* width, int* height) { + if (*x >= bmp->Width || *y >= bmp->Height) return false; + + /* origin is negative, move inside */ + if (*x < 0) { *width += *x; *x = 0; } + if (*y < 0) { *height += *y; *y = 0; } + + *width = min(*x + *width, bmp->Width) - *x; + *height = min(*y + *height, bmp->Height) - *y; + return *width > 0 && *height > 0; +} +#define Drawer2D_ClampPixel(p) (p < 0 ? 0 : (p > 255 ? 255 : p)) + +void Gradient_Noise(Bitmap* bmp, int x, int y, int width, int height, + BitmapCol col, int variation) { + BitmapCol* dst; + int xx, yy, n; + float noise; + if (!Drawer2D_Clamp(bmp, &x, &y, &width, &height)) return; + + for (yy = 0; yy < height; yy++) { + dst = Bitmap_GetRow(bmp, y + yy) + x; + + for (xx = 0; xx < width; xx++, dst++) { + n = (x + xx) + (y + yy) * 57; + n = (n << 13) ^ n; + noise = 1.0f - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f; + + n = col.B + (int)(noise * variation); + dst->B = Drawer2D_ClampPixel(n); + n = col.G + (int)(noise * variation); + dst->G = Drawer2D_ClampPixel(n); + n = col.R + (int)(noise * variation); + dst->R = Drawer2D_ClampPixel(n); + + dst->A = 255; + } + } +} + +void Gradient_Vertical(Bitmap* bmp, int x, int y, int width, int height, + PackedCol a, PackedCol b) { + BitmapCol* row, col; + int xx, yy; + float t; + if (!Drawer2D_Clamp(bmp, &x, &y, &width, &height)) return; + col.A = 255; + + for (yy = 0; yy < height; yy++) { + row = Bitmap_GetRow(bmp, y + yy) + x; + t = (float)yy / (height - 1); /* so last row has colour of b */ + + col.B = (uint8_t)Math_Lerp(a.B, b.B, t); + col.G = (uint8_t)Math_Lerp(a.G, b.G, t); + col.R = (uint8_t)Math_Lerp(a.R, b.R, t); + + for (xx = 0; xx < width; xx++) { row[xx] = col; } + } +} + +void Gradient_Blend(Bitmap* bmp, int x, int y, int width, int height, + PackedCol col, int blend) { + BitmapCol* dst; + int xx, yy, t; + if (!Drawer2D_Clamp(bmp, &x, &y, &width, &height)) return; + + /* Pre compute the alpha blended source colour */ + col.R = (uint8_t)(col.R * blend / 255); + col.G = (uint8_t)(col.G * blend / 255); + col.B = (uint8_t)(col.B * blend / 255); + blend = 255 - blend; /* inverse for existing pixels */ + + t = 0; + for (yy = 0; yy < height; yy++) { + dst = Bitmap_GetRow(bmp, y + yy) + x; + + for (xx = 0; xx < width; xx++, dst++) { + t = col.B + (dst->B * blend) / 255; + dst->B = Drawer2D_ClampPixel(t); + t = col.G + (dst->G * blend) / 255; + dst->G = Drawer2D_ClampPixel(t); + t = col.R + (dst->R * blend) / 255; + dst->R = Drawer2D_ClampPixel(t); + + dst->A = 255; + } + } +} + +void Drawer2D_BmpIndexed(Bitmap* bmp, int x, int y, int size, + uint8_t* indices, BitmapCol* palette) { + BitmapCol* row; + BitmapColUnion col; + int xx, yy; + + for (yy = 0; yy < size; yy++) { + if ((y + yy) < 0) { indices += size; continue; } + if ((y + yy) >= bmp->Height) break; + + row = Bitmap_GetRow(bmp, y + yy) + x; + for (xx = 0; xx < size; xx++) { + col.C = palette[*indices++]; + + if (col.Raw == 0) continue; /* transparent pixel */ + if ((x + xx) < 0 || (x + xx) >= bmp->Width) continue; + row[xx] = col.C; + } + } +} + +void Drawer2D_BmpScaled(Bitmap* dst, int x, int y, int width, int height, + Bitmap* src, int srcX, int srcY, int srcWidth, int srcHeight, + int scaleWidth, int scaleHeight, uint8_t scaleA, uint8_t scaleB) { + BitmapCol* dstRow, col; + BitmapCol* srcRow; + int xx, yy; + int scaledX, scaledY; + uint8_t scale; + + for (yy = 0; yy < height; yy++) { + scaledY = (y + yy) * srcHeight / scaleHeight; + srcRow = Bitmap_GetRow(src, srcY + (scaledY % srcHeight)); + dstRow = Bitmap_GetRow(dst, y + yy) + x; + scale = (uint8_t)Math_Lerp(scaleA, scaleB, (float)yy / height); + + for (xx = 0; xx < width; xx++) { + scaledX = (x + xx) * srcWidth / scaleWidth; + col = srcRow[srcX + (scaledX % srcWidth)]; + + dstRow[xx].B = (col.B * scale) / 255; + dstRow[xx].G = (col.G * scale) / 255; + dstRow[xx].R = (col.R * scale) / 255; + dstRow[xx].A = col.A; + } + } +} + +void Drawer2D_BmpTiled(Bitmap* dst, int x, int y, int width, int height, + Bitmap* src, int srcX, int srcY, int srcWidth, int srcHeight) { + BitmapCol* dstRow; + BitmapCol* srcRow; + int xx, yy; + if (!Drawer2D_Clamp(dst, &x, &y, &width, &height)) return; + + for (yy = 0; yy < height; yy++) { + srcRow = Bitmap_GetRow(src, srcY + ((y + yy) % srcHeight)); + dstRow = Bitmap_GetRow(dst, y + yy) + x; + + for (xx = 0; xx < width; xx++) { + dstRow[xx] = srcRow[srcX + ((x + xx) % srcWidth)]; + } + } +} + +void Drawer2D_BmpCopy(Bitmap* dst, int x, int y, int width, int height, Bitmap* src) { + BitmapCol* dstRow; + BitmapCol* srcRow; + int xx, yy; + if (!Drawer2D_Clamp(dst, &x, &y, &width, &height)) return; + + for (yy = 0; yy < height; yy++) { + srcRow = Bitmap_GetRow(src, yy); + dstRow = Bitmap_GetRow(dst, y + yy) + x; + + for (xx = 0; xx < width; xx++) { dstRow[xx] = srcRow[xx]; } + } +} void Drawer2D_Clear(Bitmap* bmp, BitmapCol col, int x, int y, int width, int height) { BitmapCol* row; int xx, yy; + if (!Drawer2D_Clamp(bmp, &x, &y, &width, &height)) return; - if (x < 0 || y < 0 || (x + width) > bmp->Width || (y + height) > bmp->Height) { - ErrorHandler_Fail("Drawer2D_Clear - tried to clear at invalid coords"); - } - for (yy = 0; yy < height; yy++) { row = Bitmap_GetRow(bmp, y + yy) + x; for (xx = 0; xx < width; xx++) { row[xx] = col; } } } + int Drawer2D_FontHeight(const FontDesc* font, bool useShadow) { static String text = String_FromConst("I"); struct DrawTextArgs args; diff --git a/src/Drawer2D.h b/src/Drawer2D.h index 5bc64bcb5..024ad73d1 100644 --- a/src/Drawer2D.h +++ b/src/Drawer2D.h @@ -26,9 +26,30 @@ extern BitmapCol Drawer2D_Cols[DRAWER2D_MAX_COLS]; #define DRAWER2D_OFFSET 1 #define Drawer2D_GetCol(c) Drawer2D_Cols[(uint8_t)c] +/* Clamps the given rectangle to line inside the bitmap. */ +/* Returns false if rectangle is completely outside bitmap's rectangle. */ +bool Drawer2D_Clamp(Bitmap* bmp, int* x, int* y, int* width, int* height); + +void Gradient_Noise(Bitmap* bmp, int x, int y, int width, int height, + BitmapCol col, int variation); +void Gradient_Vertical(Bitmap* bmp, int x, int y, int width, int height, + PackedCol a, PackedCol b); +void Gradient_Blend(Bitmap* bmp, int x, int y, int width, int height, + PackedCol col, int blend); + +void Drawer2D_BmpIndexed(Bitmap* bmp, int x, int y, int size, + uint8_t* indices, BitmapCol* palette); +void Drawer2D_BmpScaled(Bitmap* dst, int x, int y, int width, int height, + Bitmap* src, int srcX, int srcY, int srcWidth, int srcHeight, + int scaleWidth, int scaleHeight, uint8_t scaleA, uint8_t scaleB); +void Drawer2D_BmpTiled(Bitmap* dst, int x, int y, int width, int height, + Bitmap* src, int srcX, int srcY, int srcWidth, int srcHeight); +void Drawer2D_BmpCopy(Bitmap* dst, int x, int y, int width, int height, Bitmap* src); + + /* Draws a 2D flat rectangle. */ void Drawer2D_Rect(Bitmap* bmp, BitmapCol col, int x, int y, int width, int height); -/* Clears the entire given area to the specified colour. */ +/* Fills the given rectangular area with the given colour. */ void Drawer2D_Clear(Bitmap* bmp, BitmapCol col, int x, int y, int width, int height); void Drawer2D_Underline(Bitmap* bmp, int x, int y, int width, int height, BitmapCol col); diff --git a/src/Options.h b/src/Options.h index 3a196e9e5..d76bbd105 100644 --- a/src/Options.h +++ b/src/Options.h @@ -72,9 +72,9 @@ extern const char* FpsLimit_Names[FPS_LIMIT_COUNT]; extern struct EntryList Options; /* Returns whether user has changed any options this session. */ -CC_NOINLINE bool Options_HasAnyChanged(void); +bool Options_HasAnyChanged(void); /* Frees any memory allocated in storing options. */ -CC_NOINLINE void Options_Free(void); +void Options_Free(void); /* Returns value of given option, or defalt value if not found. */ CC_EXPORT void Options_Get(const char* key, String* value, const char* defValue); diff --git a/src/Platform.c b/src/Platform.c index f8c512692..19668d18a 100644 --- a/src/Platform.c +++ b/src/Platform.c @@ -9,7 +9,6 @@ #include "Bitmap.h" #include "Window.h" -#define FT_EXPORT(x) extern x #include "freetype/ft2build.h" #include "freetype/freetype.h" #include "freetype/ftmodapi.h" diff --git a/src/freetype/ftconfig.h b/src/freetype/ftconfig.h index 68d40ef6c..12a8a0e86 100644 --- a/src/freetype/ftconfig.h +++ b/src/freetype/ftconfig.h @@ -452,7 +452,7 @@ FT_BEGIN_HEADER /* */ #ifndef FT_EXPORT -#ifdef FT2_BUILD_LIBRARY +/*#ifdef FT2_BUILD_LIBRARY #if defined( _WIN32 ) && ( defined( _DLL ) || defined( DLL_EXPORT ) ) #define FT_EXPORT( x ) __declspec( dllexport ) x @@ -474,6 +474,12 @@ FT_BEGIN_HEADER #define FT_EXPORT( x ) extern x #endif +#endif*/ + +#if defined(__cplusplus) +#define FT_EXPORT( x ) extern "C" x +#else +#define FT_EXPORT( x ) extern x #endif #endif /* !FT_EXPORT */ diff --git a/src/freetype/ftheader.h b/src/freetype/ftheader.h index c2c75282e..c89ce2c3b 100644 --- a/src/freetype/ftheader.h +++ b/src/freetype/ftheader.h @@ -603,9 +603,6 @@ */ #define FT_FONT_FORMATS_H "ftfntfmt.h" - /* deprecated */ -#define FT_XFREE86_H FT_FONT_FORMATS_H - /************************************************************************* * diff --git a/src/freetype/ftobjs.c b/src/freetype/ftobjs.c index dde5e26ea..3d5a1571b 100644 --- a/src/freetype/ftobjs.c +++ b/src/freetype/ftobjs.c @@ -3529,117 +3529,6 @@ } } -#ifdef FT_DEBUG_LEVEL_TRACE - -#undef FT_COMPONENT -#define FT_COMPONENT trace_bitmap - - /* - * Computing the MD5 checksum is expensive, unnecessarily distorting a - * possible profiling of FreeType if compiled with tracing support. For - * this reason, we execute the following code only if explicitly - * requested. - */ - - /* we use FT_TRACE3 in this block */ - if ( !error && - ft_trace_levels[trace_bitmap] >= 3 && - slot->bitmap.buffer ) - { - FT_Bitmap bitmap; - FT_Error err; - - - FT_Bitmap_Init( &bitmap ); - - /* we convert to a single bitmap format for computing the checksum */ - /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */ - err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); - if ( !err ) - { - MD5_CTX ctx; - unsigned char md5[16]; - unsigned long coverage = 0; - int i, j; - int rows = (int)bitmap.rows; - int pitch = bitmap.pitch; - - - FT_TRACE3(( "FT_Render_Glyph: bitmap %dx%d, mode %d\n", - rows, pitch, slot->bitmap.pixel_mode )); - - for ( i = 0; i < rows; i++ ) - for ( j = 0; j < pitch; j++ ) - coverage += bitmap.buffer[i * pitch + j]; - - FT_TRACE3(( " Total coverage: %lu\n", coverage )); - - MD5_Init( &ctx ); - if ( bitmap.buffer ) - MD5_Update( &ctx, bitmap.buffer, - (unsigned long)rows * (unsigned long)pitch ); - MD5_Final( md5, &ctx ); - - FT_TRACE3(( " MD5 checksum: " )); - for ( i = 0; i < 16; i++ ) - FT_TRACE3(( "%02X", md5[i] )); - FT_TRACE3(( "\n" )); - } - - FT_Bitmap_Done( library, &bitmap ); - } - - /* - * Dump bitmap in Netpbm format (PBM or PGM). - */ - - /* we use FT_TRACE7 in this block */ - if ( !error && - ft_trace_levels[trace_bitmap] >= 7 && - slot->bitmap.rows < 128U && - slot->bitmap.width < 128U && - slot->bitmap.buffer ) - { - int rows = (int)slot->bitmap.rows; - int width = (int)slot->bitmap.width; - int pitch = slot->bitmap.pitch; - int i, j, m; - unsigned char* topleft = slot->bitmap.buffer; - - if ( pitch < 0 ) - topleft -= pitch * ( rows - 1 ); - - FT_TRACE7(( "Netpbm image: start\n" )); - switch ( slot->bitmap.pixel_mode ) - { - case FT_PIXEL_MODE_MONO: - FT_TRACE7(( "P1 %d %d\n", width, rows )); - for ( i = 0; i < rows; i++ ) - { - for ( j = 0; j < width; ) - for ( m = 128; m > 0 && j < width; m >>= 1, j++ ) - FT_TRACE7(( " %d", ( topleft[i * pitch + j / 8] & m ) != 0 )); - FT_TRACE7(( "\n" )); - } - break; - - default: - FT_TRACE7(( "P2 %d %d 255\n", width, rows )); - for ( i = 0; i < rows; i++ ) - { - for ( j = 0; j < width; j += 1 ) - FT_TRACE7(( " %3u", topleft[i * pitch + j] )); - FT_TRACE7(( "\n" )); - } - } - FT_TRACE7(( "Netpbm image: end\n" )); - } - -#undef FT_COMPONENT -#define FT_COMPONENT trace_objs - -#endif /* FT_DEBUG_LEVEL_TRACE */ - return error; }