diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index 162f641a3b..4daa9cef58 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -208,10 +208,17 @@ ShapePainter::Draw(BRect frame, bool filled) fPtStack.pop(); } - BPoint offset(fCanvas->CurrentState()->PenLocation()); - fCanvas->PenToScreenTransform().Apply(&offset); + // this might seem a bit weird, but under R5, the shapes + // are always offset by the current pen location + BPoint screenOffset = fCanvas->CurrentState()->PenLocation(); + frame.OffsetBy(screenOffset); + + const SimpleTransform transform = fCanvas->PenToScreenTransform(); + transform.Apply(&screenOffset); + transform.Apply(&frame); + fCanvas->GetDrawingEngine()->DrawShape(frame, opCount, opList, - ptCount, ptList, filled, offset, fCanvas->Scale()); + ptCount, ptList, filled, screenOffset, fCanvas->Scale()); delete[] opList; delete[] ptList; @@ -407,9 +414,18 @@ draw_string(void* _canvas, const char* string, size_t length, float deltaSpace, static void draw_string_locations(void* _canvas, const char* string, size_t length, - const BPoint* locations, size_t locationsCount) + const BPoint* _locations, size_t locationsCount) { Canvas* const canvas = reinterpret_cast(_canvas); + BStackOrHeapArray locations(locationsCount); + if (!locations.IsValid()) + return; + + const SimpleTransform transform = canvas->PenToScreenTransform(); + for (size_t i = 0; i < locationsCount; i++) { + locations[i] = _locations[i]; + transform.Apply(&locations[i]); + } BPoint location = canvas->GetDrawingEngine()->DrawString(string, length, locations); @@ -758,8 +774,13 @@ static void set_transform(void* _canvas, const BAffineTransform& transform) { Canvas* const canvas = reinterpret_cast(_canvas); + + BPoint leftTop(0, 0); + canvas->PenToScreenTransform().Apply(&leftTop); + canvas->CurrentState()->SetTransform(transform); - canvas->GetDrawingEngine()->SetTransform(transform); + canvas->GetDrawingEngine()->SetTransform( + canvas->CurrentState()->CombinedTransform(), leftTop.x, leftTop.y); } @@ -767,10 +788,15 @@ static void translate_by(void* _canvas, double x, double y) { Canvas* const canvas = reinterpret_cast(_canvas); + + BPoint leftTop(0, 0); + canvas->PenToScreenTransform().Apply(&leftTop); + BAffineTransform transform = canvas->CurrentState()->Transform(); transform.PreTranslateBy(x, y); canvas->CurrentState()->SetTransform(transform); - canvas->GetDrawingEngine()->SetTransform(transform); + canvas->GetDrawingEngine()->SetTransform( + canvas->CurrentState()->CombinedTransform(), leftTop.x, leftTop.y); } @@ -778,10 +804,15 @@ static void scale_by(void* _canvas, double x, double y) { Canvas* const canvas = reinterpret_cast(_canvas); + + BPoint leftTop(0, 0); + canvas->PenToScreenTransform().Apply(&leftTop); + BAffineTransform transform = canvas->CurrentState()->Transform(); transform.PreScaleBy(x, y); canvas->CurrentState()->SetTransform(transform); - canvas->GetDrawingEngine()->SetTransform(transform); + canvas->GetDrawingEngine()->SetTransform( + canvas->CurrentState()->CombinedTransform(), leftTop.x, leftTop.y); } @@ -789,10 +820,15 @@ static void rotate_by(void* _canvas, double angleRadians) { Canvas* const canvas = reinterpret_cast(_canvas); + + BPoint leftTop(0, 0); + canvas->PenToScreenTransform().Apply(&leftTop); + BAffineTransform transform = canvas->CurrentState()->Transform(); transform.PreRotateBy(angleRadians); canvas->CurrentState()->SetTransform(transform); - canvas->GetDrawingEngine()->SetTransform(transform); + canvas->GetDrawingEngine()->SetTransform( + canvas->CurrentState()->CombinedTransform(), leftTop.x, leftTop.y); } diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index f236c10969..16a4ad7b6a 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -3671,24 +3671,16 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) link.Read(&opCount); link.Read(&ptCount); - uint32* opList = new(std::nothrow) uint32[opCount]; - BPoint* ptList = new(std::nothrow) BPoint[ptCount]; - if (opList != NULL && ptList != NULL - && link.Read(opList, opCount * sizeof(uint32)) >= B_OK - && link.Read(ptList, ptCount * sizeof(BPoint)) >= B_OK) { - // This might seem a bit weird, but under BeOS, the shapes - // are always offset by the current pen location - BPoint penLocation - = fCurrentView->CurrentState()->PenLocation(); - for (int32 i = 0; i < ptCount; i++) { - ptList[i] += penLocation; - } - const bool fill = (code == AS_FILL_SHAPE); - picture->WriteDrawShape(opCount, opList, ptCount, ptList, fill); + BStackOrHeapArray opList(opCount); + BStackOrHeapArray ptList(ptCount); + if (!opList.IsValid() || !ptList.IsValid() + || link.Read(opList, opCount * sizeof(uint32)) < B_OK + || link.Read(ptList, ptCount * sizeof(BPoint)) < B_OK) { + break; } + picture->WriteDrawShape(opCount, opList, ptCount, + ptList, code == AS_FILL_SHAPE); - delete[] opList; - delete[] ptList; break; } diff --git a/src/servers/app/drawing/DrawingEngine.cpp b/src/servers/app/drawing/DrawingEngine.cpp index c4e50f6da0..8d50de84a5 100644 --- a/src/servers/app/drawing/DrawingEngine.cpp +++ b/src/servers/app/drawing/DrawingEngine.cpp @@ -323,9 +323,10 @@ DrawingEngine::SetFont(const DrawState* state) void -DrawingEngine::SetTransform(const BAffineTransform& transform) +DrawingEngine::SetTransform(const BAffineTransform& transform, int32 xOffset, + int32 yOffset) { - fPainter->SetTransform(transform); + fPainter->SetTransform(transform, xOffset, yOffset); } diff --git a/src/servers/app/drawing/DrawingEngine.h b/src/servers/app/drawing/DrawingEngine.h index dc010bb925..763e8f995d 100644 --- a/src/servers/app/drawing/DrawingEngine.h +++ b/src/servers/app/drawing/DrawingEngine.h @@ -86,7 +86,8 @@ public: alpha_function alphaFunc); virtual void SetFont(const ServerFont& font); virtual void SetFont(const DrawState* state); - virtual void SetTransform(const BAffineTransform& transform); + virtual void SetTransform(const BAffineTransform& transform, + int32 xOffset, int32 yOffset); void SuspendAutoSync(); void Sync(); diff --git a/src/servers/app/drawing/Painter/Painter.h b/src/servers/app/drawing/Painter/Painter.h index fc22b08193..c997dfd00e 100644 --- a/src/servers/app/drawing/Painter/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -68,8 +68,7 @@ public: // object settings void SetTransform(BAffineTransform transform, - int32 xOffset = 0, - int32 yOffset = 0); + int32 xOffset, int32 yOffset); inline bool IsIdentityTransform() const { return fIdentityTransform; } diff --git a/src/servers/app/drawing/interface/remote/RemoteDrawingEngine.cpp b/src/servers/app/drawing/interface/remote/RemoteDrawingEngine.cpp index 5bd301859f..81034a5a66 100644 --- a/src/servers/app/drawing/interface/remote/RemoteDrawingEngine.cpp +++ b/src/servers/app/drawing/interface/remote/RemoteDrawingEngine.cpp @@ -114,7 +114,7 @@ RemoteDrawingEngine::SetDrawState(const DrawState* state, int32 xOffset, SetHighColor(state->HighColor()); SetLowColor(state->LowColor()); SetFont(state->Font()); - SetTransform(state->CombinedTransform()); + SetTransform(state->CombinedTransform(), xOffset, yOffset); RemoteMessage message(NULL, fHWInterface->SendBuffer()); message.Start(RP_SET_OFFSETS); @@ -270,8 +270,11 @@ RemoteDrawingEngine::SetFont(const DrawState* state) void -RemoteDrawingEngine::SetTransform(const BAffineTransform& transform) +RemoteDrawingEngine::SetTransform(const BAffineTransform& transform, + int32 xOffset, int32 yOffset) { + // TODO: take offset into account + if (fState.Transform() == transform) return; diff --git a/src/servers/app/drawing/interface/remote/RemoteDrawingEngine.h b/src/servers/app/drawing/interface/remote/RemoteDrawingEngine.h index 6fc3e71d24..2aea3fd5d6 100644 --- a/src/servers/app/drawing/interface/remote/RemoteDrawingEngine.h +++ b/src/servers/app/drawing/interface/remote/RemoteDrawingEngine.h @@ -55,7 +55,8 @@ public: alpha_function alphaFunc); virtual void SetFont(const ServerFont& font); virtual void SetFont(const DrawState* state); - virtual void SetTransform(const BAffineTransform& transform); + virtual void SetTransform(const BAffineTransform& transform, + int32 xOffset, int32 yOffset); // drawing functions virtual void InvertRect(BRect rect);