C

Qt Quick Ultralite 绘制项示例

/****************************************************************************** ** ** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Quick Ultralite module. ** ** $QT_BEGIN_LICENSE:COMM$ ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** $QT_END_LICENSE$ ** ******************************************************************************/
#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); }