[haiku-commits] Change in haiku[master]: app_server: fix transformations in BPicture

  • From: Gerrit <review@xxxxxxxxxxxxxxxxxxx>
  • To: waddlesplash <waddlesplash@xxxxxxxxx>, haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 10 Jun 2020 02:11:40 +0000

From X512 <danger_mail@xxxxxxx>:

X512 has uploaded this change for review. ( 
https://review.haiku-os.org/c/haiku/+/2898 ;)


Change subject: app_server: fix transformations in BPicture
......................................................................

app_server: fix transformations in BPicture

Fixes #16122, #16147.

Change-Id: Iee7aa8a2325d34a526578a58507ea3690459c8d7
---
M src/servers/app/ServerPicture.cpp
M src/servers/app/ServerWindow.cpp
M src/servers/app/drawing/DrawingEngine.cpp
M src/servers/app/drawing/DrawingEngine.h
M src/servers/app/drawing/Painter/Painter.h
M src/servers/app/drawing/interface/remote/RemoteDrawingEngine.cpp
M src/servers/app/drawing/interface/remote/RemoteDrawingEngine.h
7 files changed, 63 insertions(+), 32 deletions(-)



  git pull ssh://git.haiku-os.org:22/haiku refs/changes/98/2898/1

diff --git a/src/servers/app/ServerPicture.cpp 
b/src/servers/app/ServerPicture.cpp
index 162f641..4daa9ce 100644
--- a/src/servers/app/ServerPicture.cpp
+++ b/src/servers/app/ServerPicture.cpp
@@ -208,10 +208,17 @@
                        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 @@

 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*>(_canvas);
+       BStackOrHeapArray<BPoint, 200> 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 @@
 set_transform(void* _canvas, const BAffineTransform& transform)
 {
        Canvas* const canvas = reinterpret_cast<Canvas*>(_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 @@
 translate_by(void* _canvas, double x, double y)
 {
        Canvas* const canvas = reinterpret_cast<Canvas*>(_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 @@
 scale_by(void* _canvas, double x, double y)
 {
        Canvas* const canvas = reinterpret_cast<Canvas*>(_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 @@
 rotate_by(void* _canvas, double angleRadians)
 {
        Canvas* const canvas = reinterpret_cast<Canvas*>(_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 f236c10..16a4ad7 100644
--- a/src/servers/app/ServerWindow.cpp
+++ b/src/servers/app/ServerWindow.cpp
@@ -3671,24 +3671,16 @@
                        link.Read<int32>(&opCount);
                        link.Read<int32>(&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<uint32, 512> opList(opCount);
+                       BStackOrHeapArray<BPoint, 512> 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 c4e50f6..8d50de8 100644
--- a/src/servers/app/drawing/DrawingEngine.cpp
+++ b/src/servers/app/drawing/DrawingEngine.cpp
@@ -323,9 +323,10 @@


 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 dc010bb..763e8f9 100644
--- a/src/servers/app/drawing/DrawingEngine.h
+++ b/src/servers/app/drawing/DrawingEngine.h
@@ -86,7 +86,8 @@
                                                                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 fc22b08..c997dfd 100644
--- a/src/servers/app/drawing/Painter/Painter.h
+++ b/src/servers/app/drawing/Painter/Painter.h
@@ -68,8 +68,7 @@

                                                                // 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 5bd3018..c6db7ba 100644
--- a/src/servers/app/drawing/interface/remote/RemoteDrawingEngine.cpp
+++ b/src/servers/app/drawing/interface/remote/RemoteDrawingEngine.cpp
@@ -114,7 +114,7 @@
        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,7 +270,8 @@


 void
-RemoteDrawingEngine::SetTransform(const BAffineTransform& transform)
+RemoteDrawingEngine::SetTransform(const BAffineTransform& transform,
+       int32 xOffset, int32 yOffset)
 {
        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 6fc3e71..2aea3fd 100644
--- a/src/servers/app/drawing/interface/remote/RemoteDrawingEngine.h
+++ b/src/servers/app/drawing/interface/remote/RemoteDrawingEngine.h
@@ -55,7 +55,8 @@
                                                                        
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);

--
To view, visit https://review.haiku-os.org/c/haiku/+/2898
To unsubscribe, or for help writing mail filters, visit 
https://review.haiku-os.org/settings

Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: Iee7aa8a2325d34a526578a58507ea3690459c8d7
Gerrit-Change-Number: 2898
Gerrit-PatchSet: 1
Gerrit-Owner: X512 <danger_mail@xxxxxxx>
Gerrit-MessageType: newchange

Other related posts: