// +-------------------------------- DISCLAIMER ---------------------------------+ // | | // | This application program is provided to you free of charge as an example. | // | Despite the considerable efforts of Euresys personnel to create a usable | // | example, you should not assume that this program is error-free or suitable | // | for any purpose whatsoever. | // | | // | EURESYS does not give any representation, warranty or undertaking that this | // | program is free of any defect or error or suitable for any purpose. EURESYS | // | shall not be liable, in contract, in torts or otherwise, for any damages, | // | loss, costs, expenses or other claims for compensation, including those | // | asserted by third parties, arising out of or in connection with the use of | // | this program. | // +-----------------------------------------------------------------------------+ #pragma once #include "EasyImage_22_12.h" #include #include namespace Euresys { namespace Open_eVision_22_12 { class QtDrawAdapter : public EExternalDrawAdapter { const float f32Pi = 3.14159265358979323846264338327950288f; class PenHandler { QPen oldPen_; QPainter* painter_; public: PenHandler(QPainter* painter, QPen pen) { painter_ = painter; oldPen_ = painter_->pen(); painter_->setPen(pen); } ~PenHandler() { painter_->setPen(oldPen_); } }; class BrushHandler { QBrush oldBrush_; QPainter* painter_; public: BrushHandler(QPainter* painter, QBrush brush) { painter_ = painter; oldBrush_ = painter_->brush(); painter_->setBrush(brush); } ~BrushHandler() { painter_->setBrush(oldBrush_); } }; class FontHandler { QFont oldFont_; QPainter* painter_; public: FontHandler(QPainter* painter, QFont font) { painter_ = painter; oldFont_ = painter_->font(); painter_->setFont(font); } ~FontHandler() { painter_->setFont(oldFont_); } }; public: QtDrawAdapter(QPainter* painter); virtual ~QtDrawAdapter() {} void DrawPoint(int x1, int y1, EPen* pen) { PenHandler handler(painter_, pen ? ConvertPen(*pen) : defaultPen_); painter_->drawPoint(x1, y1); } void Line(int x1, int y1, int x2, int y2, EPen* pen) { PenHandler handler(painter_, pen ? ConvertPen(*pen) : defaultPen_); painter_->drawLine(x1, y1, x2, y2); } void Arc(int orgX, int orgY, int width, int height, float startAngle, float amplitude, EPen* pen) { PenHandler handler(painter_, pen ? ConvertPen(*pen) : defaultPen_); startAngle = -startAngle * 180.f / f32Pi; amplitude = -amplitude * 180.f / f32Pi; // Qt requires angles specified in 1/16th of a degree (i.e. a full circle equals 16*360=5760) painter_->drawArc(orgX, orgY, width, height, static_cast(std::round(16 * startAngle)), static_cast(std::round(16 * amplitude))); } void Rectangle(int orgX, int orgY, int width, int height, EPen* pen) { PenHandler handler(painter_, pen ? ConvertPen(*pen) : defaultPen_); painter_->drawRect(orgX, orgY, width, height); } void Polygon(const float* points, int numPoints, EPen* pen) { PenHandler handler(painter_, pen ? ConvertPen(*pen) : defaultPen_); std::vector qtPoints(numPoints); for (int i = 0; i < numPoints; i++) { qtPoints[i].setX(points[2*i]); qtPoints[i].setY(points[2*i+1]); } painter_->drawPolygon(qtPoints.data(), static_cast(qtPoints.size())); } void Ellipse(int orgX, int orgY, int width, int height, EPen* pen) { PenHandler handler(painter_, pen ? ConvertPen(*pen) : defaultPen_); painter_->drawEllipse(orgX, orgY, width, height); } void FilledRectangle(int orgX, int orgY, int width, int height, EPen* pen, EBrush* brush) { PenHandler penHandler(painter_, pen ? ConvertPen(*pen) : defaultPen_); BrushHandler brushHandler(painter_, brush ? ConvertBrush(*brush) : defaultBrush_); painter_->drawRect(orgX, orgY, width, height); } void FilledEllipse(int orgX, int orgY, int width, int height, EPen* pen, EBrush* brush) { PenHandler penHandler(painter_, pen ? ConvertPen(*pen) : defaultPen_); BrushHandler brushHandler(painter_, brush ? ConvertBrush(*brush) : defaultBrush_); painter_->drawEllipse(orgX, orgY, width, height); } void FilledPolygon(const float* points, int numPoints, EPen* pen, EBrush* brush) { PenHandler penHandler(painter_, pen ? ConvertPen(*pen) : defaultPen_); BrushHandler brushHandler(painter_, brush ? ConvertBrush(*brush) : defaultBrush_); std::vector qtPoints(numPoints); for (int i = 0; i < numPoints; i++) { qtPoints[i].setX(points[2*i]); qtPoints[i].setY(points[2*i+1]); } painter_->drawPolygon(qtPoints.data(), static_cast(qtPoints.size())); } void Text(const char* text, int x, int y, float orientation, EBrush* textBrush) { FontHandler fontHandler(painter_, defaultFont_); QPen qtTextPen; if (textBrush) qtTextPen.setBrush(ConvertBrush(*textBrush)); else qtTextPen = defaultPen_; PenHandler textColorHandler(painter_, qtTextPen); float width, height; GetTextSize(text, &width, &height); painter_->save(); painter_->translate(QPointF(x, y)); painter_->rotate(-orientation * 180.f / f32Pi); painter_->drawText(0, 0, width, height, 0, QString::fromStdString(text)); painter_->restore(); } void BackedText(const char* text, int x, int y, float orientation, EBrush* textBrush, EBrush* backgroundBrush) { FontHandler fontHandler(painter_, defaultFont_); QPen qtTextPen; if (textBrush) qtTextPen.setBrush(ConvertBrush(*textBrush)); else qtTextPen = defaultPen_; PenHandler textColorHandler(painter_, qtTextPen); float width, height; GetTextSize(text, &width, &height); QBrush qtBrush = backgroundBrush ? ConvertBrush(*backgroundBrush) : defaultBrush_; painter_->save(); painter_->translate(QPointF(x, y)); painter_->rotate(-orientation * 180.f / f32Pi); painter_->fillRect(QRectF(0, 0, width, height), qtBrush); painter_->drawText(0, 0, width, height, 0, QString::fromStdString(text)); painter_->restore(); } void Image(void* imagePtr, int imageType, int imageWidth, int imageHeight, int imagePitch, float orgX, float orgY, float width, float height) { if (!imagePtr) return; painter_->drawImage(QRectF(orgX, orgY, width, height), ConvertImage(imagePtr, imageType, imageWidth, imageHeight, imagePitch)); } void ImageWithC24ColorScale(void* imagePtr, int imageType, int imageWidth, int imageHeight, int imagePitch, const void* colorScale, int numScale, float orgX, float orgY, float width, float height) { if (!imagePtr) return; painter_->drawImage(QRectF(orgX, orgY, width, height), ConvertImageC24ColorScale(imagePtr, imageType, imageWidth, imageHeight, imagePitch, colorScale, numScale)); } void ImageWithBW8ColorScale(void* imagePtr, int imageType, int imageWidth, int imageHeight, int imagePitch, const void* colorScale, int numScale, float orgX, float orgY, float width, float height) { if (!imagePtr) return; painter_->drawImage(QRectF(orgX, orgY, width, height), ConvertImageBW8ColorScale(imagePtr, imageType, imageWidth, imageHeight, imagePitch, colorScale, numScale)); } void GetTextSize(const char* text, float* width, float* height) { FontHandler fontHandler(painter_, defaultFont_); QRect bbox = painter_->boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignLeft, QString::fromStdString(text)); *width = bbox.width(); *height = bbox.height(); } void GetExtent(int* orgX, int* orgY, int* width, int* height) { QRect rect = painter_->window(); *orgX = rect.left(); *orgY = rect.top(); *width = rect.width(); *height = rect.height(); } void UseCurrentPen() { QPen qtPen = painter_->pen(); QBrush qtBrush = qtPen.brush(); EPen pen; switch (qtPen.style()) { default: case Qt::SolidLine: pen.Style = EPenStyle_Solid; break; case Qt::DashLine: pen.Style = EPenStyle_Dash; break; case Qt::DashDotLine: pen.Style = EPenStyle_DashDot; break; case Qt::DashDotDotLine: pen.Style = EPenStyle_DashDotDot; break; case Qt::DotLine: pen.Style = EPenStyle_Dot; break; } pen.Brush.Color = ERGBColor(qtBrush.color().red(), qtBrush.color().green(), qtBrush.color().blue()); pen.Brush.Opacity = qtBrush.color().alphaF(); EExternalDrawAdapter::SetPen(pen); } void UseCurrentBrush() { QBrush qtBrush = painter_->brush(); EBrush brush; brush.Color = ERGBColor(qtBrush.color().red(), qtBrush.color().green(), qtBrush.color().blue()); brush.Opacity = qtBrush.color().alphaF(); EExternalDrawAdapter::SetBrush(brush); } void SetPenInternal(EPen* pen) { defaultPen_ = ConvertPen(*pen); } void SetBrushInternal(EBrush* brush) { defaultBrush_ = ConvertBrush(*brush); } void SetFontInternal(const char* fontName, int fontSize, int fontStyle) { defaultFont_.setFamily(fontName); defaultFont_.setPointSizeF(fontSize); switch (fontStyle) { default: case EFontStyle_Regular: break; case EFontStyle_Bold: defaultFont_.setBold(true); break; case EFontStyle_BoldItalic: defaultFont_.setBold(true); defaultFont_.setItalic(true); break; case EFontStyle_Italic: defaultFont_.setItalic(true); break; case EFontStyle_Strikeout: defaultFont_.setStrikeOut(true); break; case EFontStyle_Underline: defaultFont_.setUnderline(true); break; } } static QImage ConvertImageC24ColorScale(void* imagePtr, int imageType, int imageWidth, int imageHeight, int imagePitch, const void* colorScale, int numScale) { QVector colors; if (colorScale) { for (int i = 0; i < numScale; i++) { EC24 c = reinterpret_cast(colorScale)[i]; colors.push_back(qRgb(c.C0, c.C1, c.C2)); } } return ConvertImage(imagePtr, imageType, imageWidth, imageHeight, imagePitch, colors); } static QImage ConvertImageBW8ColorScale(void* imagePtr, int imageType, int imageWidth, int imageHeight, int imagePitch, const void* colorScale, int numScale) { QVector colors; if (colorScale) { for (int i = 0; i < numScale; i++) { EBW8 c = reinterpret_cast(colorScale)[i]; colors.push_back(qRgb(c.Value, c.Value, c.Value)); } } return ConvertImage(imagePtr, imageType, imageWidth, imageHeight, imagePitch, colors); } static QImage ConvertImage(void* imagePtr, int imageType, int imageWidth, int imageHeight, int imagePitch, const QVector& colors = QVector()) { QImage qtImage; switch (imageType) { case EImageType_BW1: qtImage = QImage((const uchar*)imagePtr, imageWidth, imageHeight, imagePitch, QImage::Format_Mono); break; case EImageType_BW8: qtImage = QImage((const uchar*)imagePtr, imageWidth, imageHeight, imagePitch, colors.size() > 0 ? QImage::Format_Indexed8 : QImage::Format_Grayscale8); break; case EImageType_BW16: { qtImage = QImage(imageWidth, imageHeight, colors.size() > 0 ? QImage::Format_Indexed8 : QImage::Format_Grayscale8); EImageBW16 src; src.SetImagePtr(imageWidth, imageHeight, imagePtr, imagePitch * 8); EImageBW8 dst; dst.SetImagePtr(imageWidth, imageHeight, qtImage.scanLine(0), qtImage.bytesPerLine() * 8); // Convert the image to BW8 EasyImage::Convert(&src, &dst); break; } case EImageType_BW32: { qtImage = QImage(imageWidth, imageHeight, colors.size() > 0 ? QImage::Format_Indexed8 : QImage::Format_Grayscale8); EImageBW32 src; src.SetImagePtr(imageWidth, imageHeight, imagePtr, imagePitch * 8); EImageBW8 dst; dst.SetImagePtr(imageWidth, imageHeight, qtImage.scanLine(0), qtImage.bytesPerLine() * 8); // Convert the image to BW8 EasyImage::Convert(&src, &dst); break; } case EImageType_C15: qtImage = QImage((const uchar*)imagePtr, imageWidth, imageHeight, imagePitch, QImage::Format_RGB555); qtImage = qtImage.rgbSwapped(); break; case EImageType_C16: qtImage = QImage((const uchar*)imagePtr, imageWidth, imageHeight, imagePitch, QImage::Format_RGB16); qtImage = qtImage.rgbSwapped(); break; case EImageType_C24: qtImage = QImage((const uchar*)imagePtr, imageWidth, imageHeight, imagePitch, QImage::Format_RGB888); qtImage = qtImage.rgbSwapped(); break; case EImageType_C24A: qtImage = QImage((const uchar*)imagePtr, imageWidth, imageHeight, imagePitch, QImage::Format_RGBA8888); qtImage = qtImage.rgbSwapped(); break; case EImageType_C48: { qtImage = QImage(imageWidth, imageHeight, QImage::Format_RGB888); EImageC48 src; src.SetImagePtr(imageWidth, imageHeight, imagePtr, imagePitch * 8); EImageC24 dst; dst.SetImagePtr(imageWidth, imageHeight, qtImage.scanLine(0), qtImage.bytesPerLine() * 8); // Convert the image to C24 EasyImage::Convert(&src, &dst); qtImage = qtImage.rgbSwapped(); break; } default: throw EException(EError_NotImplemented); } if (colors.size() > 0) qtImage.setColorTable(colors); return qtImage; } static QPen ConvertPen(EPen pen) { QPen qtPen; qtPen.setWidth(pen.Width); if (pen.Brush.Color.Red >= 0) qtPen.setColor(QColor(pen.Brush.Color.Red, pen.Brush.Color.Green, pen.Brush.Color.Blue, static_cast(255.f * pen.Brush.Opacity))); switch (pen.Style) { default: case EPenStyle_Solid: qtPen.setStyle(Qt::SolidLine); break; case EPenStyle_Dash: qtPen.setStyle(Qt::DashLine); break; case EPenStyle_DashDot: qtPen.setStyle(Qt::DashDotLine); break; case EPenStyle_DashDotDot: qtPen.setStyle(Qt::DashDotDotLine); break; case EPenStyle_Dot: qtPen.setStyle(Qt::DotLine); break; } return qtPen; } static QBrush ConvertBrush(EBrush brush) { QBrush qtBrush(Qt::SolidPattern); if (brush.Color.Red >= 0) qtBrush.setColor(QColor(brush.Color.Red, brush.Color.Green, brush.Color.Blue, static_cast(255.f * brush.Opacity))); return qtBrush; } private: QPainter* painter_; QPen defaultPen_; QBrush defaultBrush_; QFont defaultFont_; }; void QtDrawPoint(void* adapter, int x, int y, void* pen) { reinterpret_cast(adapter)->DrawPoint(x, y, reinterpret_cast(pen)); } void QtLine(void* adapter, int x1, int y1, int x2, int y2, void* pen) { reinterpret_cast(adapter)->Line(x1, y1, x2, y2, reinterpret_cast(pen)); } void QtArc(void* adapter, int orgX, int orgY, int width, int height, float startAngle, float amplitude, void* pen) { reinterpret_cast(adapter)->Arc(orgX, orgY, width, height, startAngle, amplitude, reinterpret_cast(pen)); } void QtRectangle(void* adapter, int orgX, int orgY, int width, int height, void* pen) { reinterpret_cast(adapter)->Rectangle(orgX, orgY, width, height, reinterpret_cast(pen)); } void QtEllipse(void* adapter, int orgX, int orgY, int width, int height, void* pen) { reinterpret_cast(adapter)->Ellipse(orgX, orgY, width, height, reinterpret_cast(pen)); } void QtPolygon(void* adapter, const float* points, int numPoints, void* pen) { reinterpret_cast(adapter)->Polygon(points, numPoints, reinterpret_cast(pen)); } void QtFillRectangle(void* adapter, int orgX, int orgY, int width, int height, void* pen, void* brush) { reinterpret_cast(adapter)->FilledRectangle(orgX, orgY, width, height, reinterpret_cast(pen), reinterpret_cast(brush)); } void QtFillEllipse(void* adapter, int orgX, int orgY, int width, int height, void* pen, void* brush) { reinterpret_cast(adapter)->FilledEllipse(orgX, orgY, width, height, reinterpret_cast(pen), reinterpret_cast(brush)); } void QtFillPolygon(void* adapter, const float* points, int numPoints, void* pen, void* brush) { reinterpret_cast(adapter)->FilledPolygon(points, numPoints, reinterpret_cast(pen), reinterpret_cast(brush)); } void QtText(void* adapter, const char* text, int x, int y, float orientation, void* textBrush) { reinterpret_cast(adapter)->Text(text, x, y, orientation, reinterpret_cast(textBrush)); } void QtBackedText(void* adapter, const char* text, int x, int y, float orientation, void* textBrush, void* backgroundBrush) { reinterpret_cast(adapter)->BackedText(text, x, y, orientation, reinterpret_cast(textBrush), reinterpret_cast(backgroundBrush)); } void QtImage(void* adapter, void* imagePtr, int imageType, int imageWidth, int imageHeight, int imagePitch, float orgX, float orgY, float width, float height) { reinterpret_cast(adapter)->Image(imagePtr, imageType, imageWidth, imageHeight, imagePitch, orgX, orgY, width, height); } void QtImageWithColorScale(void* adapter, void* imagePtr, int imageType, int imageWidth, int imageHeight, int imagePitch, const void* colorScale, int numScale, float orgX, float orgY, float width, float height) { reinterpret_cast(adapter)->ImageWithC24ColorScale(imagePtr, imageType, imageWidth, imageHeight, imagePitch, colorScale, numScale, orgX, orgY, width, height); } void QtImageWithGrayscaleScale(void* adapter, void* imagePtr, int imageType, int imageWidth, int imageHeight, int imagePitch, const void* colorScale, int numScale, float orgX, float orgY, float width, float height) { reinterpret_cast(adapter)->ImageWithBW8ColorScale(imagePtr, imageType, imageWidth, imageHeight, imagePitch, colorScale, numScale, orgX, orgY, width, height); } void QtGetTextSize(void* adapter, const char* text, float* width, float* height) { reinterpret_cast(adapter)->GetTextSize(text, width, height); } void QtGetExtent(void* adapter, int* orgX, int* orgY, int* width, int* height) { reinterpret_cast(adapter)->GetExtent(orgX, orgY, width, height); } void QtUseCurrentPen(void* adapter) { reinterpret_cast(adapter)->UseCurrentPen(); } void QtUseCurrentBrush(void* adapter) { reinterpret_cast(adapter)->UseCurrentBrush(); } void QtSetPen(void* adapter, void* pen) { reinterpret_cast(adapter)->SetPenInternal(reinterpret_cast(pen)); } void QtSetBrush(void* adapter, void* brush) { reinterpret_cast(adapter)->SetBrushInternal(reinterpret_cast(brush)); } void QtSetFont(void* adapter, char* fontName, int fontSize, int fontStyle) { reinterpret_cast(adapter)->SetFontInternal(fontName, fontSize, fontStyle); } inline QtDrawAdapter::QtDrawAdapter(QPainter* painter): EExternalDrawAdapter(this), painter_(painter) { static bool initialized = false; if (!initialized) { SetDrawPointFunctionPtr(reinterpret_cast(&QtDrawPoint)); SetLineFunctionPtr(reinterpret_cast(&QtLine)); SetArcFunctionPtr(reinterpret_cast(&QtArc)); SetRectangleFunctionPtr(reinterpret_cast(&QtRectangle)); SetPolygonFunctionPtr(reinterpret_cast(&QtPolygon)); SetEllipseFunctionPtr(reinterpret_cast(&QtEllipse)); SetFillRectangleFunctionPtr(reinterpret_cast(&QtFillRectangle)); SetFillEllipseFunctionPtr(reinterpret_cast(&QtFillEllipse)); SetFillPolygonFunctionPtr(reinterpret_cast(&QtFillPolygon)); SetTextFunctionPtr(reinterpret_cast(&QtText)); SetBackedTextFunctionPtr(reinterpret_cast(&QtBackedText)); SetImageFunctionPtr(reinterpret_cast(&QtImage)); SetImageWithColorScaleFunctionPtr(reinterpret_cast(&QtImageWithColorScale)); SetImageWithGrayscaleScaleFunctionPtr(reinterpret_cast(&QtImageWithGrayscaleScale)); SetGetTextSizeFunctionPtr(reinterpret_cast(&QtGetTextSize)); SetGetExtentFunctionPtr(reinterpret_cast(&QtGetExtent)); SetUseCurrentPenFunctionPtr(reinterpret_cast(&QtUseCurrentPen)); SetUseCurrentBrushFunctionPtr(reinterpret_cast(&QtUseCurrentBrush)); SetSetPenFunctionPtr(reinterpret_cast(&QtSetPen)); SetSetBrushFunctionPtr(reinterpret_cast(&QtSetBrush)); SetSetFontFunctionPtr(reinterpret_cast(&QtSetFont)); } } } }