C
Qt Quick Ultralite painteditem Example
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
#include "oscPaintedItem.h"
#include <cstring>
#include <memory>
#include <cassert>
#include <platforminterface/drawingengine.h>
#include <qul/painteditemdelegate.h>
const double FACTOR_DEGREE_TO_RAD = 0.0174533;
static uint16_t convertRgb32To16(uint32_t c)
{
return (((c) >> 3) & 0x001f) | (((c) >> 5) & 0x07e0) | (((c) >> 8) & 0xf800);
}
void pixelBlend(Qul::PlatformInterface::DrawingDevice *device,
const Qul::PlatformInterface::Rect &clip,
int x,
int y,
Qul::PlatformInterface::Rgba32 color)
{
assert(device->bitsPerPixel() % 8 == 0);
if (!clip.contains(x, y)) {
return;
}
uchar *d = device->bits() + (x * device->bitsPerPixel() >> 3) + y * device->bytesPerLine();
if (16 == device->bitsPerPixel()) {
uint16_t valRgb565;
valRgb565 = convertRgb32To16(color.value);
d[1] = (uint8_t) ((valRgb565 & 0xff00) >> 8);
d[0] = (uint8_t) (valRgb565 & 0x00ff);
} else {
//Written for ARM. For different architecture, endianess has to be taken into considered.
d[2] = (uint8_t) color.red();
d[1] = (uint8_t) color.green();
d[0] = (uint8_t) color.blue();
}
}
void OscillatorPaintedItem::paintCurvePath(Qul::PlatformInterface::DrawingDevice *device,
const Qul::PlatformInterface::Rect &clip,
const Qul::PlatformInterface::Transform &transform,
Qul::PlatformInterface::Point focus,
int radius,
uint16_t startAngle,
uint16_t endAngle,
Qul::PlatformInterface::Rgba32 color) const
{
uint16_t angleInDegress = 0;
for (angleInDegress = startAngle; angleInDegress <= endAngle; angleInDegress++) {
Qul::PlatformInterface::PointF pos;
pos.setX(radius * std::cos(FACTOR_DEGREE_TO_RAD * angleInDegress) + focus.x());
pos.setY(radius * std::sin(FACTOR_DEGREE_TO_RAD * angleInDegress) + focus.y());
const Qul::PlatformInterface::Point rounded = transform.map(pos).toPoint();
pixelBlend(device, clip, rounded.x(), rounded.y(), color);
}
}
void OscillatorPaintedItem::paintBlob(Qul::PlatformInterface::DrawingDevice *device,
const Qul::PlatformInterface::Rect &clip,
Qul::PlatformInterface::Point center,
int radius,
Qul::PlatformInterface::Rgba32 color) const
{
int angleInDegress = 0;
Qul::PlatformInterface::Point pos;
for (angleInDegress = 0; angleInDegress < 360; angleInDegress++) {
pos.setX(static_cast<int>(radius * std::cos(FACTOR_DEGREE_TO_RAD * angleInDegress) + center.x()));
pos.setY(static_cast<int>(radius * std::sin(FACTOR_DEGREE_TO_RAD * angleInDegress) + center.y()));
pixelBlend(device, clip, pos.x(), pos.y(), color);
}
}
Qul::PlatformInterface::Rect OscillatorPaintedItem::boundingRect(Qul::PlatformInterface::Size size) const
{
return Qul::PlatformInterface::Rect(0, 0, size.width(), size.height());
}
void OscillatorPaintedItem::paint(Qul::PlatformInterface::DrawingDevice *device,
const Qul::PlatformInterface::Rect &clip,
const Qul::PlatformInterface::Transform &transform,
Qul::PlatformInterface::Size size,
float opacity) const
{
QUL_UNUSED(opacity);
static Qul::PlatformInterface::Rgba32 color(static_cast<uint32_t>(0),
static_cast<uint32_t>(0),
static_cast<uint32_t>(0),
static_cast<uint32_t>(255));
/* Focus of the circular arc is at the center of the bounding rectangle of the painted item */
Qul::PlatformInterface::PointF focus(size.width() / 2, size.height() / 2);
device->drawingEngine()->synchronizeForCpuAccess(device, clip);
/*Paint the curve with its center at middle of the screen
with arc ranging from 30 to 150 degrees*/
uint16_t curveRadius = (size.width() / 2) - 10;
color.setRed(0);
color.setGreen(0);
color.setBlue(9);
paintCurvePath(device, clip, transform, focus.toPoint(), curveRadius, 30, 150, color);
/* Paint the blob of radius 20.
Blob center is offset to 20 (equal to radius) to appear above the curve */
uint16_t blobRadius = 20;
Qul::PlatformInterface::PointF blobCenter;
blobCenter.setX((curveRadius - blobRadius) * ::cosf(FACTOR_DEGREE_TO_RAD * angle.value()) + focus.x());
blobCenter.setY((curveRadius - blobRadius) * ::sinf(FACTOR_DEGREE_TO_RAD * angle.value()) + focus.y());
blobCenter = transform.map(blobCenter);
color.setRed(0);
color.setGreen(0);
color.setBlue(255);
paintBlob(device, clip, blobCenter.toPoint(), blobRadius, color);
}