Implement missing methods in PictureBoundingBoxPlayer
* Remove const from gradient in StrokeLineGradient. BoundingBoxPlayer needs to apply transform to it. * Extend LayersTest. * Use BStackOrHeapArray for polygons. * Fixes #12937. Change-Id: If0a4abec0168dbe9afe7ea92bb29017ea8c89c79 Reviewed-on: https://review.haiku-os.org/c/haiku/+/10211 Tested-by: Commit checker robot <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
a65ba286ee
commit
d620b23279
@@ -101,8 +101,7 @@ public:
|
||||
BGradient& gradient, bool fill);
|
||||
virtual void DrawShapeGradient(const BShape& shape, BGradient& gradient, bool fill);
|
||||
virtual void SetFillRule(int32 fillRule);
|
||||
virtual void StrokeLineGradient(const BPoint& start, const BPoint& end,
|
||||
const BGradient& gradient);
|
||||
virtual void StrokeLineGradient(const BPoint& start, const BPoint& end, BGradient& gradient);
|
||||
|
||||
private:
|
||||
void* fUserData;
|
||||
@@ -626,7 +625,7 @@ CallbackAdapterPlayer::SetFillRule(int32 fillRule)
|
||||
|
||||
|
||||
void
|
||||
CallbackAdapterPlayer::StrokeLineGradient(const BPoint& start, const BPoint& end, const BGradient& gradient)
|
||||
CallbackAdapterPlayer::StrokeLineGradient(const BPoint& start, const BPoint& end, BGradient& gradient)
|
||||
{
|
||||
fCallbacks->stroke_line_gradient(fUserData, start, end, gradient);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <PicturePlayer.h>
|
||||
#include <PictureProtocol.h>
|
||||
#include <Shape.h>
|
||||
#include <StackOrHeapArray.h>
|
||||
|
||||
|
||||
//#define DEBUG_TRACE_BB
|
||||
@@ -194,6 +195,23 @@ public:
|
||||
virtual void ScaleBy(double x, double y);
|
||||
virtual void RotateBy(double angleRadians);
|
||||
virtual void BlendLayer(Layer* layer);
|
||||
virtual void ClipToRect(const BRect& rect, bool inverse);
|
||||
virtual void ClipToShape(int32 opCount, const uint32 opList[], int32 ptCount,
|
||||
const BPoint ptList[], bool inverse);
|
||||
virtual void DrawStringLocations(const char* string, size_t length, const BPoint locations[],
|
||||
size_t locationCount);
|
||||
virtual void DrawRectGradient(const BRect& rect, BGradient& gradient, bool fill);
|
||||
virtual void DrawRoundRectGradient(const BRect& rect, const BPoint& radii, BGradient& gradient,
|
||||
bool fill);
|
||||
virtual void DrawBezierGradient(const BPoint controlPoints[4], BGradient& gradient, bool fill);
|
||||
virtual void DrawArcGradient(const BPoint& center, const BPoint& radii, float startTheta,
|
||||
float arcTheta, BGradient& gradient, bool fill);
|
||||
virtual void DrawEllipseGradient(const BRect& rect, BGradient& gradient, bool fill);
|
||||
virtual void DrawPolygonGradient(size_t numPoints, const BPoint points[], bool isClosed,
|
||||
BGradient& gradient, bool fill);
|
||||
virtual void DrawShapeGradient(const BShape& shape, BGradient& gradient, bool fill);
|
||||
virtual void SetFillRule(int32 fillRule);
|
||||
virtual void StrokeLineGradient(const BPoint& start, const BPoint& end, BGradient& gradient);
|
||||
|
||||
private:
|
||||
BoundingBoxState* const fState;
|
||||
@@ -248,7 +266,7 @@ expand_rect_for_pen_size(BoundingBoxState* state, RectType& rect)
|
||||
void
|
||||
BoundingBoxCallbacks::MovePenBy(const BPoint& delta)
|
||||
{
|
||||
TRACE_BB("%p move pen by %.2f %.2f\n", _state, delta.x, delta.y);
|
||||
TRACE_BB("%p move pen by %.2f %.2f\n", fState, delta.x, delta.y);
|
||||
|
||||
fState->GetDrawState()->SetPenLocation(
|
||||
fState->GetDrawState()->PenLocation() + delta);
|
||||
@@ -259,7 +277,7 @@ void
|
||||
BoundingBoxCallbacks::StrokeLine(const BPoint& _start,
|
||||
const BPoint& _end)
|
||||
{
|
||||
TRACE_BB("%p stroke line %.2f %.2f -> %.2f %.2f\n", _state,
|
||||
TRACE_BB("%p stroke line %.2f %.2f -> %.2f %.2f\n", fState,
|
||||
_start.x, _start.y, _end.x, _end.y);
|
||||
|
||||
BPoint start = _start;
|
||||
@@ -295,7 +313,7 @@ BoundingBoxCallbacks::StrokeLine(const BPoint& _start,
|
||||
void
|
||||
BoundingBoxCallbacks::DrawRect(const BRect& _rect, bool fill)
|
||||
{
|
||||
TRACE_BB("%p draw rect fill=%d %.2f %.2f %.2f %.2f\n", _state, fill,
|
||||
TRACE_BB("%p draw rect fill=%d %.2f %.2f %.2f %.2f\n", fState, fill,
|
||||
_rect.left, _rect.top, _rect.right, _rect.bottom);
|
||||
|
||||
BRect rect = _rect;
|
||||
@@ -344,7 +362,7 @@ BoundingBoxCallbacks::DrawBezier(const BPoint viewPoints[4], bool fill)
|
||||
{
|
||||
TRACE_BB("%p draw bezier fill=%d (%.2f %.2f) (%.2f %.2f) "
|
||||
"(%.2f %.2f) (%.2f %.2f)\n",
|
||||
_state,
|
||||
fState,
|
||||
fill,
|
||||
viewPoints[0].x, viewPoints[0].y,
|
||||
viewPoints[1].x, viewPoints[1].y,
|
||||
@@ -362,7 +380,7 @@ BoundingBoxCallbacks::DrawBezier(const BPoint viewPoints[4], bool fill)
|
||||
void
|
||||
BoundingBoxCallbacks::DrawEllipse(const BRect& _rect, bool fill)
|
||||
{
|
||||
TRACE_BB("%p draw ellipse fill=%d (%.2f %.2f) (%.2f %.2f)\n", _state, fill,
|
||||
TRACE_BB("%p draw ellipse fill=%d (%.2f %.2f) (%.2f %.2f)\n", fState, fill,
|
||||
_rect.left, _rect.top, _rect.right, _rect.bottom);
|
||||
|
||||
BRect rect = _rect;
|
||||
@@ -390,27 +408,9 @@ determine_bounds_polygon(BoundingBoxState* state, int32 numPoints,
|
||||
if (numPoints <= 0)
|
||||
return;
|
||||
|
||||
if (numPoints <= 200) {
|
||||
// fast path: no malloc/free, also avoid
|
||||
// constructor/destructor calls
|
||||
char data[200 * sizeof(BPoint)];
|
||||
BPoint* points = (BPoint*)data;
|
||||
|
||||
state->PenToLocalTransform().Apply(points, viewPoints, numPoints);
|
||||
get_polygon_frame(points, numPoints, &outRect);
|
||||
|
||||
} else {
|
||||
// avoid constructor/destructor calls by
|
||||
// using malloc instead of new []
|
||||
BPoint* points = (BPoint*)malloc(numPoints * sizeof(BPoint));
|
||||
if (points == NULL)
|
||||
return;
|
||||
|
||||
state->PenToLocalTransform().Apply(points, viewPoints, numPoints);
|
||||
get_polygon_frame(points, numPoints, &outRect);
|
||||
|
||||
free(points);
|
||||
}
|
||||
BStackOrHeapArray<BPoint, 200> points(numPoints);
|
||||
state->PenToLocalTransform().Apply(points, viewPoints, numPoints);
|
||||
get_polygon_frame(points, numPoints, &outRect);
|
||||
}
|
||||
|
||||
|
||||
@@ -769,7 +769,155 @@ BoundingBoxCallbacks::BlendLayer(Layer* layer)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - PictureBoundingBoxPlayer
|
||||
void
|
||||
BoundingBoxCallbacks::DrawRectGradient(const BRect& _rect, BGradient& gradient, bool fill)
|
||||
{
|
||||
TRACE_BB("%p draw rect gradient fill=%d %.2f %.2f %.2f %.2f\n", fState, fill,
|
||||
_rect.left, _rect.top, _rect.right, _rect.bottom);
|
||||
|
||||
BRect rect = _rect;
|
||||
const SimpleTransform transform = fState->PenToLocalTransform();
|
||||
transform.Apply(&rect);
|
||||
transform.Apply(&gradient);
|
||||
if (!fill)
|
||||
expand_rect_for_pen_size(fState, rect);
|
||||
fState->IncludeRect(rect);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BoundingBoxCallbacks::DrawRoundRectGradient(const BRect& rect, const BPoint& radii,
|
||||
BGradient& gradient, bool fill)
|
||||
{
|
||||
TRACE_BB("%p draw round rect gradient fill=%d %.2f %.2f %.2f %.2f\n", fState, fill,
|
||||
rect.left, rect.top, rect.right, rect.bottom);
|
||||
DrawRectGradient(rect, gradient, fill);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BoundingBoxCallbacks::DrawBezierGradient(const BPoint controlPoints[4], BGradient& gradient,
|
||||
bool fill)
|
||||
{
|
||||
TRACE_BB("%p draw bezier gradient fill=%d (%.2f %.2f) (%.2f %.2f) "
|
||||
"(%.2f %.2f) (%.2f %.2f)\n",
|
||||
fState,
|
||||
fill,
|
||||
viewPoints[0].x, viewPoints[0].y,
|
||||
viewPoints[1].x, viewPoints[1].y,
|
||||
viewPoints[2].x, viewPoints[2].y,
|
||||
viewPoints[3].x, viewPoints[3].y);
|
||||
|
||||
BRect rect;
|
||||
determine_bounds_bezier(fState, controlPoints, rect);
|
||||
fState->PenToLocalTransform().Apply(&gradient);
|
||||
if (!fill)
|
||||
expand_rect_for_pen_size(fState, rect);
|
||||
fState->IncludeRect(rect);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BoundingBoxCallbacks::DrawEllipseGradient(const BRect& _rect, BGradient& gradient, bool fill)
|
||||
{
|
||||
TRACE_BB("%p draw ellipse gradient fill=%d (%.2f %.2f) (%.2f %.2f)\n", fState, fill,
|
||||
_rect.left, _rect.top, _rect.right, _rect.bottom);
|
||||
|
||||
BRect rect = _rect;
|
||||
const SimpleTransform transform = fState->PenToLocalTransform();
|
||||
transform.Apply(&rect);
|
||||
transform.Apply(&gradient);
|
||||
if (!fill)
|
||||
expand_rect_for_pen_size(fState, rect);
|
||||
fState->IncludeRect(rect);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BoundingBoxCallbacks::DrawArcGradient(const BPoint& center, const BPoint& radii, float startTheta,
|
||||
float arcTheta, BGradient& gradient, bool fill)
|
||||
{
|
||||
BRect rect(center.x - radii.x, center.y - radii.y,
|
||||
center.x + radii.x - 1, center.y + radii.y - 1);
|
||||
DrawEllipseGradient(rect, gradient, fill);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BoundingBoxCallbacks::DrawPolygonGradient(size_t numPoints, const BPoint points[], bool isClosed,
|
||||
BGradient& gradient, bool fill)
|
||||
{
|
||||
TRACE_BB("%p draw polygon fill=%d (%ld points)\n", fState, fill, numPoints);
|
||||
if (numPoints <= 0)
|
||||
return;
|
||||
|
||||
BRect rect;
|
||||
determine_bounds_polygon(fState, numPoints, points, rect);
|
||||
fState->PenToLocalTransform().Apply(&gradient);
|
||||
if (!fill)
|
||||
expand_rect_for_pen_size(fState, rect);
|
||||
fState->IncludeRect(rect);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BoundingBoxCallbacks::DrawShapeGradient(const BShape& shape, BGradient& gradient, bool fill)
|
||||
{
|
||||
BRect rect = shape.Bounds();
|
||||
|
||||
// FIXME: this doesn't work - ShapePainter uses ScreenTransform unconditionally
|
||||
TRACE_BB("%p stroke shape gradient (bounds %.2f %.2f %.2f %.2f)\n", fState,
|
||||
rect.left, rect.top, rect.right, rect.bottom);
|
||||
|
||||
const SimpleTransform transform = fState->PenToLocalTransform();
|
||||
transform.Apply(&rect);
|
||||
transform.Apply(&gradient);
|
||||
if (!fill)
|
||||
expand_rect_for_pen_size(fState, rect);
|
||||
fState->IncludeRect(rect);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BoundingBoxCallbacks::ClipToRect(const BRect& rect, bool inverse)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BoundingBoxCallbacks::ClipToShape(int32 opCount, const uint32 opList[], int32 ptCount,
|
||||
const BPoint ptList[], bool inverse)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BoundingBoxCallbacks::DrawStringLocations(const char* string, size_t length,
|
||||
const BPoint locations[], size_t locationCount)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BoundingBoxCallbacks::SetFillRule(int32 fillRule)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BoundingBoxCallbacks::StrokeLineGradient(const BPoint& start, const BPoint& end,
|
||||
BGradient& gradient)
|
||||
{
|
||||
TRACE_BB("%p stroke line gradient %.2f %.2f -> %.2f %.2f\n", fState,
|
||||
start.x, start.y, end.x, end.y);
|
||||
const SimpleTransform transform = fState->PenToLocalTransform();
|
||||
transform.Apply(&gradient);
|
||||
StrokeLine(start, end);
|
||||
}
|
||||
|
||||
|
||||
/* static */ void
|
||||
|
||||
@@ -305,8 +305,7 @@ public:
|
||||
BGradient& gradient, bool fill);
|
||||
virtual void DrawShapeGradient(const BShape& shape, BGradient& gradient, bool fill);
|
||||
virtual void SetFillRule(int32 fillRule);
|
||||
virtual void StrokeLineGradient(const BPoint& start, const BPoint& end,
|
||||
const BGradient& gradient);
|
||||
virtual void StrokeLineGradient(const BPoint& start, const BPoint& end, BGradient& gradient);
|
||||
|
||||
private:
|
||||
Canvas* const fCanvas;
|
||||
@@ -570,7 +569,7 @@ CanvasCallbacks::DrawShapeGradient(const BShape& shape, BGradient& gradient, boo
|
||||
|
||||
void
|
||||
CanvasCallbacks::StrokeLineGradient(const BPoint& _start, const BPoint& _end,
|
||||
const BGradient& gradient)
|
||||
BGradient& gradient)
|
||||
{
|
||||
BPoint start = _start;
|
||||
BPoint end = _end;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016, Haiku Inc.
|
||||
* Copyright 2016, 2026, Haiku Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
#include <Application.h>
|
||||
#include <GradientRadial.h>
|
||||
#include <GradientLinear.h>
|
||||
#include <Shape.h>
|
||||
#include <Polygon.h>
|
||||
#include <String.h>
|
||||
#include <View.h>
|
||||
#include <Window.h>
|
||||
@@ -24,11 +27,33 @@ class View : public BView {
|
||||
virtual ~View();
|
||||
|
||||
virtual void Draw(BRect);
|
||||
BGradientLinear g[3];
|
||||
BPoint bezierPoints[3][4];
|
||||
BShape shapes[3];
|
||||
BPolygon polygon;
|
||||
};
|
||||
|
||||
View::View(BRect rect)
|
||||
: BView(rect, "gradients", B_FOLLOW_ALL, B_WILL_DRAW)
|
||||
{
|
||||
SetViewColor(0, 255, 0);
|
||||
for(int i = 0; i < 3; i++) {
|
||||
g[i].SetStart(BPoint(0, i * 100));
|
||||
g[i].SetEnd(BPoint(0, (i + 1) * 100));
|
||||
g[i].AddColor((rgb_color) { 255, 0, 0, 255 }, 255.0);
|
||||
g[i].AddColor((rgb_color) { 255, 255, 255, 0 }, 0.0);
|
||||
bezierPoints[i][0] = BPoint(540, i * 100 + 10);
|
||||
bezierPoints[i][1] = BPoint(610, i * 100 + 10);
|
||||
bezierPoints[i][2] = BPoint(580, (i + 1) * 100);
|
||||
bezierPoints[i][3] = BPoint(630, (i + 1) * 100);
|
||||
shapes[i].MoveTo(BPoint(640, i * 100 + 10));
|
||||
shapes[i].LineTo(BPoint(670, i * 100 + 40));
|
||||
shapes[i].LineTo(BPoint(700, i * 100 + 40));
|
||||
shapes[i].LineTo(BPoint(640, i * 100 + 100));
|
||||
shapes[i].Close();
|
||||
}
|
||||
BPoint p[4] = { BPoint(0, 0), BPoint(0, 50), BPoint(90, 90), BPoint(50, 50) };
|
||||
polygon.AddPoints(p, 4);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,22 +65,36 @@ View::~View()
|
||||
void
|
||||
View::Draw(BRect)
|
||||
{
|
||||
BGradientRadial g(BPoint(50, 50), 50.0);
|
||||
g.AddColor((rgb_color) { 0, 0, 0, 255 }, 255.0);
|
||||
g.AddColor((rgb_color) { 255, 255, 255, 0 }, 0.0);
|
||||
SetHighColor(0, 0, 0);
|
||||
BeginLayer(255);
|
||||
// 1, 1
|
||||
FillRect(BRect(10, 10, 90, 90));
|
||||
// 2, 1
|
||||
FillRect(BRect(100, 10, 190, 90), g);
|
||||
EndLayer();
|
||||
BeginLayer(100);
|
||||
// 1, 2
|
||||
FillRect(BRect(10, 100, 90, 190));
|
||||
// 2, 2
|
||||
FillRect(BRect(100, 100, 190, 190), g);
|
||||
EndLayer();
|
||||
BPoint text(5, 60);
|
||||
BRect rect(10, 10, 100, 100);
|
||||
BRect gradient(110, 10, 200, 100);
|
||||
rect.OffsetBy(30, 0);
|
||||
gradient.OffsetBy(30, 0);
|
||||
int opacity[3] = {255, 254, 100};
|
||||
for(int i = 0; i < 3; i++) {
|
||||
BString s;
|
||||
s << opacity[i];
|
||||
DrawString(s, 3, text);
|
||||
BeginLayer(opacity[i]);
|
||||
FillRect(rect);
|
||||
FillRect(gradient, g[i]);
|
||||
FillRoundRect(gradient.OffsetByCopy(100, 0), 10, 10, g[i]);
|
||||
FillEllipse(gradient.OffsetByCopy(200, 0), g[i]);
|
||||
FillArc(gradient.OffsetByCopy(300, 0), 30, 120, g[i]);
|
||||
FillBezier(bezierPoints[i], g[i]);
|
||||
BShape sh = shapes[i];
|
||||
MovePenTo(B_ORIGIN);
|
||||
FillShape(&sh, g[i]);
|
||||
BPolygon p = polygon;
|
||||
p.MapTo(BRect(0, 0, 90, 90), gradient.OffsetByCopy(600, 0));
|
||||
FillPolygon(&p, g[i]);
|
||||
StrokeLine(BPoint(840, i * 100 + 10), BPoint(930, i * 100 + 100), g[i]);
|
||||
EndLayer();
|
||||
rect.OffsetBy(0, 100);
|
||||
gradient.OffsetBy(0, 100);
|
||||
text.y += 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +111,7 @@ class Window : public BWindow {
|
||||
|
||||
|
||||
Window::Window()
|
||||
: BWindow(BRect(100, 100, 300, 300), "Layers-Test",
|
||||
: BWindow(BRect(100, 100, 1040, 410), "Layers-Test",
|
||||
B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS)
|
||||
{
|
||||
BView *view = new View(Bounds());
|
||||
|
||||
Reference in New Issue
Block a user