6d9c0146a5
The BGradient class is a bit strange as it can store any gradient on its own, butonly the subclasses allow to set some of the fields. In the asignment operator, the non-base data (which is in an union) was not copied over. More importantly, the missing copy constructor led to the default implementation being used, and BList (used for the color stops) was being copied using its default copy constructor, resulting in the two BGradient (original and copy) poinitng to the same stops data. Heap corruption resulted whenever one of them was deleted. Having a working copy ocnstructor fixes this. The alternative is making the copy constructor private or protected to make sure gradients are not copied, since normally you'd copy only the subclasses, preserving the C++ type. However there is nothing enforcing that, and manipulating a BGradient copied from a subclass works just fine. Change-Id: I28e733eb8a2970b76ae623eabb75ef8435f508af Reviewed-on: https://review.haiku-os.org/c/haiku/+/3144 Reviewed-by: waddlesplash <waddlesplash@gmail.com>
124 lines
2.8 KiB
C++
124 lines
2.8 KiB
C++
/*
|
|
* Copyright 2006-2009, Haiku, Inc. All rights reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
#ifndef _GRADIENT_H
|
|
#define _GRADIENT_H
|
|
|
|
|
|
#include <Archivable.h>
|
|
#include <GraphicsDefs.h>
|
|
#include <List.h>
|
|
|
|
|
|
class BDataIO;
|
|
class BMessage;
|
|
class BRect;
|
|
|
|
|
|
// WARNING! This is experimental API and may change! Be prepared to
|
|
// recompile your software in a next version of haiku. In particular,
|
|
// the offsets are currently specified on [0..255], but may be changed
|
|
// to the interval [0..1]. This class also does not have any FBC padding,
|
|
// So your software will definitely break when this class gets new
|
|
// virtuals. And the object size may change too...
|
|
|
|
|
|
class BGradient : public BArchivable {
|
|
public:
|
|
enum Type {
|
|
TYPE_LINEAR = 0,
|
|
TYPE_RADIAL,
|
|
TYPE_RADIAL_FOCUS,
|
|
TYPE_DIAMOND,
|
|
TYPE_CONIC,
|
|
TYPE_NONE
|
|
};
|
|
|
|
struct ColorStop {
|
|
ColorStop(const rgb_color c, float o);
|
|
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;
|
|
};
|
|
|
|
public:
|
|
BGradient();
|
|
BGradient(const BGradient& other);
|
|
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;
|
|
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 fColorStops;
|
|
Type fType;
|
|
};
|
|
|
|
#endif // _GRADIENT_H
|