Patch by Artur Wyszynski:

* Implemented BGradient, BGradientLinear, BGradientRadial,
  BGradientDiamond, BGradientConic and BGradientRadialFocus
  new Interface Kit classes.
* Implemented all the (AGG-based) backend necessary in
  the app_server to render gradients (Painter, DrawingEngine)
* app_server/View can convert a BGradient layout to screen
  coordinates.
* Added BGradient methods of the Fill* methods in BView.
* Implemented a test app and added it to the image as a
  demo.
* Adopted Icon-O-Matic and libs/icon in order to avoid
  clashing with the new BGradient class. Re-use some
  parts where possible.

Awesome work, Artur! Thanks a lot. Now a more modern
looking GUI has just become much easier to implement! :-)

TODO:
* Remove the need to have gradient type twice in the
  app_server protocol.
* Refactor some parts of the patch to remove duplicated
  code (Painter, DrawingEngine).
* Adopt the BPicture protocol to know about BGradients.
* Review some parts of the BArchivable implementation.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28109 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2008-10-14 21:27:42 +00:00
parent 9e6975723d
commit 991547ef6c
57 changed files with 3458 additions and 125 deletions
+1 -1
View File
@@ -66,7 +66,7 @@ BEOS_PREFERENCES = Appearance Backgrounds DataTranslations E-mail
;
BEOS_DEMOS = BSnow Chart Clock $(X86_ONLY)Cortex FontDemo
$(X86_ONLY)GLDirectMode $(X86_ONLY)GLTeapot Mandelbrot Pairs
Playground Pulse Sudoku
Playground Pulse Sudoku Gradients
;
BEOS_SYSTEM_LIBS = libbe.so $(HAIKU_LIBSTDC++) libmedia.so libtracker.so
libtranslation.so libbnetapi.so libnetwork.so libdebug.so libbsd.so
+2
View File
@@ -50,6 +50,7 @@ class ServerLink {
status_t AttachString(const char *string, int32 length = -1);
status_t AttachRegion(const BRegion &region);
status_t AttachShape(BShape &shape);
status_t AttachGradient(const BGradient &gradient);
template <class Type> status_t Attach(const Type& data);
// receive methods
@@ -63,6 +64,7 @@ class ServerLink {
status_t ReadString(char **string);
status_t ReadRegion(BRegion *region);
status_t ReadShape(BShape *shape);
status_t ReadGradient(BGradient *gradient);
template <class Type> status_t Read(Type *data);
// convenience methods
@@ -219,14 +219,23 @@ enum {
AS_STROKE_TRIANGLE,
AS_FILL_ARC,
AS_FILL_ARC_GRADIENT,
AS_FILL_BEZIER,
AS_FILL_BEZIER_GRADIENT,
AS_FILL_ELLIPSE,
AS_FILL_ELLIPSE_GRADIENT,
AS_FILL_POLYGON,
AS_FILL_POLYGON_GRADIENT,
AS_FILL_RECT,
AS_FILL_RECT_GRADIENT,
AS_FILL_REGION,
AS_FILL_REGION_GRADIENT,
AS_FILL_ROUNDRECT,
AS_FILL_ROUNDRECT_GRADIENT,
AS_FILL_SHAPE,
AS_FILL_SHAPE_GRADIENT,
AS_FILL_TRIANGLE,
AS_FILL_TRIANGLE_GRADIENT,
AS_MOVEPENBY,
AS_MOVEPENTO,
+110
View File
@@ -0,0 +1,110 @@
/*
* Copyright 2006-2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <[email protected]>
* Artur Wyszynski <[email protected]>
*/
#ifndef GRADIENT_H
#define GRADIENT_H
#include <Archivable.h>
#include <GraphicsDefs.h>
#include <List.h>
class BMessage;
class BRect;
enum gradient_type {
B_GRADIENT_LINEAR = 0,
B_GRADIENT_RADIAL,
B_GRADIENT_RADIAL_FOCUS,
B_GRADIENT_DIAMOND,
B_GRADIENT_CONIC,
B_GRADIENT_NONE
};
struct color_step {
color_step(const rgb_color c, float o);
color_step(uint8 r, uint8 g, uint8 b, uint8 a, float o);
color_step(const color_step& other);
color_step();
bool operator!=(const color_step& other) const;
rgb_color color;
float offset;
};
class BGradient : public BArchivable {
public:
BGradient();
BGradient(BMessage* archive);
virtual ~BGradient();
status_t Archive(BMessage* into, bool deep = true) const;
BGradient& operator=(const BGradient& other);
bool operator==(const BGradient& other) const;
bool operator!=(const BGradient& other) const;
bool ColorStepsAreEqual(const BGradient& other) const;
void SetColors(const BGradient& other);
int32 AddColor(const rgb_color& color, float offset);
bool AddColor(const color_step& color, int32 index);
bool RemoveColor(int32 index);
bool SetColor(int32 index, const color_step& step);
bool SetColor(int32 index, const rgb_color& color);
bool SetOffset(int32 index, float offset);
int32 CountColors() const;
color_step* ColorAt(int32 index) const;
color_step* ColorAtFast(int32 index) const;
color_step* Colors() const;
void SortColorStepsByOffset();
gradient_type Type() const
{ return fType; }
void MakeEmpty();
private:
friend class BGradientLinear;
friend class BGradientRadial;
friend class BGradientRadialFocus;
friend class BGradientDiamond;
friend class BGradientConic;
union {
struct {
float x1, y1, x2, y2;
} linear;
struct {
float cx, cy, radius;
} radial;
struct {
float cx, cy, fx, fy, radius;
} radial_focus;
struct {
float cx, cy;
} diamond;
struct {
float cx, cy, angle;
} conic;
} fData;
BList fColors;
gradient_type fType;
};
#endif // GRADIENT_H
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright 2006-2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Artur Wyszynski <[email protected]>
*/
#ifndef GRADIENT_CONIC_H
#define GRADIENT_CONIC_H
#include <Gradient.h>
class BPoint;
class BGradientConic : public BGradient {
public:
BGradientConic();
BGradientConic(const BPoint& center, float angle);
BGradientConic(float cx, float cy, float angle);
BPoint Center() const;
void SetCenter(const BPoint& center);
void SetCenter(float cx, float cy);
float Angle() const;
void SetAngle(float angle);
};
#endif // GRADIENT_CONIC_H
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright 2006-2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Artur Wyszynski <[email protected]>
*/
#ifndef GRADIENT_DIAMOND_H
#define GRADIENT_DIAMOND_H
#include <Gradient.h>
class BPoint;
class BGradientDiamond : public BGradient {
public:
BGradientDiamond();
BGradientDiamond(const BPoint& center);
BGradientDiamond(float cx, float cy);
BPoint Center() const;
void SetCenter(const BPoint& center);
void SetCenter(float cx, float cy);
};
#endif // GRADIENT_DIAMOND_H
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright 2006-2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Artur Wyszynski <[email protected]>
*/
#ifndef GRADIENT_LINEAR_H
#define GRADIENT_LINEAR_H
#include <Gradient.h>
class BPoint;
class BGradientLinear : public BGradient {
public:
BGradientLinear();
BGradientLinear(const BPoint& start, const BPoint& end);
BGradientLinear(float x1, float y1, float x2, float y2);
BPoint Start() const;
void SetStart(const BPoint& start);
void SetStart(float x1, float y1);
BPoint End() const;
void SetEnd(const BPoint& end);
void SetEnd(float x2, float y2);
};
#endif // GRADIENT_LINEAR_H
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright 2006-2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Artur Wyszynski <[email protected]>
*/
#ifndef GRADIENT_RADIAL_H
#define GRADIENT_RADIAL_H
#include <Gradient.h>
class BPoint;
class BGradientRadial : public BGradient {
public:
BGradientRadial();
BGradientRadial(const BPoint& center, float radius);
BGradientRadial(float cx, float cy, float radius);
BPoint Center() const;
void SetCenter(const BPoint& center);
void SetCenter(float cx, float cy);
float Radius() const;
void SetRadius(float radius);
};
#endif // GRADIENT_RADIAL_H
@@ -0,0 +1,35 @@
/*
* Copyright 2006-2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Artur Wyszynski <[email protected]>
*/
#ifndef GRADIENT_RADIAL_FOCUS_H
#define GRADIENT_RADIAL_FOCUS_H
#include <Gradient.h>
class BPoint;
class BGradientRadialFocus : public BGradient {
public:
BGradientRadialFocus();
BGradientRadialFocus(const BPoint& center, float radius,
const BPoint& focal);
BGradientRadialFocus(float cx, float cy, float radius, float fx, float fy);
BPoint Center() const;
void SetCenter(const BPoint& center);
void SetCenter(float cx, float cy);
BPoint Focal() const;
void SetFocal(const BPoint& focal);
void SetFocal(float fx, float fy);
float Radius() const;
void SetRadius(float radius);
};
#endif // GRADIENT_RADIAL_FOCUS_H
+30 -3
View File
@@ -16,6 +16,7 @@
#include <InterfaceDefs.h>
#include <Rect.h>
#include <Size.h>
#include <Gradient.h>
// mouse button
@@ -317,7 +318,13 @@ public:
pattern p = B_SOLID_HIGH);
void FillPolygon(const BPoint* ptArray, int32 numPts,
BRect bounds, pattern p = B_SOLID_HIGH);
void FillPolygon(const BPolygon* polygon,
const BGradient& gradient);
void FillPolygon(const BPoint* ptArray, int32 numPts,
const BGradient& gradient);
void FillPolygon(const BPoint* ptArray, int32 numPts,
BRect bounds, const BGradient& gradient);
void StrokeTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
BRect bounds, pattern p = B_SOLID_HIGH);
void StrokeTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
@@ -326,17 +333,26 @@ public:
pattern p = B_SOLID_HIGH);
void FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
BRect bounds, pattern p = B_SOLID_HIGH);
void FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
const BGradient& gradient);
void FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
BRect bounds, const BGradient& gradient);
void StrokeRect(BRect r, pattern p = B_SOLID_HIGH);
void FillRect(BRect r, pattern p = B_SOLID_HIGH);
void FillRect(BRect r, const BGradient& gradient);
void FillRegion(BRegion* region,
pattern p = B_SOLID_HIGH);
void FillRegion(BRegion* region,
const BGradient& gradient);
void InvertRect(BRect r);
void StrokeRoundRect(BRect r, float xRadius,
float yRadius, pattern p = B_SOLID_HIGH);
void FillRoundRect(BRect r, float xRadius, float yRadius,
pattern p = B_SOLID_HIGH);
void FillRoundRect(BRect r, float xRadius, float yRadius,
const BGradient& gradient);
void StrokeEllipse(BPoint center, float xRadius,
float yRadius, pattern p = B_SOLID_HIGH);
@@ -344,7 +360,10 @@ public:
void FillEllipse(BPoint center, float xRadius,
float yRadius, pattern p = B_SOLID_HIGH);
void FillEllipse(BRect r, pattern p = B_SOLID_HIGH);
void FillEllipse(BPoint center, float xRadius,
float yRadius, const BGradient& gradient);
void FillEllipse(BRect r, const BGradient& gradient);
void StrokeArc(BPoint center, float xRadius,
float yRadius, float startAngle, float arcAngle,
pattern p = B_SOLID_HIGH);
@@ -355,15 +374,23 @@ public:
pattern p = B_SOLID_HIGH);
void FillArc(BRect r, float startAngle, float arcAngle,
pattern p = B_SOLID_HIGH);
void FillArc(BPoint center, float xRadius, float yRadius,
float startAngle, float arcAngle,
const BGradient& gradient);
void FillArc(BRect r, float startAngle, float arcAngle,
const BGradient& gradient);
void StrokeBezier(BPoint* controlPoints,
pattern p = B_SOLID_HIGH);
void FillBezier(BPoint* controlPoints,
pattern p = B_SOLID_HIGH);
void FillBezier(BPoint* controlPoints,
const BGradient& gradient);
void StrokeShape(BShape* shape,
pattern p = B_SOLID_HIGH);
void FillShape(BShape* shape, pattern p = B_SOLID_HIGH);
void FillShape(BShape* shape, const BGradient& gradient);
void CopyBits(BRect src, BRect dst);
+2
View File
@@ -15,6 +15,7 @@
class BString;
class BRegion;
class BGradient;
namespace BPrivate {
@@ -37,6 +38,7 @@ class LinkReceiver {
status_t ReadString(BString& string, size_t* _length = NULL);
status_t ReadString(char* buffer, size_t bufferSize);
status_t ReadRegion(BRegion* region);
status_t ReadGradient(BGradient *gradient);
template <class Type> status_t Read(Type *data)
{ return Read(data, sizeof(Type)); }
+3
View File
@@ -17,6 +17,7 @@
class BShape;
class BString;
class BGradient;
/*
* Error checking rules: (for if you don't want to check every return code)
@@ -49,6 +50,7 @@ class ServerLink {
status_t AttachString(const char *string, int32 length = -1);
status_t AttachRegion(const BRegion &region);
status_t AttachShape(BShape &shape);
status_t AttachGradient(const BGradient &gradient);
template <class Type> status_t Attach(const Type& data);
// receive methods
@@ -64,6 +66,7 @@ class ServerLink {
status_t ReadString(char** _string, size_t* _length = NULL);
status_t ReadRegion(BRegion *region);
status_t ReadShape(BShape *shape);
status_t ReadGradient(BGradient *gradient);
template <class Type> status_t Read(Type *data);
// convenience methods
+9
View File
@@ -218,14 +218,23 @@ enum {
AS_STROKE_TRIANGLE,
AS_FILL_ARC,
AS_FILL_ARC_GRADIENT,
AS_FILL_BEZIER,
AS_FILL_BEZIER_GRADIENT,
AS_FILL_ELLIPSE,
AS_FILL_ELLIPSE_GRADIENT,
AS_FILL_POLYGON,
AS_FILL_POLYGON_GRADIENT,
AS_FILL_RECT,
AS_FILL_RECT_GRADIENT,
AS_FILL_REGION,
AS_FILL_REGION_GRADIENT,
AS_FILL_ROUNDRECT,
AS_FILL_ROUNDRECT_GRADIENT,
AS_FILL_SHAPE,
AS_FILL_SHAPE_GRADIENT,
AS_FILL_TRIANGLE,
AS_FILL_TRIANGLE_GRADIENT,
AS_DRAW_STRING,
AS_DRAW_STRING_WITH_DELTA,
+1
View File
@@ -18,6 +18,7 @@ SubInclude HAIKU_TOP src apps drivesetup ;
SubInclude HAIKU_TOP src apps expander ;
SubInclude HAIKU_TOP src apps fontdemo ;
SubInclude HAIKU_TOP src apps glteapot ;
SubInclude HAIKU_TOP src apps gradients ;
SubInclude HAIKU_TOP src apps icon-o-matic ;
SubInclude HAIKU_TOP src apps installedpackages ;
SubInclude HAIKU_TOP src apps installer ;
+445
View File
@@ -0,0 +1,445 @@
/*
* Copyright (c) 2008, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* Artur Wyszynski <harakash@gmail.com>
*/
#include <Application.h>
#include <GradientLinear.h>
#include <GradientRadial.h>
#include <GradientRadialFocus.h>
#include <GradientDiamond.h>
#include <GradientConic.h>
#include <View.h>
#include <Screen.h>
#include <Window.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <PopUpMenu.h>
#define MSG_LINEAR 'gtli'
#define MSG_RADIAL 'gtra'
#define MSG_RADIAL_FOCUS 'gtrf'
#define MSG_DIAMOND 'gtdi'
#define MSG_CONIC 'gtco'
class GradientsApp : public BApplication {
public:
GradientsApp(void);
};
class GradientsView : public BView {
public:
GradientsView(const BRect &r);
virtual ~GradientsView(void);
virtual void Draw(BRect update);
void DrawLinear(BRect update);
void DrawRadial(BRect update);
void DrawRadialFocus(BRect update);
void DrawDiamond(BRect update);
void DrawConic(BRect update);
void SetType(gradient_type type);
private:
gradient_type fType;
};
class GradientsWindow : public BWindow {
public:
GradientsWindow(void);
bool QuitRequested(void);
virtual void MessageReceived(BMessage *msg);
private:
BPopUpMenu* fGradientsMenu;
BMenuItem* fLinearItem;
BMenuItem* fRadialItem;
BMenuItem* fRadialFocusItem;
BMenuItem* fDiamondItem;
BMenuItem* fConicItem;
BMenuField* fGradientsTypeField;
GradientsView* fGradientsView;
};
// #pragma mark -
GradientsApp::GradientsApp(void)
: BApplication("application/x-vnd.Haiku-Gradients")
{
GradientsWindow *window = new GradientsWindow();
window->Show();
}
// #pragma mark -
GradientsWindow::GradientsWindow()
: BWindow(BRect(0, 0, 230, 490), "Gradients Test", B_TITLED_WINDOW,
B_NOT_RESIZABLE | B_NOT_ZOOMABLE)
{
BRect field(10, 10, Bounds().Width() - 10, 30);
fGradientsMenu = new BPopUpMenu("gradientsType");
fLinearItem = new BMenuItem("Linear", new BMessage(MSG_LINEAR));
fRadialItem = new BMenuItem("Radial", new BMessage(MSG_RADIAL));
fRadialFocusItem = new BMenuItem("Radial Focus",
new BMessage(MSG_RADIAL_FOCUS));
fDiamondItem = new BMenuItem("Diamond", new BMessage(MSG_DIAMOND));
fConicItem = new BMenuItem("Conic", new BMessage(MSG_CONIC));
fGradientsMenu->AddItem(fLinearItem);
fGradientsMenu->AddItem(fRadialItem);
fGradientsMenu->AddItem(fRadialFocusItem);
fGradientsMenu->AddItem(fDiamondItem);
fGradientsMenu->AddItem(fConicItem);
fLinearItem->SetMarked(true);
fGradientsTypeField = new BMenuField(field, "gradientsField",
"Gradient type:",
fGradientsMenu,
B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
B_WILL_DRAW | B_NAVIGABLE
| B_FRAME_EVENTS);
fGradientsTypeField->SetViewColor(255, 255, 255);
fGradientsTypeField->SetDivider(110);
AddChild(fGradientsTypeField);
BRect bounds = Bounds();
bounds.top = 40;
fGradientsView = new GradientsView(bounds);
AddChild(fGradientsView);
MoveTo((BScreen().Frame().Width() - Bounds().Width()) / 2,
(BScreen().Frame().Height() - Bounds().Height()) / 2 );
}
bool
GradientsWindow::QuitRequested()
{
be_app->PostMessage(B_QUIT_REQUESTED);
return true;
}
void
GradientsWindow::MessageReceived(BMessage *msg)
{
switch (msg->what) {
case MSG_LINEAR:
fGradientsView->SetType(B_GRADIENT_LINEAR);
break;
case MSG_RADIAL:
fGradientsView->SetType(B_GRADIENT_RADIAL);
break;
case MSG_RADIAL_FOCUS:
fGradientsView->SetType(B_GRADIENT_RADIAL_FOCUS);
break;
case MSG_DIAMOND:
fGradientsView->SetType(B_GRADIENT_DIAMOND);
break;
case MSG_CONIC:
fGradientsView->SetType(B_GRADIENT_CONIC);
break;
default:
BWindow::MessageReceived(msg);
break;
}
}
// #pragma mark -
GradientsView::GradientsView(const BRect &rect)
: BView(rect, "gradientsview", B_FOLLOW_ALL, B_WILL_DRAW | B_PULSE_NEEDED),
fType(B_GRADIENT_LINEAR)
{
}
GradientsView::~GradientsView()
{
}
void
GradientsView::Draw(BRect update)
{
switch (fType) {
case B_GRADIENT_LINEAR: {
DrawLinear(update);
break;
}
case B_GRADIENT_RADIAL: {
DrawRadial(update);
break;
}
case B_GRADIENT_RADIAL_FOCUS: {
DrawRadialFocus(update);
break;
}
case B_GRADIENT_DIAMOND: {
DrawDiamond(update);
break;
}
case B_GRADIENT_CONIC: {
DrawConic(update);
break;
}
case B_GRADIENT_NONE:
default: {
break;
}
}
}
void
GradientsView::DrawLinear(BRect update)
{
BGradientLinear gradient;
rgb_color c;
c.red = 255;
c.green = 0;
c.blue = 0;
gradient.AddColor(c, 0);
c.red = 0;
c.green = 255;
c.blue = 0;
gradient.AddColor(c, 127);
c.red = 0;
c.green = 0;
c.blue = 255;
gradient.AddColor(c, 255);
// RoundRect
SetHighColor(0, 0, 0);
FillRoundRect(BRect(10, 10, 110, 110), 5, 5);
gradient.SetStart(BPoint(120, 10));
gradient.SetEnd(BPoint(220, 110));
FillRoundRect(BRect(120, 10, 220, 110), 5, 5, gradient);
// Rect
SetHighColor(0, 0, 0);
FillRect(BRect(10, 120, 110, 220));
gradient.SetStart(BPoint(120, 120));
gradient.SetEnd(BPoint(220, 220));
FillRect(BRect(120, 120, 220, 220), gradient);
// Triangle
SetHighColor(0, 0, 0);
FillTriangle(BPoint(60, 230), BPoint(10, 330), BPoint(110, 330));
gradient.SetStart(BPoint(60, 230));
gradient.SetEnd(BPoint(60, 330));
FillTriangle(BPoint(170, 230), BPoint(120, 330), BPoint(220, 330), gradient);
// Ellipse
SetHighColor(0, 0, 0);
FillEllipse(BPoint(60, 390), 50, 50);
gradient.SetStart(BPoint(60, 340));
gradient.SetEnd(BPoint(60, 440));
FillEllipse(BPoint(170, 390), 50, 50, gradient);
}
void
GradientsView::DrawRadial(BRect update)
{
BGradientRadial gradient;
rgb_color c;
c.red = 255;
c.green = 0;
c.blue = 0;
gradient.AddColor(c, 0);
c.red = 0;
c.green = 255;
c.blue = 0;
gradient.AddColor(c, 127);
c.red = 0;
c.green = 0;
c.blue = 255;
gradient.AddColor(c, 255);
// RoundRect
SetHighColor(0, 0, 0);
FillRoundRect(BRect(10, 10, 110, 110), 5, 5);
gradient.SetCenter(BPoint(170, 60));
FillRoundRect(BRect(120, 10, 220, 110), 5, 5, gradient);
// Rect
SetHighColor(0, 0, 0);
FillRect(BRect(10, 120, 110, 220));
gradient.SetCenter(BPoint(170, 170));
FillRect(BRect(120, 120, 220, 220), gradient);
// Triangle
SetHighColor(0, 0, 0);
FillTriangle(BPoint(60, 230), BPoint(10, 330), BPoint(110, 330));
gradient.SetCenter(BPoint(170, 280));
FillTriangle(BPoint(170, 230), BPoint(120, 330), BPoint(220, 330), gradient);
// Ellipse
SetHighColor(0, 0, 0);
FillEllipse(BPoint(60, 390), 50, 50);
gradient.SetCenter(BPoint(170, 390));
FillEllipse(BPoint(170, 390), 50, 50, gradient);
}
void
GradientsView::DrawRadialFocus(BRect update)
{
BGradientRadialFocus gradient;
rgb_color c;
c.red = 255;
c.green = 0;
c.blue = 0;
gradient.AddColor(c, 0);
c.red = 0;
c.green = 255;
c.blue = 0;
gradient.AddColor(c, 127);
c.red = 0;
c.green = 0;
c.blue = 255;
gradient.AddColor(c, 255);
// RoundRect
SetHighColor(0, 0, 0);
FillRoundRect(BRect(10, 10, 110, 110), 5, 5);
gradient.SetCenter(BPoint(170, 60));
FillRoundRect(BRect(120, 10, 220, 110), 5, 5, gradient);
// Rect
SetHighColor(0, 0, 0);
FillRect(BRect(10, 120, 110, 220));
gradient.SetCenter(BPoint(170, 170));
FillRect(BRect(120, 120, 220, 220), gradient);
// Triangle
SetHighColor(0, 0, 0);
FillTriangle(BPoint(60, 230), BPoint(10, 330), BPoint(110, 330));
gradient.SetCenter(BPoint(170, 280));
FillTriangle(BPoint(170, 230), BPoint(120, 330), BPoint(220, 330), gradient);
// Ellipse
SetHighColor(0, 0, 0);
FillEllipse(BPoint(60, 390), 50, 50);
gradient.SetCenter(BPoint(170, 390));
FillEllipse(BPoint(170, 390), 50, 50, gradient);
}
void
GradientsView::DrawDiamond(BRect update)
{
BGradientDiamond gradient;
rgb_color c;
c.red = 255;
c.green = 0;
c.blue = 0;
gradient.AddColor(c, 0);
c.red = 0;
c.green = 255;
c.blue = 0;
gradient.AddColor(c, 127);
c.red = 0;
c.green = 0;
c.blue = 255;
gradient.AddColor(c, 255);
// RoundRect
SetHighColor(0, 0, 0);
FillRoundRect(BRect(10, 10, 110, 110), 5, 5);
gradient.SetCenter(BPoint(170, 60));
FillRoundRect(BRect(120, 10, 220, 110), 5, 5, gradient);
// Rect
SetHighColor(0, 0, 0);
FillRect(BRect(10, 120, 110, 220));
gradient.SetCenter(BPoint(170, 170));
FillRect(BRect(120, 120, 220, 220), gradient);
// Triangle
SetHighColor(0, 0, 0);
FillTriangle(BPoint(60, 230), BPoint(10, 330), BPoint(110, 330));
gradient.SetCenter(BPoint(170, 280));
FillTriangle(BPoint(170, 230), BPoint(120, 330), BPoint(220, 330), gradient);
// Ellipse
SetHighColor(0, 0, 0);
FillEllipse(BPoint(60, 390), 50, 50);
gradient.SetCenter(BPoint(170, 390));
FillEllipse(BPoint(170, 390), 50, 50, gradient);
}
void
GradientsView::DrawConic(BRect update)
{
BGradientConic gradient;
rgb_color c;
c.red = 255;
c.green = 0;
c.blue = 0;
gradient.AddColor(c, 0);
c.red = 0;
c.green = 255;
c.blue = 0;
gradient.AddColor(c, 127);
c.red = 0;
c.green = 0;
c.blue = 255;
gradient.AddColor(c, 255);
// RoundRect
SetHighColor(0, 0, 0);
FillRoundRect(BRect(10, 10, 110, 110), 5, 5);
gradient.SetCenter(BPoint(170, 60));
FillRoundRect(BRect(120, 10, 220, 110), 5, 5, gradient);
// Rect
SetHighColor(0, 0, 0);
FillRect(BRect(10, 120, 110, 220));
gradient.SetCenter(BPoint(170, 170));
FillRect(BRect(120, 120, 220, 220), gradient);
// Triangle
SetHighColor(0, 0, 0);
FillTriangle(BPoint(60, 230), BPoint(10, 330), BPoint(110, 330));
gradient.SetCenter(BPoint(170, 280));
FillTriangle(BPoint(170, 230), BPoint(120, 330), BPoint(220, 330), gradient);
// Ellipse
SetHighColor(0, 0, 0);
FillEllipse(BPoint(60, 390), 50, 50);
gradient.SetCenter(BPoint(170, 390));
FillEllipse(BPoint(170, 390), 50, 50, gradient);
}
void
GradientsView::SetType(gradient_type type)
{
fType = type;
Invalidate();
}
// #pragma mark -
int
main()
{
GradientsApp app;
app.Run();
return 0;
}
+27
View File
@@ -0,0 +1,27 @@
resource app_signature "application/x-vnd.Haiku-Gradients";
resource app_version {
major = 1,
middle = 0,
minor = 0,
variety = B_APPV_BETA,
internal = 0,
short_info = "Gradients",
long_info = "Gradients ©2008 Haiku, Inc."
};
resource app_flags B_SINGLE_LAUNCH;
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
resource vector_icon {
$"6E636966020200040269FF0000D000FF000200040308FF0000C700FF00FF0000"
$"FF020A0420204020406020600A044020602060604060020A000100000A010101"
$"00"
};
#endif // HAIKU_TARGET_PLATFORM_HAIKU
+7
View File
@@ -0,0 +1,7 @@
SubDir HAIKU_TOP src apps gradients ;
Application Gradients :
Gradients.cpp
: be
: Gradients.rdef
;
+1 -1
View File
@@ -85,7 +85,7 @@ Application Icon-O-Matic :
VectorPath.cpp
# icon/style
Gradient.cpp
GradientTransformable.cpp
Style.cpp
StyleContainer.cpp
+1 -1
View File
@@ -52,7 +52,7 @@
// TODO: just for testing
#include "AffineTransformer.h"
#include "Gradient.h"
#include "GradientTransformable.h"
#include "Icon.h"
#include "MultipleManipulatorState.h"
#include "PathManipulator.h"
@@ -18,7 +18,7 @@
#include "ui_defines.h"
#include "support_ui.h"
#include "Gradient.h"
#include "GradientTransformable.h"
// constructor
GradientControl::GradientControl(BMessage* message, BHandler* target)
+1 -1
View File
@@ -22,7 +22,7 @@
#include "AssignStyleCommand.h"
#include "CurrentColor.h"
#include "CommandStack.h"
#include "Gradient.h"
#include "GradientTransformable.h"
#include "MoveStylesCommand.h"
#include "RemoveStylesCommand.h"
#include "Style.h"
+2 -2
View File
@@ -23,7 +23,7 @@
#include "CommandStack.h"
#include "CurrentColor.h"
#include "Gradient.h"
#include "GradientTransformable.h"
#include "GradientControl.h"
#include "SetColorCommand.h"
#include "SetGradientCommand.h"
@@ -438,7 +438,7 @@ StyleView::_SetStyleType(int32 type)
void
StyleView::_SetGradientType(int32 type)
{
fGradientControl->Gradient()->SetType((gradient_type)type);
fGradientControl->Gradient()->SetType((gradients_type)type);
}
// _AdoptCurrentColor
@@ -19,7 +19,7 @@
#include "AffineTransformer.h"
#include "ContourTransformer.h"
#include "FlatIconFormat.h"
#include "Gradient.h"
#include "GradientTransformable.h"
#include "Icon.h"
#include "LittleEndianBuffer.h"
#include "PathCommandQueue.h"
@@ -31,7 +31,7 @@
#include <agg_bounding_rect.h>
#include "AutoDeleter.h"
#include "Gradient.h"
#include "GradientTransformable.h"
#include "Icon.h"
#include "PathContainer.h"
#include "Shape.h"
@@ -16,7 +16,7 @@
#include "support.h"
#include "Icon.h"
#include "Gradient.h"
#include "GradientTransformable.h"
#include "Shape.h"
#include "StrokeTransformer.h"
#include "Style.h"
@@ -10,7 +10,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "Gradient.h"
#include "GradientTransformable.h"
#include "SVGGradients.h"
@@ -12,7 +12,7 @@
#include <stdio.h>
#include <string.h>
#include "Gradient.h"
#include "GradientTransformable.h"
#include "Shape.h"
#include "Style.h"
#include "VectorPath.h"
@@ -11,7 +11,7 @@
#include <new>
#include <stdio.h>
#include "Gradient.h"
#include "GradientTransformable.h"
#include "Style.h"
using std::nothrow;
@@ -11,7 +11,7 @@
#include <new>
#include <stdio.h>
#include "Gradient.h"
#include "GradientTransformable.h"
#include "Style.h"
using std::nothrow;
@@ -13,7 +13,7 @@
#include <string.h>
#include "CanvasView.h"
#include "Gradient.h"
#include "GradientTransformable.h"
#include "Shape.h"
#include "StateView.h"
#include "TransformObjectsCommand.h"
+97 -2
View File
@@ -19,6 +19,11 @@
#include <ServerProtocol.h>
#include <String.h>
#include <Region.h>
#include <GradientLinear.h>
#include <GradientRadial.h>
#include <GradientRadialFocus.h>
#include <GradientDiamond.h>
#include <GradientConic.h>
#include "link_message.h"
#include "syscalls.h"
@@ -31,6 +36,15 @@
# define STRACE(x) ;
#endif
//#define TRACE_LINK_RECEIVER_GRADIENTS
#ifdef TRACE_LINK_RECEIVER_GRADIENTS
# include <OS.h>
# define GTRACE(x) debug_printf x
#else
# define GTRACE(x) ;
#endif
namespace BPrivate {
LinkReceiver::LinkReceiver(port_id port)
@@ -455,6 +469,87 @@ LinkReceiver::ReadRegion(BRegion* region)
}
status_t
LinkReceiver::ReadGradient(BGradient *gradient)
{
GTRACE(("LinkReceiver::ReadGradient\n"));
gradient_type gradientType;
int32 colorsCount;
Read(&gradientType, sizeof(gradient_type));
Read(&colorsCount, sizeof(int32));
if (colorsCount > 0) {
color_step step;
for (int i = 0; i < colorsCount; i++) {
Read(&step, sizeof(color_step));
gradient->AddColor(step, i);
}
}
switch(gradientType) {
case B_GRADIENT_LINEAR: {
GTRACE(("LinkReceiver::ReadGradient> type == B_GRADIENT_LINEAR\n"));
BGradientLinear* linear = (BGradientLinear*) gradient;
BPoint start;
BPoint end;
Read(&start, sizeof(BPoint));
Read(&end, sizeof(BPoint));
linear->SetStart(start);
linear->SetEnd(end);
break;
}
case B_GRADIENT_RADIAL: {
GTRACE(("LinkReceiver::ReadGradient> type == B_GRADIENT_RADIAL\n"));
BGradientRadial* radial = (BGradientRadial*) gradient;
BPoint center;
float radius;
Read(&center, sizeof(BPoint));
Read(&radius, sizeof(float));
radial->SetCenter(center);
radial->SetRadius(radius);
break;
}
case B_GRADIENT_RADIAL_FOCUS: {
GTRACE(("LinkReceiver::ReadGradient> type == B_GRADIENT_RADIAL_FOCUS\n"));
BGradientRadialFocus* radialFocus =
(BGradientRadialFocus*) gradient;
BPoint center;
BPoint focal;
float radius;
Read(&center, sizeof(BPoint));
Read(&focal, sizeof(BPoint));
Read(&radius, sizeof(float));
radialFocus->SetCenter(center);
radialFocus->SetFocal(focal);
radialFocus->SetRadius(radius);
break;
}
case B_GRADIENT_DIAMOND: {
GTRACE(("LinkReceiver::ReadGradient> type == B_GRADIENT_DIAMOND\n"));
BGradientDiamond* diamond = (BGradientDiamond*) gradient;
BPoint center;
Read(&center, sizeof(BPoint));
diamond->SetCenter(center);
break;
}
case B_GRADIENT_CONIC: {
GTRACE(("LinkReceiver::ReadGradient> type == B_GRADIENT_CONIC\n"));
BGradientConic* conic = (BGradientConic*) gradient;
BPoint center;
float angle;
Read(&center, sizeof(BPoint));
Read(&angle, sizeof(float));
conic->SetCenter(center);
conic->SetAngle(angle);
break;
}
case B_GRADIENT_NONE: {
GTRACE(("LinkReceiver::ReadGradient> type == B_GRADIENT_NONE\n"));
break;
}
}
return B_OK;
}
} // namespace BPrivate
+171
View File
@@ -12,12 +12,26 @@
#include <stdlib.h>
#include <string.h>
#include <new>
#include <Gradient.h>
#include <GradientLinear.h>
#include <GradientRadial.h>
#include <GradientRadialFocus.h>
#include <GradientDiamond.h>
#include <GradientConic.h>
#include <Region.h>
#include <Shape.h>
#include <ServerLink.h>
#include <ServerProtocol.h>
//#define TRACE_SERVER_LINK_GRADIENTS
#ifdef TRACE_SERVER_LINK_GRADIENTS
# include <OS.h>
# define GTRACE(x) debug_printf x
#else
# define GTRACE(x) ;
#endif
namespace BPrivate {
@@ -100,6 +114,163 @@ ServerLink::AttachShape(BShape &shape)
}
status_t
ServerLink::ReadGradient(BGradient *gradient)
{
GTRACE(("ServerLink::ReadGradient\n"));
fReceiver->ReadGradient(gradient);
/* gradient_type gradientType;
int32 colorsCount;
fReceiver->Read(&gradientType, sizeof(gradient_type));
fReceiver->Read(&colorsCount, sizeof(int32));
if (colorsCount > 0) {
color_step step;
for (int i = 0; i < colorsCount; i++) {
fReceiver->Read(&step, sizeof(color_step));
gradient->AddColor(step, i);
}
}
switch(gradientType) {
case B_GRADIENT_LINEAR: {
GTRACE(("ServerLink::ReadGradient> type == B_GRADIENT_LINEAR\n"));
BGradientLinear* linear = (BGradientLinear*) gradient;
BPoint start;
BPoint end;
fReceiver->Read(&start, sizeof(BPoint));
fReceiver->Read(&end, sizeof(BPoint));
linear->SetStart(start);
linear->SetEnd(end);
break;
}
case B_GRADIENT_RADIAL: {
GTRACE(("ServerLink::ReadGradient> type == B_GRADIENT_RADIAL\n"));
BGradientRadial* radial = (BGradientRadial*) gradient;
BPoint center;
float radius;
fReceiver->Read(&center, sizeof(BPoint));
fReceiver->Read(&radius, sizeof(float));
radial->SetCenter(center);
radial->SetRadius(radius);
break;
}
case B_GRADIENT_RADIAL_FOCUS: {
GTRACE(("ServerLink::ReadGradient> type == B_GRADIENT_RADIAL_FOCUS\n"));
BGradientRadialFocus* radialFocus =
(BGradientRadialFocus*) gradient;
BPoint center;
BPoint focal;
float radius;
fReceiver->Read(&center, sizeof(BPoint));
fReceiver->Read(&focal, sizeof(BPoint));
fReceiver->Read(&radius, sizeof(float));
radialFocus->SetCenter(center);
radialFocus->SetFocal(focal);
radialFocus->SetRadius(radius);
break;
}
case B_GRADIENT_DIAMOND: {
GTRACE(("ServerLink::ReadGradient> type == B_GRADIENT_DIAMOND\n"));
BGradientDiamond* diamond = (BGradientDiamond*) gradient;
BPoint center;
fReceiver->Read(&center, sizeof(BPoint));
diamond->SetCenter(center);
break;
}
case B_GRADIENT_CONIC: {
GTRACE(("ServerLink::ReadGradient> type == B_GRADIENT_CONIC\n"));
BGradientConic* conic = (BGradientConic*) gradient;
BPoint center;
float angle;
fReceiver->Read(&center, sizeof(BPoint));
fReceiver->Read(&angle, sizeof(float));
conic->SetCenter(center);
conic->SetAngle(angle);
break;
}
case B_GRADIENT_NONE: {
GTRACE(("ServerLink::ReadGradient> type == B_GRADIENT_NONE\n"));
break;
}
}
*/
return B_OK;
}
status_t
ServerLink::AttachGradient(const BGradient &gradient)
{
GTRACE(("ServerLink::AttachGradient\n"));
gradient_type gradientType = gradient.Type();
int32 colorsCount = gradient.CountColors();
GTRACE(("ServerLink::AttachGradient> colors count == %d\n", (int)colorsCount));
fSender->Attach(&gradientType, sizeof(gradient_type));
fSender->Attach(&colorsCount, sizeof(int32));
if (colorsCount > 0) {
for (int i = 0; i < colorsCount; i++) {
fSender->Attach((color_step*) gradient.ColorAtFast(i),
sizeof(color_step));
}
}
switch(gradientType) {
case B_GRADIENT_LINEAR: {
GTRACE(("ServerLink::AttachGradient> type == B_GRADIENT_LINEAR\n"));
const BGradientLinear* linear = (BGradientLinear*) &gradient;
BPoint start = linear->Start();
BPoint end = linear->End();
fSender->Attach(&start, sizeof(BPoint));
fSender->Attach(&end, sizeof(BPoint));
break;
}
case B_GRADIENT_RADIAL: {
GTRACE(("ServerLink::AttachGradient> type == B_GRADIENT_RADIAL\n"));
const BGradientRadial* radial = (BGradientRadial*) &gradient;
BPoint center = radial->Center();
float radius = radial->Radius();
fSender->Attach(&center, sizeof(BPoint));
fSender->Attach(&radius, sizeof(float));
break;
}
case B_GRADIENT_RADIAL_FOCUS: {
GTRACE(("ServerLink::AttachGradient> type == B_GRADIENT_RADIAL_FOCUS\n"));
const BGradientRadialFocus* radialFocus =
(BGradientRadialFocus*) &gradient;
BPoint center = radialFocus->Center();
BPoint focal = radialFocus->Focal();
float radius = radialFocus->Radius();
fSender->Attach(&center, sizeof(BPoint));
fSender->Attach(&focal, sizeof(BPoint));
fSender->Attach(&radius, sizeof(float));
break;
}
case B_GRADIENT_DIAMOND: {
GTRACE(("ServerLink::AttachGradient> type == B_GRADIENT_DIAMOND\n"));
const BGradientDiamond* diamond = (BGradientDiamond*) &gradient;
BPoint center = diamond->Center();
fSender->Attach(&center, sizeof(BPoint));
break;
}
case B_GRADIENT_CONIC: {
GTRACE(("ServerLink::AttachGradient> type == B_GRADIENT_CONIC\n"));
const BGradientConic* conic = (BGradientConic*) &gradient;
BPoint center = conic->Center();
float angle = conic->Angle();
fSender->Attach(&center, sizeof(BPoint));
fSender->Attach(&angle, sizeof(float));
break;
}
case B_GRADIENT_NONE: {
GTRACE(("ServerLink::AttachGradient> type == B_GRADIENT_NONE\n"));
break;
}
}
return B_OK;
}
status_t
ServerLink::FlushWithReply(int32 &code)
{
+448
View File
@@ -0,0 +1,448 @@
/*
* Copyright 2006-2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Artur Wyszynski <harakash@gmail.com>
*/
#include "Gradient.h"
#include <math.h>
#include <stdio.h>
#include <Message.h>
// constructor
color_step::color_step(const rgb_color c, float o)
{
color.red = c.red;
color.green = c.green;
color.blue = c.blue;
color.alpha = c.alpha;
offset = o;
}
// constructor
color_step::color_step(uint8 r, uint8 g, uint8 b, uint8 a, float o)
{
color.red = r;
color.green = g;
color.blue = b;
color.alpha = a;
offset = o;
}
// constructor
color_step::color_step(const color_step& other)
{
color.red = other.color.red;
color.green = other.color.green;
color.blue = other.color.blue;
color.alpha = other.color.alpha;
offset = other.offset;
}
// constructor
color_step::color_step()
{
color.red = 0;
color.green = 0;
color.blue = 0;
color.alpha = 255;
offset = 0;
}
// operator!=
bool
color_step::operator!=(const color_step& other) const
{
return color.red != other.color.red ||
color.green != other.color.green ||
color.blue != other.color.blue ||
color.alpha != other.color.alpha ||
offset != other.offset;
}
static int
sort_color_steps_by_offset(const void* left, const void* right)
{
const color_step **firstStep((const color_step**) left),
**secondStep((const color_step**) right);
int ret = 0;
if ((*firstStep)->offset > (*secondStep)->offset) {
ret = 1;
} if ((*firstStep)->offset < (*secondStep)->offset) {
ret = -1;
} if ((*firstStep)->offset == (*secondStep)->offset) {
ret = 0;
}
return ret;
}
// #pragma mark -
// constructor
BGradient::BGradient()
: BArchivable(),
fColors(4),
fType(B_GRADIENT_NONE)
{
}
// constructor
BGradient::BGradient(BMessage* archive)
: BArchivable(archive),
fColors(4),
fType(B_GRADIENT_NONE)
{
if (!archive)
return;
// color steps
color_step step;
for (int32 i = 0; archive->FindFloat("offset", i, &step.offset) >= B_OK; i++) {
if (archive->FindInt32("color", i, (int32*)&step.color) >= B_OK)
AddColor(step, i);
else
break;
}
if (archive->FindInt32("type", (int32*)&fType) < B_OK)
fType = B_GRADIENT_LINEAR;
// linear
if (archive->FindFloat("linear_x1", (float*)&fData.linear.x1) < B_OK)
fData.linear.x1 = 0.0f;
if (archive->FindFloat("linear_y1", (float*)&fData.linear.y1) < B_OK)
fData.linear.y1 = 0.0f;
if (archive->FindFloat("linear_x2", (float*)&fData.linear.x2) < B_OK)
fData.linear.x2 = 0.0f;
if (archive->FindFloat("linear_y2", (float*)&fData.linear.y2) < B_OK)
fData.linear.x2 = 0.0f;
// radial
if (archive->FindFloat("radial_cx", (float*)&fData.radial.cx) < B_OK)
fData.radial.cx = 0.0f;
if (archive->FindFloat("radial_cy", (float*)&fData.radial.cy) < B_OK)
fData.radial.cy = 0.0f;
if (archive->FindFloat("radial_radius", (float*)&fData.radial.radius) < B_OK)
fData.radial.radius = 0.0f;
// radial focus
if (archive->FindFloat("radial_f_cx", (float*)&fData.radial_focus.cx) < B_OK)
fData.radial_focus.cx = 0.0f;
if (archive->FindFloat("radial_f_cy", (float*)&fData.radial_focus.cy) < B_OK)
fData.radial_focus.cy = 0.0f;
if (archive->FindFloat("radial_f_fx", (float*)&fData.radial_focus.fx) < B_OK)
fData.radial_focus.fx = 0.0f;
if (archive->FindFloat("radial_f_fy", (float*)&fData.radial_focus.fy) < B_OK)
fData.radial_focus.fy = 0.0f;
if (archive->FindFloat("radial_f_radius", (float*)&fData.radial.radius) < B_OK)
fData.radial.radius = 0.0f;
// diamond
if (archive->FindFloat("diamond_cx", (float*)&fData.diamond.cx) < B_OK)
fData.diamond.cx = 0.0f;
if (archive->FindFloat("diamond_cy", (float*)&fData.diamond.cy) < B_OK)
fData.diamond.cy = 0.0f;
// conic
if (archive->FindFloat("conic_cx", (float*)&fData.conic.cx) < B_OK)
fData.conic.cx = 0.0f;
if (archive->FindFloat("conic_cy", (float*)&fData.conic.cy) < B_OK)
fData.conic.cy = 0.0f;
if (archive->FindFloat("conic_angle", (float*)&fData.conic.angle) < B_OK)
fData.conic.angle = 0.0f;
}
// destructor
BGradient::~BGradient()
{
MakeEmpty();
}
// Archive
status_t
BGradient::Archive(BMessage* into, bool deep) const
{
status_t ret = BArchivable::Archive(into, deep);
// color steps
if (ret >= B_OK) {
for (int32 i = 0; color_step* step = ColorAt(i); i++) {
ret = into->AddInt32("color", (const uint32&)step->color);
if (ret < B_OK)
break;
ret = into->AddFloat("offset", step->offset);
if (ret < B_OK)
break;
}
}
// gradient type
if (ret >= B_OK)
ret = into->AddInt32("type", (int32)fType);
// linear
if (ret >= B_OK)
ret = into->AddFloat("linear_x1", (float)fData.linear.x1);
if (ret >= B_OK)
ret = into->AddFloat("linear_y1", (float)fData.linear.y1);
if (ret >= B_OK)
ret = into->AddFloat("linear_x2", (float)fData.linear.x2);
if (ret >= B_OK)
ret = into->AddFloat("linear_y2", (float)fData.linear.y2);
// radial
if (ret >= B_OK)
ret = into->AddFloat("radial_cx", (float)fData.radial.cx);
if (ret >= B_OK)
ret = into->AddFloat("radial_cy", (float)fData.radial.cy);
if (ret >= B_OK)
ret = into->AddFloat("radial_radius", (float)fData.radial.radius);
// radial focus
if (ret >= B_OK)
ret = into->AddFloat("radial_f_cx", (float)fData.radial_focus.cx);
if (ret >= B_OK)
ret = into->AddFloat("radial_f_cy", (float)fData.radial_focus.cy);
if (ret >= B_OK)
ret = into->AddFloat("radial_f_fx", (float)fData.radial_focus.fx);
if (ret >= B_OK)
ret = into->AddFloat("radial_f_fy", (float)fData.radial_focus.fy);
if (ret >= B_OK)
ret = into->AddFloat("radial_radius", (float)fData.radial.radius);
// diamond
if (ret >= B_OK)
ret = into->AddFloat("diamond_cx", (float)fData.diamond.cx);
if (ret >= B_OK)
ret = into->AddFloat("diamond_cy", (float)fData.diamond.cy);
// conic
if (ret >= B_OK)
ret = into->AddFloat("conic_cx", (float)fData.conic.cx);
if (ret >= B_OK)
ret = into->AddFloat("conic_cy", (float)fData.conic.cy);
if (ret >= B_OK)
ret = into->AddFloat("conic_angle", (float)fData.conic.angle);
// finish off
if (ret >= B_OK)
ret = into->AddString("class", "BGradient");
return ret;
}
// operator=
BGradient&
BGradient::operator=(const BGradient& other)
{
SetColors(other);
fType = other.fType;
return *this;
}
// operator==
bool
BGradient::operator==(const BGradient& other) const
{
return ((other.Type() == Type()) && ColorStepsAreEqual(other));
}
// operator!=
bool
BGradient::operator!=(const BGradient& other) const
{
return !(*this == other);
}
// ColorStepsAreEqual
bool
BGradient::ColorStepsAreEqual(const BGradient& other) const
{
int32 count = CountColors();
if (count == other.CountColors() &&
fType == other.fType) {
bool equal = true;
for (int32 i = 0; i < count; i++) {
color_step* ourStep = ColorAtFast(i);
color_step* otherStep = other.ColorAtFast(i);
if (*ourStep != *otherStep) {
equal = false;
break;
}
}
return equal;
}
return false;
}
// SetColors
void
BGradient::SetColors(const BGradient& other)
{
MakeEmpty();
for (int32 i = 0; color_step* step = other.ColorAt(i); i++)
AddColor(*step, i);
}
// AddColor
int32
BGradient::AddColor(const rgb_color& color, float offset)
{
// find the correct index (sorted by offset)
color_step* step = new color_step(color, offset);
int32 index = 0;
int32 count = CountColors();
for (; index < count; index++) {
color_step* s = ColorAtFast(index);
if (s->offset > step->offset)
break;
}
if (!fColors.AddItem((void*)step, index)) {
delete step;
return -1;
}
return index;
}
// AddColor
bool
BGradient::AddColor(const color_step& color, int32 index)
{
color_step* step = new color_step(color);
if (!fColors.AddItem((void*)step, index)) {
delete step;
return false;
}
return true;
}
// RemoveColor
bool
BGradient::RemoveColor(int32 index)
{
color_step* step = (color_step*)fColors.RemoveItem(index);
if (!step) {
return false;
}
delete step;
return true;
}
// SetColor
bool
BGradient::SetColor(int32 index, const color_step& color)
{
if (color_step* step = ColorAt(index)) {
if (*step != color) {
step->color = color.color;
step->offset = color.offset;
return true;
}
}
return false;
}
// SetColor
bool
BGradient::SetColor(int32 index, const rgb_color& color)
{
if (color_step* step = ColorAt(index)) {
if ((uint32&)step->color != (uint32&)color) {
step->color = color;
return true;
}
}
return false;
}
// SetOffset
bool
BGradient::SetOffset(int32 index, float offset)
{
color_step* step = ColorAt(index);
if (step && step->offset != offset) {
step->offset = offset;
return true;
}
return false;
}
// CountColors
int32
BGradient::CountColors() const
{
return fColors.CountItems();
}
// ColorAt
color_step*
BGradient::ColorAt(int32 index) const
{
return (color_step*)fColors.ItemAt(index);
}
// ColorAtFast
color_step*
BGradient::ColorAtFast(int32 index) const
{
return (color_step*)fColors.ItemAtFast(index);
}
// Colors
color_step*
BGradient::Colors() const
{
if (CountColors() > 0) {
return (color_step*) fColors.Items();
}
return NULL;
}
// SortColorStepsByOffset
void
BGradient::SortColorStepsByOffset()
{
fColors.SortItems(sort_color_steps_by_offset);
}
// MakeEmpty
void
BGradient::MakeEmpty()
{
int32 count = CountColors();
for (int32 i = 0; i < count; i++)
delete ColorAtFast(i);
fColors.MakeEmpty();
}
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright 2006-2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Artur Wyszynski <harakash@gmail.com>
*/
#include <Point.h>
#include <Gradient.h>
#include <GradientConic.h>
// constructor
BGradientConic::BGradientConic()
{
fData.conic.cx = 0.0f;
fData.conic.cy = 0.0f;
fData.conic.angle = 0.0f;
fType = B_GRADIENT_CONIC;
}
// constructor
BGradientConic::BGradientConic(const BPoint& center, float angle)
{
fData.conic.cx = center.x;
fData.conic.cy = center.y;
fData.conic.angle = angle;
fType = B_GRADIENT_CONIC;
}
// constructor
BGradientConic::BGradientConic(float cx, float cy, float angle)
{
fData.conic.cx = cx;
fData.conic.cy = cy;
fData.conic.angle = angle;
fType = B_GRADIENT_CONIC;
}
// Center
BPoint
BGradientConic::Center() const
{
return BPoint(fData.conic.cx, fData.conic.cy);
}
// SetCenter
void
BGradientConic::SetCenter(const BPoint& center)
{
fData.conic.cx = center.x;
fData.conic.cy = center.y;
}
// SetCenter
void
BGradientConic::SetCenter(float cx, float cy)
{
fData.conic.cx = cx;
fData.conic.cy = cy;
}
// Angle
float
BGradientConic::Angle() const
{
return fData.conic.angle;
}
// SetAngle
void
BGradientConic::SetAngle(float angle)
{
fData.conic.angle = angle;
}
+64
View File
@@ -0,0 +1,64 @@
/*
* Copyright 2006-2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Artur Wyszynski <harakash@gmail.com>
*/
#include <Point.h>
#include <Gradient.h>
#include <GradientDiamond.h>
// constructor
BGradientDiamond::BGradientDiamond()
{
fData.diamond.cx = 0.0f;
fData.diamond.cy = 0.0f;
fType = B_GRADIENT_DIAMOND;
}
// constructor
BGradientDiamond::BGradientDiamond(const BPoint& center)
{
fData.diamond.cx = center.x;
fData.diamond.cy = center.y;
fType = B_GRADIENT_DIAMOND;
}
// constructor
BGradientDiamond::BGradientDiamond(float cx, float cy)
{
fData.diamond.cx = cx;
fData.diamond.cy = cy;
fType = B_GRADIENT_DIAMOND;
}
// Center
BPoint
BGradientDiamond::Center() const
{
return BPoint(fData.diamond.cx, fData.diamond.cy);
}
// SetCenter
void
BGradientDiamond::SetCenter(const BPoint& center)
{
fData.diamond.cx = center.x;
fData.diamond.cy = center.y;
}
// SetCenter
void
BGradientDiamond::SetCenter(float cx, float cy)
{
fData.diamond.cx = cx;
fData.diamond.cy = cy;
}
+96
View File
@@ -0,0 +1,96 @@
/*
* Copyright 2006-2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Artur Wyszynski <harakash@gmail.com>
*/
#include <Point.h>
#include <Gradient.h>
#include <GradientLinear.h>
// constructor
BGradientLinear::BGradientLinear()
{
fData.linear.x1 = 0.0f;
fData.linear.y1 = 0.0f;
fData.linear.x2 = 0.0f;
fData.linear.y2 = 0.0f;
fType = B_GRADIENT_LINEAR;
}
// constructor
BGradientLinear::BGradientLinear(const BPoint& start, const BPoint& end)
{
fData.linear.x1 = start.x;
fData.linear.y1 = start.y;
fData.linear.x2 = end.x;
fData.linear.y2 = end.y;
fType = B_GRADIENT_LINEAR;
}
// constructor
BGradientLinear::BGradientLinear(float x1, float y1, float x2, float y2)
{
fData.linear.x1 = x1;
fData.linear.y1 = y1;
fData.linear.x2 = x2;
fData.linear.y2 = y2;
fType = B_GRADIENT_LINEAR;
}
// Start
BPoint
BGradientLinear::Start() const
{
return BPoint(fData.linear.x1, fData.linear.y1);
}
// SetStart
void
BGradientLinear::SetStart(const BPoint& start)
{
fData.linear.x1 = start.x;
fData.linear.y1 = start.y;
}
// SetStart
void
BGradientLinear::SetStart(float x, float y)
{
fData.linear.x1 = x;
fData.linear.y1 = y;
}
// End
BPoint
BGradientLinear::End() const
{
return BPoint(fData.linear.x2, fData.linear.y2);
}
// SetEnd
void
BGradientLinear::SetEnd(const BPoint& end)
{
fData.linear.x2 = end.x;
fData.linear.y2 = end.y;
}
// SetEnd
void
BGradientLinear::SetEnd(float x, float y)
{
fData.linear.x2 = x;
fData.linear.y2 = y;
}
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright 2006-2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Artur Wyszynski <harakash@gmail.com>
*/
#include <Point.h>
#include <Gradient.h>
#include <GradientRadial.h>
// constructor
BGradientRadial::BGradientRadial()
{
fData.radial.cx = 0.0f;
fData.radial.cy = 0.0f;
fData.radial.radius = 0.0f;
fType = B_GRADIENT_RADIAL;
}
// constructor
BGradientRadial::BGradientRadial(const BPoint& center, float radius)
{
fData.radial.cx = center.x;
fData.radial.cy = center.y;
fData.radial.radius = radius;
fType = B_GRADIENT_RADIAL;
}
// constructor
BGradientRadial::BGradientRadial(float cx, float cy, float radius)
{
fData.radial.cx = cx;
fData.radial.cy = cy;
fData.radial.radius = radius;
fType = B_GRADIENT_RADIAL;
}
// Center
BPoint
BGradientRadial::Center() const
{
return BPoint(fData.radial.cx, fData.radial.cy);
}
// SetCenter
void
BGradientRadial::SetCenter(const BPoint& center)
{
fData.radial.cx = center.x;
fData.radial.cy = center.y;
}
// SetCenter
void
BGradientRadial::SetCenter(float cx, float cy)
{
fData.radial.cx = cx;
fData.radial.cy = cy;
}
// Radius
float
BGradientRadial::Radius() const
{
return fData.radial.radius;
}
// SetRadius
void
BGradientRadial::SetRadius(float radius)
{
fData.radial.radius = radius;
}
+117
View File
@@ -0,0 +1,117 @@
/*
* Copyright 2006-2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Artur Wyszynski <harakash@gmail.com>
*/
#include <Point.h>
#include <Gradient.h>
#include <GradientRadialFocus.h>
// constructor
BGradientRadialFocus::BGradientRadialFocus()
{
fData.radial_focus.cx = 0.0f;
fData.radial_focus.cy = 0.0f;
fData.radial_focus.fx = 0.0f;
fData.radial_focus.fy = 0.0f;
fData.radial_focus.radius = 0.0f;
fType = B_GRADIENT_RADIAL_FOCUS;
}
// constructor
BGradientRadialFocus::BGradientRadialFocus(const BPoint& center, float radius,
const BPoint& focal)
{
fData.radial_focus.cx = center.x;
fData.radial_focus.cy = center.y;
fData.radial_focus.fx = focal.x;
fData.radial_focus.fy = focal.y;
fData.radial_focus.radius = radius;
fType = B_GRADIENT_RADIAL_FOCUS;
}
// constructor
BGradientRadialFocus::BGradientRadialFocus(float cx, float cy, float radius,
float fx, float fy)
{
fData.radial_focus.cx = cx;
fData.radial_focus.cy = cy;
fData.radial_focus.fx = fx;
fData.radial_focus.fy = fy;
fData.radial_focus.radius = radius;
fType = B_GRADIENT_RADIAL_FOCUS;
}
// Center
BPoint
BGradientRadialFocus::Center() const
{
return BPoint(fData.radial_focus.cx, fData.radial_focus.cy);
}
// SetCenter
void
BGradientRadialFocus::SetCenter(const BPoint& center)
{
fData.radial_focus.cx = center.x;
fData.radial_focus.cy = center.y;
}
// SetCenter
void
BGradientRadialFocus::SetCenter(float cx, float cy)
{
fData.radial_focus.cx = cx;
fData.radial_focus.cy = cy;
}
// Focal
BPoint
BGradientRadialFocus::Focal() const
{
return BPoint(fData.radial_focus.fx, fData.radial_focus.fy);
}
// SetFocal
void
BGradientRadialFocus::SetFocal(const BPoint& focal)
{
fData.radial_focus.fx = focal.x;
fData.radial_focus.fy = focal.y;
}
// SetFocal
void
BGradientRadialFocus::SetFocal(float fx, float fy)
{
fData.radial_focus.fx = fx;
fData.radial_focus.fy = fy;
}
// Radius
float
BGradientRadialFocus::Radius() const
{
return fData.radial_focus.radius;
}
// SetRadius
void
BGradientRadialFocus::SetRadius(float radius)
{
fData.radial_focus.radius = radius;
}
+6
View File
@@ -57,6 +57,12 @@ MergeObject <libbe>interface_kit.o :
Deskbar.cpp
Dragger.cpp
Font.cpp
Gradient.cpp
GradientLinear.cpp
GradientRadial.cpp
GradientRadialFocus.cpp
GradientDiamond.cpp
GradientConic.cpp
GraphicsDefs.cpp
GridLayout.cpp
GridLayoutBuilder.cpp
+278 -2
View File
@@ -44,6 +44,12 @@
#include <View.h>
#include <Window.h>
#include <GradientLinear.h>
#include <GradientRadial.h>
#include <GradientRadialFocus.h>
#include <GradientDiamond.h>
#include <GradientConic.h>
#include <math.h>
#include <new>
#include <stdio.h>
@@ -2573,6 +2579,15 @@ BView::FillEllipse(BPoint center, float xRadius, float yRadius,
}
void
BView::FillEllipse(BPoint center, float xRadius, float yRadius,
const BGradient& gradient)
{
FillEllipse(BRect(center.x - xRadius, center.y - yRadius,
center.x + xRadius, center.y + yRadius), gradient);
}
void
BView::FillEllipse(BRect rect, ::pattern pattern)
{
@@ -2589,6 +2604,23 @@ BView::FillEllipse(BRect rect, ::pattern pattern)
}
void
BView::FillEllipse(BRect rect, const BGradient& gradient)
{
if (fOwner == NULL)
return;
_CheckLockAndSwitchCurrent();
fOwner->fLink->StartMessage(AS_FILL_ELLIPSE_GRADIENT);
fOwner->fLink->Attach<BRect>(rect);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
}
void
BView::StrokeArc(BPoint center, float xRadius, float yRadius, float startAngle,
float arcAngle, ::pattern pattern)
@@ -2626,6 +2658,15 @@ BView::FillArc(BPoint center,float xRadius, float yRadius, float startAngle,
}
void
BView::FillArc(BPoint center,float xRadius, float yRadius, float startAngle,
float arcAngle, const BGradient& gradient)
{
FillArc(BRect(center.x - xRadius, center.y - yRadius, center.x + xRadius,
center.y + yRadius), startAngle, arcAngle, gradient);
}
void
BView::FillArc(BRect rect, float startAngle, float arcAngle,
::pattern pattern)
@@ -2645,6 +2686,26 @@ BView::FillArc(BRect rect, float startAngle, float arcAngle,
}
void
BView::FillArc(BRect rect, float startAngle, float arcAngle,
const BGradient& gradient)
{
if (fOwner == NULL)
return;
_CheckLockAndSwitchCurrent();
fOwner->fLink->StartMessage(AS_FILL_ARC_GRADIENT);
fOwner->fLink->Attach<BRect>(rect);
fOwner->fLink->Attach<float>(startAngle);
fOwner->fLink->Attach<float>(arcAngle);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
}
void
BView::StrokeBezier(BPoint *controlPoints, ::pattern pattern)
{
@@ -2683,6 +2744,26 @@ BView::FillBezier(BPoint *controlPoints, ::pattern pattern)
}
void
BView::FillBezier(BPoint *controlPoints, const BGradient& gradient)
{
if (fOwner == NULL)
return;
_CheckLockAndSwitchCurrent();
fOwner->fLink->StartMessage(AS_FILL_BEZIER_GRADIENT);
fOwner->fLink->Attach<BPoint>(controlPoints[0]);
fOwner->fLink->Attach<BPoint>(controlPoints[1]);
fOwner->fLink->Attach<BPoint>(controlPoints[2]);
fOwner->fLink->Attach<BPoint>(controlPoints[3]);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
}
void
BView::StrokePolygon(const BPolygon *polygon, bool closed, ::pattern pattern)
{
@@ -2761,6 +2842,33 @@ BView::FillPolygon(const BPolygon *polygon, ::pattern pattern)
}
void
BView::FillPolygon(const BPolygon *polygon, const BGradient& gradient)
{
if (polygon == NULL
|| polygon->fCount <= 2
|| fOwner == NULL)
return;
_CheckLockAndSwitchCurrent();
if (fOwner->fLink->StartMessage(AS_FILL_POLYGON_GRADIENT,
polygon->fCount * sizeof(BPoint)
+ sizeof(BRect) + sizeof(int32)) == B_OK) {
fOwner->fLink->Attach<BRect>(polygon->Frame());
fOwner->fLink->Attach<int32>(polygon->fCount);
fOwner->fLink->Attach(polygon->fPoints,
polygon->fCount * sizeof(BPoint));
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
} else {
fprintf(stderr, "ERROR: Can't send polygon to app_server!\n");
}
}
void
BView::FillPolygon(const BPoint *ptArray, int32 numPts, ::pattern pattern)
{
@@ -2772,6 +2880,18 @@ BView::FillPolygon(const BPoint *ptArray, int32 numPts, ::pattern pattern)
}
void
BView::FillPolygon(const BPoint *ptArray, int32 numPts,
const BGradient& gradient)
{
if (!ptArray)
return;
BPolygon polygon(ptArray, numPts);
FillPolygon(&polygon, gradient);
}
void
BView::FillPolygon(const BPoint *ptArray, int32 numPts, BRect bounds,
pattern p)
@@ -2786,6 +2906,20 @@ BView::FillPolygon(const BPoint *ptArray, int32 numPts, BRect bounds,
}
void
BView::FillPolygon(const BPoint *ptArray, int32 numPts, BRect bounds,
const BGradient& gradient)
{
if (!ptArray)
return;
BPolygon polygon(ptArray, numPts);
polygon.MapTo(polygon.Frame(), bounds);
FillPolygon(&polygon, gradient);
}
void
BView::StrokeRect(BRect rect, ::pattern pattern)
{
@@ -2823,6 +2957,28 @@ BView::FillRect(BRect rect, ::pattern pattern)
}
void
BView::FillRect(BRect rect, const BGradient& gradient)
{
if (fOwner == NULL)
return;
// NOTE: ensuring compatibility with R5,
// invalid rects are not filled, they are stroked though!
if (!rect.IsValid())
return;
_CheckLockAndSwitchCurrent();
fOwner->fLink->StartMessage(AS_FILL_RECT_GRADIENT);
fOwner->fLink->Attach<BRect>(rect);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
}
void
BView::StrokeRoundRect(BRect rect, float xRadius, float yRadius,
::pattern pattern)
@@ -2862,6 +3018,26 @@ BView::FillRoundRect(BRect rect, float xRadius, float yRadius,
}
void
BView::FillRoundRect(BRect rect, float xRadius, float yRadius,
const BGradient& gradient)
{
if (fOwner == NULL)
return;
_CheckLockAndSwitchCurrent();
fOwner->fLink->StartMessage(AS_FILL_ROUNDRECT_GRADIENT);
fOwner->fLink->Attach<BRect>(rect);
fOwner->fLink->Attach<float>(xRadius);
fOwner->fLink->Attach<float>(yRadius);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
}
void
BView::FillRegion(BRegion *region, ::pattern pattern)
{
@@ -2879,6 +3055,23 @@ BView::FillRegion(BRegion *region, ::pattern pattern)
}
void
BView::FillRegion(BRegion *region, const BGradient& gradient)
{
if (region == NULL || fOwner == NULL)
return;
_CheckLockAndSwitchCurrent();
fOwner->fLink->StartMessage(AS_FILL_REGION_GRADIENT);
fOwner->fLink->AttachRegion(*region);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
}
void
BView::StrokeTriangle(BPoint pt1, BPoint pt2, BPoint pt3, BRect bounds,
::pattern pattern)
@@ -2978,6 +3171,46 @@ BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3, pattern p)
}
void
BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
const BGradient& gradient)
{
if (fOwner) {
// we construct the smallest rectangle that contains the 3 points
// for the 1st point
BRect bounds(pt1, pt1);
// for the 2nd point
if (pt2.x < bounds.left)
bounds.left = pt2.x;
if (pt2.y < bounds.top)
bounds.top = pt2.y;
if (pt2.x > bounds.right)
bounds.right = pt2.x;
if (pt2.y > bounds.bottom)
bounds.bottom = pt2.y;
// for the 3rd point
if (pt3.x < bounds.left)
bounds.left = pt3.x;
if (pt3.y < bounds.top)
bounds.top = pt3.y;
if (pt3.x > bounds.right)
bounds.right = pt3.x;
if (pt3.y > bounds.bottom)
bounds.bottom = pt3.y;
FillTriangle(pt1, pt2, pt3, bounds, gradient);
}
}
void
BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
BRect bounds, ::pattern pattern)
@@ -2998,6 +3231,26 @@ BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
}
void
BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
BRect bounds, const BGradient& gradient)
{
if (fOwner == NULL)
return;
_CheckLockAndSwitchCurrent();
fOwner->fLink->StartMessage(AS_FILL_TRIANGLE_GRADIENT);
fOwner->fLink->Attach<BPoint>(pt1);
fOwner->fLink->Attach<BPoint>(pt2);
fOwner->fLink->Attach<BPoint>(pt3);
fOwner->fLink->Attach<BRect>(bounds);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
}
void
BView::StrokeLine(BPoint toPt, pattern p)
{
@@ -3073,6 +3326,31 @@ BView::FillShape(BShape *shape, ::pattern pattern)
}
void
BView::FillShape(BShape *shape, const BGradient& gradient)
{
if (shape == NULL || fOwner == NULL)
return;
shape_data *sd = (shape_data *)(shape->fPrivateData);
if (sd->opCount == 0 || sd->ptCount == 0)
return;
_CheckLockAndSwitchCurrent();
fOwner->fLink->StartMessage(AS_FILL_SHAPE_GRADIENT);
fOwner->fLink->Attach<BRect>(shape->Bounds());
fOwner->fLink->Attach<int32>(sd->opCount);
fOwner->fLink->Attach<int32>(sd->ptCount);
fOwner->fLink->Attach(sd->opList, sd->opCount * sizeof(int32));
fOwner->fLink->Attach(sd->ptList, sd->ptCount * sizeof(BPoint));
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
}
void
BView::BeginLineArray(int32 count)
{
@@ -5170,5 +5448,3 @@ BView::_PrintTree()
}
}
}
+1 -1
View File
@@ -17,7 +17,7 @@
#include <agg_span_gradient.h>
#include <agg_span_interpolator_linear.h>
#include "Gradient.h"
#include "GradientTransformable.h"
#include "Icon.h"
#include "Shape.h"
#include "ShapeContainer.h"
+1 -1
View File
@@ -36,7 +36,7 @@ StaticLibrary libicon.a :
VectorPath.cpp
# style
Gradient.cpp
GradientTransformable.cpp
Style.cpp
StyleContainer.cpp
+2 -2
View File
@@ -19,7 +19,7 @@
#include "AutoDeleter.h"
#include "ContourTransformer.h"
#include "FlatIconFormat.h"
#include "Gradient.h"
#include "GradientTransformable.h"
#include "Icon.h"
#include "LittleEndianBuffer.h"
#include "PathCommandQueue.h"
@@ -221,7 +221,7 @@ _ReadGradientStyle(LittleEndianBuffer& buffer)
Gradient gradient(true);
// empty gradient
gradient.SetType((gradient_type)gradientType);
gradient.SetType((gradients_type)gradientType);
// TODO: support more stuff with flags
// ("inherits transformation" and so on)
if (gradientFlags & GRADIENT_FLAG_TRANSFORM) {
@@ -6,7 +6,7 @@
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "Gradient.h"
#include "GradientTransformable.h"
#include <math.h>
#include <stdio.h>
@@ -17,59 +17,6 @@
# include "support.h"
#endif
// constructor
color_step::color_step(const rgb_color c, float o)
{
color.red = c.red;
color.green = c.green;
color.blue = c.blue;
color.alpha = c.alpha;
offset = o;
}
// constructor
color_step::color_step(uint8 r, uint8 g, uint8 b, uint8 a, float o)
{
color.red = r;
color.green = g;
color.blue = b;
color.alpha = a;
offset = o;
}
// constructor
color_step::color_step(const color_step& other)
{
color.red = other.color.red;
color.green = other.color.green;
color.blue = other.color.blue;
color.alpha = other.color.alpha;
offset = other.offset;
}
// constructor
color_step::color_step()
{
color.red = 0;
color.green = 0;
color.blue = 0;
color.alpha = 255;
offset = 0;
}
// operator!=
bool
color_step::operator!=(const color_step& other) const
{
return color.red != other.color.red ||
color.green != other.color.green ||
color.blue != other.color.blue ||
color.alpha != other.color.alpha ||
offset != other.offset;
}
// #pragma mark -
// constructor
Gradient::Gradient(bool empty)
#ifdef ICON_O_MATIC
@@ -398,7 +345,7 @@ Gradient::ColorAtFast(int32 index) const
// SetType
void
Gradient::SetType(gradient_type type)
Gradient::SetType(gradients_type type)
{
if (fType != type) {
fType = type;
@@ -575,7 +522,7 @@ Gradient::FitToBounds(const BRect& bounds)
// string_for_type
static const char*
string_for_type(gradient_type type)
string_for_type(gradients_type type)
{
switch (type) {
case GRADIENT_LINEAR:
@@ -5,8 +5,8 @@
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef GRADIENT_H
#define GRADIENT_H
#ifndef GRADIENT_TRANSFORMABLE_H
#define GRADIENT_TRANSFORMABLE_H
#ifdef ICON_O_MATIC
@@ -18,39 +18,27 @@
#include "Transformable.h"
#include <GraphicsDefs.h>
#include <Gradient.h>
#include <List.h>
class BMessage;
namespace BPrivate {
namespace Icon {
enum gradient_type {
enum gradients_type {
GRADIENT_LINEAR = 0,
GRADIENT_CIRCULAR,
GRADIENT_DIAMOND,
GRADIENT_CONIC,
GRADIENT_XY,
GRADIENT_SQRT_XY,
GRADIENT_SQRT_XY
};
enum interpolation_type {
INTERPOLATION_LINEAR = 0,
INTERPOLATION_SMOOTH,
INTERPOLATION_SMOOTH
};
struct color_step {
color_step(const rgb_color c, float o);
color_step(uint8 r, uint8 g, uint8 b, uint8 a, float o);
color_step(const color_step& other);
color_step();
bool operator!=(const color_step& other) const;
rgb_color color;
float offset;
};
namespace BPrivate {
namespace Icon {
#ifdef ICON_O_MATIC
class Gradient : public BArchivable,
@@ -97,8 +85,8 @@ class Gradient : public Transformable {
color_step* ColorAt(int32 index) const;
color_step* ColorAtFast(int32 index) const;
void SetType(gradient_type type);
gradient_type Type() const
void SetType(gradients_type type);
gradients_type Type() const
{ return fType; }
void SetInterpolation(interpolation_type type);
@@ -122,7 +110,7 @@ class Gradient : public Transformable {
void _MakeEmpty();
BList fColors;
gradient_type fType;
gradients_type fType;
interpolation_type fInterpolation;
bool fInheritTransformation;
};
@@ -130,4 +118,4 @@ class Gradient : public Transformable {
} // namespace Icon
} // namespace BPrivate
#endif // GRADIENT_H
#endif // GRADIENT_TRANSFORMABLE_H
+1 -1
View File
@@ -18,7 +18,7 @@
# define kWhite (rgb_color){ 255, 255, 255, 255 }
#endif // ICON_O_MATIC
#include "Gradient.h"
#include "GradientTransformable.h"
using std::nothrow;
+8 -8
View File
@@ -976,7 +976,7 @@ Desktop::_SetWorkspace(int32 index)
// is up-to-date
if (window->Frame().LeftTop() != position) {
BPoint offset = position - window->Frame().LeftTop();
window->MoveBy(offset.x, offset.y);
window->MoveBy((int32)offset.x, (int32)offset.y);
}
continue;
}
@@ -1822,7 +1822,7 @@ Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace)
window->Anchor(workspace).position += BPoint(x, y);
_WindowChanged(window);
} else
window->MoveBy(x, y);
window->MoveBy((int32)x, (int32)y);
UnlockAllWindows();
return;
@@ -1834,7 +1834,7 @@ Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace)
// no more drawing for DirectWindows
window->ServerWindow()->HandleDirectConnection(B_DIRECT_STOP);
window->MoveBy(x, y);
window->MoveBy((int32)x, (int32)y);
BRegion background;
_RebuildClippingForAllWindows(background);
@@ -1842,7 +1842,7 @@ Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace)
// construct the region that is possible to be blitted
// to move the contents of the window
BRegion copyRegion(window->VisibleRegion());
copyRegion.OffsetBy(-x, -y);
copyRegion.OffsetBy((int32)-x, (int32)-y);
copyRegion.IntersectWith(&newDirtyRegion);
// newDirtyRegion == the windows old visible region
@@ -1850,7 +1850,7 @@ Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace)
// moved into the dirty region (for now)
newDirtyRegion.Include(&window->VisibleRegion());
GetDrawingEngine()->CopyRegion(&copyRegion, x, y);
GetDrawingEngine()->CopyRegion(&copyRegion, (int32)x, (int32)y);
// allow DirectWindows to draw again after the visual
// content is at the new location
@@ -1858,7 +1858,7 @@ Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace)
// in the dirty region, exclude the parts that we
// could move by blitting
copyRegion.OffsetBy(x, y);
copyRegion.OffsetBy((int32)x, (int32)y);
newDirtyRegion.Exclude(&copyRegion);
MarkDirty(newDirtyRegion);
@@ -1876,7 +1876,7 @@ Desktop::ResizeWindowBy(Window* window, float x, float y)
return;
if (!window->IsVisible()) {
window->ResizeBy(x, y, NULL);
window->ResizeBy((int32)x, (int32)y, NULL);
UnlockAllWindows();
return;
}
@@ -1888,7 +1888,7 @@ Desktop::ResizeWindowBy(Window* window, float x, float y)
// it is shrunk in "previouslyOccupiedRegion"
BRegion previouslyOccupiedRegion(window->VisibleRegion());
window->ResizeBy(x, y, &newDirtyRegion);
window->ResizeBy((int32)x, (int32)y, &newDirtyRegion);
BRegion background;
_RebuildClippingForAllWindows(background);
@@ -202,14 +202,23 @@ string_for_message_code(uint32 code, BString& string)
case AS_STROKE_TRIANGLE: string = "AS_STROKE_TRIANGLE"; break;
case AS_FILL_ARC: string = "AS_FILL_ARC"; break;
case AS_FILL_ARC_GRADIENT: string = "AS_FILL_ARC_GRADIENT"; break;
case AS_FILL_BEZIER: string = "AS_FILL_BEZIER"; break;
case AS_FILL_BEZIER_GRADIENT: string = "AS_FILL_BEZIER_GRADIENT"; break;
case AS_FILL_ELLIPSE: string = "AS_FILL_ELLIPSE"; break;
case AS_FILL_ELLIPSE_GRADIENT: string = "AS_FILL_ELLIPSE_GRADIENT"; break;
case AS_FILL_POLYGON: string = "AS_FILL_POLYGON"; break;
case AS_FILL_POLYGON_GRADIENT: string = "AS_FILL_POLYGON_GRADIENT"; break;
case AS_FILL_RECT: string = "AS_FILL_RECT"; break;
case AS_FILL_RECT_GRADIENT: string = "AS_FILL_RECT_GRADIENT"; break;
case AS_FILL_REGION: string = "AS_FILL_REGION"; break;
case AS_FILL_REGION_GRADIENT: string = "AS_FILL_REGION_GRADIENT"; break;
case AS_FILL_ROUNDRECT: string = "AS_FILL_ROUNDRECT"; break;
case AS_FILL_ROUNDRECT_GRADIENT: string = "AS_FILL_ROUNDRECT_GRADIENT"; break;
case AS_FILL_SHAPE: string = "AS_FILL_SHAPE"; break;
case AS_FILL_SHAPE_GRADIENT: string = "AS_FILL_SHAPE_GRADIENT"; break;
case AS_FILL_TRIANGLE: string = "AS_FILL_TRIANGLE"; break;
case AS_FILL_TRIANGLE_GRADIENT: string = "AS_FILL_TRIANGLE_GRADIENT"; break;
case AS_DRAW_STRING: string = "AS_DRAW_STRING"; break;
case AS_DRAW_STRING_WITH_DELTA: string = "AS_DRAW_STRING_WITH_DELTA"; break;
+241
View File
@@ -51,6 +51,11 @@
#include <DirectWindow.h>
#include <TokenSpace.h>
#include <View.h>
#include <GradientLinear.h>
#include <GradientRadial.h>
#include <GradientRadialFocus.h>
#include <GradientDiamond.h>
#include <GradientConic.h>
#include <new>
@@ -58,6 +63,7 @@ using std::nothrow;
//#define TRACE_SERVER_WINDOW
//#define TRACE_SERVER_WINDOW_MESSAGES
//#define TRACE_SERVER_GRADIENTS
//#define PROFILE_MESSAGE_LOOP
@@ -75,6 +81,13 @@ using std::nothrow;
# define DTRACE(x) ;
#endif
#ifdef TRACE_SERVER_GRADIENTS
# include <OS.h>
# define GTRACE(x) debug_printf x
#else
# define GTRACE(x) ;
#endif
#ifdef PROFILE_MESSAGE_LOOP
struct profile { int32 code; int32 count; bigtime_t time; };
static profile sMessageProfile[AS_LAST_CODE];
@@ -2120,6 +2133,23 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
drawingEngine->FillRect(rect);
break;
}
case AS_FILL_RECT_GRADIENT:
{
GTRACE(("ServerWindow %s: Message AS_FILL_RECT_GRADIENT\n", Title()));
BRect rect;
link.Read<BRect>(&rect);
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillRectGradient(rect, *gradient);
}
break;
}
case AS_VIEW_DRAW_BITMAP:
{
DTRACE(("ServerWindow %s: Message AS_VIEW_DRAW_BITMAP: View name: %s\n", fTitle, fCurrentView->Name()));
@@ -2159,6 +2189,26 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
drawingEngine->DrawArc(r, angle, span, code == AS_FILL_ARC);
break;
}
case AS_FILL_ARC_GRADIENT:
{
GTRACE(("ServerWindow %s: Message AS_FILL_ARC_GRADIENT\n", Title()));
float angle, span;
BRect r;
link.Read<BRect>(&r);
link.Read<float>(&angle);
link.Read<float>(&span);
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(&r);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillArcGradient(r, angle, span, *gradient);
}
break;
}
case AS_STROKE_BEZIER:
case AS_FILL_BEZIER:
{
@@ -2173,6 +2223,25 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
drawingEngine->DrawBezier(pts, code == AS_FILL_BEZIER);
break;
}
case AS_FILL_BEZIER_GRADIENT:
{
GTRACE(("ServerWindow %s: Message AS_FILL_BEZIER_GRADIENT\n", Title()));
BPoint pts[4];
for (int32 i = 0; i < 4; i++) {
link.Read<BPoint>(&(pts[i]));
fCurrentView->ConvertToScreenForDrawing(&pts[i]);
}
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillBezierGradient(pts, *gradient);
}
break;
}
case AS_STROKE_ELLIPSE:
case AS_FILL_ELLIPSE:
{
@@ -2185,6 +2254,23 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
drawingEngine->DrawEllipse(rect, code == AS_FILL_ELLIPSE);
break;
}
case AS_FILL_ELLIPSE_GRADIENT:
{
GTRACE(("ServerWindow %s: Message AS_FILL_ELLIPSE_GRADIENT\n", Title()));
BRect rect;
link.Read<BRect>(&rect);
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillEllipseGradient(rect, *gradient);
}
break;
}
case AS_STROKE_ROUNDRECT:
case AS_FILL_ROUNDRECT:
{
@@ -2200,6 +2286,26 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
drawingEngine->DrawRoundRect(rect, xrad, yrad, code == AS_FILL_ROUNDRECT);
break;
}
case AS_FILL_ROUNDRECT_GRADIENT:
{
GTRACE(("ServerWindow %s: Message AS_FILL_ROUNDRECT_GRADIENT\n", Title()));
BRect rect;
float xrad,yrad;
link.Read<BRect>(&rect);
link.Read<float>(&xrad);
link.Read<float>(&yrad);
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillRoundRectGradient(rect, xrad, yrad, *gradient);
}
break;
}
case AS_STROKE_TRIANGLE:
case AS_FILL_TRIANGLE:
{
@@ -2219,6 +2325,28 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
drawingEngine->DrawTriangle(pts, rect, code == AS_FILL_TRIANGLE);
break;
}
case AS_FILL_TRIANGLE_GRADIENT:
{
DTRACE(("ServerWindow %s: Message AS_FILL_TRIANGLE_GRADIENT\n", Title()));
BPoint pts[3];
BRect rect;
for (int32 i = 0; i < 3; i++) {
link.Read<BPoint>(&(pts[i]));
fCurrentView->ConvertToScreenForDrawing(&pts[i]);
}
link.Read<BRect>(&rect);
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillTriangleGradient(pts, rect, *gradient);
}
break;
}
case AS_STROKE_POLYGON:
case AS_FILL_POLYGON:
{
@@ -2245,6 +2373,35 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
delete[] pointList;
break;
}
case AS_FILL_POLYGON_GRADIENT:
{
DTRACE(("ServerWindow %s: Message AS_FILL_POLYGON_GRADIENT\n", Title()));
BRect polyFrame;
bool isClosed = true;
int32 pointCount;
link.Read<BRect>(&polyFrame);
link.Read<int32>(&pointCount);
BPoint* pointList = new(nothrow) BPoint[pointCount];
if (link.Read(pointList, pointCount * sizeof(BPoint)) >= B_OK) {
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
for (int32 i = 0; i < pointCount; i++)
fCurrentView->ConvertToScreenForDrawing(&pointList[i]);
fCurrentView->ConvertToScreenForDrawing(&polyFrame);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillPolygonGradient(pointList, pointCount,
polyFrame, *gradient, isClosed && pointCount > 2);
}
}
delete[] pointList;
break;
}
case AS_STROKE_SHAPE:
case AS_FILL_SHAPE:
{
@@ -2279,6 +2436,45 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
delete[] ptList;
break;
}
case AS_FILL_SHAPE_GRADIENT:
{
DTRACE(("ServerWindow %s: Message AS_FILL_SHAPE_GRADIENT\n", Title()));
BRect shapeFrame;
int32 opCount;
int32 ptCount;
link.Read<BRect>(&shapeFrame);
link.Read<int32>(&opCount);
link.Read<int32>(&ptCount);
uint32* opList = new(nothrow) uint32[opCount];
BPoint* ptList = new(nothrow) BPoint[ptCount];
if (link.Read(opList, opCount * sizeof(uint32)) >= B_OK &&
link.Read(ptList, ptCount * sizeof(BPoint)) >= B_OK) {
// this might seem a bit weird, but under R5, 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;
fCurrentView->ConvertToScreenForDrawing(&ptList[i]);
}
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillShapeGradient(shapeFrame, opCount, opList,
ptCount, ptList, *gradient);
}
}
delete[] opList;
delete[] ptList;
break;
}
case AS_FILL_REGION:
{
DTRACE(("ServerWindow %s: Message AS_FILL_REGION\n", Title()));
@@ -2292,6 +2488,24 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
break;
}
case AS_FILL_REGION_GRADIENT:
{
DTRACE(("ServerWindow %s: Message AS_FILL_REGION_GRADIENT\n", Title()));
BRegion region;
if (link.ReadRegion(&region) < B_OK)
break;
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(&region);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillRegionGradient(region, *gradient);
}
break;
}
case AS_STROKE_LINEARRAY:
{
DTRACE(("ServerWindow %s: Message AS_STROKE_LINEARRAY\n", Title()));
@@ -3277,3 +3491,30 @@ ServerWindow::PictureToRegion(ServerPicture *picture, BRegion &region,
region.MakeEmpty();
return B_ERROR;
}
BGradient*
ServerWindow::_GetNewGradientForType(gradient_type type)
{
switch (type) {
case B_GRADIENT_LINEAR: {
return new (std::nothrow) BGradientLinear();
}
case B_GRADIENT_RADIAL: {
return new (std::nothrow) BGradientRadial();
}
case B_GRADIENT_RADIAL_FOCUS: {
return new (std::nothrow) BGradientRadialFocus();
}
case B_GRADIENT_DIAMOND: {
return new (std::nothrow) BGradientDiamond();
}
case B_GRADIENT_CONIC: {
return new (std::nothrow) BGradientConic();
}
case B_GRADIENT_NONE: {
return new (std::nothrow) BGradient();
}
}
return NULL;
}
+2
View File
@@ -130,6 +130,8 @@ private:
void _UpdateCurrentDrawingRegion();
bool _MessageNeedsAllWindowsLocked(uint32 code) const;
BGradient* _GetNewGradientForType(gradient_type type);
// TODO: Move me elsewhere
status_t PictureToRegion(ServerPicture *picture,
+72 -1
View File
@@ -32,6 +32,12 @@
#include <View.h> // for resize modes
#include <WindowPrivate.h>
#include <GradientLinear.h>
#include <GradientRadial.h>
#include <GradientRadialFocus.h>
#include <GradientDiamond.h>
#include <GradientConic.h>
#include <stdio.h>
#include <new>
@@ -793,7 +799,7 @@ View::ConvertToScreenForDrawing(BRect* rect) const
}
//! converts a region from local *drawing* to screen coordinate system
//! converts a region from local *drawing* to screen coordinate system
void
View::ConvertToScreenForDrawing(BRegion* region) const
{
@@ -804,6 +810,71 @@ View::ConvertToScreenForDrawing(BRegion* region) const
}
//! converts a gradient from local *drawing* to screen coordinate system
void
View::ConvertToScreenForDrawing(BGradient* gradient) const
{
switch(gradient->Type()) {
case B_GRADIENT_LINEAR: {
BGradientLinear* linear = (BGradientLinear*) gradient;
BPoint start = linear->Start();
BPoint end = linear->End();
fDrawState->Transform(&start);
ConvertToScreen(&start);
fDrawState->Transform(&end);
ConvertToScreen(&end);
linear->SetStart(start);
linear->SetEnd(end);
linear->SortColorStepsByOffset();
break;
}
case B_GRADIENT_RADIAL: {
BGradientRadial* radial = (BGradientRadial*) gradient;
BPoint center = radial->Center();
fDrawState->Transform(&center);
ConvertToScreen(&center);
radial->SetCenter(center);
radial->SortColorStepsByOffset();
break;
}
case B_GRADIENT_RADIAL_FOCUS: {
BGradientRadialFocus* radialFocus = (BGradientRadialFocus*) gradient;
BPoint center = radialFocus->Center();
BPoint focal = radialFocus->Focal();
fDrawState->Transform(&center);
ConvertToScreen(&center);
fDrawState->Transform(&focal);
ConvertToScreen(&focal);
radialFocus->SetCenter(center);
radialFocus->SetFocal(focal);
radialFocus->SortColorStepsByOffset();
break;
}
case B_GRADIENT_DIAMOND: {
BGradientDiamond* diamond = (BGradientDiamond*) gradient;
BPoint center = diamond->Center();
fDrawState->Transform(&center);
ConvertToScreen(&center);
diamond->SetCenter(center);
diamond->SortColorStepsByOffset();
break;
}
case B_GRADIENT_CONIC: {
BGradientConic* conic = (BGradientConic*) gradient;
BPoint center = conic->Center();
fDrawState->Transform(&center);
ConvertToScreen(&center);
conic->SetCenter(center);
conic->SortColorStepsByOffset();
break;
}
case B_GRADIENT_NONE: {
break;
}
}
}
//! converts points from local *drawing* to screen coordinate system
void
View::ConvertToScreenForDrawing(BPoint* dst, const BPoint* src, int32 num) const
+2
View File
@@ -34,6 +34,7 @@ class Window;
class ServerBitmap;
class ServerCursor;
class ServerPicture;
class BGradient;
class View {
public:
@@ -133,6 +134,7 @@ class View {
void ConvertToScreenForDrawing(BPoint* point) const;
void ConvertToScreenForDrawing(BRect* rect) const;
void ConvertToScreenForDrawing(BRegion* region) const;
void ConvertToScreenForDrawing(BGradient* gradient) const;
void ConvertToScreenForDrawing(BPoint* dst, const BPoint* src, int32 num) const;
void ConvertToScreenForDrawing(BRect* dst, const BRect* src, int32 num) const;
+188
View File
@@ -610,6 +610,34 @@ DrawingEngine::DrawArc(BRect r, const float& angle, const float& span,
}
}
// FillArcGradient
void
DrawingEngine::FillArcGradient(BRect r, const float& angle, const float& span,
const BGradient& gradient)
{
CRASH_IF_NOT_LOCKED
make_rect_valid(r);
fPainter->AlignEllipseRect(&r, true);
BRect clipped(r);
clipped = fPainter->ClipRect(r);
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
float xRadius = r.Width() / 2.0;
float yRadius = r.Height() / 2.0;
BPoint center(r.left + xRadius,
r.top + yRadius);
fPainter->FillArcGradient(center, xRadius, yRadius, angle, span,
gradient);
_CopyToFront(clipped);
}
}
// DrawBezier
void
DrawingEngine::DrawBezier(BPoint* pts, bool filled)
@@ -624,6 +652,20 @@ DrawingEngine::DrawBezier(BPoint* pts, bool filled)
_CopyToFront(touched);
}
// FillBezierGradient
void
DrawingEngine::FillBezierGradient(BPoint* pts, const BGradient& gradient)
{
CRASH_IF_NOT_LOCKED
// TODO: figure out bounds and hide cursor depending on that
AutoFloatingOverlaysHider _(fGraphicsCard);
BRect touched = fPainter->FillBezierGradient(pts, gradient);
_CopyToFront(touched);
}
// DrawEllipse
void
DrawingEngine::DrawEllipse(BRect r, bool filled)
@@ -653,6 +695,32 @@ DrawingEngine::DrawEllipse(BRect r, bool filled)
}
}
// FillEllipseGradient
void
DrawingEngine::FillEllipseGradient(BRect r, const BGradient& gradient)
{
CRASH_IF_NOT_LOCKED
make_rect_valid(r);
BRect clipped = r;
fPainter->AlignEllipseRect(&clipped, true);
clipped.left = floorf(clipped.left);
clipped.top = floorf(clipped.top);
clipped.right = ceilf(clipped.right);
clipped.bottom = ceilf(clipped.bottom);
clipped = fPainter->ClipRect(clipped);
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
fPainter->FillEllipseGradient(r, gradient);
_CopyToFront(clipped);
}
}
// DrawPolygon
void
DrawingEngine::DrawPolygon(BPoint* ptlist, int32 numpts, BRect bounds,
@@ -673,6 +741,24 @@ DrawingEngine::DrawPolygon(BPoint* ptlist, int32 numpts, BRect bounds,
}
}
// FillPolygonGradient
void
DrawingEngine::FillPolygonGradient(BPoint* ptlist, int32 numpts, BRect bounds,
const BGradient& gradient, bool closed)
{
CRASH_IF_NOT_LOCKED
make_rect_valid(bounds);
bounds = fPainter->ClipRect(bounds);
if (bounds.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, bounds);
fPainter->FillPolygonGradient(ptlist, numpts, gradient, closed);
_CopyToFront(bounds);
}
}
// #pragma mark - rgb_color
void
@@ -876,6 +962,25 @@ DrawingEngine::FillRect(BRect r)
}
void
DrawingEngine::FillRectGradient(BRect r, const BGradient& gradient)
{
CRASH_IF_NOT_LOCKED
make_rect_valid(r);
r = fPainter->AlignAndClipRect(r);
if (!r.IsValid())
return;
AutoFloatingOverlaysHider overlaysHider(fGraphicsCard, r);
fPainter->FillRectGradient(r, gradient);
if (fGraphicsCard->IsDoubleBuffered())
_CopyToFront(r);
}
void
DrawingEngine::FillRegion(BRegion& r)
{
@@ -930,6 +1035,28 @@ DrawingEngine::FillRegion(BRegion& r)
}
void
DrawingEngine::FillRegionGradient(BRegion& r, const BGradient& gradient)
{
CRASH_IF_NOT_LOCKED
BRect clipped = fPainter->ClipRect(r.Frame());
if (!clipped.IsValid())
return;
AutoFloatingOverlaysHider overlaysHider(fGraphicsCard, clipped);
BRect touched = fPainter->FillRectGradient(r.RectAt(0), gradient);
int32 count = r.CountRects();
for (int32 i = 1; i < count; i++)
touched = touched | fPainter->FillRectGradient(r.RectAt(i), gradient);
if (fGraphicsCard->IsDoubleBuffered())
_CopyToFront(r.Frame());
}
void
DrawingEngine::DrawRoundRect(BRect r, float xrad, float yrad, bool filled)
{
@@ -956,6 +1083,32 @@ DrawingEngine::DrawRoundRect(BRect r, float xrad, float yrad, bool filled)
}
void
DrawingEngine::FillRoundRectGradient(BRect r, float xrad, float yrad,
const BGradient& gradient)
{
CRASH_IF_NOT_LOCKED
// NOTE: the stroke does not extend past "r" in R5,
// though I consider this unexpected behaviour.
make_rect_valid(r);
BRect clipped = fPainter->ClipRect(r);
clipped.left = floorf(clipped.left);
clipped.top = floorf(clipped.top);
clipped.right = ceilf(clipped.right);
clipped.bottom = ceilf(clipped.bottom);
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
BRect touched = fPainter->FillRoundRectGradient(r, xrad, yrad, gradient);
_CopyToFront(touched);
}
}
void
DrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
const uint32* opList, int32 ptCount, const BPoint* ptList, bool filled)
@@ -974,6 +1127,24 @@ DrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
}
void
DrawingEngine::FillShapeGradient(const BRect& bounds, int32 opCount,
const uint32* opList, int32 ptCount, const BPoint* ptList,
const BGradient& gradient)
{
CRASH_IF_NOT_LOCKED
// NOTE: hides cursor regardless of if and where
// shape is drawn on screen, TODO: optimize
AutoFloatingOverlaysHider _(fGraphicsCard);
BRect touched = fPainter->FillShapeGradient(opCount, opList, ptCount,
ptList, gradient);
_CopyToFront(touched);
}
void
DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds, bool filled)
{
@@ -995,6 +1166,23 @@ DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds, bool filled)
}
}
void
DrawingEngine::FillTriangleGradient(BPoint* pts, const BRect& bounds,
const BGradient& gradient)
{
CRASH_IF_NOT_LOCKED
BRect clipped(bounds);
clipped = fPainter->ClipRect(clipped);
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
fPainter->FillTriangleGradient(pts[0], pts[1], pts[2], gradient);
_CopyToFront(clipped);
}
}
// StrokeLine
void
DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end)
+22 -1
View File
@@ -15,6 +15,7 @@
#include <Font.h>
#include <Locker.h>
#include <Point.h>
#include <Gradient.h>
#include "HWInterface.h"
@@ -99,13 +100,22 @@ public:
void DrawArc(BRect r, const float& angle,
const float& span, bool filled);
void FillArcGradient(BRect r, const float& angle,
const float& span, const BGradient& gradient);
void DrawBezier(BPoint* pts, bool filled);
void FillBezierGradient(BPoint* pts,
const BGradient& gradient);
void DrawEllipse(BRect r, bool filled);
void FillEllipseGradient(BRect r,
const BGradient& gradient);
void DrawPolygon(BPoint* ptlist, int32 numpts,
BRect bounds, bool filled, bool closed);
void FillPolygonGradient(BPoint* ptlist, int32 numpts,
BRect bounds, const BGradient& gradient,
bool closed);
// these rgb_color versions are used internally by the server
void StrokePoint(const BPoint& pt,
@@ -116,19 +126,30 @@ public:
void StrokeRect(BRect r);
void FillRect(BRect r);
void FillRectGradient(BRect r, const BGradient& gradient);
void FillRegion(BRegion& r);
void FillRegionGradient(BRegion& r,
const BGradient& gradient);
void DrawRoundRect(BRect r, float xrad,
float yrad, bool filled);
void FillRoundRectGradient(BRect r, float xrad,
float yrad, const BGradient& gradient);
void DrawShape(const BRect& bounds,
int32 opcount, const uint32* oplist,
int32 ptcount, const BPoint* ptlist,
bool filled);
void FillShapeGradient(const BRect& bounds,
int32 opcount, const uint32* oplist,
int32 ptcount, const BPoint* ptlist,
const BGradient& gradient);
void DrawTriangle(BPoint* pts, const BRect& bounds,
bool filled);
void FillTriangleGradient(BPoint* pts,
const BRect& bounds, const BGradient& gradient);
// this version used by Decorator
void StrokeLine(const BPoint& start,
+569 -1
View File
@@ -15,6 +15,11 @@
#include <GraphicsDefs.h>
#include <Region.h>
#include <String.h>
#include <GradientLinear.h>
#include <GradientRadial.h>
#include <GradientRadialFocus.h>
#include <GradientDiamond.h>
#include <GradientConic.h>
#include <ShapePrivate.h>
@@ -52,13 +57,22 @@
using std::nothrow;
#undef TRACE
//#define TRACE_PAINTER
// #define TRACE_PAINTER
#ifdef TRACE_PAINTER
# define TRACE(x...) printf(x)
#else
# define TRACE(x...)
#endif
//#define TRACE_GRADIENTS
#ifdef TRACE_GRADIENTS
# include <OS.h>
# define GTRACE(x...) debug_printf(x)
#else
# define GTRACE(x...)
#endif
#define CHECK_CLIPPING if (!fValidClipping) return BRect(0, 0, -1, -1);
#define CHECK_CLIPPING_NO_RETURN if (!fValidClipping) return;
@@ -492,6 +506,28 @@ Painter::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3) const
return _DrawTriangle(pt1, pt2, pt3, true);
}
// FillTriangleGradient
BRect
Painter::FillTriangleGradient(BPoint pt1, BPoint pt2, BPoint pt3,
const BGradient& gradient) const
{
CHECK_CLIPPING
_Transform(&pt1);
_Transform(&pt2);
_Transform(&pt3);
fPath.remove_all();
fPath.move_to(pt1.x, pt1.y);
fPath.line_to(pt2.x, pt2.y);
fPath.line_to(pt3.x, pt3.y);
fPath.close_polygon();
return _FillPathGradient(fPath, gradient);
}
// DrawPolygon
BRect
Painter::DrawPolygon(BPoint* p, int32 numPts,
@@ -523,6 +559,34 @@ Painter::DrawPolygon(BPoint* p, int32 numPts,
return BRect(0.0, 0.0, -1.0, -1.0);
}
// FillPolygonGradient
BRect
Painter::FillPolygonGradient(BPoint* p, int32 numPts,
const BGradient& gradient, bool closed) const
{
CHECK_CLIPPING
if (numPts > 0) {
fPath.remove_all();
_Transform(p);
fPath.move_to(p->x, p->y);
for (int32 i = 1; i < numPts; i++) {
p++;
_Transform(p);
fPath.line_to(p->x, p->y);
}
if (closed)
fPath.close_polygon();
return _FillPathGradient(fPath, gradient);
}
return BRect(0.0, 0.0, -1.0, -1.0);
}
// DrawBezier
BRect
Painter::DrawBezier(BPoint* p, bool filled) const
@@ -550,6 +614,28 @@ Painter::DrawBezier(BPoint* p, bool filled) const
}
}
// FillBezierGradient
BRect
Painter::FillBezierGradient(BPoint* p, const BGradient& gradient) const
{
CHECK_CLIPPING
fPath.remove_all();
_Transform(&(p[0]));
_Transform(&(p[1]));
_Transform(&(p[2]));
_Transform(&(p[3]));
fPath.move_to(p[0].x, p[0].y);
fPath.curve4(p[1].x, p[1].y,
p[2].x, p[2].y,
p[3].x, p[3].y);
fPath.close_polygon();
return _FillPathGradient(fCurve, gradient);
}
// DrawShape
@@ -600,6 +686,51 @@ Painter::DrawShape(const int32& opCount, const uint32* opList,
return _StrokePath(fCurve);
}
// FillShapeGradient
BRect
Painter::FillShapeGradient(const int32& opCount, const uint32* opList,
const int32& ptCount, const BPoint* points,
const BGradient& gradient) const
{
CHECK_CLIPPING
// TODO: if shapes are ever used more heavily in Haiku,
// it would be nice to use BShape data directly (write
// an AGG "VertexSource" adaptor)
fPath.remove_all();
for (int32 i = 0; i < opCount; i++) {
uint32 op = opList[i] & 0xFF000000;
if (op & OP_MOVETO) {
fPath.move_to(points->x, points->y);
points++;
}
if (op & OP_LINETO) {
int32 count = opList[i] & 0x00FFFFFF;
while (count--) {
fPath.line_to(points->x, points->y);
points++;
}
}
if (op & OP_BEZIERTO) {
int32 count = opList[i] & 0x00FFFFFF;
while (count) {
fPath.curve4(points[0].x, points[0].y,
points[1].x, points[1].y,
points[2].x, points[2].y);
points += 3;
count -= 3;
}
}
if (op & OP_CLOSE)
fPath.close_polygon();
}
return _FillPathGradient(fCurve, gradient);
}
// StrokeRect
BRect
Painter::StrokeRect(const BRect& r) const
@@ -723,6 +854,34 @@ Painter::FillRect(const BRect& r) const
return _FillPath(fPath);
}
// FillRectGradient
BRect
Painter::FillRectGradient(const BRect& r, const BGradient& gradient) const
{
CHECK_CLIPPING
// support invalid rects
BPoint a(min_c(r.left, r.right), min_c(r.top, r.bottom));
BPoint b(max_c(r.left, r.right), max_c(r.top, r.bottom));
_Transform(&a, false);
_Transform(&b, false);
// account for stricter interpretation of coordinates in AGG
// the rectangle ranges from the top-left (.0, .0)
// to the bottom-right (.9999, .9999) corner of pixels
b.x += 1.0;
b.y += 1.0;
fPath.remove_all();
fPath.move_to(a.x, a.y);
fPath.line_to(b.x, a.y);
fPath.line_to(b.x, b.y);
fPath.line_to(a.x, b.y);
fPath.close_polygon();
return _FillPathGradient(fPath, gradient);
}
// FillRect
void
Painter::FillRect(const BRect& r, const rgb_color& c) const
@@ -907,6 +1066,31 @@ Painter::FillRoundRect(const BRect& r, float xRadius, float yRadius) const
return _FillPath(rect);
}
// FillRoundRectGradient
BRect
Painter::FillRoundRectGradient(const BRect& r, float xRadius, float yRadius,
const BGradient& gradient) const
{
CHECK_CLIPPING
BPoint lt(r.left, r.top);
BPoint rb(r.right, r.bottom);
_Transform(&lt, false);
_Transform(&rb, false);
// account for stricter interpretation of coordinates in AGG
// the rectangle ranges from the top-left (.0, .0)
// to the bottom-right (.9999, .9999) corner of pixels
rb.x += 1.0;
rb.y += 1.0;
agg::rounded_rect rect;
rect.rect(lt.x, lt.y, rb.x, rb.y);
rect.radius(xRadius, yRadius);
return _FillPathGradient(rect, gradient);
}
// AlignEllipseRect
void
Painter::AlignEllipseRect(BRect* rect, bool filled) const
@@ -999,6 +1183,29 @@ Painter::DrawEllipse(BRect r, bool fill) const
}
}
// FillEllipseGradient
BRect
Painter::FillEllipseGradient(BRect r, const BGradient& gradient) const
{
CHECK_CLIPPING
AlignEllipseRect(&r, true);
float xRadius = r.Width() / 2.0;
float yRadius = r.Height() / 2.0;
BPoint center(r.left + xRadius, r.top + yRadius);
int32 divisions = (int32)((xRadius + yRadius + 2 * fPenSize) * PI / 2);
if (divisions < 12)
divisions = 12;
if (divisions > 4096)
divisions = 4096;
agg::ellipse path(center.x, center.y, xRadius, yRadius, divisions);
return _FillPathGradient(path, gradient);
}
// StrokeArc
BRect
Painter::StrokeArc(BPoint center, float xRadius, float yRadius, float angle,
@@ -1055,6 +1262,42 @@ Painter::FillArc(BPoint center, float xRadius, float yRadius, float angle,
return _FillPath(fPath);
}
// FillArcGradient
BRect
Painter::FillArcGradient(BPoint center, float xRadius, float yRadius, float angle,
float span, const BGradient& gradient) const
{
CHECK_CLIPPING
_Transform(&center);
double angleRad = (angle * PI) / 180.0;
double spanRad = (span * PI) / 180.0;
agg::bezier_arc arc(center.x, center.y, xRadius, yRadius,
-angleRad, -spanRad);
agg::conv_curve<agg::bezier_arc> segmentedArc(arc);
fPath.remove_all();
// build a new path by starting at the center point,
// then traversing the arc, then going back to the center
fPath.move_to(center.x, center.y);
segmentedArc.rewind(0);
double x;
double y;
unsigned cmd = segmentedArc.vertex(&x, &y);
while (!agg::is_stop(cmd)) {
fPath.line_to(x, y);
cmd = segmentedArc.vertex(&x, &y);
}
fPath.close_polygon();
return _FillPathGradient(fPath, gradient);
}
// #pragma mark -
// DrawString
@@ -1161,6 +1404,21 @@ Painter::FillRegion(const BRegion* region) const
return touched;
}
// FillRegionGradient
BRect
Painter::FillRegionGradient(const BRegion* region, const BGradient& gradient) const
{
CHECK_CLIPPING
BRegion copy(*region);
int32 count = copy.CountRects();
BRect touched = FillRectGradient(copy.RectAt(0), gradient);
for (int32 i = 1; i < count; i++) {
touched = touched | FillRectGradient(copy.RectAt(i), gradient);
}
return touched;
}
// InvertRect
BRect
Painter::InvertRect(const BRect& r) const
@@ -2255,3 +2513,313 @@ Painter::_FillPath(VertexSource& path) const
return _Clipped(_BoundingBox(path));
}
// _FillPathGradient
template<class VertexSource>
BRect
Painter::_FillPathGradient(VertexSource& path, const BGradient& gradient) const
{
GTRACE("Painter::_FillPathGradient\n");
switch(gradient.Type()) {
case B_GRADIENT_LINEAR: {
GTRACE(("Painter::_FillPathGradient> type == B_GRADIENT_LINEAR\n"));
_FillPathGradientLinear(path, *((const BGradientLinear*) &gradient));
break;
}
case B_GRADIENT_RADIAL: {
GTRACE(("Painter::_FillPathGradient> type == B_GRADIENT_RADIAL\n"));
_FillPathGradientRadial(path,
*((const BGradientRadial*) &gradient));
break;
}
case B_GRADIENT_RADIAL_FOCUS: {
GTRACE(("Painter::_FillPathGradient> type == B_GRADIENT_RADIAL_FOCUS\n"));
_FillPathGradientRadialFocus(path,
*((const BGradientRadialFocus*) &gradient));
break;
}
case B_GRADIENT_DIAMOND: {
GTRACE(("Painter::_FillPathGradient> type == B_GRADIENT_DIAMOND\n"));
_FillPathGradientDiamond(path,
*((const BGradientDiamond*) &gradient));
break;
}
case B_GRADIENT_CONIC: {
GTRACE(("Painter::_FillPathGradient> type == B_GRADIENT_CONIC\n"));
_FillPathGradientConic(path,
*((const BGradientConic*) &gradient));
break;
}
case B_GRADIENT_NONE: {
GTRACE(("Painter::_FillPathGradient> type == B_GRADIENT_NONE\n"));
break;
}
}
return _Clipped(_BoundingBox(path));
}
// _MakeGradient
template<class Array>
void
Painter::_MakeGradient(Array& array, const BGradient& gradient) const
{
for (int i = 0; i < gradient.CountColors() - 1; i++) {
color_step* from = gradient.ColorAtFast(i);
color_step* to = gradient.ColorAtFast(i + 1);
agg::rgba8 fromColor(from->color.red, from->color.green,
from->color.blue, from->color.alpha);
agg::rgba8 toColor(to->color.red, to->color.green,
to->color.blue, to->color.alpha);
GTRACE("Painter::_MakeGradient> fromColor(%d, %d, %d) offset = %f\n",
fromColor.r, fromColor.g, fromColor.b, from->offset);
GTRACE("Painter::_MakeGradient> toColor(%d, %d, %d) offset = %f\n",
toColor.r, toColor.g, toColor.b, to->offset);
float dist = to->offset - from->offset;
GTRACE("Painter::_MakeGradient> dist = %f\n", dist);
if (dist > 0) {
for (int j = from->offset; j <= to->offset; j++) {
float f = (float)(to->offset - j) / (float)(dist + 1);
array[j] = toColor.gradient(fromColor, f);
GTRACE("Painter::_MakeGradient> array[%d](%d, %d, %d)\n",
array[j].r, array[j].g, array[j].b);
}
}
}
}
// _CalcLinearGradientTransform
void Painter::_CalcLinearGradientTransform(BPoint startPoint, BPoint endPoint,
agg::trans_affine& mtx,
float gradient_d2) const
{
float dx = endPoint.x - startPoint.x;
float dy = endPoint.y - startPoint.y;
mtx.reset();
mtx *= agg::trans_affine_scaling(sqrt(dx * dx + dy * dy) / gradient_d2);
mtx *= agg::trans_affine_rotation(atan2(dy, dx));
mtx *= agg::trans_affine_translation(startPoint.x, startPoint.y);
mtx.invert();
}
// _FillPathGradientLinear
template<class VertexSource>
void
Painter::_FillPathGradientLinear(VertexSource& path,
const BGradientLinear& linear) const
{
GTRACE("Painter::_FillPathGradientLinear\n");
BPoint start = linear.Start();
BPoint end = linear.End();
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::pod_auto_array<agg::rgba8, 256> color_array_type;
typedef agg::span_allocator<agg::rgba8> span_allocator_type;
typedef agg::gradient_x gradient_func_type;
typedef agg::span_gradient<agg::rgba8, interpolator_type,
gradient_func_type, color_array_type> span_gradient_type;
typedef agg::renderer_scanline_aa<renderer_base, span_allocator_type,
span_gradient_type> renderer_gradient_type;
gradient_func_type gradientFunc;
agg::trans_affine gradientMtx;
interpolator_type spanInterpolator(gradientMtx);
span_allocator_type spanAllocator;
color_array_type colorArray;
_MakeGradient(colorArray, linear);
span_gradient_type spanGradient(spanInterpolator, gradientFunc,
colorArray, 0, 100);
renderer_gradient_type gradientRenderer(fBaseRenderer, spanAllocator,
spanGradient);
_CalcLinearGradientTransform(start, end, gradientMtx);
fRasterizer.reset();
fRasterizer.add_path(path);
agg::render_scanlines(fRasterizer, fPackedScanline, gradientRenderer);
}
// _FillPathGradientRadial
template<class VertexSource>
void
Painter::_FillPathGradientRadial(VertexSource& path,
const BGradientRadial& radial) const
{
GTRACE("Painter::_FillPathGradientRadial\n");
BPoint center = radial.Center();
float radius = radial.Radius();
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::pod_auto_array<agg::rgba8, 256> color_array_type;
typedef agg::span_allocator<agg::rgba8> span_allocator_type;
typedef agg::gradient_radial gradient_func_type;
typedef agg::span_gradient<agg::rgba8, interpolator_type,
gradient_func_type, color_array_type> span_gradient_type;
typedef agg::renderer_scanline_aa<renderer_base, span_allocator_type,
span_gradient_type> renderer_gradient_type;
gradient_func_type gradientFunc;
agg::trans_affine gradientMtx;
interpolator_type spanInterpolator(gradientMtx);
span_allocator_type spanAllocator;
color_array_type colorArray;
_MakeGradient(colorArray, radial);
span_gradient_type spanGradient(spanInterpolator, gradientFunc,
colorArray, 0, 100);
renderer_gradient_type gradientRenderer(fBaseRenderer, spanAllocator,
spanGradient);
gradientMtx.reset();
gradientMtx *= agg::trans_affine_translation(center.x, center.y);
gradientMtx.invert();
// _CalcLinearGradientTransform(start, end, gradientMtx);
fRasterizer.reset();
fRasterizer.add_path(path);
agg::render_scanlines(fRasterizer, fPackedScanline, gradientRenderer);
}
// _FillPathGradientRadialFocus
template<class VertexSource>
void
Painter::_FillPathGradientRadialFocus(VertexSource& path,
const BGradientRadialFocus& focus) const
{
GTRACE("Painter::_FillPathGradientRadialFocus\n");
BPoint center = focus.Center();
BPoint focal = focus.Focal();
float radius = focus.Radius();
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::pod_auto_array<agg::rgba8, 256> color_array_type;
typedef agg::span_allocator<agg::rgba8> span_allocator_type;
typedef agg::gradient_radial_focus gradient_func_type;
typedef agg::span_gradient<agg::rgba8, interpolator_type,
gradient_func_type, color_array_type> span_gradient_type;
typedef agg::renderer_scanline_aa<renderer_base, span_allocator_type,
span_gradient_type> renderer_gradient_type;
gradient_func_type gradientFunc;
agg::trans_affine gradientMtx;
interpolator_type spanInterpolator(gradientMtx);
span_allocator_type spanAllocator;
color_array_type colorArray;
_MakeGradient(colorArray, focus);
span_gradient_type spanGradient(spanInterpolator, gradientFunc,
colorArray, 0, 100);
renderer_gradient_type gradientRenderer(fBaseRenderer, spanAllocator,
spanGradient);
gradientMtx.reset();
gradientMtx *= agg::trans_affine_translation(center.x, center.y);
gradientMtx.invert();
// _CalcLinearGradientTransform(start, end, gradientMtx);
fRasterizer.reset();
fRasterizer.add_path(path);
agg::render_scanlines(fRasterizer, fPackedScanline, gradientRenderer);
}
// _FillPathGradientDiamond
template<class VertexSource>
void
Painter::_FillPathGradientDiamond(VertexSource& path,
const BGradientDiamond& diamond) const
{
GTRACE("Painter::_FillPathGradientDiamond\n");
BPoint center = diamond.Center();
// float radius = diamond.Radius();
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::pod_auto_array<agg::rgba8, 256> color_array_type;
typedef agg::span_allocator<agg::rgba8> span_allocator_type;
typedef agg::gradient_diamond gradient_func_type;
typedef agg::span_gradient<agg::rgba8, interpolator_type,
gradient_func_type, color_array_type> span_gradient_type;
typedef agg::renderer_scanline_aa<renderer_base, span_allocator_type,
span_gradient_type> renderer_gradient_type;
gradient_func_type gradientFunc;
agg::trans_affine gradientMtx;
interpolator_type spanInterpolator(gradientMtx);
span_allocator_type spanAllocator;
color_array_type colorArray;
_MakeGradient(colorArray, diamond);
span_gradient_type spanGradient(spanInterpolator, gradientFunc,
colorArray, 0, 100);
renderer_gradient_type gradientRenderer(fBaseRenderer, spanAllocator,
spanGradient);
gradientMtx.reset();
gradientMtx *= agg::trans_affine_translation(center.x, center.y);
gradientMtx.invert();
// _CalcLinearGradientTransform(start, end, gradientMtx);
fRasterizer.reset();
fRasterizer.add_path(path);
agg::render_scanlines(fRasterizer, fPackedScanline, gradientRenderer);
}
// _FillPathGradientConic
template<class VertexSource>
void
Painter::_FillPathGradientConic(VertexSource& path,
const BGradientConic& conic) const
{
GTRACE("Painter::_FillPathGradientConic\n");
BPoint center = conic.Center();
// float radius = conic.Radius();
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::pod_auto_array<agg::rgba8, 256> color_array_type;
typedef agg::span_allocator<agg::rgba8> span_allocator_type;
typedef agg::gradient_conic gradient_func_type;
typedef agg::span_gradient<agg::rgba8, interpolator_type,
gradient_func_type, color_array_type> span_gradient_type;
typedef agg::renderer_scanline_aa<renderer_base, span_allocator_type,
span_gradient_type> renderer_gradient_type;
gradient_func_type gradientFunc;
agg::trans_affine gradientMtx;
interpolator_type spanInterpolator(gradientMtx);
span_allocator_type spanAllocator;
color_array_type colorArray;
_MakeGradient(colorArray, conic);
span_gradient_type spanGradient(spanInterpolator, gradientFunc,
colorArray, 0, 100);
renderer_gradient_type gradientRenderer(fBaseRenderer, spanAllocator,
spanGradient);
gradientMtx.reset();
gradientMtx *= agg::trans_affine_translation(center.x, center.y);
gradientMtx.invert();
// _CalcLinearGradientTransform(start, end, gradientMtx);
fRasterizer.reset();
fRasterizer.add_path(path);
agg::render_scanlines(fRasterizer, fPackedScanline, gradientRenderer);
}
+66 -6
View File
@@ -26,6 +26,12 @@
class BBitmap;
class BRegion;
class BGradient;
class BGradientLinear;
class BGradientRadial;
class BGradientRadialFocus;
class BGradientDiamond;
class BGradientConic;
class DrawState;
class FontCacheReference;
class RenderingBuffer;
@@ -101,16 +107,25 @@ class Painter {
BRect FillTriangle( BPoint pt1,
BPoint pt2,
BPoint pt3) const;
BRect FillTriangleGradient(BPoint pt1, BPoint pt2,
BPoint pt3,
const BGradient& gradient) const;
// polygons
BRect DrawPolygon( BPoint* ptArray,
int32 numPts,
bool filled,
bool closed) const;
BRect FillPolygonGradient(BPoint* ptArray,
int32 numPts,
const BGradient& gradient,
bool closed) const;
// bezier curves
BRect DrawBezier( BPoint* controlPoints,
bool filled) const;
BRect FillBezierGradient(BPoint* controlPoints,
const BGradient& gradient) const;
// shapes
BRect DrawShape( const int32& opCount,
@@ -118,7 +133,12 @@ class Painter {
const int32& ptCount,
const BPoint* ptList,
bool filled) const;
BRect FillShapeGradient(const int32& opCount,
const uint32* opList,
const int32& ptCount,
const BPoint* ptList,
const BGradient& gradient) const;
// rects
BRect StrokeRect( const BRect& r) const;
@@ -127,6 +147,8 @@ class Painter {
const rgb_color& c) const;
BRect FillRect( const BRect& r) const;
BRect FillRectGradient(const BRect& r,
const BGradient& gradient) const;
// fills a solid rect with color c, no blending
void FillRect( const BRect& r,
@@ -143,13 +165,19 @@ class Painter {
BRect FillRoundRect( const BRect& r,
float xRadius,
float yRadius) const;
BRect FillRoundRectGradient(const BRect& r,
float xRadius,
float yRadius,
const BGradient& gradient) const;
// ellipses
void AlignEllipseRect(BRect* rect,
bool filled) const;
BRect DrawEllipse( BRect r,
bool filled) const;
BRect FillEllipseGradient(BRect r,
const BGradient& gradient) const;
// arcs
BRect StrokeArc( BPoint center,
@@ -163,7 +191,13 @@ class Painter {
float yRadius,
float angle,
float span) const;
BRect FillArcGradient(BPoint center,
float xRadius,
float yRadius,
float angle,
float span,
const BGradient& gradient) const;
// strings
BRect DrawString( const char* utf8String,
uint32 length,
@@ -191,6 +225,8 @@ class Painter {
// some convenience stuff
BRect FillRegion( const BRegion* region) const;
BRect FillRegionGradient(const BRegion* region,
const BGradient& gradient) const;
BRect InvertRect( const BRect& r) const;
@@ -265,7 +301,31 @@ class Painter {
BRect _StrokePath(VertexSource& path) const;
template<class VertexSource>
BRect _FillPath(VertexSource& path) const;
void _CalcLinearGradientTransform(BPoint startPoint,
BPoint endPoint, agg::trans_affine& mtx,
float gradient_d2 = 100.0f) const;
template<class Array>
void _MakeGradient(Array& array,
const BGradient& gradient) const;
template<class VertexSource>
BRect _FillPathGradient(VertexSource& path,
const BGradient& gradient) const;
template<class VertexSource>
void _FillPathGradientLinear(VertexSource& path,
const BGradientLinear& linear) const;
template<class VertexSource>
void _FillPathGradientRadial(VertexSource& path,
const BGradientRadial& radial) const;
template<class VertexSource>
void _FillPathGradientRadialFocus(VertexSource& path,
const BGradientRadialFocus& focus) const;
template<class VertexSource>
void _FillPathGradientDiamond(VertexSource& path,
const BGradientDiamond& diamond) const;
template<class VertexSource>
void _FillPathGradientConic(VertexSource& path,
const BGradientConic& conic) const;
mutable agg::rendering_buffer fBuffer;
// AGG rendering and rasterization classes
+3 -1
View File
@@ -20,6 +20,9 @@
#include <agg_scanline_bin.h>
#include <agg_scanline_p.h>
#include <agg_scanline_u.h>
#include <agg_span_allocator.h>
#include <agg_span_gradient.h>
#include <agg_span_interpolator_linear.h>
#include <agg_rendering_buffer.h>
#include "agg_rasterizer_scanline_aa_subpix.h"
@@ -68,7 +71,6 @@
typedef agg::rasterizer_scanline_aa<> rasterizer_type;
typedef agg::rasterizer_scanline_aa_subpix<> rasterizer_subpix_type;
#endif // DEFINES_H