app_server: fix transformations in BPicture

Fixes #16122, #16147.

Change-Id: Iee7aa8a2325d34a526578a58507ea3690459c8d7
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2898
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
X512
2020-06-10 04:04:24 +00:00
committed by waddlesplash
parent 2d69e313a8
commit 2e4991285b
7 changed files with 65 additions and 32 deletions
+44 -8
View File
@@ -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*>(_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 @@ static void
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 @@ static void
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 @@ static void
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 @@ static void
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);
}
+8 -16
View File
@@ -3671,24 +3671,16 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link)
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;
}
+3 -2
View File
@@ -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);
}
+2 -1
View File
@@ -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();
+1 -2
View File
@@ -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; }
@@ -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;
@@ -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);