diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index c4db76efb3..7380b47269 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -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(&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(&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(&scale); fCurrentLayer->SetScale(scale); + _UpdateDrawState(fCurrentLayer); break; } case AS_LAYER_GET_SCALE: @@ -1468,6 +1486,8 @@ ServerWindow::_DispatchViewMessage(int32 code, link.Read(&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(&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(&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(&fontAliasing) == B_OK) + if (link.Read(&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); } } diff --git a/src/servers/app/ServerWindow.h b/src/servers/app/ServerWindow.h index 4e3bd379ce..41d53ce94f 100644 --- a/src/servers/app/ServerWindow.h +++ b/src/servers/app/ServerWindow.h @@ -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, diff --git a/src/servers/app/WindowLayer.cpp b/src/servers/app/WindowLayer.cpp index b5a997ded9..cc00e9aa3b 100644 --- a/src/servers/app/WindowLayer.cpp +++ b/src/servers/app/WindowLayer.cpp @@ -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); diff --git a/src/servers/app/drawing/DrawingEngine.cpp b/src/servers/app/drawing/DrawingEngine.cpp index 7ef304e959..c2185dcecc 100644 --- a/src/servers/app/drawing/DrawingEngine.cpp +++ b/src/servers/app/drawing/DrawingEngine.cpp @@ -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!?! diff --git a/src/servers/app/drawing/DrawingEngine.h b/src/servers/app/drawing/DrawingEngine.h index cbfe14a48a..23c830d86b 100644 --- a/src/servers/app/drawing/DrawingEngine.h +++ b/src/servers/app/drawing/DrawingEngine.h @@ -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(); diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 9990a6311e..9d3bb57756 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006, Stephan Aßmus . All rights reserved. + * Copyright 2005-2007, Stephan Aßmus . 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) diff --git a/src/servers/app/drawing/Painter/Painter.h b/src/servers/app/drawing/Painter/Painter.h index 490e3365f0..eaf1bffb13 100644 --- a/src/servers/app/drawing/Painter/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006, Stephan Aßmus . All rights reserved. + * Copyright 2005-2007, Stephan Aßmus . 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