qt 6.5.1 original

This commit is contained in:
kleuter
2023-10-29 23:33:08 +01:00
parent 71d22ab6b0
commit 85d238dfda
21202 changed files with 5499099 additions and 0 deletions

View File

@ -0,0 +1,102 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(deform LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/painting/deform")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(deform
main.cpp
pathdeform.cpp pathdeform.h
)
set_target_properties(deform PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
if(NOT TARGET painting_shared::painting_shared)
include(../shared/use_lib.cmake)
endif()
target_link_libraries(deform PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
painting_shared::painting_shared
)
# Resources:
set(shared_resource_files
"../shared/images/button_normal_cap_left.png"
"../shared/images/button_normal_cap_right.png"
"../shared/images/button_normal_stretch.png"
"../shared/images/button_pressed_cap_left.png"
"../shared/images/button_pressed_cap_right.png"
"../shared/images/button_pressed_stretch.png"
"../shared/images/frame_bottom.png"
"../shared/images/frame_bottomleft.png"
"../shared/images/frame_bottomright.png"
"../shared/images/frame_left.png"
"../shared/images/frame_right.png"
"../shared/images/frame_top.png"
"../shared/images/frame_topleft.png"
"../shared/images/frame_topright.png"
"../shared/images/groupframe_bottom_left.png"
"../shared/images/groupframe_bottom_right.png"
"../shared/images/groupframe_bottom_stretch.png"
"../shared/images/groupframe_left_stretch.png"
"../shared/images/groupframe_right_stretch.png"
"../shared/images/groupframe_top_stretch.png"
"../shared/images/groupframe_topleft.png"
"../shared/images/groupframe_topright.png"
"../shared/images/line_dash_dot.png"
"../shared/images/line_dash_dot_dot.png"
"../shared/images/line_dashed.png"
"../shared/images/line_dotted.png"
"../shared/images/line_solid.png"
"../shared/images/radiobutton-on.png"
"../shared/images/radiobutton_off.png"
"../shared/images/radiobutton_on.png"
"../shared/images/slider_bar.png"
"../shared/images/slider_thumb_on.png"
"../shared/images/title_cap_left.png"
"../shared/images/title_cap_right.png"
"../shared/images/title_stretch.png"
)
qt_add_resources(deform "shared"
PREFIX
"/res"
BASE
"../shared"
FILES
${shared_resource_files}
)
set(deform_resource_files
"pathdeform.cpp"
"pathdeform.html"
)
qt_add_resources(deform "deform"
PREFIX
"/res/deform"
FILES
${deform_resource_files}
)
install(TARGETS deform
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -0,0 +1,14 @@
SOURCES += main.cpp pathdeform.cpp
HEADERS += pathdeform.h
SHARED_FOLDER = ../shared
include($$SHARED_FOLDER/shared.pri)
RESOURCES += deform.qrc
QT += widgets
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/painting/deform
INSTALLS += target

View File

@ -0,0 +1,6 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/res/deform">
<file>pathdeform.cpp</file>
<file>pathdeform.html</file>
</qresource>
</RCC>

View File

@ -0,0 +1,33 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "pathdeform.h"
#include <QApplication>
int main(int argc, char **argv)
{
Q_INIT_RESOURCE(deform);
QApplication app(argc, argv);
bool smallScreen = QApplication::arguments().contains("-small-screen");
PathDeformWidget deformWidget(nullptr, smallScreen);
QStyle *arthurStyle = new ArthurStyle;
deformWidget.setStyle(arthurStyle);
const QList<QWidget *> widgets = deformWidget.findChildren<QWidget *>();
for (QWidget *w : widgets)
w->setStyle(arthurStyle);
if (smallScreen)
deformWidget.showFullScreen();
else
deformWidget.show();
#ifdef QT_KEYPAD_NAVIGATION
QApplication::setNavigationMode(Qt::NavigationModeCursorAuto);
#endif
return app.exec();
}

View File

@ -0,0 +1,596 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "pathdeform.h"
#include <QGuiApplication>
#include <QScreen>
#include <QtDebug>
#include <QMouseEvent>
#include <QTimerEvent>
#include <QLayout>
#include <QLineEdit>
#include <QPainter>
#include <QSlider>
#include <QLabel>
#include <qmath.h>
PathDeformControls::PathDeformControls(QWidget *parent,
PathDeformRenderer* renderer, bool smallScreen)
: QWidget(parent)
{
m_renderer = renderer;
if (smallScreen)
layoutForSmallScreen();
else
layoutForDesktop();
}
void PathDeformControls::layoutForDesktop()
{
QGroupBox* mainGroup = new QGroupBox(this);
mainGroup->setTitle(tr("Controls"));
QGroupBox *radiusGroup = new QGroupBox(mainGroup);
radiusGroup->setTitle(tr("Lens Radius"));
QSlider *radiusSlider = new QSlider(Qt::Horizontal, radiusGroup);
radiusSlider->setRange(15, 150);
radiusSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
QGroupBox *deformGroup = new QGroupBox(mainGroup);
deformGroup->setTitle(tr("Deformation"));
QSlider *deformSlider = new QSlider(Qt::Horizontal, deformGroup);
deformSlider->setRange(-100, 100);
deformSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
QGroupBox *fontSizeGroup = new QGroupBox(mainGroup);
fontSizeGroup->setTitle(tr("Font Size"));
QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, fontSizeGroup);
fontSizeSlider->setRange(16, 200);
fontSizeSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
QGroupBox *textGroup = new QGroupBox(mainGroup);
textGroup->setTitle(tr("Text"));
QLineEdit *textInput = new QLineEdit(textGroup);
QPushButton *animateButton = new QPushButton(mainGroup);
animateButton->setText(tr("Animated"));
animateButton->setCheckable(true);
QPushButton *showSourceButton = new QPushButton(mainGroup);
showSourceButton->setText(tr("Show Source"));
#if QT_CONFIG(opengl)
QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
enableOpenGLButton->setText(tr("Use OpenGL"));
enableOpenGLButton->setCheckable(true);
enableOpenGLButton->setChecked(m_renderer->usesOpenGL());
#endif
QPushButton *whatsThisButton = new QPushButton(mainGroup);
whatsThisButton->setText(tr("What's This?"));
whatsThisButton->setCheckable(true);
mainGroup->setFixedWidth(180);
QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
mainGroupLayout->addWidget(radiusGroup);
mainGroupLayout->addWidget(deformGroup);
mainGroupLayout->addWidget(fontSizeGroup);
mainGroupLayout->addWidget(textGroup);
mainGroupLayout->addWidget(animateButton);
mainGroupLayout->addStretch(1);
#if QT_CONFIG(opengl)
mainGroupLayout->addWidget(enableOpenGLButton);
#endif
mainGroupLayout->addWidget(showSourceButton);
mainGroupLayout->addWidget(whatsThisButton);
QVBoxLayout *radiusGroupLayout = new QVBoxLayout(radiusGroup);
radiusGroupLayout->addWidget(radiusSlider);
QVBoxLayout *deformGroupLayout = new QVBoxLayout(deformGroup);
deformGroupLayout->addWidget(deformSlider);
QVBoxLayout *fontSizeGroupLayout = new QVBoxLayout(fontSizeGroup);
fontSizeGroupLayout->addWidget(fontSizeSlider);
QVBoxLayout *textGroupLayout = new QVBoxLayout(textGroup);
textGroupLayout->addWidget(textInput);
QVBoxLayout * mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(mainGroup);
mainLayout->setContentsMargins(QMargins());
connect(radiusSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setRadius);
connect(deformSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setIntensity);
connect(fontSizeSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setFontSize);
connect(animateButton, &QAbstractButton::clicked, m_renderer, &PathDeformRenderer::setAnimated);
#if QT_CONFIG(opengl)
connect(enableOpenGLButton, &QAbstractButton::clicked, m_renderer, &ArthurFrame::enableOpenGL);
#endif
connect(textInput, &QLineEdit::textChanged, m_renderer, &PathDeformRenderer::setText);
connect(m_renderer, &ArthurFrame::descriptionEnabledChanged,
whatsThisButton, &QAbstractButton::setChecked);
connect(whatsThisButton, &QAbstractButton::clicked, m_renderer, &ArthurFrame::setDescriptionEnabled);
connect(showSourceButton, &QAbstractButton::clicked, m_renderer, &ArthurFrame::showSource);
animateButton->animateClick();
deformSlider->setValue(80);
fontSizeSlider->setValue(120);
radiusSlider->setValue(100);
textInput->setText(tr("Qt"));
}
void PathDeformControls::layoutForSmallScreen()
{
QGroupBox* mainGroup = new QGroupBox(this);
mainGroup->setTitle(tr("Controls"));
QLabel *radiusLabel = new QLabel(mainGroup);
radiusLabel->setText(tr("Lens Radius:"));
QSlider *radiusSlider = new QSlider(Qt::Horizontal, mainGroup);
radiusSlider->setRange(15, 150);
radiusSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
QLabel *deformLabel = new QLabel(mainGroup);
deformLabel->setText(tr("Deformation:"));
QSlider *deformSlider = new QSlider(Qt::Horizontal, mainGroup);
deformSlider->setRange(-100, 100);
deformSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
QLabel *fontSizeLabel = new QLabel(mainGroup);
fontSizeLabel->setText(tr("Font Size:"));
QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, mainGroup);
fontSizeSlider->setRange(16, 200);
fontSizeSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
QPushButton *animateButton = new QPushButton(tr("Animated"), mainGroup);
animateButton->setCheckable(true);
#if QT_CONFIG(opengl)
QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
enableOpenGLButton->setText(tr("Use OpenGL"));
enableOpenGLButton->setCheckable(mainGroup);
enableOpenGLButton->setChecked(m_renderer->usesOpenGL());
#endif
QPushButton *quitButton = new QPushButton(tr("Quit"), mainGroup);
QPushButton *okButton = new QPushButton(tr("OK"), mainGroup);
QGridLayout *mainGroupLayout = new QGridLayout(mainGroup);
mainGroupLayout->setContentsMargins(QMargins());
mainGroupLayout->addWidget(radiusLabel, 0, 0, Qt::AlignRight);
mainGroupLayout->addWidget(radiusSlider, 0, 1);
mainGroupLayout->addWidget(deformLabel, 1, 0, Qt::AlignRight);
mainGroupLayout->addWidget(deformSlider, 1, 1);
mainGroupLayout->addWidget(fontSizeLabel, 2, 0, Qt::AlignRight);
mainGroupLayout->addWidget(fontSizeSlider, 2, 1);
mainGroupLayout->addWidget(animateButton, 3,0, 1,2);
#if QT_CONFIG(opengl)
mainGroupLayout->addWidget(enableOpenGLButton, 4,0, 1,2);
#endif
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(mainGroup);
mainLayout->addStretch(1);
mainLayout->addWidget(okButton);
mainLayout->addWidget(quitButton);
connect(quitButton, &QAbstractButton::clicked, this, &PathDeformControls::quitPressed);
connect(okButton, &QAbstractButton::clicked, this, &PathDeformControls::okPressed);
connect(radiusSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setRadius);
connect(deformSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setIntensity);
connect(fontSizeSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setFontSize);
connect(animateButton, &QAbstractButton::clicked, m_renderer, &PathDeformRenderer::setAnimated);
#if QT_CONFIG(opengl)
connect(enableOpenGLButton, &QAbstractButton::clicked, m_renderer, &ArthurFrame::enableOpenGL);
#endif
animateButton->animateClick();
deformSlider->setValue(80);
fontSizeSlider->setValue(120);
QRect screen_size = QGuiApplication::primaryScreen()->geometry();
radiusSlider->setValue(qMin(screen_size.width(), screen_size.height())/5);
m_renderer->setText(tr("Qt"));
}
PathDeformWidget::PathDeformWidget(QWidget *parent, bool smallScreen)
: QWidget(parent)
{
setWindowTitle(tr("Vector Deformation"));
m_renderer = new PathDeformRenderer(this, smallScreen);
m_renderer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
// Layouts
QHBoxLayout *mainLayout = new QHBoxLayout(this);
mainLayout->addWidget(m_renderer);
m_controls = new PathDeformControls(nullptr, m_renderer, smallScreen);
m_controls->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
if (!smallScreen)
mainLayout->addWidget(m_controls);
m_renderer->loadSourceFile(":res/deform/pathdeform.cpp");
m_renderer->loadDescription(":res/deform/pathdeform.html");
m_renderer->setDescriptionEnabled(false);
connect(m_renderer, &PathDeformRenderer::clicked,
this, &PathDeformWidget::showControls);
connect(m_controls, &PathDeformControls::okPressed,
this, &PathDeformWidget::hideControls);
connect(m_controls, &PathDeformControls::quitPressed,
qApp, &QCoreApplication::quit);
}
void PathDeformWidget::showControls()
{
m_controls->showFullScreen();
}
void PathDeformWidget::hideControls()
{
m_controls->hide();
}
void PathDeformWidget::setStyle(QStyle *style)
{
QWidget::setStyle(style);
if (!m_controls)
return;
m_controls->setStyle(style);
const QList<QWidget *> widgets = m_controls->findChildren<QWidget *>();
for (QWidget *w : widgets)
w->setStyle(style);
}
static inline QRect circle_bounds(const QPointF &center, qreal radius, qreal compensation)
{
return QRect(qRound(center.x() - radius - compensation),
qRound(center.y() - radius - compensation),
qRound((radius + compensation) * 2),
qRound((radius + compensation) * 2));
}
const int LENS_EXTENT = 10;
PathDeformRenderer::PathDeformRenderer(QWidget *widget, bool smallScreen)
: ArthurFrame(widget)
{
m_radius = 100;
m_pos = QPointF(m_radius, m_radius);
m_direction = QPointF(1, 1);
m_fontSize = 24;
m_animated = true;
m_repaintTimer.start(25, this);
m_repaintTracker.start();
m_intensity = 100;
m_smallScreen = smallScreen;
// m_fpsTimer.start(1000, this);
// m_fpsCounter = 0;
generateLensPixmap();
}
void PathDeformRenderer::setText(const QString &text)
{
m_text = text;
QFont f("times new roman,utopia");
f.setStyleStrategy(QFont::ForceOutline);
f.setPointSize(m_fontSize);
f.setStyleHint(QFont::Times);
QFontMetrics fm(f);
m_paths.clear();
m_pathBounds = QRect();
QPointF advance(0, 0);
bool do_quick = true;
for (int i=0; i<text.size(); ++i) {
if (text.at(i).unicode() >= 0x4ff && text.at(i).unicode() <= 0x1e00) {
do_quick = false;
break;
}
}
if (do_quick) {
for (int i=0; i<text.size(); ++i) {
QPainterPath path;
path.addText(advance, f, text.mid(i, 1));
m_pathBounds |= path.boundingRect();
m_paths << path;
advance += QPointF(fm.horizontalAdvance(text.mid(i, 1)), 0);
}
} else {
QPainterPath path;
path.addText(advance, f, text);
m_pathBounds |= path.boundingRect();
m_paths << path;
}
for (int i=0; i<m_paths.size(); ++i)
m_paths[i] = m_paths[i] * QTransform(1, 0, 0, 1, -m_pathBounds.x(), -m_pathBounds.y());
update();
}
void PathDeformRenderer::generateLensPixmap()
{
qreal rad = m_radius + LENS_EXTENT;
QRect bounds = circle_bounds(QPointF(), rad, 0);
QPainter painter;
if (preferImage()) {
m_lens_image = QImage(bounds.size(), QImage::Format_ARGB32_Premultiplied);
m_lens_image.fill(0);
painter.begin(&m_lens_image);
} else {
m_lens_pixmap = QPixmap(bounds.size());
m_lens_pixmap.fill(Qt::transparent);
painter.begin(&m_lens_pixmap);
}
QRadialGradient gr(rad, rad, rad, 3 * rad / 5, 3 * rad / 5);
gr.setColorAt(0.0, QColor(255, 255, 255, 191));
gr.setColorAt(0.2, QColor(255, 255, 127, 191));
gr.setColorAt(0.9, QColor(150, 150, 200, 63));
gr.setColorAt(0.95, QColor(0, 0, 0, 127));
gr.setColorAt(1, QColor(0, 0, 0, 0));
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(gr);
painter.setPen(Qt::NoPen);
painter.drawEllipse(0, 0, bounds.width(), bounds.height());
}
void PathDeformRenderer::setAnimated(bool animated)
{
m_animated = animated;
if (m_animated) {
// m_fpsTimer.start(1000, this);
// m_fpsCounter = 0;
m_repaintTimer.start(25, this);
m_repaintTracker.start();
} else {
// m_fpsTimer.stop();
m_repaintTimer.stop();
}
}
void PathDeformRenderer::timerEvent(QTimerEvent *e)
{
if (e->timerId() == m_repaintTimer.timerId()) {
if (QLineF(QPointF(0,0), m_direction).length() > 1)
m_direction *= 0.995;
qreal time = m_repaintTracker.restart();
QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize);
qreal dx = m_direction.x();
qreal dy = m_direction.y();
if (time > 0) {
dx = dx * time * .1;
dy = dy * time * .1;
}
m_pos += QPointF(dx, dy);
if (m_pos.x() - m_radius < 0) {
m_direction.setX(-m_direction.x());
m_pos.setX(m_radius);
} else if (m_pos.x() + m_radius > width()) {
m_direction.setX(-m_direction.x());
m_pos.setX(width() - m_radius);
}
if (m_pos.y() - m_radius < 0) {
m_direction.setY(-m_direction.y());
m_pos.setY(m_radius);
} else if (m_pos.y() + m_radius > height()) {
m_direction.setY(-m_direction.y());
m_pos.setY(height() - m_radius);
}
#if QT_CONFIG(opengl)
if (usesOpenGL()) {
update();
} else
#endif
{
QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize);
update(rectAfter | rectBefore);
}
}
// else if (e->timerId() == m_fpsTimer.timerId()) {
// printf("fps: %d\n", m_fpsCounter);
// emit frameRate(m_fpsCounter);
// m_fpsCounter = 0;
// }
}
void PathDeformRenderer::mousePressEvent(QMouseEvent *e)
{
if (m_showDoc) {
setDescriptionEnabled(false);
return;
}
setDescriptionEnabled(false);
m_repaintTimer.stop();
m_offset = QPointF();
if (QLineF(m_pos, e->position().toPoint()).length() <= m_radius)
m_offset = m_pos - e->position().toPoint();
m_mousePress = e->position().toPoint();
// If we're not running in small screen mode, always assume we're dragging
m_mouseDrag = !m_smallScreen;
mouseMoveEvent(e);
}
void PathDeformRenderer::mouseReleaseEvent(QMouseEvent *e)
{
if (e->buttons() == Qt::NoButton && m_animated) {
m_repaintTimer.start(10, this);
m_repaintTracker.start();
}
if (!m_mouseDrag && m_smallScreen)
emit clicked();
}
void PathDeformRenderer::mouseMoveEvent(QMouseEvent *e)
{
if (!m_mouseDrag && (QLineF(m_mousePress, e->position().toPoint()).length() > 25.0) )
m_mouseDrag = true;
if (m_mouseDrag) {
QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize);
if (e->type() == QEvent::MouseMove) {
QLineF line(m_pos, e->position().toPoint() + m_offset);
line.setLength(line.length() * .1);
QPointF dir(line.dx(), line.dy());
m_direction = (m_direction + dir) / 2;
}
m_pos = e->position().toPoint() + m_offset;
#if QT_CONFIG(opengl)
if (usesOpenGL()) {
update();
} else
#endif
{
QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize);
update(rectBefore | rectAfter);
}
}
}
QPainterPath PathDeformRenderer::lensDeform(const QPainterPath &source, const QPointF &offset)
{
QPainterPath path;
path.addPath(source);
qreal flip = m_intensity / qreal(100);
for (int i=0; i<path.elementCount(); ++i) {
const QPainterPath::Element &e = path.elementAt(i);
qreal x = e.x + offset.x();
qreal y = e.y + offset.y();
qreal dx = x - m_pos.x();
qreal dy = y - m_pos.y();
qreal len = m_radius - qSqrt(dx * dx + dy * dy);
if (len > 0) {
path.setElementPositionAt(i,
x + flip * dx * len / m_radius,
y + flip * dy * len / m_radius);
} else {
path.setElementPositionAt(i, x, y);
}
}
return path;
}
void PathDeformRenderer::paint(QPainter *painter)
{
int pad_x = 5;
int pad_y = 5;
int skip_x = qRound(m_pathBounds.width() + pad_x + m_fontSize/2);
int skip_y = qRound(m_pathBounds.height() + pad_y);
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::black);
QRectF clip(painter->clipPath().boundingRect());
int overlap = pad_x / 2;
for (int start_y=0; start_y < height(); start_y += skip_y) {
if (start_y > clip.bottom())
break;
int start_x = -overlap;
for (; start_x < width(); start_x += skip_x) {
if (start_y + skip_y >= clip.top() &&
start_x + skip_x >= clip.left() &&
start_x <= clip.right()) {
for (int i=0; i<m_paths.size(); ++i) {
QPainterPath path = lensDeform(m_paths[i], QPointF(start_x, start_y));
painter->drawPath(path);
}
}
}
overlap = skip_x - (start_x - width());
}
if (preferImage()) {
painter->drawImage(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT),
m_lens_image);
} else {
painter->drawPixmap(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT),
m_lens_pixmap);
}
}
void PathDeformRenderer::setRadius(int radius)
{
qreal max = qMax(m_radius, (qreal)radius);
m_radius = radius;
generateLensPixmap();
if (!m_animated || m_radius < max) {
#if QT_CONFIG(opengl)
if (usesOpenGL()){
update();
return;
}
#endif
update(circle_bounds(m_pos, max, m_fontSize));
}
}
void PathDeformRenderer::setIntensity(int intensity)
{
m_intensity = intensity;
if (!m_animated) {
#if QT_CONFIG(opengl)
if (usesOpenGL()) {
update();
return;
}
#endif
update(circle_bounds(m_pos, m_radius, m_fontSize));
}
}

