Add new classes required for picture clipping
* agg_clipped_alpha_mask is a modified version of agg alpha mask class, allowing us to offset the mask bitmap to follow the view position, and also allows "inverse" clipping, where everything outside the bitmap is considered inside the clipping region. * AlphaMask is a container class keeping the ServerPicture, it's bitmap rendering, and other relevant information. It will be used to save and restore the clipping picture as part of the view state. * Because these classes introduce more coupling within app_server, it's not possible anymore to split out tst_app_server from libtestappserver.so. Instead, move everything to libtestappserver.so, except the things that actually need to not be there (to avoid interferences with the host API). As a result, the previously introduced stub cpp file to work around this problem isn't needed anymore. The design for all this (and the previous commit) is Stippi's work. Thanks for the advice and implementation hints!
This commit is contained in:
parent
f08d5477d8
commit
35d6e0fe81
59
src/servers/app/AlphaMask.cpp
Normal file
59
src/servers/app/AlphaMask.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2014, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "AlphaMask.h"
|
||||
|
||||
#include "ServerBitmap.h"
|
||||
#include "View.h"
|
||||
|
||||
|
||||
AlphaMask::AlphaMask(View& view, ServerPicture& picture, bool inverse,
|
||||
BPoint origin)
|
||||
:
|
||||
fPicture(picture),
|
||||
fInverse(inverse),
|
||||
fOrigin(origin),
|
||||
fView(view),
|
||||
fCachedBitmap(NULL),
|
||||
fBuffer(),
|
||||
fCachedMask(),
|
||||
fScanline(fCachedMask)
|
||||
{
|
||||
fPicture.AcquireReference();
|
||||
}
|
||||
|
||||
|
||||
AlphaMask::~AlphaMask()
|
||||
{
|
||||
fPicture.ReleaseReference();
|
||||
if (fCachedBitmap)
|
||||
fCachedBitmap->ReleaseReference();
|
||||
}
|
||||
|
||||
|
||||
scanline_unpacked_masked_type*
|
||||
AlphaMask::Generate()
|
||||
{
|
||||
// If rendering the picture fails, we will draw without any clipping.
|
||||
ServerBitmap* bitmap = fView._RenderPicture(&fPicture, fInverse);
|
||||
if (!bitmap)
|
||||
return NULL;
|
||||
|
||||
// FIXME actually use the cached bitmap whenever possible, instead of
|
||||
// rendering the BPicture again and again.
|
||||
if (fCachedBitmap)
|
||||
fCachedBitmap->ReleaseReference();
|
||||
fCachedBitmap = bitmap;
|
||||
|
||||
fBuffer.attach(fCachedBitmap->Bits(), fCachedBitmap->Width(),
|
||||
fCachedBitmap->Height(), fCachedBitmap->BytesPerRow());
|
||||
|
||||
BPoint offset(B_ORIGIN);
|
||||
fView.ConvertToScreen(&offset);
|
||||
fCachedMask.attach(fBuffer, offset.x + fOrigin.x, offset.y + fOrigin.y,
|
||||
fInverse ? 255 : 0);
|
||||
return &fScanline;
|
||||
}
|
42
src/servers/app/AlphaMask.h
Normal file
42
src/servers/app/AlphaMask.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2014, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef ALPHA_MASK_H
|
||||
#define ALPHA_MASK_H
|
||||
|
||||
|
||||
#include "agg_clipped_alpha_mask.h"
|
||||
#include "ServerBitmap.h"
|
||||
#include "ServerPicture.h"
|
||||
|
||||
#include "drawing/Painter/defines.h"
|
||||
|
||||
|
||||
class ServerBitmap;
|
||||
|
||||
|
||||
class AlphaMask
|
||||
{
|
||||
public:
|
||||
AlphaMask(View& view,
|
||||
ServerPicture& mask, bool inverse,
|
||||
BPoint origin);
|
||||
~AlphaMask();
|
||||
scanline_unpacked_masked_type* Generate();
|
||||
|
||||
private:
|
||||
ServerPicture& fPicture;
|
||||
const bool fInverse;
|
||||
const BPoint fOrigin;
|
||||
View& fView;
|
||||
|
||||
ServerBitmap* fCachedBitmap;
|
||||
agg::rendering_buffer fBuffer;
|
||||
agg::clipped_alpha_mask fCachedMask;
|
||||
scanline_unpacked_masked_type fScanline;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -79,7 +79,6 @@ Server app_server :
|
||||
ScreenConfigurations.cpp
|
||||
ScreenManager.cpp
|
||||
ServerApp.cpp
|
||||
ServerAppStub.cpp
|
||||
ServerBitmap.cpp
|
||||
ServerCursor.cpp
|
||||
ServerFont.cpp
|
||||
|
@ -472,6 +472,36 @@ ServerApp::RemovePicture(ServerPicture* picture)
|
||||
}
|
||||
|
||||
|
||||
/*! Called from the ClientMemoryAllocator whenever a server area could be
|
||||
deleted.
|
||||
A message is then sent to the client telling it that it can delete its
|
||||
client area, too.
|
||||
*/
|
||||
void
|
||||
ServerApp::NotifyDeleteClientArea(area_id serverArea)
|
||||
{
|
||||
BMessage notify(kMsgDeleteServerMemoryArea);
|
||||
notify.AddInt32("server area", serverArea);
|
||||
|
||||
SendMessageToClient(¬ify);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Send a message to the ServerApp's BApplication
|
||||
\param message The message to send
|
||||
*/
|
||||
void
|
||||
ServerApp::SendMessageToClient(BMessage* message) const
|
||||
{
|
||||
status_t status = fHandlerMessenger.SendMessage(message, (BHandler*)NULL,
|
||||
100000);
|
||||
if (status != B_OK) {
|
||||
syslog(LOG_ERR, "app %s send to client failed: %s\n", Signature(),
|
||||
strerror(status));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - private methods
|
||||
|
||||
|
||||
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2013, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* DarkWyrm <bpmagic@columbus.rr.com>
|
||||
* Adrian Oanca <adioanca@cotty.iren.ro>
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
* Stefano Ceccherini (burton666@libero.it)
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
* Jérôme Duval, jerome.duval@free.fr
|
||||
* Andrej Spielmann, <andrej.spielmann@seh.ox.ac.uk>
|
||||
* Philippe Saint-Pierre, stpere@gmail.com
|
||||
* Wim van der Meer, <WPJvanderMeer@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "ServerApp.h"
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#include <ServerProtocol.h>
|
||||
|
||||
|
||||
/* These methods are split to a separate compilation unit to allow splitting
|
||||
* the test_app_server and libtestappserver.so on a convenient boundary.
|
||||
*/
|
||||
|
||||
|
||||
/*! Called from the ClientMemoryAllocator whenever a server area could be
|
||||
deleted.
|
||||
A message is then sent to the client telling it that it can delete its
|
||||
client area, too.
|
||||
*/
|
||||
void
|
||||
ServerApp::NotifyDeleteClientArea(area_id serverArea)
|
||||
{
|
||||
BMessage notify(kMsgDeleteServerMemoryArea);
|
||||
notify.AddInt32("server area", serverArea);
|
||||
|
||||
SendMessageToClient(¬ify);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Send a message to the ServerApp's BApplication
|
||||
\param message The message to send
|
||||
*/
|
||||
void
|
||||
ServerApp::SendMessageToClient(BMessage* message) const
|
||||
{
|
||||
status_t status = fHandlerMessenger.SendMessage(message, (BHandler*)NULL,
|
||||
100000);
|
||||
if (status != B_OK) {
|
||||
syslog(LOG_ERR, "app %s send to client failed: %s\n", Signature(),
|
||||
strerror(status));
|
||||
}
|
||||
}
|
114
src/servers/app/agg_clipped_alpha_mask.h
Normal file
114
src/servers/app/agg_clipped_alpha_mask.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2014, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
|
||||
*
|
||||
* Class clipped_alpha_mask, a modified version of alpha_mask_u8 that can
|
||||
* offset the mask, and has a controllable value for the area outside it.
|
||||
*/
|
||||
|
||||
#ifndef AGG_CLIPED_ALPHA_MASK_INCLUDED
|
||||
#define AGG_CLIPED_ALPHA_MASK_INCLUDED
|
||||
|
||||
|
||||
#include <agg_alpha_mask_u8.h>
|
||||
#include <agg_rendering_buffer.h>
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
class clipped_alpha_mask
|
||||
{
|
||||
public:
|
||||
typedef int8u cover_type;
|
||||
enum cover_scale_e
|
||||
{
|
||||
cover_shift = 8,
|
||||
cover_none = 0,
|
||||
cover_full = 255
|
||||
};
|
||||
|
||||
clipped_alpha_mask()
|
||||
: m_xOffset(0), m_yOffset(0), m_rbuf(0), m_outside(0) {}
|
||||
clipped_alpha_mask(rendering_buffer& rbuf)
|
||||
: m_xOffset(0), m_yOffset(0), m_rbuf(&rbuf), m_outside(0) {}
|
||||
|
||||
void attach(rendering_buffer& rbuf, int x, int y, int8u outside)
|
||||
{
|
||||
m_rbuf = &rbuf;
|
||||
m_xOffset = x;
|
||||
m_yOffset = y;
|
||||
m_outside = outside;
|
||||
}
|
||||
|
||||
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
|
||||
{
|
||||
x -= m_xOffset;
|
||||
y -= m_yOffset;
|
||||
|
||||
int xmax = m_rbuf->width() - 1;
|
||||
int ymax = m_rbuf->height() - 1;
|
||||
|
||||
int count = num_pix;
|
||||
cover_type* covers = dst;
|
||||
|
||||
if(y < 0 || y > ymax)
|
||||
{
|
||||
memset(dst, m_outside, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
|
||||
if(x < 0)
|
||||
{
|
||||
count += x;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, m_outside, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
memset(covers, m_outside, -x * sizeof(cover_type));
|
||||
covers -= x;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if(x + count > xmax)
|
||||
{
|
||||
int rest = x + count - xmax - 1;
|
||||
count -= rest;
|
||||
if(count <= 0)
|
||||
{
|
||||
memset(dst, m_outside, num_pix * sizeof(cover_type));
|
||||
return;
|
||||
}
|
||||
memset(covers + count, m_outside, rest * sizeof(cover_type));
|
||||
}
|
||||
|
||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||
do
|
||||
{
|
||||
*covers = (cover_type)((cover_full + (*covers) * (*mask))
|
||||
>> cover_shift);
|
||||
++covers;
|
||||
mask += Step;
|
||||
}
|
||||
while(--count);
|
||||
}
|
||||
|
||||
private:
|
||||
int m_xOffset;
|
||||
int m_yOffset;
|
||||
|
||||
rendering_buffer* m_rbuf;
|
||||
int8u m_outside;
|
||||
|
||||
// TODO this assumes an RGBA bitmap and only uses the alpha channel.
|
||||
// We should keep the masking bitmap as an 8-bit bitmap with only the
|
||||
// alpha channel, to save memory. (this would be Step=1, Offset=0)
|
||||
static const int Step = 4;
|
||||
static const int Offset = 3;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@ -100,26 +100,16 @@ SharedLibrary libtestappserver.so :
|
||||
MultiLocker.cpp
|
||||
Overlay.cpp
|
||||
RGBColor.cpp
|
||||
ServerAppStub.cpp
|
||||
ServerBitmap.cpp
|
||||
ServerCursor.cpp
|
||||
ServerFont.cpp
|
||||
SystemPalette.cpp
|
||||
|
||||
# drawing
|
||||
drawing_support.cpp
|
||||
PatternHandler.cpp
|
||||
|
||||
# trace.c
|
||||
|
||||
# libraries
|
||||
: be libpainter.a libagg.a libtextencoding.so libshared.a
|
||||
[ BuildFeatureAttribute freetype : library ]
|
||||
;
|
||||
|
||||
AddResources test_app_server : test_app_server.rdef ;
|
||||
|
||||
Server test_app_server :
|
||||
# Misc. Sources
|
||||
ProfileMessageSupport.cpp
|
||||
EventDispatcher.cpp
|
||||
@ -152,6 +142,7 @@ Server test_app_server :
|
||||
drawing_support.cpp
|
||||
MallocBuffer.cpp
|
||||
|
||||
AlphaMask.cpp
|
||||
BitmapHWInterface.cpp
|
||||
DesktopSettings.cpp
|
||||
DrawingContext.cpp
|
||||
@ -175,11 +166,22 @@ Server test_app_server :
|
||||
StackAndTile.cpp
|
||||
Stacking.cpp
|
||||
Tiling.cpp
|
||||
# libraries
|
||||
: be libpainter.a libagg.a liblinprog.a libtextencoding.so libshared.a
|
||||
[ BuildFeatureAttribute freetype : library ]
|
||||
;
|
||||
|
||||
AddResources test_app_server : test_app_server.rdef ;
|
||||
|
||||
Server test_app_server :
|
||||
|
||||
# drawing
|
||||
drawing_support.cpp
|
||||
|
||||
# libraries
|
||||
:
|
||||
[ BuildFeatureAttribute zlib : library ] libtestappserver.so be
|
||||
libhwinterface.so libhwinterfaceimpl.so liblinprog.a libtextencoding.so
|
||||
libhwinterface.so libhwinterfaceimpl.so libtextencoding.so
|
||||
[ BuildFeatureAttribute freetype : library ]
|
||||
$(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++)
|
||||
;
|
||||
|
Loading…
Reference in New Issue
Block a user