ServerFont:
* fixed weird pointer conversion in SetStyle() * fixed a potential mix up in operator=() in case the other ServerFont has fStyle == NULL ServerWindow: * the WindowLayer fTopLayer cannot be deleted by client request, just for safety reasons * the link is flushed if there is no drawing engine, but this case is theoretical only * deleting the ServerWindow object syncs with the client, so that when BBitmaps are deleted, they can be sure there are no pending messages (which would be executed in a nother thread) * there is no timeout anymore when sending messages to the client, which made absolutely no sense AGGTextRenderer: * renamed fFontManager to fFontCache, because that's what it really is * fLastFamilyAndStyle defaulted to the system plain font and therefor that font was never loaded when the font never changed meanwhile DrawingMode: * I'm not quite sure but I think there was the potential of a division by zero, at least I had crashes with "divide error" HWInterface: * fix update when the cursor shape changed in double buffered mode ViewLayer: * since the top layer is never really deleted before its time has come, it is not necessary to set it to NULL in the ViewLayer destructor ViewLayer/WindowLayer: * added a function to collect the view tokens that are affected by an update session EventDispatcher: * use the importance of the message for the timeout in _SendMessage() * drop mouse moved events in the server if we're lagging behind more than 5 ms (Axel, maybe review) View: * there were some problems with the locking of the BWindow looper in RemoveSelf(), since this is called from the window destructor, also of BWindows from BBitmaps, which have never been run (this might need review), at least I seem to have solved the crashing problems introduced by actually deleting the view hirarchy in the BWindow destructor * fixed _Draw() for being used non-recursively, temporarily disabled DrawAfterChildren, which didn't work yet anyways (because views cannot draw over children in the server yet) Window: * small cleanup when deleting shortcuts * sync with the server when having send AS_DELETE_WINDOW (see ServerWindow above) * fixed locking in Begin/EndViewTransaction() * removed folding of _UPDATE_ messages, since there is only one ever in the queue * set the fInTransaction flag during an update, I plan to use this in BView later to flush the link when drawing outside of an update * BView::_Draw() is now called by view token, this gives the next leap forward in speed, the overhead because of drawing clean views was considerable git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15878 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
f15ba33751
commit
7afc7c5074
@ -63,7 +63,7 @@ class ServerFont {
|
||||
const char* Path() const
|
||||
{ return fStyle->Path(); }
|
||||
|
||||
void SetStyle(FontStyle& style);
|
||||
void SetStyle(FontStyle* style);
|
||||
status_t SetFamilyAndStyle(uint16 familyID,
|
||||
uint16 styleID);
|
||||
status_t SetFamilyAndStyle(uint32 fontID);
|
||||
|
@ -3325,15 +3325,19 @@ BView::RemoveSelf()
|
||||
|
||||
// Remove this child from its parent
|
||||
|
||||
if (fOwner) {
|
||||
if (fOwner && fOwner->Lock()) {
|
||||
BLooper* owner = fOwner;
|
||||
|
||||
_UpdateStateForRemove();
|
||||
_Detach();
|
||||
|
||||
owner->Unlock();
|
||||
}
|
||||
|
||||
if (!fParent || !fParent->_RemoveChildFromList(this))
|
||||
return false;
|
||||
|
||||
STRACE(("DONE: BView(%s)::removeSelf()\n", Name()));
|
||||
STRACE(("DONE: BView(%s)::RemoveSelf()\n", Name()));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -4122,55 +4126,49 @@ BView::_Detach()
|
||||
}
|
||||
|
||||
void
|
||||
BView::_Draw(BRect updateRect)
|
||||
BView::_Draw(BRect updateRectScreen)
|
||||
{
|
||||
if (IsHidden(this))
|
||||
return;
|
||||
|
||||
check_lock();
|
||||
|
||||
ConvertFromScreen(&updateRectScreen);
|
||||
BRect updateRect = Bounds() & updateRectScreen;
|
||||
|
||||
if (Flags() & B_WILL_DRAW) {
|
||||
// find out if we should draw at all
|
||||
// TODO: can we optimize this some more? Should the app_server
|
||||
// really send _UPDATE_ requests for all dirty views separately?
|
||||
BRegion updateRegion(updateRect);
|
||||
for (BView *child = fFirstChild; child != NULL; child = child->fNextSibling) {
|
||||
updateRegion.Exclude(child->Frame());
|
||||
if (updateRegion.CountRects() == 0)
|
||||
break;
|
||||
}
|
||||
if (updateRegion.CountRects() > 0) {
|
||||
// TODO: make states robust
|
||||
PushState();
|
||||
Draw(updateRect);
|
||||
PopState();
|
||||
}
|
||||
// TODO: make states robust
|
||||
PushState();
|
||||
Draw(updateRect);
|
||||
PopState();
|
||||
Flush();
|
||||
// } else {
|
||||
// ViewColor() == B_TRANSPARENT_COLOR and no B_WILL_DRAW
|
||||
// -> View is simply not drawn at all
|
||||
}
|
||||
|
||||
for (BView *child = fFirstChild; child != NULL; child = child->fNextSibling) {
|
||||
BRect rect = child->Frame();
|
||||
if (!updateRect.Intersects(rect))
|
||||
continue;
|
||||
|
||||
// get new update rect in child coordinates
|
||||
rect = updateRect & rect;
|
||||
child->ConvertFromParent(&rect);
|
||||
|
||||
child->_Draw(rect);
|
||||
}
|
||||
|
||||
if (Flags() & B_DRAW_ON_CHILDREN) {
|
||||
// TODO: Since we have hard clipping in the app_server,
|
||||
// a view can never draw "on top of it's child views" as
|
||||
// the BeBook describes.
|
||||
// (TODO: Test if this is really possible in BeOS.)
|
||||
PushState();
|
||||
DrawAfterChildren(updateRect);
|
||||
PopState();
|
||||
}
|
||||
// for (BView *child = fFirstChild; child != NULL; child = child->fNextSibling) {
|
||||
// BRect rect = child->Frame();
|
||||
// if (!updateRect.Intersects(rect))
|
||||
// continue;
|
||||
//
|
||||
// // get new update rect in child coordinates
|
||||
// rect = updateRect & rect;
|
||||
// child->ConvertFromParent(&rect);
|
||||
//
|
||||
// child->_Draw(rect);
|
||||
// }
|
||||
//
|
||||
// if (Flags() & B_DRAW_ON_CHILDREN) {
|
||||
// // TODO: Since we have hard clipping in the app_server,
|
||||
// // a view can never draw "on top of it's child views" as
|
||||
// // the BeBook describes.
|
||||
// // (TODO: Test if this is really possible in BeOS.)
|
||||
// PushState();
|
||||
// DrawAfterChildren(updateRect);
|
||||
// PopState();
|
||||
// Flush();
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@ -4208,7 +4206,8 @@ BView::_UpdateStateForRemove()
|
||||
// update children as well
|
||||
|
||||
for (BView *child = fFirstChild; child != NULL; child = child->fNextSibling) {
|
||||
child->_UpdateStateForRemove();
|
||||
if (child->fOwner)
|
||||
child->_UpdateStateForRemove();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,10 +315,10 @@ BWindow::~BWindow()
|
||||
fTopView->RemoveSelf();
|
||||
delete fTopView;
|
||||
|
||||
// remove all existing shortcuts
|
||||
int32 noOfItems = fShortcuts.CountItems();
|
||||
for (int32 index = noOfItems - 1; index >= 0; index--) {
|
||||
delete (Shortcut *)fShortcuts.ItemAt(index);
|
||||
// remove all remaining shortcuts
|
||||
int32 shortCutCount = fShortcuts.CountItems();
|
||||
for (int32 i = 0; i < shortCutCount; i++) {
|
||||
delete (Shortcut*)fShortcuts.ItemAtFast(i);
|
||||
}
|
||||
|
||||
// TODO: release other dynamically-allocated objects
|
||||
@ -332,7 +332,13 @@ BWindow::~BWindow()
|
||||
|
||||
// tell app_server about our demise
|
||||
fLink->StartMessage(AS_DELETE_WINDOW);
|
||||
fLink->Flush();
|
||||
// sync with the server so that for example
|
||||
// a BBitmap can be sure that there are no
|
||||
// more pending messages that are executed
|
||||
// after the bitmap is deleted (which uses
|
||||
// a different link and server side thread)
|
||||
int32 code;
|
||||
fLink->FlushWithReply(code);
|
||||
|
||||
// the sender port belongs to the app_server
|
||||
delete_port(fLink->ReceiverPort());
|
||||
@ -511,7 +517,7 @@ BWindow::Sync() const
|
||||
const_cast<BWindow*>(this)->Lock();
|
||||
fLink->StartMessage(AS_SYNC);
|
||||
|
||||
// ToDo: why with reply?
|
||||
// waiting for the reply is the actual syncing
|
||||
int32 code;
|
||||
fLink->FlushWithReply(code);
|
||||
|
||||
@ -542,12 +548,15 @@ BWindow::EnableUpdates()
|
||||
void
|
||||
BWindow::BeginViewTransaction()
|
||||
{
|
||||
if (!fInTransaction) {
|
||||
Lock();
|
||||
if (Lock()) {
|
||||
if (fInTransaction) {
|
||||
Unlock();
|
||||
return;
|
||||
}
|
||||
fLink->StartMessage(AS_BEGIN_TRANSACTION);
|
||||
Unlock();
|
||||
|
||||
fInTransaction = true;
|
||||
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -555,13 +564,16 @@ BWindow::BeginViewTransaction()
|
||||
void
|
||||
BWindow::EndViewTransaction()
|
||||
{
|
||||
if (fInTransaction) {
|
||||
Lock();
|
||||
if (Lock()) {
|
||||
if (!fInTransaction) {
|
||||
Unlock();
|
||||
return;
|
||||
}
|
||||
fLink->StartMessage(AS_END_TRANSACTION);
|
||||
fLink->Flush();
|
||||
Unlock();
|
||||
|
||||
fInTransaction = false;
|
||||
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -896,8 +908,14 @@ BWindow::DispatchMessage(BMessage *msg, BHandler *target)
|
||||
uint32 buttons;
|
||||
uint32 transit;
|
||||
msg->FindPoint("be:view_where", &where);
|
||||
msg->FindInt32("buttons", (int32 *)&buttons);
|
||||
msg->FindInt32("be:transit", (int32 *)&transit);
|
||||
msg->FindInt32("buttons", (int32*)&buttons);
|
||||
msg->FindInt32("be:transit", (int32*)&transit);
|
||||
// bigtime_t when;
|
||||
// if (msg->FindInt64("when", (int64*)&when) < B_OK)
|
||||
// printf("BWindow B_MOUSE_MOVED no when\n");
|
||||
// else if (system_time() - when > 5000) {
|
||||
// printf("BWindow B_MOUSE_MOVED lagging behind\n");
|
||||
// }
|
||||
BMessage* dragMessage = NULL;
|
||||
if (msg->HasMessage("be:drag_message")) {
|
||||
dragMessage = new BMessage();
|
||||
@ -927,41 +945,23 @@ BWindow::DispatchMessage(BMessage *msg, BHandler *target)
|
||||
case _UPDATE_:
|
||||
{
|
||||
STRACE(("info:BWindow handling _UPDATE_.\n"));
|
||||
// BRect updateRect;
|
||||
// int32 token;
|
||||
// msg->FindRect("_rect", &updateRect);
|
||||
// msg->FindInt32("_token", &token);
|
||||
// // TODO: why is "_token" ignored?
|
||||
//
|
||||
// fLink->StartMessage(AS_BEGIN_UPDATE);
|
||||
// fTopView->_Draw(updateRect);
|
||||
// fLink->StartMessage(AS_END_UPDATE);
|
||||
// fLink->Flush();
|
||||
|
||||
BRect total;
|
||||
msg->FindRect("_rect", &total);
|
||||
|
||||
// combine with pending update requests
|
||||
BRect next;
|
||||
BMessage* pendingMessage;
|
||||
while ((pendingMessage = MessageQueue()->FindMessage(_UPDATE_, 0))) {
|
||||
if (pendingMessage != msg) {
|
||||
pendingMessage->FindRect("_rect", &next);
|
||||
total = total | next;
|
||||
MessageQueue()->RemoveMessage(pendingMessage);
|
||||
// TODO: the BeBook says that MessageQueue::RemoveMessage() deletes the message!
|
||||
// this deletes the first *additional* message
|
||||
// fCurrentMessage is safe
|
||||
delete pendingMessage;
|
||||
} else {
|
||||
MessageQueue()->RemoveMessage(pendingMessage);
|
||||
}
|
||||
}
|
||||
BRect updateRect;
|
||||
msg->FindRect("_rect", &updateRect);
|
||||
updateRect.OffsetBy(fFrame.LeftTop());
|
||||
|
||||
fLink->StartMessage(AS_BEGIN_UPDATE);
|
||||
fTopView->_Draw(total);
|
||||
fInTransaction = true;
|
||||
|
||||
int32 token;
|
||||
for (int32 i = 0; msg->FindInt32("_token", i, &token) == B_OK; i++) {
|
||||
if (BView* view = _FindView(token))
|
||||
view->_Draw(updateRect);
|
||||
}
|
||||
|
||||
fLink->StartMessage(AS_END_UPDATE);
|
||||
fLink->Flush();
|
||||
fInTransaction = false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -533,7 +533,7 @@ EventDispatcher::_SendMessage(BMessenger& messenger, BMessage* message,
|
||||
{
|
||||
// TODO: add failed messages to a queue, and start dropping them by importance
|
||||
|
||||
status_t status = messenger.SendMessage(message, (BHandler*)NULL, 100000);
|
||||
status_t status = messenger.SendMessage(message, (BHandler*)NULL, (bigtime_t)(importance * 100000));
|
||||
if (status != B_OK) {
|
||||
printf("EventDispatcher: failed to send message '%.4s' to target: %s\n",
|
||||
(char*)&message->what, strerror(status));
|
||||
@ -662,6 +662,14 @@ EventDispatcher::_EventLoop()
|
||||
fLastCursorPosition.y);
|
||||
}
|
||||
}
|
||||
bigtime_t eventTime;
|
||||
if (event->FindInt64("when", &eventTime) == B_OK) {
|
||||
if (system_time() - eventTime > 5000) {
|
||||
// the server itself lags behind too much
|
||||
// -> drop the event
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// supposed to fall through
|
||||
}
|
||||
|
@ -181,17 +181,18 @@ ServerFont::~ServerFont()
|
||||
ServerFont&
|
||||
ServerFont::operator=(const ServerFont& font)
|
||||
{
|
||||
fSize = font.fSize;
|
||||
fRotation = font.fRotation;
|
||||
fShear = font.fShear;
|
||||
fFlags = font.fFlags;
|
||||
fSpacing = font.fSpacing;
|
||||
fDirection = font.fDirection;
|
||||
fFace = font.fFace;
|
||||
fEncoding = font.fEncoding;
|
||||
fBounds = font.fBounds;
|
||||
if (font.fStyle) {
|
||||
fSize = font.fSize;
|
||||
fRotation = font.fRotation;
|
||||
fShear = font.fShear;
|
||||
fFlags = font.fFlags;
|
||||
fSpacing = font.fSpacing;
|
||||
fEncoding = font.fEncoding;
|
||||
fBounds = font.fBounds;
|
||||
|
||||
SetStyle(font.fStyle);
|
||||
}
|
||||
|
||||
SetStyle(*font.fStyle);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -233,19 +234,20 @@ ServerFont::Family() const
|
||||
|
||||
|
||||
void
|
||||
ServerFont::SetStyle(FontStyle& style)
|
||||
ServerFont::SetStyle(FontStyle* style)
|
||||
{
|
||||
if (&style != fStyle) {
|
||||
if (style && style != fStyle) {
|
||||
// detach from old style
|
||||
if (fStyle)
|
||||
fStyle->Release();
|
||||
|
||||
// attach to new style
|
||||
fStyle = &style;
|
||||
fFace = style.Face();
|
||||
fDirection = style.Direction();
|
||||
fStyle = style;
|
||||
|
||||
fStyle->Acquire();
|
||||
|
||||
fFace = fStyle->Face();
|
||||
fDirection = fStyle->Direction();
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,7 +274,7 @@ ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID)
|
||||
if (!style)
|
||||
return B_ERROR;
|
||||
|
||||
SetStyle(*style);
|
||||
SetStyle(style);
|
||||
style->Release();
|
||||
|
||||
return B_OK;
|
||||
|
@ -904,7 +904,7 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
case AS_LAYER_DELETE_ROOT:
|
||||
{
|
||||
// Received when a window deletes its internal top view
|
||||
|
||||
printf("AS_LAYER_DELETE_ROOT\n");
|
||||
// TODO: Implement AS_LAYER_DELETE_ROOT
|
||||
STRACE(("ServerWindow %s: Message Delete_Layer_Root unimplemented\n", Title()));
|
||||
break;
|
||||
@ -1064,15 +1064,16 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
STRACE(("ServerWindow %s: AS_LAYER_DELETE view: %p, parent: %p\n", fTitle,
|
||||
fCurrentLayer, parent));
|
||||
|
||||
if (parent != NULL)
|
||||
if (parent != NULL) {
|
||||
parent->RemoveChild(fCurrentLayer);
|
||||
|
||||
if (fCurrentLayer->EventMask() != 0) {
|
||||
fDesktop->EventDispatcher().RemoveListener(EventTarget(),
|
||||
fCurrentLayer->Token());
|
||||
if (fCurrentLayer->EventMask() != 0) {
|
||||
fDesktop->EventDispatcher().RemoveListener(EventTarget(),
|
||||
fCurrentLayer->Token());
|
||||
}
|
||||
|
||||
delete fCurrentLayer;
|
||||
}
|
||||
|
||||
delete fCurrentLayer;
|
||||
// TODO: It is necessary to do this, but I find it very obscure.
|
||||
_SetCurrentLayer(parent);
|
||||
break;
|
||||
@ -1847,6 +1848,11 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
|
||||
if (!drawingEngine) {
|
||||
// ?!?
|
||||
DTRACE(("ServerWindow %s: no drawing engine!!\n", Title()));
|
||||
if (link.NeedsReply()) {
|
||||
// the client is now blocking and waiting for a reply!
|
||||
fLink.StartMessage(B_ERROR);
|
||||
fLink.Flush();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2308,6 +2314,11 @@ ServerWindow::_MessageLooper()
|
||||
STRACE(("ServerWindow %s received 'AS_DELETE_WINDOW' message code\n",
|
||||
Title()));
|
||||
|
||||
if (code == AS_DELETE_WINDOW) {
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Flush();
|
||||
}
|
||||
|
||||
if (lockedDesktop)
|
||||
fDesktop->UnlockSingleWindow();
|
||||
|
||||
@ -2385,7 +2396,7 @@ ServerWindow::SendMessageToClient(const BMessage* msg, int32 target) const
|
||||
|
||||
if ((ret = msg->Flatten(buffer, size)) == B_OK) {
|
||||
ret = BMessage::Private::SendFlattenedMessage(buffer, size,
|
||||
fClientLooperPort, target, 100000);
|
||||
fClientLooperPort, target, 0);
|
||||
if (ret < B_OK) {
|
||||
fprintf(stderr, "ServerWindow(\"%s\")::SendMessageToClient('%.4s'): %s\n",
|
||||
Title(), (char*)&msg->what, strerror(ret));
|
||||
@ -2398,7 +2409,7 @@ ServerWindow::SendMessageToClient(const BMessage* msg, int32 target) const
|
||||
#else
|
||||
BMessenger reply;
|
||||
BMessage::Private messagePrivate((BMessage *)msg);
|
||||
return messagePrivate.SendMessage(fClientLooperPort, target, 100000,
|
||||
return messagePrivate.SendMessage(fClientLooperPort, target, 0,
|
||||
false, reply);
|
||||
#endif
|
||||
}
|
||||
@ -2542,7 +2553,7 @@ ServerWindow::_SetCurrentLayer(ViewLayer* layer)
|
||||
#if 0
|
||||
#if DELAYED_BACKGROUND_CLEARING
|
||||
fWindowLayer->ReadLockWindows();
|
||||
if (fCurrentLayer->IsBackgroundDirty() && fWindowLayer->InUpdate()) {
|
||||
if (fCurrentLayer && fCurrentLayer->IsBackgroundDirty() && fWindowLayer->InUpdate()) {
|
||||
DrawingEngine* drawingEngine = fWindowLayer->GetDrawingEngine();
|
||||
if (drawingEngine->Lock()) {
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "WindowLayer.h"
|
||||
|
||||
#include <List.h>
|
||||
#include <Message.h>
|
||||
#include <View.h> // for resize modes
|
||||
|
||||
#include <stdio.h>
|
||||
@ -84,9 +85,9 @@ ViewLayer::~ViewLayer()
|
||||
|
||||
delete fDrawState;
|
||||
|
||||
if (fWindow && this == fWindow->TopLayer())
|
||||
fWindow->SetTopLayer(NULL);
|
||||
|
||||
// if (fWindow && this == fWindow->TopLayer())
|
||||
// fWindow->SetTopLayer(NULL);
|
||||
//
|
||||
// TODO: Don't know yet if we should also delete fPicture
|
||||
|
||||
// iterate over children and delete each one
|
||||
@ -1003,6 +1004,20 @@ ViewLayer::MarkBackgroundDirty()
|
||||
child->MarkBackgroundDirty();
|
||||
}
|
||||
|
||||
// AddTokensForLayersInRegion
|
||||
void
|
||||
ViewLayer::AddTokensForLayersInRegion(BMessage* message,
|
||||
BRegion& region,
|
||||
BRegion* windowContentClipping)
|
||||
{
|
||||
if (region.Intersects(ScreenClipping(windowContentClipping).Frame()))
|
||||
message->AddInt32("_token", fToken);
|
||||
|
||||
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling())
|
||||
child->AddTokensForLayersInRegion(message, region,
|
||||
windowContentClipping);
|
||||
}
|
||||
|
||||
// PrintToStream
|
||||
void
|
||||
ViewLayer::PrintToStream() const
|
||||
|
@ -170,6 +170,10 @@ class ViewLayer {
|
||||
bool IsBackgroundDirty() const
|
||||
{ return fBackgroundDirty; }
|
||||
|
||||
void AddTokensForLayersInRegion(BMessage* message,
|
||||
BRegion& region,
|
||||
BRegion* windowContentClipping);
|
||||
|
||||
// clipping
|
||||
void RebuildClipping(bool deep);
|
||||
BRegion& ScreenClipping(BRegion* windowContentClipping,
|
||||
|
@ -159,8 +159,7 @@ WindowLayer::WindowLayer(const BRect& frame, const char *name,
|
||||
|
||||
WindowLayer::~WindowLayer()
|
||||
{
|
||||
if (fTopLayer)
|
||||
fTopLayer->DetachedFromWindow();
|
||||
fTopLayer->DetachedFromWindow();
|
||||
|
||||
delete fTopLayer;
|
||||
delete fDecorator;
|
||||
@ -1678,6 +1677,15 @@ WindowLayer::_SendUpdateMessage()
|
||||
BRect updateRect = fPendingUpdateSession.DirtyRegion().Frame();
|
||||
updateRect.OffsetBy(-fFrame.left, -fFrame.top);
|
||||
message.AddRect("_rect", updateRect);
|
||||
|
||||
// find all views that need an update
|
||||
if (!fContentRegionValid)
|
||||
_UpdateContentRegion();
|
||||
|
||||
fTopLayer->AddTokensForLayersInRegion(&message,
|
||||
fPendingUpdateSession.DirtyRegion(),
|
||||
&fContentRegion);
|
||||
|
||||
ServerWindow()->SendMessageToClient(&message);
|
||||
|
||||
fUpdateRequested = true;
|
||||
|
@ -584,6 +584,7 @@ HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset)
|
||||
}
|
||||
|
||||
_RestoreCursorArea();
|
||||
Invalidate(_CursorFrame());
|
||||
|
||||
if (fCursorAndDragBitmap != fCursor) {
|
||||
delete fCursorAndDragBitmap;
|
||||
|
@ -78,14 +78,21 @@ typedef PixelFormat::agg_buffer agg_buffer;
|
||||
if (_p.data8[3] == 255) { \
|
||||
BLEND(d, r, g, b, a); \
|
||||
} else { \
|
||||
uint8 alphaRest = 255 - (a); \
|
||||
uint32 alphaTemp = (65025 - alphaRest * (255 - _p.data8[3])); \
|
||||
uint32 alphaDest = _p.data8[3] * alphaRest; \
|
||||
uint32 alphaSrc = 255 * (a); \
|
||||
d[0] = (_p.data8[0] * alphaDest + (b) * alphaSrc) / alphaTemp; \
|
||||
d[1] = (_p.data8[1] * alphaDest + (g) * alphaSrc) / alphaTemp; \
|
||||
d[2] = (_p.data8[2] * alphaDest + (r) * alphaSrc) / alphaTemp; \
|
||||
d[3] = alphaTemp >> 8; \
|
||||
if (_p.data8[3] == 0) { \
|
||||
d[0] = (b); \
|
||||
d[1] = (g); \
|
||||
d[2] = (r); \
|
||||
d[3] = (a); \
|
||||
} else { \
|
||||
uint8 alphaRest = 255 - (a); \
|
||||
uint32 alphaTemp = (65025 - alphaRest * (255 - _p.data8[3])); \
|
||||
uint32 alphaDest = _p.data8[3] * alphaRest; \
|
||||
uint32 alphaSrc = 255 * (a); \
|
||||
d[0] = (_p.data8[0] * alphaDest + (b) * alphaSrc) / alphaTemp; \
|
||||
d[1] = (_p.data8[1] * alphaDest + (g) * alphaSrc) / alphaTemp; \
|
||||
d[2] = (_p.data8[2] * alphaDest + (r) * alphaSrc) / alphaTemp; \
|
||||
d[3] = alphaTemp >> 8; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -57,9 +57,9 @@ is_white_space(uint16 glyph)
|
||||
// constructor
|
||||
AGGTextRenderer::AGGTextRenderer()
|
||||
: fFontEngine(gFreeTypeLibrary),
|
||||
fFontManager(fFontEngine),
|
||||
fFontCache(fFontEngine),
|
||||
|
||||
fCurves(fFontManager.path_adaptor()),
|
||||
fCurves(fFontCache.path_adaptor()),
|
||||
fContour(fCurves),
|
||||
|
||||
fUnicodeBuffer((char*)malloc(DEFAULT_UNI_CODE_BUFFER_SIZE)),
|
||||
@ -71,7 +71,7 @@ AGGTextRenderer::AGGTextRenderer()
|
||||
fEmbeddedTransformation(),
|
||||
|
||||
fFont(),
|
||||
fLastFamilyAndStyle(0),
|
||||
fLastFamilyAndStyle(0xffffffff),
|
||||
fLastPointSize(-1.0),
|
||||
fLastHinted(false)
|
||||
{
|
||||
@ -102,12 +102,14 @@ AGGTextRenderer::SetFont(const ServerFont &font)
|
||||
|
||||
if (load) {
|
||||
if (transform.IsIdentity()) {
|
||||
//printf("AGGTextRenderer::SetFont() - native\n");
|
||||
success = fFontEngine.load_font(font, agg::glyph_ren_native_gray8);
|
||||
//printf("AGGTextRenderer::SetFont() - native: %d\n", success);
|
||||
} else {
|
||||
//printf("AGGTextRenderer::SetFont() - outline\n");
|
||||
success = fFontEngine.load_font(font, agg::glyph_ren_outline);
|
||||
//printf("AGGTextRenderer::SetFont() - outline: %d\n", success);
|
||||
}
|
||||
// } else {
|
||||
//printf("AGGTextRenderer::SetFont() - already loaded\n");
|
||||
}
|
||||
|
||||
fLastFamilyAndStyle = font.GetFamilyAndStyle();
|
||||
@ -214,11 +216,11 @@ AGGTextRenderer::RenderString(const char* string,
|
||||
continue;
|
||||
}*/
|
||||
|
||||
const agg::glyph_cache* glyph = fFontManager.glyph(*p);
|
||||
const agg::glyph_cache* glyph = fFontCache.glyph(*p);
|
||||
|
||||
if (glyph) {
|
||||
if (i > 0 && fKerning) {
|
||||
fFontManager.add_kerning(&advanceX, &advanceY);
|
||||
fFontCache.add_kerning(&advanceX, &advanceY);
|
||||
}
|
||||
|
||||
x += advanceX;
|
||||
@ -258,26 +260,26 @@ AGGTextRenderer::RenderString(const char* string,
|
||||
// we cannot use the transformation pipeline
|
||||
double transformedX = x + transformOffset.x;
|
||||
double transformedY = y + transformOffset.y;
|
||||
fFontManager.init_embedded_adaptors(glyph,
|
||||
fFontCache.init_embedded_adaptors(glyph,
|
||||
transformedX,
|
||||
transformedY);
|
||||
glyphBounds.OffsetBy(transformOffset);
|
||||
} else {
|
||||
fFontManager.init_embedded_adaptors(glyph, x, y);
|
||||
fFontCache.init_embedded_adaptors(glyph, x, y);
|
||||
glyphBounds = transform.TransformBounds(glyphBounds);
|
||||
}
|
||||
|
||||
if (clippingFrame.Intersects(glyphBounds)) {
|
||||
switch (glyph->data_type) {
|
||||
case agg::glyph_data_mono:
|
||||
agg::render_scanlines(fFontManager.mono_adaptor(),
|
||||
fFontManager.mono_scanline(),
|
||||
agg::render_scanlines(fFontCache.mono_adaptor(),
|
||||
fFontCache.mono_scanline(),
|
||||
*binRenderer);
|
||||
break;
|
||||
|
||||
case agg::glyph_data_gray8:
|
||||
agg::render_scanlines(fFontManager.gray8_adaptor(),
|
||||
fFontManager.gray8_scanline(),
|
||||
agg::render_scanlines(fFontCache.gray8_adaptor(),
|
||||
fFontCache.gray8_scanline(),
|
||||
*solidRenderer);
|
||||
break;
|
||||
|
||||
@ -370,10 +372,10 @@ AGGTextRenderer::StringWidth(const char* utf8String, uint32 length)
|
||||
|
||||
for (uint32 i = 0; i < glyphCount; i++) {
|
||||
|
||||
if ((glyph = fFontManager.glyph(*p))) {
|
||||
if ((glyph = fFontCache.glyph(*p))) {
|
||||
|
||||
if (i > 0 && fKerning) {
|
||||
fFontManager.add_kerning(&width, &y);
|
||||
fFontCache.add_kerning(&width, &y);
|
||||
}
|
||||
|
||||
width += glyph->advance_x;
|
||||
|
@ -56,13 +56,13 @@ class AGGTextRenderer {
|
||||
|
||||
|
||||
typedef agg::font_engine_freetype_int32 font_engine_type;
|
||||
typedef agg::font_cache_manager<font_engine_type> font_manager_type;
|
||||
typedef agg::conv_curve<font_manager_type::path_adaptor_type>
|
||||
typedef agg::font_cache_manager<font_engine_type> font_cache_type;
|
||||
typedef agg::conv_curve<font_cache_type::path_adaptor_type>
|
||||
conv_font_curve_type;
|
||||
typedef agg::conv_contour<conv_font_curve_type> conv_font_contour_type;
|
||||
|
||||
font_engine_type fFontEngine;
|
||||
font_manager_type fFontManager;
|
||||
font_cache_type fFontCache;
|
||||
|
||||
// Pipeline to process the vectors glyph paths (curves + contour)
|
||||
conv_font_curve_type fCurves;
|
||||
|
Loading…
Reference in New Issue
Block a user