commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
184
include/framework/picture/pict_gradient.cpp
Normal file
184
include/framework/picture/pict_gradient.cpp
Normal file
@ -0,0 +1,184 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "picture/pict_gradient.h"
|
||||
#include "picture/pict.h"
|
||||
#include "metafile/nml.h"
|
||||
#include "log/log.h"
|
||||
|
||||
using namespace GS;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static uchar ClampChannel(int v)
|
||||
{
|
||||
if (v < 0)
|
||||
return 0;
|
||||
if (v > 255)
|
||||
return 255;
|
||||
return (uchar)v;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Picture::DrawGradient(const Gradient &gradient, const Rect <int> *clip_rect)
|
||||
{
|
||||
if (!gradient.GetControlPointCount())
|
||||
return;
|
||||
|
||||
Rect <int> rect = GetRect();
|
||||
if (!clip_rect)
|
||||
clip_rect = ▭
|
||||
|
||||
uint current_control_point = 0,
|
||||
next_control_point = 1;
|
||||
if (next_control_point == gradient.GetControlPointCount())
|
||||
next_control_point = current_control_point;
|
||||
uchar *pdata = GetDataOffset(clip_rect->sx, clip_rect->sy);
|
||||
|
||||
for (int y = 0; y < clip_rect->GetHeight(); ++y)
|
||||
{
|
||||
float c_k = (float)y / clip_rect->GetHeight();
|
||||
|
||||
// Check gradient interval change.
|
||||
if ((c_k > gradient.k[next_control_point]) && (current_control_point + 1 < gradient.GetControlPointCount()))
|
||||
{
|
||||
current_control_point++;
|
||||
next_control_point++;
|
||||
if (next_control_point == gradient.GetControlPointCount())
|
||||
next_control_point = current_control_point;
|
||||
}
|
||||
|
||||
// Blend.
|
||||
Color blend_color = gradient.color[current_control_point];
|
||||
|
||||
if (current_control_point != next_control_point)
|
||||
blend_color = (gradient.color[next_control_point] - gradient.color[current_control_point]) *
|
||||
(c_k - gradient.k[current_control_point]) / (gradient.k[next_control_point] - gradient.k[current_control_point]) +
|
||||
gradient.color[current_control_point];
|
||||
|
||||
uchar *pscan = pdata,
|
||||
r = (uchar)(blend_color.x * 255),
|
||||
g = (uchar)(blend_color.y * 255),
|
||||
b = (uchar)(blend_color.z * 255),
|
||||
a = (uchar)(blend_color.w * 255);
|
||||
|
||||
switch (gradient.GetOperator())
|
||||
{
|
||||
case Picture::BlendReplace:
|
||||
for (int x = 0; x < rect.GetWidth(); ++x)
|
||||
{
|
||||
pscan[0] = r;
|
||||
pscan[1] = g;
|
||||
pscan[2] = b;
|
||||
pscan[3] = a;
|
||||
pscan += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case Picture::BlendCompose:
|
||||
for (int x = 0; x < rect.GetWidth(); ++x)
|
||||
{
|
||||
uchar a_blend = AlphaCompositeAlpha(pscan[3], a);
|
||||
pscan[0] = AlphaCompositeColor(pscan[0], r, pscan[3], a, a_blend);
|
||||
pscan[1] = AlphaCompositeColor(pscan[1], g, pscan[3], a, a_blend);
|
||||
pscan[2] = AlphaCompositeColor(pscan[2], b, pscan[3], a, a_blend);
|
||||
pscan[3] = a_blend;
|
||||
pscan += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case Picture::BlendMultiply:
|
||||
for (int x = 0; x < rect.GetWidth(); ++x)
|
||||
{
|
||||
pscan[0] = (pscan[0] * r) >> 8;
|
||||
pscan[1] = (pscan[1] * g) >> 8;
|
||||
pscan[2] = (pscan[2] * b) >> 8;
|
||||
pscan[3] = (pscan[3] * a) >> 8;
|
||||
pscan += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case Picture::BlendMultiply2x:
|
||||
for (int x = 0; x < rect.GetWidth(); ++x)
|
||||
{
|
||||
pscan[0] = ClampChannel((pscan[0] * r) >> 7);
|
||||
pscan[1] = ClampChannel((pscan[1] * g) >> 7);
|
||||
pscan[2] = ClampChannel((pscan[2] * b) >> 7);
|
||||
pscan[3] = (pscan[3] * a) >> 8;
|
||||
pscan += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case Picture::BlendAdd:
|
||||
for (int x = 0; x < rect.GetWidth(); ++x)
|
||||
{
|
||||
pscan[0] = ClampChannel(pscan[0] + r);
|
||||
pscan[1] = ClampChannel(pscan[1] + g);
|
||||
pscan[2] = ClampChannel(pscan[2] + b);
|
||||
pscan[3] = (pscan[3] * a) >> 8;
|
||||
pscan += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
pdata += GetPitch();
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Gradient::FromMetaTag(NML::Tag *tag)
|
||||
{
|
||||
control_point_count = 0;
|
||||
op = Picture::BlendMultiply;
|
||||
|
||||
NMLTagForeach(ctag, *tag)
|
||||
{
|
||||
if (ctag->name == "Operator")
|
||||
{
|
||||
String op_string(ctag->GetString());
|
||||
|
||||
if (op_string == "Replace")
|
||||
op = Picture::BlendReplace;
|
||||
else if (op_string == "Multiply")
|
||||
op = Picture::BlendMultiply;
|
||||
else if (op_string == "Multiply2x")
|
||||
op = Picture::BlendMultiply2x;
|
||||
else if (op_string == "Add")
|
||||
op = Picture::BlendAdd;
|
||||
else if (op_string == "Compose")
|
||||
op = Picture::BlendCompose;
|
||||
else __LOG_W__ << "Unknown gradient operator.\n";
|
||||
}
|
||||
else if (ctag->name == "Control")
|
||||
{
|
||||
// Control point count safety.
|
||||
if (control_point_count == 8)
|
||||
__ERR__(__LOG_E__ << "Too many control points in gradient definition.\n", false);
|
||||
|
||||
// Coordinate.
|
||||
NML::Tag *attr_tag = ctag->GetTypedTag("K", Variant::VariantFloat);
|
||||
if (!attr_tag)
|
||||
__ERR__(__LOG_E__ << "Missing tag (control point coordinate) in gradient definition.\n", false);
|
||||
k[control_point_count] = attr_tag->GetReal();
|
||||
|
||||
// Color.
|
||||
attr_tag = ctag->GetTypedTag("Color", Variant::VariantNone);
|
||||
if (!attr_tag)
|
||||
__ERR__(__LOG_E__ << "Missing tag (control point color) in gradient definition.\n", false);
|
||||
color[control_point_count].Set();
|
||||
if (!color[control_point_count].FromMetaTag(*attr_tag))
|
||||
__ERR__(__LOG_E__ << "Erroneous control point color in gradient definition.\n", false);
|
||||
|
||||
control_point_count++;
|
||||
}
|
||||
else __ERR__(__LOG_E__ << "Unexpected tag in gradient definition.\n", false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user