Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -0,0 +1,417 @@
/**
* @RDE_HEADER@
* Class ExtensionRenderer
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "symbol_extension_renderer.h"
#include "sidc_codec.h"
// ESRI
// Qt
#include <QPainter>
#include <iostream>
const double g_factor = 0.95;
namespace AdvancedSymbology
{
QImage ExtensionRenderer::createFullImage(int sizeL, const QColor &fillColor)
{
const int fullSizeW = sizeL * 1.7; // FRIEND 1.5 L
const int fullSizeH = sizeL * 1.7; // try and error: '1.7';
// N. Thoden, 17.03.2020:
// Increase height to 2.2 to avoid FeintDummy (and mobility?) exceeds upper edge.
// But unfortunately then the map_object_custom_view has small icons - :-(
// Stay at 1.7
QImage fullImage(fullSizeW, fullSizeH, QImage::Format_ARGB32);
if (fillColor.isValid())
fullImage.fill(fillColor);
else
fullImage.fill(Qt::transparent);
// for debugging :
if (0)
{
QPainter painter(&fullImage);
QPen pen(Qt::black);
pen.setWidth(2.0);
painter.setPen(pen);
painter.drawRect(fullImage.rect());
}
// : for debugging
return fullImage;
}
void ExtensionRenderer::renderMarking(QImage &fullImage, const QColor &color)
{
QPainter painter(&fullImage);
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
QRect smallerRect(0, 0,
fullImage.width()*g_factor, fullImage.width()*g_factor); // we know, that the fullImage has more height, than width
const QPoint offset(((fullImage.width() - smallerRect.width()) / 2),
((fullImage.height() - smallerRect.height()) / 2));
smallerRect.moveTo(offset);
painter.setPen(QPen(Qt::NoPen)); // rect with no outter line
// maybe: QColor colorWithoutAlpha = color; colorWithoutAlpha.setAlpha(255);
painter.setBrush(QBrush(color, Qt::Dense5Pattern)); // fillPattern (Dense4Pattern .. Dense6Pattern)
painter.drawRect(smallerRect);
painter.end();
}
// hotSpotOfCoreImage - not be finished
QPoint hotSpotOfCoreImage(const QImage &coreImage,
const QString &sidc)
{
int hqFdTf = QString(sidc[7]).toInt();
if ((hqFdTf < 1) || ((hqFdTf > 7)))
return QPoint();
// int identity = QString(sidc[3]).toInt();
// bool taskForce = hqFdTf & 4; // mask
// bool headquarters = hqFdTf & 2; // mask
// bool feintDummy = hqFdTf & 1; // mask
/*
*Identity
Pending, ///< 0
Unknown, ///< 1
AssumedFriend, ///< 2
Friend, ///< 3
Neutral, ///< 4
SuspectJoker, ///< 5
HostileFaker ///< 6
*/
// set x value:
QPoint hotSpot = coreImage.rect().center();
// set y value:
// do not honor the frame (unknown/hostile vs. friend/neutral)
// accept a small error to ease the calculation:
// move hotSpot to bottom -> /
// move hotSpot to top -> *
switch (hqFdTf)
{
case 1:
case 5:
hotSpot.ry() *= 1.3;
break;
case 2:
hotSpot.ry() /= 1.7;
break;
case 3:
case 4:
// empty (it´s not worth)
break;
case 6:
case 7:
case 8:
break;
} // switch
return hotSpot;
}
QVector<QColor> ExtensionRenderer::identityToColor(const QString &sidc)
{
// The following color constants are taken from ArcGis Qt-SDK 10.2.5
const QString &rawSidc = SidcCodec::decodeRawSidc(sidc);
QVector<QColor> colorVec;
colorVec.reserve(2);
if (rawSidc.length() >= 4)
{
const QChar pos2 = rawSidc[1]; // according Mil2525Charlie
const QChar ident = rawSidc[3]; // according Mil2525Delta
// Unknown
if (ident == QLatin1Char('0') ||
ident == QLatin1Char('1') ||
pos2 == QLatin1Char('U') ||
pos2 == QLatin1Char('P') ||
pos2 == QLatin1Char('G') ||
pos2 == QLatin1Char('W')
)
{
colorVec.append(QColor(255, 255, 128));
colorVec.append(QColor(255, 255, 0)); // 10012500002108000000@Mil2525D: color = QColor(255, 255, 0);
// secondary:
colorVec.append(QColor(239, 239, 15)); // SchadMat: 10012500003210000000@MilAPP6D: color = QColor(239, 239, 15) = some kind of yellow
}
// Friend
else if (ident == QLatin1Char('2') ||
ident == QLatin1Char('3') ||
pos2 == QLatin1Char('F') ||
pos2 == QLatin1Char('A') ||
pos2 == QLatin1Char('M') ||
pos2 == QLatin1Char('D')
)
{
colorVec.append(QColor(128, 224, 255));
// secondary:
colorVec.append(QColor(0, 0, 0)); // SchadMat: 10032500003210000000@MilAPP6D: color = QColor(0, 0, 0) = black
}
// Neutral
else if (ident == QLatin1Char('4') ||
pos2 == QLatin1Char('N') ||
pos2 == QLatin1Char('L')
)
{
colorVec.append(QColor(170, 255, 170));
// secondary:
colorVec.append(QColor(0, 255, 0)); // SchadMat: 10042500003210000000@MilAPP6D: color = QColor(0, 0, 0) = some kind of light green
colorVec.append(QColor(85, 255, 0)); // MedVaclandezone?: 10042500003211000000@MilAPP6D: color = QColor(0, 0, 0) = some kind of light green
}
// Hostile
else if (ident == QLatin1Char('5') ||
ident == QLatin1Char('6') ||
pos2 == QLatin1Char('H') ||
pos2 == QLatin1Char('S')
)
{
colorVec.append(QColor(255, 128, 128));
// secondary:
colorVec.append(QColor(255, 0, 0)); // SchadMat: 10062500003210000000@MilAPP6D: color = QColor(255, 0, 0) = red
}
} // if (rawSidc.length() >= 2)
return colorVec;
}
bool ExtensionRenderer::replaceColor(QImage &img,
const QRgb &oldColor,
const QRgb &newColor)
{
#ifdef REPLACE_COLOR_DEBUG
std::cerr << " oldColor=" << oldColor << " newColor=" << newColor << std::endl;
#endif // REPLACE_COLOR_DEBUG
bool modified = false;
if (img.format() != QImage::Format_RGB32 &&
img.format() != QImage::Format_ARGB32)
{
img = img.convertToFormat(QImage::Format_ARGB32);
modified = true;
}
if (oldColor != newColor)
{
int xmax = img.width();
int ymax = img.height();
for (int x = 0; x < xmax; ++x)
{
for (int y = 0; y < ymax; ++y)
{
const QPoint curPixel(x, y);
const QRgb &pixel = img.pixel(curPixel);
if (pixel == oldColor)
{
img.setPixel(curPixel, newColor);
modified = true;
}
} // for
} // for
}
return modified;
}
void ExtensionRenderer::mergeCoreImageIntoFullImage(QImage &fullImage,
const QImage &coreImage)
{
QPainter painter(&fullImage);
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
QPoint offset((fullImage.width() - coreImage.width()) / 2,
(fullImage.height() - coreImage.height()) / 2);
QRect r = coreImage.rect();
r.moveTo(offset);
painter.drawImage(r, coreImage, coreImage.rect());
painter.end();
}
void ExtensionRenderer::renderInjuryAddSymbols(QImage &fullImage,
const Injury &injury,
const QColor &injuryColor,
const AdditionalSymbolTypeCont &additionalSymbols,
const QColor &mainColor)
{
QPainter painter(&fullImage);
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
int width = fullImage.size().width();
// scaled and centered rect;
QRect smallerRect(0, 0,
fullImage.width()*g_factor, fullImage.width()*g_factor); // we know, that the fullImage has more height, than width
const QPoint offset(((fullImage.width() - smallerRect.width()) / 2),
((fullImage.height() - smallerRect.height()) / 2));
smallerRect.moveTo(offset);
//
// handle additionalSymbolType
//
{
int penWidth = width / 25;
for (AdditionalSymbolType additionalSymbolType : additionalSymbols)
{
double dimensionX = smallerRect.size().width(); // small
double dimensionY = fullImage.size().height(); // big
//
// First switch
//
QColor col = Qt::red;
switch (additionalSymbolType)
{
case AdditionalSymbolType::Manipulation:
col = Qt::black;
dimensionY -= penWidth * 2.5;
break;
case AdditionalSymbolType::NoPosition:
col = Qt::red;
dimensionY -= penWidth * 1.5;
break;
case AdditionalSymbolType::BiteError:
col = Qt::yellow;
dimensionY -= penWidth * 0.5;
break;
case AdditionalSymbolType::NbcProtection:
col = mainColor;
break;
} //switch (additionalSymbolType)
//
// Second switch
//
switch (additionalSymbolType)
{
case AdditionalSymbolType::Manipulation:
{
QPen pen(col);
pen.setWidth(penWidth);
double stepWidth = dimensionX / 6.0;
for (int i = 0; i < 6; ++i)
{
if (i % 2)
pen.setColor(Qt::white);
else
pen.setColor(col);
painter.setPen(pen);
painter.drawLine(QPointF(smallerRect.left() + stepWidth * i, dimensionY),
QPointF(smallerRect.left() + stepWidth * (i + 1), dimensionY));
}
}
break;
case AdditionalSymbolType::BiteError:
case AdditionalSymbolType::NoPosition:
{
QPen pen(col);
pen.setWidth(penWidth);
painter.setPen(pen);
painter.drawLine(QPointF(smallerRect.left(), dimensionY),
QPointF(smallerRect.right(), dimensionY));
}
break;
case AdditionalSymbolType::NbcProtection:
{
int y = (penWidth / 2.0) + (width * 0.01);
QPen pen(col);
pen.setWidth(penWidth);
painter.setPen(pen);
painter.drawLine(QPointF(smallerRect.left(), y),
QPointF(smallerRect.center().x() - (width * 0.1), y));
}
} // switch
} // for
} // additionalSymbolType
//
// handle injury
//
{
int penWidth = width / 20;
QPen pen(injuryColor);
pen.setWidth(penWidth);
painter.setPen(pen);
// handle injury {Hit, MobilityKill, WeaponKill, TotalKill}
switch (injury)
{
case AdvancedSymbology::Injury::Hit:
{
QPoint left(smallerRect.left(), fullImage.height() / 2);
QPoint right(smallerRect.right(), fullImage.height() / 2);
painter.drawLine(left, right);
}
break;
case AdvancedSymbology::Injury::MobilityKill:
painter.drawLine(smallerRect.topLeft(), smallerRect.bottomRight());
break;
case AdvancedSymbology::Injury::WeaponKill:
painter.drawLine(smallerRect.bottomLeft(), smallerRect.topRight());
break;
case AdvancedSymbology::Injury::TotalKill:
painter.drawLine(smallerRect.topLeft(), smallerRect.bottomRight());
painter.drawLine(smallerRect.bottomLeft(), smallerRect.topRight());
break;
case AdvancedSymbology::Injury::NoInjury:
break;
} // switch
} // injury
painter.end();
}
} // namespace AdvancedSymbology