View File

@ -0,0 +1,112 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef PATHDEFORM_H
#define PATHDEFORM_H
#include "arthurwidgets.h"
#include <QBasicTimer>
#include <QElapsedTimer>
#include <QPainterPath>
class PathDeformRenderer : public ArthurFrame
{
Q_OBJECT
Q_PROPERTY(bool animated READ animated WRITE setAnimated)
Q_PROPERTY(int radius READ radius WRITE setRadius)
Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize)
Q_PROPERTY(int intensity READ intensity WRITE setIntensity)
Q_PROPERTY(QString text READ text WRITE setText)
public:
explicit PathDeformRenderer(QWidget *widget, bool smallScreen = false);
void paint(QPainter *painter) override;
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void timerEvent(QTimerEvent *e) override;
QSize sizeHint() const override { return QSize(600, 500); }
bool animated() const { return m_animated; }
int radius() const { return int(m_radius); }
int fontSize() const { return m_fontSize; }
int intensity() const { return int(m_intensity); }
QString text() const { return m_text; }
public slots:
void setRadius(int radius);
void setFontSize(int fontSize) { m_fontSize = fontSize; setText(m_text); }
void setText(const QString &text);
void setIntensity(int intensity);
void setAnimated(bool animated);
signals:
void clicked();
// void frameRate(double fps);
private:
void generateLensPixmap();
QPainterPath lensDeform(const QPainterPath &source, const QPointF &offset);
QBasicTimer m_repaintTimer;
// QBasicTimer m_fpsTimer;
// int m_fpsCounter;
QElapsedTimer m_repaintTracker;
QList<QPainterPath> m_paths;
QList<QPointF> m_advances;
QRectF m_pathBounds;
QString m_text;
QPixmap m_lens_pixmap;
QImage m_lens_image;
int m_fontSize;
bool m_animated;
qreal m_intensity;
qreal m_radius;
QPointF m_pos;
QPointF m_offset;
QPointF m_direction;
QPointF m_mousePress;
bool m_mouseDrag;
bool m_smallScreen;
};
class PathDeformControls : public QWidget
{
Q_OBJECT
public:
PathDeformControls(QWidget *parent, PathDeformRenderer* renderer, bool smallScreen);
signals:
void okPressed();
void quitPressed();
private:
PathDeformRenderer *m_renderer;
void layoutForDesktop();
void layoutForSmallScreen();
};
class PathDeformWidget : public QWidget
{
Q_OBJECT
public:
PathDeformWidget(QWidget *parent, bool smallScreen);
void setStyle(QStyle *style);
private:
PathDeformRenderer *m_renderer;
PathDeformControls *m_controls;
private slots:
void showControls();
void hideControls();
};
#endif // PATHDEFORM_H

View File

@ -0,0 +1,24 @@
<html>
<center>
<h2>Vector deformation</h2>
</center>
<p>This demo shows how to use advanced vector techniques to draw text
using a <code>QPainterPath</code>.</p>
<p>We define a vector deformation field in the shape of a lens and apply
this to all points in a path. This means that what is rendered on
screen is not pixel manipulation, but modified vector representations of
the glyphs themselves. This is visible from the high quality of the
antialiased edges for the deformed glyphs.</p>
<p>To get a fairly complex path we allow the user to type in text and
convert the text to paths. This is done using the
<code>QPainterPath::addText()</code> function.</p>
<p>The lens is drawn using a single call to <code>drawEllipse()</code>, using
a <code>QRadialGradient</code> to fill it with a specialized color table,
giving the effect of the Sun's reflection and a drop shadow. The lens
is cached as a pixmap for better performance.</p>
</html>