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 +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 interface_kit.o = true ; BuildPlatformMergeObjectPIC 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 #include +#include #include +#include +#include +#include +#include +#include +#include + // 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 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; +}