commit 4e84c35a098b31b1f33d24d995e0edbe4dadf974
parent a4b06f3b8834a13806dee0eefb8616d8ae29c318
Author: falkTX <falktx@falktx.com>
Date: Sat, 22 May 2021 03:00:04 +0100
Implement CairoImageKnob rotation
Diffstat:
3 files changed, 41 insertions(+), 20 deletions(-)
diff --git a/dgl/src/Cairo.cpp b/dgl/src/Cairo.cpp
@@ -413,8 +413,26 @@ void CairoImage::loadFromMemory(const char* const rdata, const Size<uint>& s, co
}
break;
case kImageFormatBGRA:
- // RGB8 to CAIRO_FORMAT_ARGB32
- // TODO
+ // BGRA8 to CAIRO_FORMAT_ARGB32
+ // FIXME something is wrong here...
+ for (uint h = 0, t; h < height; ++h)
+ {
+ for (uint w = 0; w < width; ++w)
+ {
+ if ((t = rdata[h*width*4+w*4+3]) != 0)
+ {
+ newdata[h*width*4+w*4+0] = rdata[h*width*4+w*4+0];
+ newdata[h*width*4+w*4+1] = rdata[h*width*4+w*4+1];
+ newdata[h*width*4+w*4+2] = rdata[h*width*4+w*4+2];
+ newdata[h*width*4+w*4+3] = t;
+ }
+ else
+ {
+ // make all pixels zero, cairo does not render full transparency otherwise
+ memset(&newdata[h*width*4+w*4], 0, 4);
+ }
+ }
+ }
break;
case kImageFormatRGB:
// RGB8 to CAIRO_FORMAT_RGB24
@@ -564,14 +582,13 @@ template class ImageBaseButton<CairoImage>;
template <>
void ImageBaseKnob<CairoImage>::PrivateData::init()
{
- // new (&cairoDisplayImage) CairoImage();
+ alwaysRepaint = true;
cairoSurface = nullptr;
}
template <>
void ImageBaseKnob<CairoImage>::PrivateData::cleanup()
{
- // cairoDisplayImage.~CairoImage();
cairo_surface_destroy((cairo_surface_t*)cairoSurface);
cairoSurface = nullptr;
}
@@ -644,24 +661,25 @@ void ImageBaseKnob<CairoImage>::onDisplay()
const uint layerX = pData->isImgVertical ? 0 : layerNum * layerW;
const uint layerY = !pData->isImgVertical ? 0 : layerNum * layerH;
- cairo_surface_t* const newsurface = getRegion(pData->image.getSurface(), layerX, layerY, layerW, layerH);
- DISTRHO_SAFE_ASSERT_RETURN(newsurface != nullptr,);
+ cairo_surface_t* newsurface;
- if (pData->rotationAngle != 0)
+ if (pData->rotationAngle == 0)
+ {
+ newsurface = getRegion(pData->image.getSurface(), layerX, layerY, layerW, layerH);
+ }
+ else
{
- // TODO
- /*
- CairoImage rotated(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, layerW, layerH), false);
- cairo_t* cr = cairo_create(rotated.getSurface());
+ newsurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, layerW, layerH);
+ cairo_t* const cr = cairo_create(newsurface);
cairo_translate(cr, 0.5 * layerW, 0.5 * layerH);
- cairo_rotate(cr, normValue * angle * (float)(M_PI / 180));
- cairo_set_source_surface(cr, displayImage.getSurface(), -0.5f * layerW, -0.5f * layerH);
+ cairo_rotate(cr, normValue * pData->rotationAngle * (float)(M_PI / 180));
+ cairo_set_source_surface(cr, pData->image.getSurface(), -0.5f * layerW, -0.5f * layerH);
cairo_paint(cr);
cairo_destroy(cr);
- pData->cairoDisplayImage = rotated;
- */
}
+ DISTRHO_SAFE_ASSERT_RETURN(newsurface != nullptr,);
+
cairo_surface_destroy(surface);
pData->cairoSurface = surface = newsurface;
pData->isReady = true;
diff --git a/dgl/src/Common.hpp b/dgl/src/Common.hpp
@@ -140,6 +140,7 @@ struct ImageBaseKnob<ImageType>::PrivateData {
Callback* callback;
+ bool alwaysRepaint;
bool isImgVertical;
uint imgLayerWidth;
uint imgLayerHeight;
@@ -148,7 +149,6 @@ struct ImageBaseKnob<ImageType>::PrivateData {
union {
uint glTextureId;
- // ImageType cairoDisplayImage;
void* cairoSurface;
};
diff --git a/dgl/src/ImageBaseWidgets.cpp b/dgl/src/ImageBaseWidgets.cpp
@@ -204,6 +204,7 @@ ImageBaseKnob<ImageType>::PrivateData::PrivateData(const ImageType& img, const O
lastX(0),
lastY(0),
callback(nullptr),
+ alwaysRepaint(false),
isImgVertical(img.getHeight() > img.getWidth()),
imgLayerWidth(isImgVertical ? img.getWidth() : img.getHeight()),
imgLayerHeight(imgLayerWidth),
@@ -230,6 +231,7 @@ ImageBaseKnob<ImageType>::PrivateData::PrivateData(PrivateData* const other)
lastX(0),
lastY(0),
callback(other->callback),
+ alwaysRepaint(other->alwaysRepaint),
isImgVertical(other->isImgVertical),
imgLayerWidth(other->imgLayerWidth),
imgLayerHeight(other->imgLayerHeight),
@@ -258,11 +260,12 @@ void ImageBaseKnob<ImageType>::PrivateData::assignFrom(PrivateData* const other)
lastX = 0;
lastY = 0;
callback = other->callback;
+ alwaysRepaint = other->alwaysRepaint;
isImgVertical = other->isImgVertical;
imgLayerWidth = other->imgLayerWidth;
imgLayerHeight = other->imgLayerHeight;
imgLayerCount = other->imgLayerCount;
- isReady = false;
+ isReady = false;
init();
}
@@ -364,7 +367,7 @@ void ImageBaseKnob<ImageType>::setValue(float value, bool sendCallback) noexcept
if (d_isZero(pData->step))
pData->valueTmp = value;
- if (pData->rotationAngle == 0)
+ if (pData->rotationAngle == 0 || pData->alwaysRepaint)
pData->isReady = false;
repaint();
@@ -755,8 +758,8 @@ void ImageBaseSlider<ImageType>::onDisplay()
{
const GraphicsContext& context(getGraphicsContext());
-#if 1 // DEBUG, paints slider area
- Color(0.4f, 0.5f, 0.1f).setFor(context);
+#if 0 // DEBUG, paints slider area
+ Color(1.0f, 1.0f, 1.0f, 0.5f).setFor(context, true);
Rectangle<int>(pData->sliderArea.getX(),
pData->sliderArea.getY(),
pData->sliderArea.getX()+pData->sliderArea.getWidth(),