Files
GTASource/rage/scaleform/Src/GRenderer/GCompoundShape.h
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

263 lines
7.5 KiB
C++

/**********************************************************************
Filename : GCompoundShape.h
Content :
Created : 2005-2006
Authors : Maxim Shemanarev
Copyright : (c) 2001-2006 Scaleform Corp. All Rights Reserved.
Notes : Compound Shape container
Licensees may use this file in accordance with the valid Scaleform
Commercial License Agreement provided with the software.
This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR ANY PURPOSE.
**********************************************************************/
#ifndef INC_GCOMPOUNDSHAPE_H
#define INC_GCOMPOUNDSHAPE_H
#include "GArrayPaged.h"
#include "GMath2D.h"
// ***** Declared Classes
class GCompoundShape;
// See implementation in the tessellator code
enum GStatRenderGen
{
GStatRG_Default = GStatGroup_RenderGen,
GStatRG_Mem,
GStatRG_Vertices_Mem,
GStatRG_MeshFill_Mem,
GStatRG_MeshStroke_Mem,
GStatRG_Tessellator_Mem,
GStatRG_Rasterizer_Mem,
GStatRG_Stroker_Mem,
GStatRG_EdgeAA_Mem,
GStatRG_StrokerAA_Mem,
GStatRG_Other_Mem
};
//-----------------------------------------------------------------------
const GCoordType G_CollinearCurveEpsilon = (GCoordType)1e-4;
//-----------------------------------------------------------------------
class GCompoundShape
{
public:
enum { SID = GStatRG_Other_Mem };
class SPath
{
friend class GCompoundShape;
public:
typedef GPointType ValueType;
SPath() {}
int GetLeftStyle() const { return LStyle; }
int GetRightStyle() const { return RStyle; }
int GetLineStyle() const { return LineStyle; }
unsigned GetNumVertices() const
{
return NumVertices;
}
const GPointType& GetVertex(unsigned i) const
{
return Shape->GetVertex(StartVertex + i);
}
private:
SPath(const GCompoundShape* s, unsigned start,
int lStyle, int rStyle, int lineStyle) :
Shape(s),
NumVertices(0),
StartVertex(start),
LStyle(lStyle),
RStyle(rStyle),
LineStyle(lineStyle)
{}
const GCompoundShape* Shape;
unsigned NumVertices;
unsigned StartVertex;
int LStyle;
int RStyle;
int LineStyle;
};
GCompoundShape() :
CurveTolerance(1),
ToleranceSquare((GCoordType)0.0625),
Vertices(),
Paths(),
CurrPath(0),
MinStyle( 0x7FFFFFFF),
MaxStyle(-0x7FFFFFFF),
MinX(1),
MinY(1),
MaxX(0),
MaxY(0),
NonZeroFill(false)
{}
UPInt GetNumBytes() const;
void Clear();
void ClearAndRelease();
void SetCurveTolerance(GCoordType t);
GCoordType GetCurveTolerance() const { return CurveTolerance; }
void BeginPath(int lStyle, int rStyle, int lineStyle);
void BeginPath(int lStyle, int rStyle, int lineStyle,
GCoordType x, GCoordType y);
void AddVertex(GCoordType x, GCoordType y);
void AddCurve(GCoordType cx, GCoordType cy,
GCoordType ax, GCoordType ay);
void ClosePath();
void SetNonZeroFill(bool flag) { NonZeroFill = flag; }
bool IsNonZeroFill() const { return NonZeroFill; }
unsigned GetNumPaths() const { return (unsigned)Paths.GetSize(); }
const SPath& GetPath(unsigned n) const { return Paths[n]; }
SPath& GetPath(unsigned n) { return Paths[n]; }
unsigned GetNumVertices() const { return (unsigned)Vertices.GetSize(); }
const GPointType& GetVertex(unsigned n) const { return Vertices[n]; }
GPointType& GetVertex(unsigned n) { return Vertices[n]; }
int GetMinStyle() const { return MinStyle; }
int GetMaxStyle() const { return MaxStyle; }
void PerceiveBounds(GCoordType* x1, GCoordType* y1,
GCoordType* x2, GCoordType* y2) const;
static void ExpandPathBounds(const SPath& path,
GCoordType* x1, GCoordType* y1,
GCoordType* x2, GCoordType* y2);
bool PointInShape(GCoordType x, GCoordType y, bool nonZero=true) const;
void PerceiveBounds();
bool HasValidBounds() const { return MinX < MaxX && MinY < MaxY; }
GCoordType GetMinX() const { return MinX; }
GCoordType GetMinY() const { return MinY; }
GCoordType GetMaxX() const { return MaxX; }
GCoordType GetMaxY() const { return MaxY; }
static bool PathsEqual(const SPath& a, const SPath& b);
void ScaleAndTranslate(GCoordType kx, GCoordType ky,
GCoordType dx, GCoordType dy);
void RemoveShortSegments(GCoordType maxLen);
#ifdef GCONTAINERS_STANDALONE
template<class VertexSource>
void AppendPath(VertexSource& vs, unsigned path_id=0)
{
double x; // Must remain double
double y;
unsigned cmd;
vs.rewind(path_id);
while((cmd = vs.vertex(&x, &y)) != 0)
{
if(cmd < 3)
{
AddVertex(GCoordType(x), GCoordType(y));
}
else
if(cmd == 3)
{
double x2, y2;
vs.vertex(&x2, &y2);
AddCurve(GCoordType(x), GCoordType(y),
GCoordType(x2), GCoordType(y2));
}
}
}
template<class VertexSource>
void AppendMultiPath(VertexSource& vs,
int lStyle, int rStyle, int lineStyle,
unsigned path_id=0)
{
double x; // Must remain double
double y;
unsigned cmd;
vs.rewind(path_id);
while((cmd = vs.vertex(&x, &y)) != 0)
{
if(cmd < 3)
{
if(cmd == 1)
{
BeginPath(lStyle, rStyle, lineStyle);
}
AddVertex(GCoordType(x), GCoordType(y));
}
else
if(cmd == 3)
{
double x2, y2;
vs.vertex(&x2, &y2);
AddCurve(GCoordType(x), GCoordType(y),
GCoordType(x2), GCoordType(y2));
}
else
if((cmd & 0x4F) == 0x4F) // Magic number "close polygon"
{
ClosePath();
}
}
}
#endif
private:
void flattenQuadraticCurve(GCoordType x1, GCoordType y1,
GCoordType x2, GCoordType y2,
GCoordType x3, GCoordType y3);
GCoordType CurveTolerance;
GCoordType ToleranceSquare;
GArrayPagedLH_POD<GPointType, 8, 64, SID> Vertices;
GArrayPagedLH_POD<SPath, 6, 16, SID> Paths;
SPath* CurrPath;
int MinStyle;
int MaxStyle;
GCoordType MinX;
GCoordType MinY;
GCoordType MaxX;
GCoordType MaxY;
bool NonZeroFill;
};
//-----------------------------------------------------------------------
GINLINE void GCompoundShape::AddVertex(GCoordType x, GCoordType y)
{
Vertices.PushBack(GPointType(x, y));
CurrPath->NumVertices++;
}
#endif