
129727: Structurally dead code 151979, 133461: Uninitialized scalar field 129785, 129786, 129787: Use after free
529 lines
15 KiB
C++
529 lines
15 KiB
C++
/***************************************************************************
|
|
* Copyright (c) 2005 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
|
* *
|
|
* This file is part of the FreeCAD CAx development system. *
|
|
* *
|
|
* This library is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU Library General Public *
|
|
* License as published by the Free Software Foundation; either *
|
|
* version 2 of the License, or (at your option) any later version. *
|
|
* *
|
|
* This library is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Library General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Library General Public *
|
|
* License along with this library; see the file COPYING.LIB. If not, *
|
|
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
|
* Suite 330, Boston, MA 02111-1307, USA *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
|
|
#include "PreCompiled.h"
|
|
#ifndef _PreComp_
|
|
# include <cstdlib>
|
|
#endif
|
|
|
|
#include "ColorModel.h"
|
|
|
|
using namespace App;
|
|
|
|
|
|
ColorModel::ColorModel (unsigned short usCt)
|
|
: _usColors(usCt), _pclColors(0)
|
|
{
|
|
if (usCt > 0)
|
|
_pclColors = new Color[usCt];
|
|
}
|
|
|
|
ColorModel::ColorModel (const ColorModel &rclM)
|
|
: _pclColors(0)
|
|
{
|
|
*this = rclM;
|
|
}
|
|
|
|
ColorModel::~ColorModel ()
|
|
{
|
|
delete [] _pclColors;
|
|
}
|
|
|
|
ColorModel& ColorModel::operator = (const ColorModel &rclM)
|
|
{
|
|
// first check if both objects are identical
|
|
if (this->_pclColors && this->_pclColors == rclM._pclColors)
|
|
return *this;
|
|
|
|
delete [] _pclColors;
|
|
_pclColors = 0;
|
|
|
|
_usColors = rclM._usColors;
|
|
if (_usColors == 0)
|
|
return *this;
|
|
|
|
_pclColors = new Color[rclM._usColors];
|
|
for (int i = 0; i < rclM._usColors; i++)
|
|
_pclColors[i] = rclM._pclColors[i];
|
|
|
|
return *this;
|
|
}
|
|
|
|
ColorField::ColorField (void)
|
|
: _clModel(ColorModelTria())
|
|
{
|
|
set(ColorModelTria(), -1.0f, 1.0f, 13);
|
|
}
|
|
|
|
ColorField::ColorField (const ColorModel &rclModel, float fMin, float fMax, unsigned short usCt)
|
|
: _clModel(ColorModelTria())
|
|
{
|
|
set(rclModel, fMin, fMax, usCt);
|
|
}
|
|
|
|
ColorField::~ColorField ()
|
|
{
|
|
}
|
|
|
|
ColorField::ColorField (const ColorField &rclCF)
|
|
: _clModel(rclCF._clModel),
|
|
_fMin(rclCF._fMin),
|
|
_fMax(rclCF._fMax),
|
|
_fAscent(rclCF._fAscent),
|
|
_fConstant(rclCF._fConstant),
|
|
_usCtColors(rclCF._usCtColors),
|
|
_aclField(rclCF._aclField)
|
|
{
|
|
}
|
|
|
|
ColorField& ColorField::operator = (const ColorField &rclCF)
|
|
{
|
|
_aclField = rclCF._aclField;
|
|
return *this;
|
|
}
|
|
|
|
void ColorField::set (const ColorModel &rclModel, float fMin, float fMax, unsigned short usCt)
|
|
{
|
|
_clModel = rclModel;
|
|
_fMin = std::min<float>(fMin, fMax);
|
|
_fMax = std::max<float>(_fMin + CCR_EPS, fMax);
|
|
_usCtColors = std::max<unsigned short>(usCt, _clModel._usColors);
|
|
rebuild();
|
|
}
|
|
|
|
void ColorField::setColorModel (const ColorModel &rclModel)
|
|
{
|
|
_clModel = rclModel;
|
|
rebuild();
|
|
}
|
|
|
|
void ColorField::rebuild (void)
|
|
{
|
|
unsigned short usInd1, usInd2, usStep, i;
|
|
|
|
_aclField.resize(_usCtColors);
|
|
|
|
|
|
usStep = std::min<unsigned short>(_usCtColors / (_clModel._usColors-1), _usCtColors-1);
|
|
usInd1 = 0;
|
|
usInd2 = usStep;
|
|
for (i = 0; i < (_clModel._usColors - 1); i++) {
|
|
interpolate(_clModel._pclColors[i], usInd1, _clModel._pclColors[i+1], usInd2);
|
|
usInd1 = usInd2;
|
|
if ((i + 1) == (_clModel._usColors - 2))
|
|
usInd2 = _usCtColors - 1;
|
|
else
|
|
usInd2 += usStep;
|
|
}
|
|
|
|
_fAscent = float(_usCtColors) / (_fMax - _fMin);
|
|
_fConstant = -_fAscent * _fMin;
|
|
}
|
|
|
|
// fuellt das Array von Farbe 1, Index 1 bis Farbe 2, Index 2
|
|
void ColorField::interpolate (Color clCol1, unsigned short usInd1, Color clCol2, unsigned short usInd2)
|
|
{
|
|
unsigned short i;
|
|
float ucR, ucG, ucB;
|
|
float fR, fG, fB, fStep = 1.0f, fLen = float(usInd2 - usInd1);
|
|
|
|
_aclField[usInd1] = clCol1;
|
|
_aclField[usInd2] = clCol2;
|
|
|
|
fR = (float(clCol2.r) - float(clCol1.r)) / fLen;
|
|
fG = (float(clCol2.g) - float(clCol1.g)) / fLen;
|
|
fB = (float(clCol2.b) - float(clCol1.b)) / fLen;
|
|
|
|
for (i = (usInd1 + 1); i < usInd2; i++) {
|
|
ucR = clCol1.r + fR * fStep;
|
|
ucG = clCol1.g + fG * fStep;
|
|
ucB = clCol1.b + fB * fStep;
|
|
_aclField[i] = Color(ucR, ucG, ucB);
|
|
fStep += 1.0f;
|
|
}
|
|
}
|
|
|
|
|
|
ColorGradient::ColorGradient (void)
|
|
: _tColorModel(TRIA),
|
|
_tStyle(ZERO_BASED),
|
|
_bOutsideGrayed(false),
|
|
_clTotal(ColorModelTria()),
|
|
_clTop(ColorModelTriaTop()),
|
|
_clBottom(ColorModelTriaBottom())
|
|
{
|
|
setColorModel();
|
|
set(-1.0f, 1.0f, 13, ZERO_BASED, false);
|
|
}
|
|
|
|
ColorGradient::ColorGradient (float fMin, float fMax, unsigned short usCtColors, TStyle tS, bool bOG)
|
|
: _tColorModel(TRIA),
|
|
_tStyle(tS),
|
|
_bOutsideGrayed(false),
|
|
_clTotal(ColorModelTria()),
|
|
_clTop(ColorModelTriaTop()),
|
|
_clBottom(ColorModelTriaBottom())
|
|
{
|
|
setColorModel();
|
|
set(fMin, fMax, usCtColors, tS, bOG);
|
|
}
|
|
|
|
ColorGradient::ColorGradient (const ColorGradient &rclCR)
|
|
: _clColFld1(rclCR._clColFld1),
|
|
_clColFld2(rclCR._clColFld2),
|
|
_tColorModel(rclCR._tColorModel),
|
|
_tStyle(rclCR._tStyle),
|
|
_fMin(rclCR._fMin),
|
|
_fMax(rclCR._fMax),
|
|
_usCtColors(rclCR._usCtColors),
|
|
_bOutsideGrayed(rclCR._bOutsideGrayed),
|
|
_clTotal(rclCR._clTotal),
|
|
_clTop(rclCR._clTop),
|
|
_clBottom(rclCR._clBottom)
|
|
{
|
|
}
|
|
|
|
ColorGradient& ColorGradient::operator = (const ColorGradient &rclCR)
|
|
{
|
|
_tColorModel = rclCR._tColorModel;
|
|
_clTotal = rclCR._clTotal;
|
|
_clTop = rclCR._clTop;
|
|
_clBottom = rclCR._clBottom;
|
|
_bOutsideGrayed = rclCR._bOutsideGrayed;
|
|
_clColFld1 = rclCR._clColFld1;
|
|
_clColFld2 = rclCR._clColFld2;
|
|
_tStyle = rclCR._tStyle;
|
|
_fMin = rclCR._fMin;
|
|
_fMax = rclCR._fMax;
|
|
_usCtColors = rclCR._usCtColors;
|
|
|
|
return *this;
|
|
}
|
|
|
|
void ColorGradient::set (float fMin, float fMax, unsigned short usCt, TStyle tS, bool bOG)
|
|
{
|
|
_fMin = std::min<float>(fMin, fMax);
|
|
_fMax = std::max<float>(_fMin + CCR_EPS, fMax);
|
|
_usCtColors = std::max<unsigned short>(usCt, getMinColors());
|
|
_tStyle = tS;
|
|
_bOutsideGrayed = bOG;
|
|
rebuild();
|
|
}
|
|
|
|
void ColorGradient::rebuild (void)
|
|
{
|
|
switch (_tStyle)
|
|
{
|
|
case FLOW:
|
|
{
|
|
_clColFld1.set(_clTotal, _fMin, _fMax, _usCtColors);
|
|
break;
|
|
}
|
|
case ZERO_BASED:
|
|
{
|
|
if ((_fMin < 0.0f) && (_fMax > 0.0f))
|
|
{
|
|
_clColFld1.set(_clBottom, _fMin, 0.0f, _usCtColors / 2);
|
|
_clColFld2.set(_clTop, 0.0f, _fMax, _usCtColors / 2);
|
|
}
|
|
else if (_fMin >= 0.0f)
|
|
_clColFld1.set(_clTop, 0.0f, _fMax, _usCtColors);
|
|
else
|
|
_clColFld1.set(_clBottom, _fMin, 0.0f, _usCtColors);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
unsigned short ColorGradient::getMinColors (void) const
|
|
{
|
|
switch (_tStyle)
|
|
{
|
|
case FLOW:
|
|
return _clColFld1.getMinColors();
|
|
case ZERO_BASED:
|
|
{
|
|
if ((_fMin < 0.0f) && (_fMax > 0.0f))
|
|
return _clColFld1.getMinColors() + _clColFld2.getMinColors();
|
|
else
|
|
return _clColFld1.getMinColors();
|
|
}
|
|
}
|
|
return 2;
|
|
}
|
|
|
|
void ColorGradient::setColorModel (TColorModel tModel)
|
|
{
|
|
_tColorModel = tModel;
|
|
setColorModel();
|
|
rebuild();
|
|
}
|
|
|
|
void ColorGradient::setColorModel (void)
|
|
{
|
|
switch (_tColorModel)
|
|
{
|
|
case TRIA:
|
|
{
|
|
_clTotal = ColorModelTria();
|
|
_clTop = ColorModelTriaTop();
|
|
_clBottom = ColorModelTriaBottom();
|
|
break;
|
|
}
|
|
case INVERSE_TRIA:
|
|
{
|
|
_clTotal = ColorModelInverseTria();
|
|
_clTop = ColorModelInverseTriaTop();
|
|
_clBottom = ColorModelInverseTriaBottom();
|
|
break;
|
|
}
|
|
case GRAY:
|
|
{
|
|
_clTotal = ColorModelGray();
|
|
_clTop = ColorModelGrayTop();
|
|
_clBottom = ColorModelGrayBottom();
|
|
break;
|
|
}
|
|
case INVERSE_GRAY:
|
|
{
|
|
_clTotal = ColorModelInverseGray();
|
|
_clTop = ColorModelInverseGrayTop();
|
|
_clBottom = ColorModelInverseGrayBottom();
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (_tStyle)
|
|
{
|
|
case FLOW:
|
|
{
|
|
_clColFld1.setColorModel(_clTotal);
|
|
_clColFld2.setColorModel(_clBottom);
|
|
break;
|
|
}
|
|
case ZERO_BASED:
|
|
{
|
|
_clColFld1.setColorModel(_clTop);
|
|
_clColFld2.setColorModel(_clBottom);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
ColorLegend::ColorLegend (void)
|
|
: _bOutsideGrayed(false)
|
|
{
|
|
// default green, red
|
|
_aclColorFields.push_back(Color(0, 1, 0));
|
|
_aclColorFields.push_back(Color(1, 0, 0));
|
|
|
|
_aclNames.push_back("Min");
|
|
_aclNames.push_back("Max");
|
|
|
|
_aclValues.push_back(-1.0f);
|
|
_aclValues.push_back(0.0f);
|
|
_aclValues.push_back(1.0f);
|
|
}
|
|
|
|
ColorLegend::ColorLegend (const ColorLegend &rclCL)
|
|
{
|
|
*this = rclCL;
|
|
}
|
|
|
|
ColorLegend& ColorLegend::operator = (const ColorLegend &rclCL)
|
|
{
|
|
_aclColorFields = rclCL._aclColorFields;
|
|
_aclNames = rclCL._aclNames;
|
|
_aclValues = rclCL._aclValues;
|
|
_bOutsideGrayed = rclCL._bOutsideGrayed;
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool ColorLegend::operator == (const ColorLegend &rclCL) const
|
|
{
|
|
return (_aclColorFields.size() == rclCL._aclColorFields.size()) &&
|
|
(_aclNames.size() == rclCL._aclNames.size()) &&
|
|
(_aclValues.size() == rclCL._aclValues.size()) &&
|
|
std::equal(_aclColorFields.begin(), _aclColorFields.end(), rclCL._aclColorFields.begin()) &&
|
|
std::equal(_aclNames.begin(), _aclNames.end(), rclCL._aclNames.begin()) &&
|
|
std::equal(_aclValues.begin(), _aclValues.end(), rclCL._aclValues.begin()) &&
|
|
_bOutsideGrayed == rclCL._bOutsideGrayed;
|
|
}
|
|
|
|
float ColorLegend::getValue (unsigned long ulPos) const
|
|
{
|
|
if (ulPos < _aclValues.size())
|
|
return _aclValues[ulPos];
|
|
else
|
|
return 0.0f;
|
|
}
|
|
|
|
bool ColorLegend::setValue (unsigned long ulPos, float fVal)
|
|
{
|
|
if (ulPos < _aclValues.size())
|
|
{
|
|
_aclValues[ulPos] = fVal;
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
Color ColorLegend::getColor (unsigned long ulPos) const
|
|
{
|
|
if (ulPos < _aclColorFields.size())
|
|
return _aclColorFields[ulPos];
|
|
else
|
|
return Color();
|
|
}
|
|
|
|
// color as: 0x00rrggbb
|
|
uint32_t ColorLegend::getPackedColor (unsigned long ulPos) const
|
|
{
|
|
Color clRGB = getColor(ulPos);
|
|
return clRGB.getPackedValue();
|
|
}
|
|
|
|
std::string ColorLegend::getText (unsigned long ulPos) const
|
|
{
|
|
if (ulPos < _aclNames.size())
|
|
return _aclNames[ulPos];
|
|
else
|
|
return "";
|
|
}
|
|
|
|
bool ColorLegend::addMin (const std::string &rclName)
|
|
{
|
|
_aclNames.push_front(rclName);
|
|
_aclValues.push_front(*_aclValues.begin() - 1.0f);
|
|
|
|
Color clNewRGB;
|
|
clNewRGB.r = ((float)rand() / (float)RAND_MAX);
|
|
clNewRGB.g = ((float)rand() / (float)RAND_MAX);
|
|
clNewRGB.b = ((float)rand() / (float)RAND_MAX);
|
|
|
|
_aclColorFields.push_front(clNewRGB);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ColorLegend::addMax (const std::string &rclName)
|
|
{
|
|
_aclNames.push_back(rclName);
|
|
_aclValues.push_back(*(_aclValues.end()-1) + 1.0f);
|
|
|
|
Color clNewRGB;
|
|
clNewRGB.r = ((float)rand() / (float)RAND_MAX);
|
|
clNewRGB.g = ((float)rand() / (float)RAND_MAX);
|
|
clNewRGB.b = ((float)rand() / (float)RAND_MAX);
|
|
|
|
_aclColorFields.push_back(clNewRGB);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ColorLegend::remove (unsigned long ulPos)
|
|
{
|
|
if (ulPos < _aclColorFields.size())
|
|
{
|
|
_aclColorFields.erase(_aclColorFields.begin() + ulPos);
|
|
_aclNames.erase(_aclNames.begin() + ulPos);
|
|
_aclValues.erase(_aclValues.begin() + ulPos);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void ColorLegend::removeFirst (void)
|
|
{
|
|
if (_aclColorFields.size() > 0)
|
|
{
|
|
_aclColorFields.erase(_aclColorFields.begin());
|
|
_aclNames.erase(_aclNames.begin());
|
|
_aclValues.erase(_aclValues.begin());
|
|
}
|
|
}
|
|
|
|
void ColorLegend::removeLast (void)
|
|
{
|
|
if (_aclColorFields.size() > 0)
|
|
{
|
|
_aclColorFields.erase(_aclColorFields.end()-1);
|
|
_aclNames.erase(_aclNames.end()-1);
|
|
_aclValues.erase(_aclValues.end()-1);
|
|
}
|
|
}
|
|
|
|
void ColorLegend::resize (unsigned long ulCt)
|
|
{
|
|
if ((ulCt < 2) || (ulCt == _aclColorFields.size()))
|
|
return;
|
|
|
|
if (ulCt > _aclColorFields.size())
|
|
{
|
|
int k = ulCt - _aclColorFields.size();
|
|
for (int i = 0; i < k; i++)
|
|
addMin("new");
|
|
}
|
|
else
|
|
{
|
|
int k = _aclColorFields.size() - ulCt;
|
|
for (int i = 0; i < k; i++)
|
|
removeLast();
|
|
}
|
|
}
|
|
|
|
bool ColorLegend::setColor (unsigned long ulPos, float ucRed, float ucGreen, float ucBlue)
|
|
{
|
|
if (ulPos < _aclNames.size())
|
|
{
|
|
_aclColorFields[ulPos] = Color(ucRed, ucGreen, ucBlue);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
// color as 0x00rrggbb
|
|
bool ColorLegend::setColor (unsigned long ulPos, unsigned long ulColor)
|
|
{
|
|
unsigned char ucRed = (unsigned char)((ulColor & 0x00ff0000) >> 16);
|
|
unsigned char ucGreen = (unsigned char)((ulColor & 0x0000ff00) >> 8);
|
|
unsigned char ucBlue = (unsigned char)(ulColor & 0x000000ff);
|
|
return setColor(ulPos, ucRed, ucGreen, ucBlue);
|
|
}
|
|
|
|
bool ColorLegend::setText (unsigned long ulPos, const std::string &rclName)
|
|
{
|
|
if (ulPos < _aclNames.size())
|
|
{
|
|
_aclNames[ulPos] = rclName;
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|