hrev54424 adds 1 changeset to branch 'master'
old head: 4399ec510de9714e2440cdae346d00c286d69906
new head: 36ef16bf087873ebf45fe1f94511fbbe81a6773d
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=36ef16bf0878+%5E4399ec510de9
----------------------------------------------------------------------------
36ef16bf0878: BGradient: add Flatten, Unflatten methods
Change-Id: I861bab8ae19628d34297c294fd6ce3e5b6c82b34
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2827
Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>
[ X512 <danger_mail@xxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev54424
Commit: 36ef16bf087873ebf45fe1f94511fbbe81a6773d
URL: https://git.haiku-os.org/haiku/commit/?id=36ef16bf0878
Author: X512 <danger_mail@xxxxxxx>
Date: Thu May 28 00:25:21 2020 UTC
Committer: Adrien Destugues <pulkomandy@xxxxxxxxx>
Commit-Date: Mon Jul 13 15:35:38 2020 UTC
----------------------------------------------------------------------------
3 files changed, 171 insertions(+), 18 deletions(-)
headers/os/interface/Gradient.h | 28 +++---
src/build/libbe/interface/Jamfile | 5 ++
src/kits/interface/Gradient.cpp | 156 ++++++++++++++++++++++++++++++++--
----------------------------------------------------------------------------
diff --git a/headers/os/interface/Gradient.h b/headers/os/interface/Gradient.h
index f84a348ea1..846141ac51 100644
--- a/headers/os/interface/Gradient.h
+++ b/headers/os/interface/Gradient.h
@@ -11,6 +11,7 @@
#include <List.h>
+class BDataIO;
class BMessage;
class BRect;
@@ -39,9 +40,9 @@ public:
ColorStop(uint8 r, uint8 g, uint8 b, uint8 a, float o);
ColorStop(const ColorStop& other);
ColorStop();
-
+
bool operator!=(const ColorStop& other) const;
-
+
rgb_color color;
float offset;
};
@@ -50,42 +51,45 @@ 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 ColorStopsAreEqual(
const
BGradient& other) const;
-
+
void SetColorStops(const
BGradient& other);
-
+
int32 AddColor(const
rgb_color& color,
float
offset);
bool AddColorStop(const
ColorStop& colorStop,
int32
index);
-
+
bool RemoveColor(int32
index);
-
+
bool SetColorStop(int32
index,
const
ColorStop& colorStop);
bool SetColor(int32 index,
const rgb_color& color);
bool SetOffset(int32 index,
float offset);
-
+
int32 CountColorStops() const;
ColorStop* ColorStopAt(int32
index) const;
ColorStop* ColorStopAtFast(int32
index) const;
ColorStop* ColorStops() const;
void
SortColorStopsByOffset();
-
+
Type GetType() const
{
return fType; }
-
+
void MakeEmpty();
+ status_t Flatten(BDataIO*
stream) const;
+ static status_t Unflatten(BGradient *&output,
BDataIO* stream);
+
private:
friend class BGradientLinear;
friend class BGradientRadial;
diff --git a/src/build/libbe/interface/Jamfile
b/src/build/libbe/interface/Jamfile
index 4c7d415ff9..e076a8da90 100644
--- a/src/build/libbe/interface/Jamfile
+++ b/src/build/libbe/interface/Jamfile
@@ -9,6 +9,11 @@ USES_BE_API on <libbe_build>interface_kit.o = true ;
BuildPlatformMergeObjectPIC <libbe_build>interface_kit.o :
Bitmap.cpp
Gradient.cpp
+ GradientLinear.cpp
+ GradientRadial.cpp
+ GradientRadialFocus.cpp
+ GradientDiamond.cpp
+ GradientConic.cpp
GraphicsDefs.cpp
Point.cpp
Rect.cpp
diff --git a/src/kits/interface/Gradient.cpp b/src/kits/interface/Gradient.cpp
index 218323b872..e4574e5960 100644
--- a/src/kits/interface/Gradient.cpp
+++ b/src/kits/interface/Gradient.cpp
@@ -13,8 +13,16 @@
#include <math.h>
#include <stdio.h>
+#include <DataIO.h>
#include <Message.h>
+#include <AutoDeleter.h>
+#include <GradientLinear.h>
+#include <GradientRadial.h>
+#include <GradientRadialFocus.h>
+#include <GradientDiamond.h>
+#include <GradientConic.h>
+
// constructor
BGradient::ColorStop::ColorStop(const rgb_color c, float o)
@@ -195,7 +203,7 @@ BGradient::Archive(BMessage* into, bool deep) const
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);
@@ -203,7 +211,7 @@ BGradient::Archive(BMessage* into, bool deep) const
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);
@@ -215,7 +223,7 @@ BGradient::Archive(BMessage* into, bool deep) const
ret = into->AddFloat("radial_f_fy",
(float)fData.radial_focus.fy);
if (ret >= B_OK)
ret = into->AddFloat("radial_f_radius",
(float)fData.radial_focus.radius);
-
+
// diamond
if (ret >= B_OK)
ret = into->AddFloat("diamond_cx", (float)fData.diamond.cx);
@@ -229,11 +237,11 @@ BGradient::Archive(BMessage* into, bool deep) const
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;
}
@@ -271,7 +279,7 @@ BGradient::ColorStopsAreEqual(const BGradient& other) const
int32 count = CountColorStops();
if (count == other.CountColorStops() &&
fType == other.fType) {
-
+
bool equal = true;
for (int32 i = 0; i < count; i++) {
ColorStop* ourStop = ColorStopAtFast(i);
@@ -447,3 +455,139 @@ BGradient::MakeEmpty()
delete ColorStopAtFast(i);
fColorStops.MakeEmpty();
}
+
+
+status_t
+BGradient::Flatten(BDataIO* stream) const
+{
+ int32 stopCount = CountColorStops();
+ stream->Write(&fType, sizeof(Type));
+ stream->Write(&stopCount, sizeof(int32));
+ if (stopCount > 0) {
+ for (int i = 0; i < stopCount; i++) {
+ stream->Write(ColorStopAtFast(i),
+ sizeof(ColorStop));
+ }
+ }
+
+ switch (fType) {
+ case TYPE_LINEAR:
+ stream->Write(&fData.linear.x1, sizeof(float));
+ stream->Write(&fData.linear.y1, sizeof(float));
+ stream->Write(&fData.linear.x2, sizeof(float));
+ stream->Write(&fData.linear.y2, sizeof(float));
+ break;
+ case TYPE_RADIAL:
+ stream->Write(&fData.radial.cx, sizeof(float));
+ stream->Write(&fData.radial.cy, sizeof(float));
+ stream->Write(&fData.radial.radius, sizeof(float));
+ break;
+ case TYPE_RADIAL_FOCUS:
+ stream->Write(&fData.radial_focus.cx, sizeof(float));
+ stream->Write(&fData.radial_focus.cy, sizeof(float));
+ stream->Write(&fData.radial_focus.fx, sizeof(float));
+ stream->Write(&fData.radial_focus.fy, sizeof(float));
+ stream->Write(&fData.radial_focus.radius,
sizeof(float));
+ break;
+ case TYPE_DIAMOND:
+ stream->Write(&fData.diamond.cx, sizeof(float));
+ stream->Write(&fData.diamond.cy, sizeof(float));
+ break;
+ case TYPE_CONIC:
+ stream->Write(&fData.conic.cx, sizeof(float));
+ stream->Write(&fData.conic.cy, sizeof(float));
+ stream->Write(&fData.conic.angle, sizeof(float));
+ break;
+ case TYPE_NONE:
+ break;
+ }
+ return B_OK;
+}
+
+
+static BGradient*
+gradient_for_type(BGradient::Type type)
+{
+ switch (type) {
+ case BGradient::TYPE_LINEAR:
+ return new (std::nothrow) BGradientLinear();
+ case BGradient::TYPE_RADIAL:
+ return new (std::nothrow) BGradientRadial();
+ case BGradient::TYPE_RADIAL_FOCUS:
+ return new (std::nothrow) BGradientRadialFocus();
+ case BGradient::TYPE_DIAMOND:
+ return new (std::nothrow) BGradientDiamond();
+ case BGradient::TYPE_CONIC:
+ return new (std::nothrow) BGradientConic();
+ case BGradient::TYPE_NONE:
+ return new (std::nothrow) BGradient();
+ }
+ return NULL;
+}
+
+
+status_t
+BGradient::Unflatten(BGradient *&output, BDataIO* stream)
+{
+ output = NULL;
+ Type gradientType;
+ int32 colorsCount;
+ stream->Read(&gradientType, sizeof(Type));
+ status_t status = stream->Read(&colorsCount, sizeof(int32));
+ if (status < B_OK)
+ return status;
+
+ ObjectDeleter<BGradient> gradient(gradient_for_type(gradientType));
+ if (gradient.Get() == NULL)
+ return B_NO_MEMORY;
+
+ if (colorsCount > 0) {
+ ColorStop stop;
+ for (int i = 0; i < colorsCount; i++) {
+ if ((status = stream->Read(&stop, sizeof(ColorStop))) <
B_OK)
+ return status;
+ if (!gradient->AddColorStop(stop, i))
+ return B_NO_MEMORY;
+ }
+ }
+
+ switch (gradientType) {
+ case TYPE_LINEAR:
+ stream->Read(&gradient->fData.linear.x1, sizeof(float));
+ stream->Read(&gradient->fData.linear.y1, sizeof(float));
+ stream->Read(&gradient->fData.linear.x2, sizeof(float));
+ if ((status = stream->Read(&gradient->fData.linear.y2,
sizeof(float))) < B_OK)
+ return status;
+ break;
+ case TYPE_RADIAL:
+ stream->Read(&gradient->fData.radial.cx, sizeof(float));
+ stream->Read(&gradient->fData.radial.cy, sizeof(float));
+ if ((stream->Read(&gradient->fData.radial.radius,
sizeof(float))) < B_OK)
+ return status;
+ break;
+ case TYPE_RADIAL_FOCUS:
+ stream->Read(&gradient->fData.radial_focus.cx,
sizeof(float));
+ stream->Read(&gradient->fData.radial_focus.cy,
sizeof(float));
+ stream->Read(&gradient->fData.radial_focus.fx,
sizeof(float));
+ stream->Read(&gradient->fData.radial_focus.fy,
sizeof(float));
+ if ((stream->Read(&gradient->fData.radial_focus.radius,
sizeof(float))) < B_OK)
+ return status;
+ break;
+ case TYPE_DIAMOND:
+ stream->Read(&gradient->fData.diamond.cx,
sizeof(float));
+ if ((stream->Read(&gradient->fData.diamond.cy,
sizeof(float))) < B_OK)
+ return status;
+ break;
+ case TYPE_CONIC:
+ stream->Read(&gradient->fData.conic.cx, sizeof(float));
+ stream->Read(&gradient->fData.conic.cy, sizeof(float));
+ if ((stream->Read(&gradient->fData.conic.angle,
sizeof(float))) < B_OK)
+ return status;
+ break;
+ case TYPE_NONE:
+ break;
+ }
+
+ output = gradient.Detach();
+ return B_OK;
+}