* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter) for each singly drawing command. Now, painter is synchronized whenever the client changes the drawing state of the current view, or when the current view changes. * the screen offset of the current view has become part of the Painter state, in the PatternHandler. This fixes a bug in which moving or scrolling a view which used patterns for drawing, resulted in visual glitches (seams in the pattern). NOTE: this patch is a bit work in progress, most importantly, it is not complete with regards to text rendering. More specifically, the server applications and other parts of the appserver might set a font on the Painter and this might mess up the synchronization. But this happens on the Desktop's Painter instance (only?), and so it is not a problem. I did observe some drawing bugs with this patch though, so bug reports are welcome, particularily how to reproduce these bugs reliably. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
58f6e8e5e4
commit
0896fce5fb
@ -407,7 +407,8 @@ fDesktop->LockSingleWindow();
|
||||
void
|
||||
ServerWindow::NotifyQuitRequested()
|
||||
{
|
||||
// NOTE: if you do something else, other than sending a port message, PLEASE lock
|
||||
// NOTE: if you do something else, other than sending a port message,
|
||||
// PLEASE lock
|
||||
STRACE(("ServerWindow %s: Quit\n", fTitle));
|
||||
|
||||
BMessage msg(B_QUIT_REQUESTED);
|
||||
@ -435,7 +436,8 @@ ServerWindow::NotifyMinimize(bool minimize)
|
||||
void
|
||||
ServerWindow::NotifyZoom()
|
||||
{
|
||||
// NOTE: if you do something else, other than sending a port message, PLEASE lock
|
||||
// NOTE: if you do something else, other than sending a port message,
|
||||
// PLEASE lock
|
||||
BMessage msg(B_ZOOM);
|
||||
SendMessageToClient(&msg);
|
||||
}
|
||||
@ -465,6 +467,13 @@ ServerWindow::GetInfo(window_info& info)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ServerWindow::ResyncDrawState()
|
||||
{
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Returns the ServerWindow's WindowLayer, if it exists and has been
|
||||
added to the Desktop already.
|
||||
@ -1194,12 +1203,15 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
fCurrentLayer->CurrentState()->ReadFromLink(link);
|
||||
// TODO: When is this used?!?
|
||||
fCurrentLayer->RebuildClipping(true);
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_SET_FONT_STATE:
|
||||
{
|
||||
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_FONT_STATE: ViewLayer name: %s\n", fTitle, fCurrentLayer->Name()));
|
||||
fCurrentLayer->CurrentState()->ReadFontFromLink(link);
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_GET_STATE:
|
||||
@ -1323,6 +1335,7 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
link.Read<float>(&y);
|
||||
|
||||
fCurrentLayer->SetDrawingOrigin(BPoint(x, y));
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_GET_ORIGIN:
|
||||
@ -1382,6 +1395,7 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
uint32 flags;
|
||||
link.Read<uint32>(&flags);
|
||||
fCurrentLayer->SetFlags(flags);
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
|
||||
STRACE(("ServerWindow %s: Message AS_LAYER_SET_FLAGS: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
||||
break;
|
||||
@ -1411,7 +1425,9 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
fCurrentLayer->CurrentState()->SetLineCapMode((cap_mode)lineCap);
|
||||
fCurrentLayer->CurrentState()->SetLineJoinMode((join_mode)lineJoin);
|
||||
fCurrentLayer->CurrentState()->SetMiterLimit(miterLimit);
|
||||
|
||||
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_GET_LINE_MODE:
|
||||
@ -1430,7 +1446,8 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
DTRACE(("ServerWindow %s: Message AS_LAYER_PUSH_STATE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
||||
|
||||
fCurrentLayer->PushState();
|
||||
|
||||
// TODO: is this necessary?
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_POP_STATE:
|
||||
@ -1438,7 +1455,7 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
DTRACE(("ServerWindow %s: Message AS_LAYER_POP_STATE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
||||
|
||||
fCurrentLayer->PopState();
|
||||
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_SET_SCALE:
|
||||
@ -1448,6 +1465,7 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
link.Read<float>(&scale);
|
||||
|
||||
fCurrentLayer->SetScale(scale);
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_GET_SCALE:
|
||||
@ -1468,6 +1486,8 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
link.Read<float>(&y);
|
||||
|
||||
fCurrentLayer->CurrentState()->SetPenLocation(BPoint(x, y));
|
||||
// TODO: is this necessary?
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_GET_PEN_LOC:
|
||||
@ -1484,8 +1504,10 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_PEN_SIZE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
||||
float penSize;
|
||||
link.Read<float>(&penSize);
|
||||
|
||||
fCurrentLayer->CurrentState()->SetPenSize(penSize);
|
||||
|
||||
//_UpdateDrawState(fCurrentLayer);
|
||||
fWindowLayer->GetDrawingEngine()->SetPenSize(penSize);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_GET_PEN_SIZE:
|
||||
@ -1545,7 +1567,7 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
|
||||
fCurrentLayer->CurrentState()->SetBlendingMode((source_alpha)srcAlpha,
|
||||
(alpha_function)alphaFunc);
|
||||
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_GET_BLENDING_MODE:
|
||||
@ -1566,7 +1588,8 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
link.Read<int8>(&drawingMode);
|
||||
|
||||
fCurrentLayer->CurrentState()->SetDrawingMode((drawing_mode)drawingMode);
|
||||
|
||||
//_UpdateDrawState(fCurrentLayer);
|
||||
fWindowLayer->GetDrawingEngine()->SetDrawingMode((drawing_mode)drawingMode);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_GET_DRAWING_MODE:
|
||||
@ -1633,8 +1656,10 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
{
|
||||
DTRACE(("ServerWindow %s: Message AS_LAYER_PRINT_ALIASING: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
||||
bool fontAliasing;
|
||||
if (link.Read<bool>(&fontAliasing) == B_OK)
|
||||
if (link.Read<bool>(&fontAliasing) == B_OK) {
|
||||
fCurrentLayer->CurrentState()->SetForceFontAliasing(fontAliasing);
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_CLIP_TO_PICTURE:
|
||||
@ -1782,6 +1807,8 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
link.Read(&c, sizeof(rgb_color));
|
||||
|
||||
fCurrentLayer->CurrentState()->SetHighColor(RGBColor(c));
|
||||
// _UpdateDrawState(fCurrentLayer);
|
||||
fWindowLayer->GetDrawingEngine()->SetHighColor(c);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_SET_LOW_COLOR:
|
||||
@ -1792,6 +1819,8 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
link.Read(&c, sizeof(rgb_color));
|
||||
|
||||
fCurrentLayer->CurrentState()->SetLowColor(RGBColor(c));
|
||||
// _UpdateDrawState(fCurrentLayer);
|
||||
fWindowLayer->GetDrawingEngine()->SetLowColor(c);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_SET_PATTERN:
|
||||
@ -1802,6 +1831,8 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
link.Read(&pat, sizeof(pattern));
|
||||
|
||||
fCurrentLayer->CurrentState()->SetPattern(Pattern(pat));
|
||||
// _UpdateDrawState(fCurrentLayer);
|
||||
fWindowLayer->GetDrawingEngine()->SetPattern(pat);
|
||||
break;
|
||||
}
|
||||
case AS_SET_FONT:
|
||||
@ -1819,7 +1850,11 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
}
|
||||
case AS_SYNC:
|
||||
{
|
||||
// TODO: AS_SYNC is a no-op for now, just to get things working
|
||||
// the synchronisation works by the fact that the client
|
||||
// window is waiting for this reply, after having received it,
|
||||
// client and server queues are in sync (earlier, the client
|
||||
// may have pushed drawing commands at the server and now it
|
||||
// knows they have all been carried out)
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Flush();
|
||||
break;
|
||||
@ -1974,7 +2009,9 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
|
||||
}
|
||||
|
||||
drawingEngine->LockParallelAccess();
|
||||
// TODO: avoid setting the region each time
|
||||
// NOTE: the region is not copied, Painter keeps a pointer,
|
||||
// that's why you need to use the clipping only for as long
|
||||
// as you have it locked
|
||||
drawingEngine->ConstrainClippingRegion(&fCurrentDrawingRegion);
|
||||
|
||||
switch (code) {
|
||||
@ -2258,6 +2295,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
|
||||
|
||||
fCurrentLayer->ConvertFromScreenForDrawing(&penLocation);
|
||||
fCurrentLayer->CurrentState()->SetPenLocation(penLocation);
|
||||
// TODO: optimize with flags
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
|
||||
free(string);
|
||||
break;
|
||||
@ -2837,29 +2876,49 @@ ServerWindow::HandleDirectConnection(int32 bufferState, int32 driverState)
|
||||
void
|
||||
ServerWindow::_SetCurrentLayer(ViewLayer* layer)
|
||||
{
|
||||
if (fCurrentLayer != layer) {
|
||||
fCurrentLayer = layer;
|
||||
fCurrentDrawingRegionValid = false;
|
||||
if (fCurrentLayer == layer)
|
||||
return;
|
||||
|
||||
fCurrentLayer = layer;
|
||||
fCurrentDrawingRegionValid = false;
|
||||
_UpdateDrawState(fCurrentLayer);
|
||||
|
||||
#if 0
|
||||
#if DELAYED_BACKGROUND_CLEARING
|
||||
if (fCurrentLayer && fCurrentLayer->IsBackgroundDirty() && fWindowLayer->InUpdate()) {
|
||||
DrawingEngine* drawingEngine = fWindowLayer->GetDrawingEngine();
|
||||
if (drawingEngine->LockParallelAccess()) {
|
||||
|
||||
fWindowLayer->GetEffectiveDrawingRegion(fCurrentLayer, fCurrentDrawingRegion);
|
||||
fCurrentDrawingRegionValid = true;
|
||||
BRegion dirty(fCurrentDrawingRegion);
|
||||
|
||||
BRegion content;
|
||||
fWindowLayer->GetContentRegion(&content);
|
||||
|
||||
fCurrentLayer->Draw(drawingEngine, &dirty, &content, false);
|
||||
if (fCurrentLayer && fCurrentLayer->IsBackgroundDirty()
|
||||
&& fWindowLayer->InUpdate()) {
|
||||
DrawingEngine* drawingEngine = fWindowLayer->GetDrawingEngine();
|
||||
if (drawingEngine->LockParallelAccess()) {
|
||||
|
||||
drawingEngine->UnlockParallelAccess();
|
||||
}
|
||||
fWindowLayer->GetEffectiveDrawingRegion(fCurrentLayer, fCurrentDrawingRegion);
|
||||
fCurrentDrawingRegionValid = true;
|
||||
BRegion dirty(fCurrentDrawingRegion);
|
||||
|
||||
BRegion content;
|
||||
fWindowLayer->GetContentRegion(&content);
|
||||
|
||||
fCurrentLayer->Draw(drawingEngine, &dirty, &content, false);
|
||||
|
||||
drawingEngine->UnlockParallelAccess();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // 0
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ServerWindow::_UpdateDrawState(ViewLayer* layer)
|
||||
{
|
||||
// switch the drawing state
|
||||
// TODO: is it possible to scroll a view while it
|
||||
// is being drawn? probably not... otherwise the
|
||||
// "offsets" passed below would need to be updated again
|
||||
DrawingEngine* drawingEngine = fWindowLayer->GetDrawingEngine();
|
||||
if (layer && drawingEngine) {
|
||||
IntPoint p = layer->ScrollingOffset();
|
||||
p += IntPoint(layer->CurrentState()->Origin());
|
||||
drawingEngine->SetDrawState(layer->CurrentState(), p.x, p.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,8 @@ public:
|
||||
|
||||
void GetInfo(window_info& info);
|
||||
|
||||
void ResyncDrawState();
|
||||
|
||||
private:
|
||||
ViewLayer* _CreateLayerTree(BPrivate::LinkReceiver &link,
|
||||
ViewLayer **_parent);
|
||||
@ -123,6 +125,7 @@ private:
|
||||
status_t _EnableDirectWindowMode();
|
||||
|
||||
void _SetCurrentLayer(ViewLayer* view);
|
||||
void _UpdateDrawState(ViewLayer* view);
|
||||
|
||||
// TODO: Move me elsewhere
|
||||
status_t PictureToRegion(ServerPicture *picture,
|
||||
|
@ -1784,6 +1784,14 @@ WindowLayer::_DrawBorder()
|
||||
engine->ConstrainClippingRegion(dirtyBorderRegion);
|
||||
fDecorator->Draw(dirtyBorderRegion->Frame());
|
||||
|
||||
// TODO: remove this once the DrawState stuff is handled
|
||||
// more cleanly. The reason why this is needed is that
|
||||
// when the decorator draws strings, a draw state is set
|
||||
// on the Painter object, and this is were it might get
|
||||
// out of sync with what the ServerWindow things is the
|
||||
// current DrawState set on the Painter
|
||||
fWindow->ResyncDrawState();
|
||||
|
||||
engine->UnlockParallelAccess();
|
||||
}
|
||||
fRegionPool.Recycle(dirtyBorderRegion);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2005, Haiku, Inc.
|
||||
* Copyright 2001-2007, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@ -181,6 +181,53 @@ DrawingEngine::ConstrainClippingRegion(const BRegion* region)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawingEngine::SetDrawState(const DrawState* state, int32 xOffset, int32 yOffset)
|
||||
{
|
||||
fPainter->SetDrawState(state, false, xOffset, yOffset);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawingEngine::SetHighColor(const rgb_color& color)
|
||||
{
|
||||
fPainter->SetHighColor(color);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawingEngine::SetLowColor(const rgb_color& color)
|
||||
{
|
||||
fPainter->SetLowColor(color);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawingEngine::SetPenSize(float size)
|
||||
{
|
||||
fPainter->SetPenSize(size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawingEngine::SetPattern(const struct pattern& pattern)
|
||||
{
|
||||
// TODO: doing it like this prevents an optimization
|
||||
// for font rendering (special "solid" drawing mode)
|
||||
fPainter->SetPattern(pattern, false);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawingEngine::SetDrawingMode(drawing_mode mode)
|
||||
{
|
||||
fPainter->SetDrawingMode(mode);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
void
|
||||
DrawingEngine::SuspendAutoSync()
|
||||
{
|
||||
@ -467,7 +514,7 @@ DrawingEngine::DrawBitmap(ServerBitmap *bitmap,
|
||||
if (clipped.IsValid()) {
|
||||
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
// fPainter->SetDrawState(d);
|
||||
fPainter->DrawBitmap(bitmap, source, dest);
|
||||
|
||||
fGraphicsCard->Invalidate(clipped);
|
||||
@ -492,7 +539,7 @@ DrawingEngine::DrawArc(BRect r, const float &angle,
|
||||
if (clipped.IsValid()) {
|
||||
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
// fPainter->SetDrawState(d);
|
||||
|
||||
float xRadius = r.Width() / 2.0;
|
||||
float yRadius = r.Height() / 2.0;
|
||||
@ -519,7 +566,7 @@ DrawingEngine::DrawBezier(BPoint *pts, const DrawState *d, bool filled)
|
||||
// TODO: figure out bounds and hide cursor depending on that
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
// fPainter->SetDrawState(d);
|
||||
BRect touched = fPainter->DrawBezier(pts, filled);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
@ -549,7 +596,7 @@ DrawingEngine::DrawEllipse(BRect r, const DrawState *d, bool filled)
|
||||
if (clipped.IsValid()) {
|
||||
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
// fPainter->SetDrawState(d);
|
||||
fPainter->DrawEllipse(r, filled);
|
||||
|
||||
fGraphicsCard->Invalidate(clipped);
|
||||
@ -573,7 +620,7 @@ DrawingEngine::DrawPolygon(BPoint* ptlist, int32 numpts,
|
||||
if (bounds.IsValid()) {
|
||||
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(bounds);
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
// fPainter->SetDrawState(d);
|
||||
fPainter->DrawPolygon(ptlist, numpts, filled, closed);
|
||||
|
||||
fGraphicsCard->Invalidate(bounds);
|
||||
@ -606,10 +653,15 @@ DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end,
|
||||
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(touched);
|
||||
|
||||
if (!fPainter->StraightLine(start, end, color.GetColor32())) {
|
||||
DrawState context;
|
||||
context.SetHighColor(color);
|
||||
context.SetDrawingMode(B_OP_OVER);
|
||||
StrokeLine(start, end, &context);
|
||||
// TODO: all this is quite expensive, but it is currently
|
||||
// used only for the "gradient" decorator tab buttons
|
||||
rgb_color previousColor = fPainter->HighColor();
|
||||
drawing_mode previousMode = fPainter->DrawingMode();
|
||||
fPainter->SetHighColor(color);
|
||||
fPainter->SetDrawingMode(B_OP_OVER);
|
||||
fPainter->StrokeLine(start, end);
|
||||
fPainter->SetHighColor(previousColor);
|
||||
fPainter->SetDrawingMode(previousMode);
|
||||
} else {
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
}
|
||||
@ -717,7 +769,7 @@ DrawingEngine::StrokeRect(BRect r, const DrawState *d)
|
||||
|
||||
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
// fPainter->SetDrawState(d);
|
||||
fPainter->StrokeRect(r);
|
||||
|
||||
fGraphicsCard->Invalidate(clipped);
|
||||
@ -763,7 +815,7 @@ DrawingEngine::FillRect(BRect r, const DrawState *d)
|
||||
}
|
||||
}
|
||||
if (doInSoftware) {
|
||||
fPainter->SetDrawState(d);
|
||||
// fPainter->SetDrawState(d);
|
||||
fPainter->FillRect(r);
|
||||
|
||||
fGraphicsCard->Invalidate(r);
|
||||
@ -806,7 +858,7 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
|
||||
}
|
||||
|
||||
if (doInSoftware) {
|
||||
fPainter->SetDrawState(d);
|
||||
// fPainter->SetDrawState(d);
|
||||
|
||||
BRect touched = fPainter->FillRect(r.RectAt(0));
|
||||
|
||||
@ -843,7 +895,7 @@ DrawingEngine::DrawRoundRect(BRect r, float xrad, float yrad,
|
||||
if (clipped.IsValid()) {
|
||||
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
// fPainter->SetDrawState(d);
|
||||
BRect touched = filled ? fPainter->FillRoundRect(r, xrad, yrad)
|
||||
: fPainter->StrokeRoundRect(r, xrad, yrad);
|
||||
|
||||
@ -865,7 +917,7 @@ DrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
|
||||
// shape is drawn on screen, TODO: optimize
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
// fPainter->SetDrawState(d);
|
||||
BRect touched = fPainter->DrawShape(opCount, opList,
|
||||
ptCount, ptList,
|
||||
filled);
|
||||
@ -888,7 +940,7 @@ DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds,
|
||||
if (clipped.IsValid()) {
|
||||
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
// fPainter->SetDrawState(d);
|
||||
if (filled)
|
||||
fPainter->FillTriangle(pts[0], pts[1], pts[2]);
|
||||
else
|
||||
@ -913,7 +965,7 @@ DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end, DrawState* con
|
||||
if (touched.IsValid()) {
|
||||
bool cursorTouched = fGraphicsCard->HideSoftwareCursor(touched);
|
||||
|
||||
fPainter->SetDrawState(context);
|
||||
// fPainter->SetDrawState(context);
|
||||
fPainter->StrokeLine(start, end);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
@ -954,15 +1006,7 @@ DrawingEngine::StrokeLineArray(int32 numLines,
|
||||
|
||||
data = (const LineArrayData *)&(linedata[0]);
|
||||
|
||||
DrawState context;
|
||||
context.SetDrawingMode(d->GetDrawingMode());
|
||||
context.SetLowColor(d->LowColor());
|
||||
context.SetHighColor(data->color);
|
||||
context.SetPenSize(d->PenSize());
|
||||
// pen size is already correctly scaled
|
||||
|
||||
fPainter->SetDrawState(&context);
|
||||
|
||||
fPainter->SetHighColor(data->color);
|
||||
fPainter->StrokeLine(data->pt1, data->pt2);
|
||||
|
||||
for (int32 i = 1; i < numLines; i++) {
|
||||
@ -971,6 +1015,9 @@ DrawingEngine::StrokeLineArray(int32 numLines,
|
||||
fPainter->StrokeLine(data->pt1, data->pt2);
|
||||
}
|
||||
|
||||
// restore correct drawing state highcolor
|
||||
fPainter->SetHighColor(d->HighColor());
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
if (cursorTouched)
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
@ -992,6 +1039,11 @@ DrawingEngine::DrawString(const char* string, int32 length,
|
||||
BPoint penLocation = pt;
|
||||
|
||||
fPainter->SetDrawState(d, true);
|
||||
// TODO: this will reset the scrolling offsets used for
|
||||
// pattern drawing again, it is really necessary to change
|
||||
// the whole graphics state synchronization between DrawState
|
||||
// and Painter, and remove any individual SetDrawState() calls
|
||||
// like here
|
||||
//bigtime_t now = system_time();
|
||||
// TODO: BoundingBox is quite slow!! Optimizing it will be beneficial.
|
||||
// Cursiously, the DrawString after it is actually faster!?!
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2005, Haiku, Inc.
|
||||
* Copyright 2001-2007, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@ -66,6 +66,15 @@ public:
|
||||
// will remove any clipping (drawing allowed everywhere)
|
||||
void ConstrainClippingRegion(const BRegion* region);
|
||||
|
||||
void SetDrawState(const DrawState* state,
|
||||
int32 xOffset = 0, int32 yOffset = 0);
|
||||
|
||||
void SetHighColor(const rgb_color& color);
|
||||
void SetLowColor(const rgb_color& color);
|
||||
void SetPenSize(float size);
|
||||
void SetPattern(const struct pattern& pattern);
|
||||
void SetDrawingMode(drawing_mode mode);
|
||||
|
||||
void SuspendAutoSync();
|
||||
void Sync();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2006, Stephan Aßmus <superstippi@gmx.de>. All rights reserved.
|
||||
* Copyright 2005-2007, Stephan Aßmus <superstippi@gmx.de>. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* API to the Anti-Grain Geometry based "Painter" drawing backend. Manages
|
||||
@ -183,7 +183,8 @@ Painter::DetachFromBuffer()
|
||||
|
||||
// SetDrawState
|
||||
void
|
||||
Painter::SetDrawState(const DrawState* data, bool updateFont)
|
||||
Painter::SetDrawState(const DrawState* data, bool updateFont,
|
||||
int32 xOffset, int32 yOffset)
|
||||
{
|
||||
// NOTE: The custom clipping in "data" is ignored, because it has already been
|
||||
// taken into account elsewhere
|
||||
@ -211,6 +212,7 @@ Painter::SetDrawState(const DrawState* data, bool updateFont)
|
||||
fAlphaSrcMode = data->AlphaSrcMode();
|
||||
fAlphaFncMode = data->AlphaFncMode();
|
||||
fPatternHandler->SetPattern(data->GetPattern());
|
||||
fPatternHandler->SetOffsets(xOffset, yOffset);
|
||||
fLineCapMode = data->LineCapMode();
|
||||
fLineJoinMode = data->LineJoinMode();
|
||||
fMiterLimit = data->MiterLimit();
|
||||
@ -258,6 +260,16 @@ Painter::SetLowColor(const rgb_color& color)
|
||||
_SetRendererColor(color);
|
||||
}
|
||||
|
||||
// SetDrawingMode
|
||||
void
|
||||
Painter::SetDrawingMode(drawing_mode mode)
|
||||
{
|
||||
if (fDrawingMode != mode) {
|
||||
fDrawingMode = mode;
|
||||
_UpdateDrawingMode();
|
||||
}
|
||||
}
|
||||
|
||||
// SetPenSize
|
||||
void
|
||||
Painter::SetPenSize(float size)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2006, Stephan Aßmus <superstippi@gmx.de>. All rights reserved.
|
||||
* Copyright 2005-2007, Stephan Aßmus <superstippi@gmx.de>. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* API to the Anti-Grain Geometry based "Painter" drawing backend. Manages
|
||||
@ -10,6 +10,7 @@
|
||||
#define PAINTER_H
|
||||
|
||||
#include "FontManager.h"
|
||||
#include "PatternHandler.h"
|
||||
#include "RGBColor.h"
|
||||
#include "ServerFont.h"
|
||||
|
||||
@ -26,7 +27,6 @@ class AGGTextRenderer;
|
||||
class BBitmap;
|
||||
class BRegion;
|
||||
class DrawState;
|
||||
class PatternHandler;
|
||||
class RenderingBuffer;
|
||||
class ServerBitmap;
|
||||
class ServerFont;
|
||||
@ -65,13 +65,19 @@ class Painter {
|
||||
{ return fClippingRegion; }
|
||||
|
||||
void SetDrawState(const DrawState* data,
|
||||
bool updateFont = false);
|
||||
bool updateFont = false,
|
||||
int32 xOffset = 0,
|
||||
int32 yOffset = 0);
|
||||
|
||||
// object settings
|
||||
void SetHighColor(const rgb_color& color);
|
||||
inline void SetHighColor(uint8 r, uint8 g, uint8 b, uint8 a = 255);
|
||||
inline void SetHighColor(const RGBColor& color)
|
||||
{ SetHighColor(color.GetColor32()); }
|
||||
inline rgb_color HighColor() const
|
||||
{ return fPatternHandler->
|
||||
HighColor().GetColor32(); }
|
||||
|
||||
void SetLowColor(const rgb_color& color);
|
||||
inline void SetLowColor(uint8 r, uint8 g, uint8 b, uint8 a = 255);
|
||||
inline void SetLowColor(const RGBColor& color)
|
||||
@ -80,6 +86,9 @@ class Painter {
|
||||
void SetPenSize(float size);
|
||||
void SetPattern(const pattern& p,
|
||||
bool drawingText = false);
|
||||
void SetDrawingMode(drawing_mode mode);
|
||||
inline drawing_mode DrawingMode() const
|
||||
{ return fDrawingMode; }
|
||||
|
||||
void SetPenLocation(const BPoint& location);
|
||||
BPoint PenLocation() const
|
||||
|
Loading…
Reference in New Issue
Block a user