Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AGS 4: support alpha-blending DrawingSurface operations #2661

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ target_sources(common
gfx/bitmap.h
gfx/bitmapdata.cpp
gfx/bitmapdata.h
gfx/blender.cpp
gfx/blender.h
gfx/gfx_def.h
gfx/image_file.cpp
gfx/image_file.h
Expand Down
13 changes: 13 additions & 0 deletions Common/font/ttffontrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "core/platform.h"
#include "core/assetmanager.h"
#include "font/fonts.h"
#include "gfx/blender.h"
#include "util/stream.h"

using namespace AGS::Common;
Expand Down Expand Up @@ -63,11 +64,23 @@ void TTFFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *desti
if (y > destination->cb) // optimisation
return;

// Check if this is a alpha-blending case, and init corresponding draw mode
const bool alpha_blend = (bitmap_color_depth(destination) == 32) && (geta32(colour) != 0xFF);
if (alpha_blend)
{
alfont_blend_mode(_argb2argb_blender);
}

// Y - 1 because it seems to get drawn down a bit
if ((ShouldAntiAliasText()) && (bitmap_color_depth(destination) > 8))
alfont_textout_aa(destination, _fontData[fontNumber].AlFont, text, x, y - 1, colour);
else
alfont_textout(destination, _fontData[fontNumber].AlFont, text, x, y - 1, colour);

if (alpha_blend)
{
alfont_blend_mode(nullptr);
}
}

bool TTFFontRenderer::LoadFromDisk(int fontNumber, int fontSize)
Expand Down
19 changes: 19 additions & 0 deletions Common/font/wfnfontrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "debug/out.h"
#include "font/wfnfont.h"
#include "gfx/bitmap.h"
#include "gfx/blender.h"
#include "util/stream.h"

using namespace AGS::Common;
Expand Down Expand Up @@ -88,6 +89,14 @@ static int RenderChar(Bitmap *ds, const int at_x, const int at_y, Rect clip,
const unsigned char *actdata = wfn_char.Data;
const int bytewid = wfn_char.GetRowByteCount();

// Check if this is a alpha-blending case, and init corresponding draw mode
const bool alpha_blend = (ds->GetColorDepth() == 32) && (geta32(text_color) != 0xFF);
if (alpha_blend)
{
drawing_mode(DRAW_MODE_TRANS, nullptr, 0, 0);
set_argb2any_blender();
}

int sx = std::max(at_x, clip.Left), ex = clip.Right + 1;
int sy = std::max(at_y, clip.Top), ey = clip.Bottom + 1;
int sw = std::max(0, clip.Left - at_x);
Expand All @@ -102,13 +111,23 @@ static int RenderChar(Bitmap *ds, const int at_x, const int at_y, Rect clip,
{
ds->FillRect(RectWH(x, y, scale, scale), text_color);
}
else if (alpha_blend)
{
ds->BlendPixel(x, y, text_color);
}
else
{
ds->PutPixel(x, y, text_color);
}
}
}
}

if (alpha_blend)
{
drawing_mode(DRAW_MODE_SOLID, nullptr, 0, 0);
}

return width * scale;
}

Expand Down
34 changes: 33 additions & 1 deletion Common/gfx/allegrobitmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,11 +429,43 @@ void Bitmap::PutPixel(int x, int y, color_t color)
return _putpixel24(_alBitmap, x, y, color);
case 32:
return _putpixel32(_alBitmap, x, y, color);
default: assert(0); // this should not normally happen
}
assert(0); // this should not normally happen
return putpixel(_alBitmap, x, y, color);
}

// hack into allegro...
extern "C" {
extern BLENDER_FUNC _blender_func15;
extern BLENDER_FUNC _blender_func16;
extern BLENDER_FUNC _blender_func24;
extern BLENDER_FUNC _blender_func32;
}

