Port some drawing functions from launcher

This commit is contained in:
UnknownShadow200 2018-11-29 00:11:16 +11:00
parent bb234460b2
commit 39d9e40b68
8 changed files with 202 additions and 127 deletions

View File

@ -21,8 +21,8 @@ typedef struct Bitmap_ { uint8_t* Scan0; int Width, Height; } Bitmap;
#define BITMAP_SIZEOF_PIXEL 4 /* 32 bit ARGB */ #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_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_RawRow(bmp, y) ((uint32_t*)(bmp)->Scan0 + (y) * (bmp)->Width)
#define Bitmap_GetRow(bmp, y) ((BitmapCol*)((bmp)->Scan0 + ((y) * ((bmp)->Width << 2)))) #define Bitmap_GetRow(bmp, y) ((BitmapCol*)(bmp)->Scan0 + (y) * (bmp)->Width)
#define Bitmap_GetPixel(bmp, x, y) (Bitmap_GetRow(bmp, y)[x]) #define Bitmap_GetPixel(bmp, x, y) (Bitmap_GetRow(bmp, y)[x])
BitmapCol BitmapCol_Scale(BitmapCol value, float t); BitmapCol BitmapCol_Scale(BitmapCol value, float t);

View File

@ -82,16 +82,178 @@ void Drawer2D_SetFontBitmap(Bitmap* bmp) {
} }
/* Draws a 2D flat rectangle. */ bool Drawer2D_Clamp(Bitmap* bmp, int* x, int* y, int* width, int* height) {
void Drawer2D_Rect(Bitmap* bmp, BitmapCol col, 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) { void Drawer2D_Clear(Bitmap* bmp, BitmapCol col, int x, int y, int width, int height) {
BitmapCol* row; BitmapCol* row;
int xx, yy; 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++) { for (yy = 0; yy < height; yy++) {
row = Bitmap_GetRow(bmp, y + yy) + x; row = Bitmap_GetRow(bmp, y + yy) + x;
@ -99,6 +261,7 @@ void Drawer2D_Clear(Bitmap* bmp, BitmapCol col, int x, int y, int width, int hei
} }
} }
int Drawer2D_FontHeight(const FontDesc* font, bool useShadow) { int Drawer2D_FontHeight(const FontDesc* font, bool useShadow) {
static String text = String_FromConst("I"); static String text = String_FromConst("I");
struct DrawTextArgs args; struct DrawTextArgs args;

View File

@ -26,9 +26,30 @@ extern BitmapCol Drawer2D_Cols[DRAWER2D_MAX_COLS];
#define DRAWER2D_OFFSET 1 #define DRAWER2D_OFFSET 1
#define Drawer2D_GetCol(c) Drawer2D_Cols[(uint8_t)c] #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. */ /* Draws a 2D flat rectangle. */
void Drawer2D_Rect(Bitmap* bmp, BitmapCol col, int x, int y, int width, int height); 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_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); void Drawer2D_Underline(Bitmap* bmp, int x, int y, int width, int height, BitmapCol col);

View File

@ -72,9 +72,9 @@ extern const char* FpsLimit_Names[FPS_LIMIT_COUNT];
extern struct EntryList Options; extern struct EntryList Options;
/* Returns whether user has changed any options this session. */ /* 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. */ /* 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. */ /* Returns value of given option, or defalt value if not found. */
CC_EXPORT void Options_Get(const char* key, String* value, const char* defValue); CC_EXPORT void Options_Get(const char* key, String* value, const char* defValue);

View File

@ -9,7 +9,6 @@
#include "Bitmap.h" #include "Bitmap.h"
#include "Window.h" #include "Window.h"
#define FT_EXPORT(x) extern x
#include "freetype/ft2build.h" #include "freetype/ft2build.h"
#include "freetype/freetype.h" #include "freetype/freetype.h"
#include "freetype/ftmodapi.h" #include "freetype/ftmodapi.h"

View File

@ -452,7 +452,7 @@ FT_BEGIN_HEADER
/* */ /* */
#ifndef FT_EXPORT #ifndef FT_EXPORT
#ifdef FT2_BUILD_LIBRARY /*#ifdef FT2_BUILD_LIBRARY
#if defined( _WIN32 ) && ( defined( _DLL ) || defined( DLL_EXPORT ) ) #if defined( _WIN32 ) && ( defined( _DLL ) || defined( DLL_EXPORT ) )
#define FT_EXPORT( x ) __declspec( dllexport ) x #define FT_EXPORT( x ) __declspec( dllexport ) x
@ -474,6 +474,12 @@ FT_BEGIN_HEADER
#define FT_EXPORT( x ) extern x #define FT_EXPORT( x ) extern x
#endif #endif
#endif*/
#if defined(__cplusplus)
#define FT_EXPORT( x ) extern "C" x
#else
#define FT_EXPORT( x ) extern x
#endif #endif
#endif /* !FT_EXPORT */ #endif /* !FT_EXPORT */

View File

@ -603,9 +603,6 @@
*/ */
#define FT_FONT_FORMATS_H "ftfntfmt.h" #define FT_FONT_FORMATS_H "ftfntfmt.h"
/* deprecated */
#define FT_XFREE86_H FT_FONT_FORMATS_H
/************************************************************************* /*************************************************************************
* *

View File

@ -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; return error;
} }