void Bitmap::BlendPixel(int x, int y, color_t color)
{
if (x < 0 || x >= _alBitmap->w || y < 0 || y >= _alBitmap->h)
{
return;
}

switch (bitmap_color_depth(_alBitmap))
{
case 8:
return _putpixel(_alBitmap, x, y, color);
case 15:
return _putpixel15(_alBitmap, x, y, _blender_func15(color, _getpixel15(_alBitmap, x, y), 0xFF));
case 16:
return _putpixel16(_alBitmap, x, y, _blender_func16(color, _getpixel16(_alBitmap, x, y), 0xFF));
case 24:
return _putpixel24(_alBitmap, x, y, _blender_func24(color, _getpixel24(_alBitmap, x, y), 0xFF));
case 32:
return _putpixel32(_alBitmap, x, y, _blender_func32(color, _getpixel32(_alBitmap, x, y), 0xFF));
default: assert(0); // this should not normally happen
}
return putpixel(_alBitmap, x, y, color);
}

int Bitmap::GetPixel(int x, int y) const
{
if (x < 0 || x >= _alBitmap->w || y < 0 || y >= _alBitmap->h)
Expand Down
1 change: 1 addition & 0 deletions Common/gfx/allegrobitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ class Bitmap
// blocks of bitmap memory - reading/writing from/to scan lines should be
// done in such cases.
void PutPixel(int x, int y, color_t color);
void BlendPixel(int x, int y, color_t color);
int GetPixel(int x, int y) const;

//=========================================================================
Expand Down
File renamed without changes.
File renamed without changes.
23 changes: 21 additions & 2 deletions Common/libsrc/alfont-2.0.9/alfont.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct ALFONT_FONT {
BITMAP *default_bmp; //Draw Font on default BITMAP;
static FT_Library ft_library;
static int alfont_textmode = 0;
static BLENDER_FUNC alfont_blend_func = NULL;
static int alfont_inited = 0;


Expand Down Expand Up @@ -710,6 +711,12 @@ int alfont_text_mode(int mode) {
return old_mode;
}

BLENDER_FUNC alfont_blend_mode(BLENDER_FUNC blend_func) {
BLENDER_FUNC old_func = alfont_blend_func;
alfont_blend_func = blend_func;
return old_func;
}


void alfont_destroy_font(ALFONT_FONT *f) {
if (f == NULL)
Expand Down Expand Up @@ -982,7 +989,13 @@ void alfont_textout_aa_ex(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int
}

//build transparency
if (f->transparency!=255) {
if (alfont_blend_func!=NULL) {
if (bitmap_color_depth(bmp) > 8) {
drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);
set_blender_mode(NULL, NULL, alfont_blend_func, 0, 0, 0, f->transparency);
}
}
else if (f->transparency!=255) {
if (bitmap_color_depth(bmp)>8) {
drawing_mode(DRAW_MODE_TRANS,NULL,0,0);
set_preservedalpha_trans_blender(0,0,0,f->transparency);
Expand Down Expand Up @@ -2156,7 +2169,13 @@ void alfont_textout_ex(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y,
}

//build transparency
if (f->transparency!=255) {
if (alfont_blend_func!=NULL) {
if (bitmap_color_depth(bmp) > 8) {
drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);
set_blender_mode(NULL, NULL, alfont_blend_func, 0, 0, 0, f->transparency);
}
}
else if (f->transparency!=255) {
if (bitmap_color_depth(bmp)>8) {
drawing_mode(DRAW_MODE_TRANS,NULL,0,0);
set_preservedalpha_trans_blender(0,0,0,f->transparency);
Expand Down
1 change: 1 addition & 0 deletions Common/libsrc/alfont-2.0.9/alfont.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ ALFONT_DLL_DECLSPEC int alfont_get_font_real_height(ALFONT_FONT *f);
ALFONT_DLL_DECLSPEC void alfont_get_font_real_vextent(ALFONT_FONT *f, int *top, int *bottom);

ALFONT_DLL_DECLSPEC int alfont_text_mode(int mode);
ALFONT_DLL_DECLSPEC BLENDER_FUNC alfont_blend_mode(BLENDER_FUNC blend_func);

ALFONT_DLL_DECLSPEC void alfont_textout_aa(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color);
ALFONT_DLL_DECLSPEC void alfont_textout(BITMAP *bmp, ALFONT_FONT *f, const char *s, int x, int y, int color);
Expand Down
2 changes: 0 additions & 2 deletions Engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,6 @@ target_sources(engine
gfx/ali3dogl.h
gfx/ali3dsw.cpp
gfx/ali3dsw.h
gfx/blender.cpp
gfx/blender.h
gfx/ddb.h
gfx/gfx_util.cpp
gfx/gfx_util.h
Expand Down
71 changes: 26 additions & 45 deletions Engine/ac/drawingsurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,24 +204,12 @@ void DrawingSurface_BlendSurface(ScriptDrawingSurface* target, ScriptDrawingSurf

void DrawingSurface_SetDrawingColor(ScriptDrawingSurface *sds, int newColour)
{
sds->currentColourScript = newColour;
// StartDrawing to set up ds to set the colour at the appropriate
// depth for the background
Bitmap *ds = sds->StartDrawing();
if (newColour == SCR_COLOR_TRANSPARENT)
{
sds->currentColour = ds->GetMaskColor();
}
else
{
sds->currentColour = ds->GetCompatibleColor(newColour);
}
sds->FinishedDrawingReadOnly();
sds->SetDrawingColor(newColour);
}

int DrawingSurface_GetDrawingColor(ScriptDrawingSurface *sds)
{
return sds->currentColourScript;
return sds->GetScriptDrawingColor();
}

int DrawingSurface_GetHeight(ScriptDrawingSurface *sds)
Expand All @@ -244,7 +232,7 @@ int DrawingSurface_GetColorDepth(ScriptDrawingSurface *sds)

void DrawingSurface_Clear(ScriptDrawingSurface *sds, int colour)
{
Bitmap *ds = sds->StartDrawing();
Bitmap *ds = sds->StartDrawing(); // clear is always done in solid mode
int allegroColor;
if (colour == SCR_COLOR_TRANSPARENT)
{
Expand All @@ -260,33 +248,29 @@ void DrawingSurface_Clear(ScriptDrawingSurface *sds, int colour)

void DrawingSurface_DrawCircle(ScriptDrawingSurface *sds, int x, int y, int radius)
{
Bitmap *ds = sds->StartDrawing();
ds->FillCircle(Circle(x, y, radius), sds->currentColour);
sds->FinishedDrawing();
Bitmap *ds = sds->StartDrawingWithBrush();
ds->FillCircle(Circle(x, y, radius), sds->GetRealDrawingColor());
sds->FinishedDrawingWithBrush();
}

void DrawingSurface_DrawRectangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2)
{
Bitmap *ds = sds->StartDrawing();
ds->FillRect(Rect(x1,y1,x2,y2), sds->currentColour);
sds->FinishedDrawing();
Bitmap *ds = sds->StartDrawingWithBrush();
ds->FillRect(Rect(x1,y1,x2,y2), sds->GetRealDrawingColor());
sds->FinishedDrawingWithBrush();
}

void DrawingSurface_DrawTriangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2, int x3, int y3)
{
Bitmap *ds = sds->StartDrawing();
ds->DrawTriangle(Triangle(x1,y1,x2,y2,x3,y3), sds->currentColour);
sds->FinishedDrawing();
Bitmap *ds = sds->StartDrawingWithBrush();
ds->DrawTriangle(Triangle(x1,y1,x2,y2,x3,y3), sds->GetRealDrawingColor());
sds->FinishedDrawingWithBrush();
}

void DrawingSurface_DrawString(ScriptDrawingSurface *sds, int xx, int yy, int font, const char* text)
{
Bitmap *ds = sds->StartDrawing();
color_t text_color = sds->currentColour;
if ((ds->GetColorDepth() <= 8) && (text_color > 255)) {
text_color = GUI::GetStandardColorForBitmap(1);
debug_script_warn ("DrawingSurface.DrawString: Attempted to use color %d on 256-col surface", text_color);
}
Bitmap *ds = sds->StartDrawing(); // no need to use "brush", blending is done by font renderer
color_t text_color = sds->GetRealDrawingColor();
String res_str = GUI::ApplyTextDirection(text);
wouttext_outline(ds, xx, yy, font, text_color, res_str.GetCStr());
sds->FinishedDrawing();
Expand All @@ -299,8 +283,8 @@ void DrawingSurface_DrawStringWrapped(ScriptDrawingSurface *sds, int xx, int yy,
if (break_up_text_into_lines(draw_text, Lines, wid, font) == 0)
return;

Bitmap *ds = sds->StartDrawing();
color_t text_color = sds->currentColour;
Bitmap *ds = sds->StartDrawing(); // no need to use "brush", blending is done by font renderer
color_t text_color = sds->GetRealDrawingColor();

for (size_t i = 0; i < Lines.Count(); i++)
{
Expand All @@ -313,9 +297,9 @@ void DrawingSurface_DrawStringWrapped(ScriptDrawingSurface *sds, int xx, int yy,

void DrawingSurface_DrawLine(ScriptDrawingSurface *sds, int fromx, int fromy, int tox, int toy, int thickness) {
int ii,jj,xx,yy;
Bitmap *ds = sds->StartDrawing();
Bitmap *ds = sds->StartDrawingWithBrush();
// draw several lines to simulate the thickness
color_t draw_color = sds->currentColour;
color_t draw_color = sds->GetRealDrawingColor();
for (ii = 0; ii < thickness; ii++)
{
xx = (ii - (thickness / 2));
Expand All @@ -325,27 +309,24 @@ void DrawingSurface_DrawLine(ScriptDrawingSurface *sds, int fromx, int fromy, in
ds->DrawLine (Line(fromx + xx, fromy + yy, tox + xx, toy + yy), draw_color);
}
}
sds->FinishedDrawing();
sds->FinishedDrawingWithBrush();
}

void DrawingSurface_DrawPixel(ScriptDrawingSurface *sds, int x, int y) {
int thickness = 1;
int ii,jj;
Bitmap *ds = sds->StartDrawing();
// draw several pixels to simulate the thickness
color_t draw_color = sds->currentColour;
for (ii = 0; ii < thickness; ii++)
if (sds->IsAlphaBlending())
{
for (jj = 0; jj < thickness; jj++)
{
ds->PutPixel(x + ii, y + jj, draw_color);
}
ds->BlendPixel(x, y, sds->GetRealDrawingColor());
}
else
{
ds->PutPixel(x, y, sds->GetRealDrawingColor());
}
sds->FinishedDrawing();
}

int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y) {
Bitmap *ds = sds->StartDrawing();
Bitmap *ds = sds->StartDrawingReadOnly();
int rawPixel = ds->GetPixel(x, y);
int maskColor = ds->GetMaskColor();
int colDepth = ds->GetColorDepth();
Expand Down
2 changes: 1 addition & 1 deletion Engine/ac/dynamicsprite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ ScriptDynamicSprite* DynamicSprite_CreateFromDrawingSurface(ScriptDrawingSurface
height = std::max(1, height);
}

Bitmap *ds = sds->StartDrawing();
Bitmap *ds = sds->StartDrawingReadOnly();
if ((x < 0) || (y < 0) || (x + width > ds->GetWidth()) || (y + height > ds->GetHeight()))
quit("!DynamicSprite.CreateFromDrawingSurface: requested area is outside the surface");

Expand Down
Loading
Loading