Merge "Merge remote-tracking branch 'origin/dev' into wip/cmake" into wip/cmake

This commit is contained in:
The Qt Project 2020-02-12 08:47:47 +00:00
commit f4a52b79ce
213 changed files with 12055 additions and 12788 deletions
config_help.txtconfigureconfigure.bat
examples
network/multicastsender
opengl/qopenglwidget
widgets
animation/easing
desktop/screenshot
graphicsview/embeddeddialogs
itemviews/pixelator
painting
basicdrawing
imagecomposition
painterpaths
transformations
richtext
tools
codecs
completer
regularexpression
settingseditor
treemodelcompleter
undo
widgets
mkspecs
qmake
src

View File

@ -320,6 +320,6 @@ Gui, printing, widget options:
Database options:
-sql-<driver> ........ Enable SQL <driver> plugin. Supported drivers:
db2 ibase mysql oci odbc psql sqlite2 sqlite tds
db2 ibase mysql oci odbc psql sqlite
[all auto]
-sqlite .............. Select used sqlite3 [system/qt]
-sqlite .............. Select used sqlite [system/qt]

4
configure vendored
View File

@ -831,14 +831,14 @@ fi
echo "########################################################################" > "$mkfile"
echo "## This file was autogenerated by configure, all changes will be lost ##" >> "$mkfile"
echo "########################################################################" >> "$mkfile"
EXTRA_CXXFLAGS="\$(QMAKE_CXXFLAGS) \$(QMAKE_CXXFLAGS_CXX11) \$(QMAKE_CXXFLAGS_SPLIT_SECTIONS)"
EXTRA_CXXFLAGS="\$(QMAKE_CXXFLAGS) \$(QMAKE_CXXFLAGS_CXX1Z) \$(QMAKE_CXXFLAGS_SPLIT_SECTIONS)"
EXTRA_LFLAGS="\$(QMAKE_LFLAGS) \$(QMAKE_LFLAGS_GCSECTIONS)"
[ "$CFG_SILENT" = "yes" ] && CC_TRANSFORM='s,^,\@,' || CC_TRANSFORM=
setBootstrapVariable QMAKE_CC CC "$CC_TRANSFORM"
setBootstrapVariable QMAKE_CXX CXX "$CC_TRANSFORM"
setBootstrapVariable QMAKE_CXXFLAGS
setBootstrapVariable QMAKE_CXXFLAGS_CXX11
setBootstrapVariable QMAKE_CXXFLAGS_CXX1Z
setBootstrapVariable QMAKE_CXXFLAGS_SPLIT_SECTIONS
setBootstrapVariable QMAKE_LFLAGS
setBootstrapVariable QMAKE_LFLAGS_GCSECTIONS

View File

@ -261,7 +261,7 @@ if "%tmpl%" == "win32" (
echo QMAKESPEC = %PLATFORM%>> Makefile
) else (
echo QMAKESPEC = $^(SOURCE_PATH^)/mkspecs/%PLATFORM%>> Makefile
echo CONFIG_CXXFLAGS = -std=c++11 -ffunction-sections>> Makefile
echo CONFIG_CXXFLAGS = -std=c++17 -ffunction-sections>> Makefile
echo CONFIG_LFLAGS = -Wl,--gc-sections>> Makefile
type "%QTSRC%\qmake\Makefile.unix.win32" >> Makefile
type "%QTSRC%\qmake\Makefile.unix.mingw" >> Makefile

View File

@ -81,7 +81,7 @@ Sender::Sender(QWidget *parent)
buttonBox->addButton(startButton, QDialogButtonBox::ActionRole);
buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);
connect(ttlSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, &Sender::ttlChanged);
connect(ttlSpinBox, &QSpinBox::valueChanged, this, &Sender::ttlChanged);
connect(startButton, &QPushButton::clicked, this, &Sender::startSending);
connect(quitButton, &QPushButton::clicked, this, &Sender::close);
connect(&timer, &QTimer::timeout, this, &Sender::sendDatagram);

View File

@ -134,7 +134,7 @@ MainWindow::MainWindow()
connect(slider, &QAbstractSlider::valueChanged, glwidget, &GLWidget::setScaling);
connect(transparent, &QCheckBox::toggled, glwidget, &GLWidget::setTransparent);
connect(updateInterval, QOverload<int>::of(&QSpinBox::valueChanged),
connect(updateInterval, &QSpinBox::valueChanged,
this, &MainWindow::updateIntervalChanged);
connect(timerBased, &QCheckBox::toggled, this, &MainWindow::timerUsageChanged);
connect(timerBased, &QCheckBox::toggled, updateInterval, &QWidget::setEnabled);

View File

@ -67,13 +67,13 @@ Window::Window(QWidget *parent)
connect(m_ui.easingCurvePicker, &QListWidget::currentRowChanged,
this, &Window::curveChanged);
connect(m_ui.buttonGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked),
connect(m_ui.buttonGroup, &QButtonGroup::buttonClicked,
this, &Window::pathChanged);
connect(m_ui.periodSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
connect(m_ui.periodSpinBox, &QDoubleSpinBox::valueChanged,
this, &Window::periodChanged);
connect(m_ui.amplitudeSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
connect(m_ui.amplitudeSpinBox, &QDoubleSpinBox::valueChanged,
this, &Window::amplitudeChanged);
connect(m_ui.overshootSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
connect(m_ui.overshootSpinBox, &QDoubleSpinBox::valueChanged,
this, &Window::overshootChanged);
createCurveIcons();

View File

@ -70,7 +70,7 @@ Screenshot::Screenshot()
delaySpinBox->setSuffix(tr(" s"));
delaySpinBox->setMaximum(60);
connect(delaySpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(delaySpinBox, &QSpinBox::valueChanged,
this, &Screenshot::updateCheckBox);
hideThisWindowCheckBox = new QCheckBox(tr("Hide This Window"), optionsGroupBox);

View File

@ -67,7 +67,7 @@ EmbeddedDialog::EmbeddedDialog(QWidget *parent)
ui->style->setCurrentIndex(ui->style->count() - 1);
}
connect(ui->layoutDirection, QOverload<int>::of(&QComboBox::activated),
connect(ui->layoutDirection, &QComboBox::activated,
this, &EmbeddedDialog::layoutDirectionChanged);
connect(ui->spacing, &QSlider::valueChanged,
this, &EmbeddedDialog::spacingChanged);

View File

@ -116,9 +116,9 @@ MainWindow::MainWindow()
connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
connect(aboutAction, &QAction::triggered, this, &MainWindow::showAboutBox);
//! [4]
connect(pixelSizeSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(pixelSizeSpinBox, &QSpinBox::valueChanged,
delegate, &PixelDelegate::setPixelSize);
connect(pixelSizeSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(pixelSizeSpinBox, &QSpinBox::valueChanged,
this, &MainWindow::updateView);
//! [4]

View File

@ -157,17 +157,17 @@ Window::Window()
//! [7]
//! [8]
connect(shapeComboBox, QOverload<int>::of(&QComboBox::activated),
connect(shapeComboBox, &QComboBox::activated,
this, &Window::shapeChanged);
connect(penWidthSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(penWidthSpinBox, &QSpinBox::valueChanged,
this, &Window::penChanged);
connect(penStyleComboBox, QOverload<int>::of(&QComboBox::activated),
connect(penStyleComboBox, &QComboBox::activated,
this, &Window::penChanged);
connect(penCapComboBox, QOverload<int>::of(&QComboBox::activated),
connect(penCapComboBox, &QComboBox::activated,
this, &Window::penChanged);
connect(penJoinComboBox, QOverload<int>::of(&QComboBox::activated),
connect(penJoinComboBox, &QComboBox::activated,
this, &Window::penChanged);
connect(brushStyleComboBox, QOverload<int>::of(&QComboBox::activated),
connect(brushStyleComboBox, &QComboBox::activated,
this, &Window::brushChanged);
connect(antialiasingCheckBox, &QAbstractButton::toggled,
renderArea, &RenderArea::setAntialiased);

View File

@ -102,7 +102,7 @@ ImageComposer::ImageComposer()
//! [3]
connect(sourceButton, &QAbstractButton::clicked,
this, &ImageComposer::chooseSource);
connect(operatorComboBox, QOverload<int>::of(&QComboBox::activated),
connect(operatorComboBox, &QComboBox::activated,
this, &ImageComposer::recalculateResult);
connect(destinationButton, &QAbstractButton::clicked,
this, &ImageComposer::chooseDestination);

View File

@ -194,19 +194,19 @@ Window::Window()
//! [12]
//! [16]
connect(fillRuleComboBox, QOverload<int>::of(&QComboBox::activated),
connect(fillRuleComboBox, &QComboBox::activated,
this, &Window::fillRuleChanged);
connect(fillColor1ComboBox, QOverload<int>::of(&QComboBox::activated),
connect(fillColor1ComboBox, &QComboBox::activated,
this, &Window::fillGradientChanged);
connect(fillColor2ComboBox, QOverload<int>::of(&QComboBox::activated),
connect(fillColor2ComboBox, &QComboBox::activated,
this, &Window::fillGradientChanged);
connect(penColorComboBox, QOverload<int>::of(&QComboBox::activated),
connect(penColorComboBox, &QComboBox::activated,
this, &Window::penColorChanged);
for (RenderArea *area : qAsConst(renderAreas)) {
connect(penWidthSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(penWidthSpinBox, &QSpinBox::valueChanged,
area, &RenderArea::setPenWidth);
connect(rotationAngleSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(rotationAngleSpinBox, &QSpinBox::valueChanged,
area, &RenderArea::setRotationAngle);
}

View File

@ -79,7 +79,7 @@ Window::Window()
operationComboBoxes[i]->addItem(tr("Scale to 75%"));
operationComboBoxes[i]->addItem(tr("Translate by (50, 50)"));
connect(operationComboBoxes[i], QOverload<int>::of(&QComboBox::activated),
connect(operationComboBoxes[i], &QComboBox::activated,
this, &Window::operationChanged);
layout->addWidget(transformedRenderAreas[i], 0, i + 1);
@ -159,7 +159,7 @@ void Window::setupShapes()
shapes.append(text);
shapes.append(truck);
connect(shapeComboBox, QOverload<int>::of(&QComboBox::activated),
connect(shapeComboBox, &QComboBox::activated,
this, &Window::shapeSelected);
}
//! [7]

View File

@ -86,11 +86,11 @@ MainWindow::MainWindow()
//! [2]
//! [3]
connect(monthCombo, QOverload<int>::of(&QComboBox::activated),
connect(monthCombo, &QComboBox::activated,
this, &MainWindow::setMonth);
connect(yearEdit, &QDateTimeEdit::dateChanged,
this, &MainWindow::setYear);
connect(fontSizeSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(fontSizeSpinBox, &QSpinBox::valueChanged,
this, &MainWindow::setFontSize);
//! [3]

View File

@ -389,7 +389,7 @@ void TextEdit::setupTextActions()
comboStyle->addItem("Heading 5");
comboStyle->addItem("Heading 6");
connect(comboStyle, QOverload<int>::of(&QComboBox::activated), this, &TextEdit::textStyle);
connect(comboStyle, &QComboBox::activated, this, &TextEdit::textStyle);
comboFont = new QFontComboBox(tb);
tb->addWidget(comboFont);

View File

@ -167,7 +167,7 @@ PreviewForm::PreviewForm(QWidget *parent)
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
okButton = buttonBox->button(QDialogButtonBox::Ok);
connect(encodingComboBox, QOverload<int>::of(&QComboBox::activated),
connect(encodingComboBox, &QComboBox::activated,
this, &PreviewForm::updateTextEdit);
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);

View File

@ -117,13 +117,13 @@ MainWindow::MainWindow(QWidget *parent)
contentsLabel = new QLabel;
contentsLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
connect(modelCombo, QOverload<int>::of(&QComboBox::activated),
connect(modelCombo, &QComboBox::activated,
this, &MainWindow::changeModel);
connect(modeCombo, QOverload<int>::of(&QComboBox::activated),
connect(modeCombo, &QComboBox::activated,
this, &MainWindow::changeMode);
connect(caseCombo, QOverload<int>::of(&QComboBox::activated),
connect(caseCombo, &QComboBox::activated,
this, &MainWindow::changeCase);
connect(maxVisibleSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(maxVisibleSpinBox, &QSpinBox::valueChanged,
this, &MainWindow::changeMaxVisible);
//! [2]

View File

@ -222,7 +222,7 @@ RegularExpressionDialog::RegularExpressionDialog(QWidget *parent)
connect(optimizeOnFirstUsageOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh);
connect(dontAutomaticallyOptimizeOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh);
connect(offsetSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(offsetSpinBox, &QSpinBox::valueChanged,
this, &RegularExpressionDialog::refresh);
connect(matchTypeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),

View File

@ -115,9 +115,9 @@ LocationDialog::LocationDialog(QWidget *parent)
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(formatComboBox, QOverload<int>::of(&QComboBox::activated),
connect(formatComboBox, &QComboBox::activated,
this, &LocationDialog::updateLocationsTable);
connect(scopeComboBox, QOverload<int>::of(&QComboBox::activated),
connect(scopeComboBox, &QComboBox::activated,
this, &LocationDialog::updateLocationsTable);
connect(organizationComboBox->lineEdit(),
&QLineEdit::editingFinished,
@ -125,7 +125,7 @@ LocationDialog::LocationDialog(QWidget *parent)
connect(applicationComboBox->lineEdit(),
&QLineEdit::editingFinished,
this, &LocationDialog::updateLocationsTable);
connect(applicationComboBox, QOverload<int>::of(&QComboBox::activated),
connect(applicationComboBox, &QComboBox::activated,
this, &LocationDialog::updateLocationsTable);
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);

View File

@ -126,9 +126,9 @@ MainWindow::MainWindow(QWidget *parent)
//! [1]
//! [2]
connect(modeCombo, QOverload<int>::of(&QComboBox::activated),
connect(modeCombo, &QComboBox::activated,
this, &MainWindow::changeMode);
connect(caseCombo, QOverload<int>::of(&QComboBox::activated),
connect(caseCombo, &QComboBox::activated,
this, &MainWindow::changeMode);
lineEdit = new QLineEdit;

View File

@ -86,7 +86,7 @@ MainWindow::MainWindow(QWidget *parent)
connect(actionAbout, &QAction::triggered, this, &MainWindow::about);
connect(actionAboutQt, &QAction::triggered, this, &MainWindow::aboutQt);
connect(undoLimit, QOverload<int>::of(&QSpinBox::valueChanged), this, &MainWindow::updateActions);
connect(undoLimit, &QSpinBox::valueChanged, this, &MainWindow::updateActions);
connect(documentTabs, &QTabWidget::currentChanged, this, &MainWindow::updateActions);
actionOpen->setShortcut(QString("Ctrl+O"));

View File

@ -70,7 +70,7 @@ QWidget *ImageDelegate::createEditor(QWidget *parent,
else if (index.column() == 2)
comboBox->addItems(IconPreviewArea::iconStateNames());
connect(comboBox, QOverload<int>::of(&QComboBox::activated),
connect(comboBox, &QComboBox::activated,
this, &ImageDelegate::emitCommitData);
return comboBox;

View File

@ -172,15 +172,16 @@ void MainWindow::changeStyle(bool checked)
//! [4]
//! [5]
void MainWindow::changeSize(int id, bool checked)
void MainWindow::changeSize(QAbstractButton *button, bool checked)
{
if (!checked)
return;
const bool other = id == int(OtherSize);
const int index = sizeButtonGroup->id(button);
const bool other = index == int(OtherSize);
const int extent = other
? otherSpinBox->value()
: QApplication::style()->pixelMetric(static_cast<QStyle::PixelMetric>(id));
: QApplication::style()->pixelMetric(static_cast<QStyle::PixelMetric>(index));
previewArea->setSize(QSize(extent, extent));
otherSpinBox->setEnabled(other);
@ -188,7 +189,7 @@ void MainWindow::changeSize(int id, bool checked)
void MainWindow::triggerChangeSize()
{
changeSize(sizeButtonGroup->checkedId(), true);
changeSize(sizeButtonGroup->checkedButton(), true);
}
//! [5]
@ -372,7 +373,7 @@ QWidget *MainWindow::createIconSizeGroupBox()
sizeButtonGroup = new QButtonGroup(this);
sizeButtonGroup->setExclusive(true);
connect(sizeButtonGroup, QOverload<int, bool>::of(&QButtonGroup::buttonToggled),
connect(sizeButtonGroup, &QButtonGroup::buttonToggled,
this, &MainWindow::changeSize);
QRadioButton *smallRadioButton = new QRadioButton;
@ -400,7 +401,7 @@ QWidget *MainWindow::createIconSizeGroupBox()
//! [26]
//! [27]
connect(otherSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(otherSpinBox, &QSpinBox::valueChanged,
this, &MainWindow::triggerChangeSize);
QHBoxLayout *otherSizeLayout = new QHBoxLayout;

View File

@ -62,6 +62,7 @@ class QActionGroup;
class QLabel;
class QButtonGroup;
class QTableWidget;
class QAbstractButton;
QT_END_NAMESPACE
class IconPreviewArea;
class IconSizeSpinBox;
@ -81,7 +82,7 @@ public:
private slots:
void about();
void changeStyle(bool checked);
void changeSize(int, bool);
void changeSize(QAbstractButton *button, bool);
void triggerChangeSize();
void changeIcon();
void addSampleImages();

View File

@ -127,15 +127,15 @@ Window::Window(QWidget *parent)
//! [4]
//! [5]
connect(echoComboBox, QOverload<int>::of(&QComboBox::activated),
connect(echoComboBox, &QComboBox::activated,
this, &Window::echoChanged);
connect(validatorComboBox, QOverload<int>::of(&QComboBox::activated),
connect(validatorComboBox, &QComboBox::activated,
this, &Window::validatorChanged);
connect(alignmentComboBox, QOverload<int>::of(&QComboBox::activated),
connect(alignmentComboBox, &QComboBox::activated,
this, &Window::alignmentChanged);
connect(inputMaskComboBox, QOverload<int>::of(&QComboBox::activated),
connect(inputMaskComboBox, &QComboBox::activated,
this, &Window::inputMaskChanged);
connect(accessComboBox, QOverload<int>::of(&QComboBox::activated),
connect(accessComboBox, &QComboBox::activated,
this, &Window::accessChanged);
//! [5]

View File

@ -81,7 +81,7 @@ MoviePlayer::MoviePlayer(QWidget *parent)
connect(movie, &QMovie::stateChanged, this, &MoviePlayer::updateButtons);
connect(fitCheckBox, &QCheckBox::clicked, this, &MoviePlayer::fitToWindow);
connect(frameSlider, &QSlider::valueChanged, this, &MoviePlayer::goToFrame);
connect(speedSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(speedSpinBox, &QSpinBox::valueChanged,
movie, &QMovie::setSpeed);
mainLayout = new QVBoxLayout;

View File

@ -78,7 +78,7 @@ Window::Window(QWidget *parent)
verticalSliders, &SlidersGroup::setValue);
connect(verticalSliders, &SlidersGroup::valueChanged,
valueSpinBox, &QSpinBox::setValue);
connect(valueSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(valueSpinBox, &QSpinBox::valueChanged,
horizontalSliders, &SlidersGroup::setValue);
QHBoxLayout *layout = new QHBoxLayout;
@ -126,16 +126,16 @@ void Window::createControls(const QString &title)
orientationCombo->addItem(tr("Vertical slider-like widgets"));
//! [6] //! [7]
connect(orientationCombo, QOverload<int>::of(&QComboBox::activated),
connect(orientationCombo, &QComboBox::activated,
//! [7] //! [8]
stackedWidget, &QStackedWidget::setCurrentIndex);
connect(minimumSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(minimumSpinBox, &QSpinBox::valueChanged,
horizontalSliders, &SlidersGroup::setMinimum);
connect(minimumSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(minimumSpinBox, &QSpinBox::valueChanged,
verticalSliders, &SlidersGroup::setMinimum);
connect(maximumSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(maximumSpinBox, &QSpinBox::valueChanged,
horizontalSliders, &SlidersGroup::setMaximum);
connect(maximumSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(maximumSpinBox, &QSpinBox::valueChanged,
verticalSliders, &SlidersGroup::setMaximum);
connect(invertedAppearance, &QCheckBox::toggled,
horizontalSliders, &SlidersGroup::invertAppearance);

View File

@ -262,7 +262,7 @@ void Window::createDoubleSpinBoxes()
priceSpinBox->setPrefix("$");
priceSpinBox->setValue(99.99);
connect(precisionSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
connect(precisionSpinBox, &QSpinBox::valueChanged,
//! [17]
this, &Window::changePrecision);

View File

@ -75,9 +75,9 @@ ValidatorWidget::ValidatorWidget(QWidget *parent)
this, &ValidatorWidget::updateDoubleValidator);
connect(doubleMinVal, &QDoubleSpinBox::editingFinished,
this, &ValidatorWidget::updateDoubleValidator);
connect(doubleDecimals, QOverload<int>::of(&QSpinBox::valueChanged),
connect(doubleDecimals, &QSpinBox::valueChanged,
this, &ValidatorWidget::updateDoubleValidator);
connect(doubleFormat, QOverload<int>::of(&QComboBox::activated),
connect(doubleFormat, &QComboBox::activated,
this, &ValidatorWidget::updateDoubleValidator);
connect(doubleEditor, &QLineEdit::editingFinished,
doubleLedWidget, &LEDWidget::flash);

View File

@ -68,7 +68,7 @@ QMAKE_CXXFLAGS_SPLIT_SECTIONS = $$QMAKE_CFLAGS_SPLIT_SECTIONS
QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions
QMAKE_CXXFLAGS_CXX11 = -std=c++11
QMAKE_CXXFLAGS_CXX14 = -std=c++1y
QMAKE_CXXFLAGS_CXX1Z = -std=c++1z
QMAKE_CXXFLAGS_CXX1Z = -std=c++17
QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11
QMAKE_CXXFLAGS_GNUCXX14 = -std=gnu++1y
QMAKE_CXXFLAGS_GNUCXX1Z = -std=gnu++1z

View File

@ -5,7 +5,7 @@
QMAKE_PLATFORM += macos osx macx
QMAKE_MAC_SDK = macosx
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.13
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.14
QMAKE_APPLE_DEVICE_ARCHS = x86_64
# Should be 10.15, but as long as the CI builds with

View File

@ -46,7 +46,7 @@ QMAKE_RPATHLINKDIR_POST += $${QNX_DIR}/$${QNX_CPUDIR}/lib $${QNX_DIR}/$${QNX_CPU
QMAKE_CXXFLAGS_CXX11 =
QMAKE_CXXFLAGS_CXX14 =
QMAKE_CXXFLAGS_CXX1Z =
QMAKE_CXXFLAGS_CXX1Z = -Wc,-std=gnu++1z
QMAKE_CXXFLAGS_GNUCXX11 = -Wc,-std=gnu++11
QMAKE_CXXFLAGS_GNUCXX14 = -Wc,-std=gnu++1y

View File

@ -124,22 +124,20 @@ breakpad {
c++17: CONFIG += c++1z
c++latest: CONFIG *= c++2a c++1z c++14 c++11
!c++11:!c++14:!c++1z:!c++2a {
# Qt requires C++11 since 5.7, check if we need to force a compiler option
!c++1z:!c++2a {
# Qt requires C++17
QT_COMPILER_STDCXX_no_L = $$replace(QT_COMPILER_STDCXX, "L$", "")
!greaterThan(QT_COMPILER_STDCXX_no_L, 199711): CONFIG += c++11
!greaterThan(QT_COMPILER_STDCXX_no_L, 201402): CONFIG += c++1z
}
c++11|c++14|c++1z|c++2a {
c++1z|c++2a {
# Disable special compiler flags for host builds
!host_build|!cross_compile {
c++2a: cxxstd = CXX2A
else: c++1z: cxxstd = CXX1Z
else: c++14: cxxstd = CXX14
else: cxxstd = CXX11
else: cxxstd = CXX1Z
} else {
# Fall back to c++11, because since 5.7 c++11 is required everywhere,
# Fall back to c++17, because C++17 is required everywhere,
# including host builds
cxxstd = CXX11
cxxstd = CXX1Z
}
# Check if we should disable compiler extensions or not

View File

@ -28,7 +28,7 @@ CFLAGS_PCH = -Yuqmake_pch.h -FIqmake_pch.h -Fpqmake_pch.pch
PCH_OBJECT = qmake_pch.obj
CFLAGS_BARE = -c -Fo./ -Fdqmake.pdb \
-W2 -nologo -O2 \
-W2 -nologo -O2 -std:c++17 -Zc:__cplusplus \
$(CFLAGS_EXTRA) \
-I$(QMKSRC) -I$(QMKSRC)\library -I$(QMKSRC)\generators -I$(QMKSRC)\generators\unix -I$(QMKSRC)\generators\win32 -I$(QMKSRC)\generators\mac \
-I$(SOURCE_PATH)/src/3rdparty/tinycbor/src \

View File

@ -35,6 +35,7 @@
#include <qstring.h>
#include <qvector.h>
#include <qhash.h>
#include <qmap.h>
QT_BEGIN_NAMESPACE
@ -316,7 +317,7 @@ Q_DECLARE_TYPEINFO(ProStringList, Q_MOVABLE_TYPE);
inline ProStringList operator+(const ProStringList &one, const ProStringList &two)
{ ProStringList ret = one; ret += two; return ret; }
typedef QHash<ProKey, ProStringList> ProValueMap;
typedef QMap<ProKey, ProStringList> ProValueMap;
// These token definitions affect both ProFileEvaluator and ProWriter
enum ProToken {

View File

@ -149,6 +149,24 @@ std::mt19937 mt(0);
}
")
# cxx17_filesystem
qt_config_compile_test(cxx17_filesystem
LABEL "C++17 <filesystem>"
CODE
"
#include <filesystem>
int main(int argc, char **argv)
{
(void)argc; (void)argv;
/* BEGIN TEST: */
std::filesystem::path p(\"./file\");
/* END TEST: */
return 0;
}
"# FIXME: qmake: CONFIG += c++17
)
# eventfd
qt_config_compile_test(eventfd
LABEL "eventfd"
@ -515,6 +533,10 @@ qt_feature("cxx11_future" PUBLIC
LABEL "C++11 <future>"
CONDITION TEST_cxx11_future
)
qt_feature("cxx17_filesystem" PUBLIC
LABEL "C++17 <filesystem>"
CONDITION TEST_cxx17_filesystem
)
qt_feature("eventfd" PUBLIC
LABEL "eventfd"
CONDITION NOT WASM AND TEST_eventfd

View File

@ -366,6 +366,15 @@
"main": "std::mt19937 mt(0);"
}
},
"cxx17_filesystem": {
"label": "C++17 <filesystem>",
"type": "compile",
"test": {
"include": "filesystem",
"main": "std::filesystem::path p(\"./file\");",
"qmake": "CONFIG += c++17"
}
},
"eventfd": {
"label": "eventfd",
"type": "compile",
@ -613,6 +622,13 @@
"condition": "tests.cxx11_future",
"output": [ "publicFeature" ]
},
"cxx17_filesystem": {
"label": "C++17 <filesystem>",
"condition": "tests.cxx17_filesystem",
"output": [
"publicFeature"
]
},
"eventfd": {
"label": "eventfd",
"condition": "!config.wasm && tests.eventfd",

View File

@ -54,7 +54,7 @@ Q_PROPERTY(type name
MEMBER memberName [(READ getFunction | WRITE setFunction)])
[RESET resetFunction]
[NOTIFY notifySignal]
[REVISION int]
[REVISION int | REVISION(int[, int])]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]

View File

@ -115,6 +115,29 @@ vector.append(std::move(three));
//! [move-append]
//! [emplace]
QVector<QString> vector{"a", "ccc"};
vector.emplace(1, 2, 'b');
// vector: ["a", "bb", "ccc"]
//! [emplace]
//! [emplace-back]
QVector<QString> vector{"one", "two"};
vector.emplaceBack(3, 'a');
qDebug() << vector;
// vector: ["one", "two", "aaa"]
//! [emplace-back]
//! [emplace-back-ref]
QVector<QString> vector;
auto &ref = vector.emplaceBack();
ref = "one";
// vector: ["one"]
//! [emplace-back-ref]
//! [8]
QVector<QString> vector;
vector.prepend("one");

View File

@ -58,7 +58,7 @@ class Window : public QWidget
{
Q_OBJECT
Q_PROPERTY(int normalProperty READ normalProperty)
Q_PROPERTY(int newProperty READ newProperty REVISION 1)
Q_PROPERTY(int newProperty READ newProperty REVISION(2, 1))
public:
Window();
@ -66,7 +66,7 @@ public:
int newProperty();
public slots:
void normalMethod();
Q_REVISION(1) void newMethod();
Q_REVISION(2, 1) void newMethod();
};
//! [Window class with revision]

View File

@ -102,8 +102,8 @@
re-evaluated in QML, for example. Qt emits automatically that signal when
needed for MEMBER properties that do not have an explicit setter.
\li A \c REVISION number is optional. If included, it defines
the property and its notifier signal to be used in a particular
\li A \c REVISION number or \c REVISION() macro is optional. If included,
it defines the property and its notifier signal to be used in a particular
revision of the API (usually for exposure to QML). If not included, it
defaults to 0.

View File

@ -79,6 +79,7 @@
#define QT_FEATURE_cborstreamwriter 1
#define QT_CRYPTOGRAPHICHASH_ONLY_SHA1
#define QT_FEATURE_cxx11_random (__has_include(<random>) ? 1 : -1)
#define QT_FEATURE_cxx17_filesystem -1
#define QT_NO_DATASTREAM
#define QT_FEATURE_datestring 1
#define QT_FEATURE_datetimeparser -1

View File

@ -852,7 +852,9 @@ void QAbstractItemModelPrivate::rowsRemoved(const QModelIndex &parent,
for (QVector<QPersistentModelIndexData *>::const_iterator it = persistent_invalidated.constBegin();
it != persistent_invalidated.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
persistent.indexes.erase(persistent.indexes.constFind(data->index));
auto pit = persistent.indexes.constFind(data->index);
if (pit != persistent.indexes.cend())
persistent.indexes.erase(pit);
data->index = QModelIndex();
}
}

View File

@ -280,7 +280,7 @@ public:
QVector<int> proxy_rows;
QVector<int> proxy_columns;
QVector<QModelIndex> mapped_children;
QHash<QModelIndex, Mapping *>::const_iterator map_iter;
QModelIndex source_parent;
};
mutable QHash<QModelIndex, Mapping*> source_index_mapping;
@ -321,7 +321,7 @@ public:
const void *p = proxy_index.internalPointer();
Q_ASSERT(p);
QHash<QModelIndex, Mapping *>::const_iterator it =
static_cast<const Mapping*>(p)->map_iter;
source_index_mapping.constFind(static_cast<const Mapping*>(p)->source_parent);
Q_ASSERT(it != source_index_mapping.constEnd());
Q_ASSERT(it.value());
return it;
@ -517,8 +517,7 @@ IndexMap::const_iterator QSortFilterProxyModelPrivate::create_mapping(
m->proxy_columns.resize(source_cols);
build_source_to_proxy_mapping(m->source_columns, m->proxy_columns);
it = IndexMap::const_iterator(source_index_mapping.insert(source_parent, m));
m->map_iter = it;
m->source_parent = source_parent;
if (source_parent.isValid()) {
QModelIndex source_grand_parent = source_parent.parent();
@ -527,6 +526,7 @@ IndexMap::const_iterator QSortFilterProxyModelPrivate::create_mapping(
it2.value()->mapped_children.append(source_parent);
}
it = IndexMap::const_iterator(source_index_mapping.insert(source_parent, m));
Q_ASSERT(it != source_index_mapping.constEnd());
Q_ASSERT(it.value());
@ -1169,7 +1169,8 @@ void QSortFilterProxyModelPrivate::updateChildrenMapping(const QModelIndex &sour
// reinsert moved, mapped indexes
QVector<QPair<QModelIndex, Mapping*> >::iterator it = moved_source_index_mappings.begin();
for (; it != moved_source_index_mappings.end(); ++it) {
(*it).second->map_iter = QHash<QModelIndex, Mapping *>::const_iterator(source_index_mapping.insert((*it).first, (*it).second));
it->second->source_parent = it->first;
source_index_mapping.insert(it->first, it->second);
}
}

View File

@ -4674,10 +4674,15 @@ QDebug operator<<(QDebug dbg, const QObject *o)
Using the same Window class as the previous example, the newProperty and
newMethod would only be exposed in this code when the expected version is
1 or greater.
\c{2.1} or greater.
Since all methods are considered to be in revision 0 if untagged, a tag
of Q_REVISION(0) is invalid and ignored.
Since all methods are considered to be in revision \c{0} if untagged, a tag
of \c{Q_REVISION(0)} or \c{Q_REVISION(0, 0)} is invalid and ignored.
You can pass one or two integer parameters to \c{Q_REVISION}. If you pass
one parameter, it denotes the minor version only. This means that the major
version is unspecified. If you pass two, the first parameter is the major
version and the second parameter is the minor version.
This tag is not used by the meta-object system itself. Currently this is only
used by the QtQml module.

View File

@ -92,7 +92,7 @@ QT_BEGIN_NAMESPACE
#define Q_PROPERTY(...) QT_ANNOTATE_CLASS(qt_property, __VA_ARGS__)
#define Q_PRIVATE_PROPERTY(d, text) QT_ANNOTATE_CLASS2(qt_private_property, d, text)
#ifndef Q_REVISION
# define Q_REVISION(v)
# define Q_REVISION(...)
#endif
#define Q_OVERRIDE(text) QT_ANNOTATE_CLASS(qt_override, text)
#define QDOC_PROPERTY(text) QT_ANNOTATE_CLASS(qt_qdoc_property, text)
@ -211,7 +211,7 @@ private: \
#define Q_INTERFACES(x) Q_INTERFACES(x)
#define Q_PROPERTY(text) Q_PROPERTY(text)
#define Q_PRIVATE_PROPERTY(d, text) Q_PRIVATE_PROPERTY(d, text)
#define Q_REVISION(v) Q_REVISION(v)
#define Q_REVISION(...) Q_REVISION(__VA_ARGS__)
#define Q_OVERRIDE(text) Q_OVERRIDE(text)
#define Q_ENUMS(x) Q_ENUMS(x)
#define Q_FLAGS(x) Q_FLAGS(x)

View File

@ -972,7 +972,7 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
const QVariantMap *map = v_cast<QVariantMap>(d);
const auto end = map->end();
for (auto it = map->begin(); it != end; ++it)
static_cast<QMultiHash<QString, QVariant> *>(hash)->insert(it.key(), it.value());
hash->insert(it.key(), it.value());
#ifndef QT_BOOTSTRAPPED
} else if (d->type == QMetaType::QCborValue) {
if (!v_cast<QCborValue>(d)->isMap())
@ -2471,6 +2471,8 @@ static const ushort mapIdFromQt3ToCurrent[MapFromThreeCount] =
QMetaType::QBitArray,
#if QT_CONFIG(shortcut)
QMetaType::QKeySequence,
#else
0, // QKeySequence
#endif
QMetaType::QPen,
QMetaType::LongLong,

View File

@ -818,7 +818,7 @@ namespace QtPrivate {
QVariantHash l;
l.reserve(iter.size());
for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
static_cast<QMultiHash<QString, QVariant> &>(l).insert(it.key().toString(), it.value());
l.insert(it.key().toString(), it.value());
return l;
}
return QVariantValueHelper<QVariantHash>::invoke(v);

View File

@ -43,7 +43,6 @@ QT_BEGIN_NAMESPACE
QFactoryInterface::~QFactoryInterface()
{
// must be empty until ### Qt 6
}
QT_END_NAMESPACE

View File

@ -296,10 +296,7 @@ QDataStream &readAssociativeContainer(QDataStream &s, Container &c)
c.clear();
break;
}
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
c.insertMulti(k, t);
QT_WARNING_POP
c.insert(k, t);
}
return s;
@ -319,19 +316,20 @@ template <typename Container>
QDataStream &writeAssociativeContainer(QDataStream &s, const Container &c)
{
s << quint32(c.size());
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && QT_DEPRECATED_SINCE(5, 15)
// Deserialization should occur in the reverse order.
// Otherwise, value() will return the least recently inserted
// value instead of the most recently inserted one.
auto it = c.constEnd();
auto begin = c.constBegin();
while (it != begin) {
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
--it;
QT_WARNING_POP
auto it = c.constBegin();
auto end = c.constEnd();
while (it != end) {
s << it.key() << it.value();
#else
++it;
}
return s;
}
template <typename Container>
QDataStream &writeAssociativeMultiContainer(QDataStream &s, const Container &c)
{
s << quint32(c.size());
auto it = c.constBegin();
auto end = c.constEnd();
while (it != end) {
@ -343,7 +341,6 @@ QDataStream &writeAssociativeContainer(QDataStream &s, const Container &c)
auto next = std::next(rangeStart, i);
s << next.key() << next.value();
}
#endif
}
return s;
@ -440,11 +437,24 @@ inline QDataStream &operator>>(QDataStream &s, QHash<Key, T> &hash)
}
template <class Key, class T>
inline QDataStream &operator<<(QDataStream &s, const QHash<Key, T> &hash)
{
return QtPrivate::writeAssociativeContainer(s, hash);
}
template <class Key, class T>
inline QDataStream &operator>>(QDataStream &s, QMultiHash<Key, T> &hash)
{
return QtPrivate::readAssociativeContainer(s, hash);
}
template <class Key, class T>
inline QDataStream &operator<<(QDataStream &s, const QMultiHash<Key, T> &hash)
{
return QtPrivate::writeAssociativeMultiContainer(s, hash);
}
template <class Key, class T>
inline QDataStream &operator>>(QDataStream &s, QMap<Key, T> &map)
{
@ -457,6 +467,18 @@ inline QDataStream &operator<<(QDataStream &s, const QMap<Key, T> &map)
return QtPrivate::writeAssociativeContainer(s, map);
}
template <class Key, class T>
inline QDataStream &operator>>(QDataStream &s, QMultiMap<Key, T> &map)
{
return QtPrivate::readAssociativeContainer(s, map);
}
template <class Key, class T>
inline QDataStream &operator<<(QDataStream &s, const QMultiMap<Key, T> &map)
{
return QtPrivate::writeAssociativeMultiContainer(s, map);
}
#ifndef QT_NO_DATASTREAM
template <class T1, class T2>
inline QDataStream& operator>>(QDataStream& s, QPair<T1, T2>& p)

View File

@ -791,28 +791,6 @@ const QLocaleData *QLocaleData::c()
return c_data;
}
static inline QString getLocaleData(const ushort *data, int size)
{
return size > 0 ? QString::fromRawData(reinterpret_cast<const QChar *>(data), size) : QString();
}
static QString getLocaleListData(const ushort *data, int size, int index)
{
static const ushort separator = ';';
while (index && size > 0) {
while (*data != separator)
++data, --size;
--index;
++data;
--size;
}
const ushort *end = data;
while (size > 0 && *end != separator)
++end, --size;
return getLocaleData(data, end - data);
}
#ifndef QT_NO_DATASTREAM
QDataStream &operator<<(QDataStream &ds, const QLocale &l)
{
@ -1130,31 +1108,24 @@ QString QLocale::createSeparatedList(const QStringList &list) const
#endif
const int size = list.size();
if (size == 1) {
return list.at(0);
} else if (size == 2) {
QString format = getLocaleData(
list_pattern_part_data + d->m_data->m_list_pattern_part_two_idx,
d->m_data->m_list_pattern_part_two_size);
return format.arg(list.at(0), list.at(1));
} else if (size > 2) {
QString formatStart = getLocaleData(
list_pattern_part_data + d->m_data->m_list_pattern_part_start_idx,
d->m_data->m_list_pattern_part_start_size);
QString formatMid = getLocaleData(
list_pattern_part_data + d->m_data->m_list_pattern_part_mid_idx,
d->m_data->m_list_pattern_part_mid_size);
QString formatEnd = getLocaleData(
list_pattern_part_data + d->m_data->m_list_pattern_part_end_idx,
d->m_data->m_list_pattern_part_end_size);
QString result = formatStart.arg(list.at(0), list.at(1));
for (int i = 2; i < size - 1; ++i)
result = formatMid.arg(result, list.at(i));
result = formatEnd.arg(result, list.at(size - 1));
return result;
}
if (size < 1)
return QString();
return QString();
if (size == 1)
return list.at(0);
if (size == 2)
return d->m_data->pairListPattern().getData(
list_pattern_part_data).arg(list.at(0), list.at(1));
QStringView formatStart = d->m_data->startListPattern().viewData(list_pattern_part_data);
QStringView formatMid = d->m_data->midListPattern().viewData(list_pattern_part_data);
QStringView formatEnd = d->m_data->endListPattern().viewData(list_pattern_part_data);
QString result = formatStart.arg(list.at(0), list.at(1));
for (int i = 2; i < size - 1; ++i)
result = formatMid.arg(result, list.at(i));
result = formatEnd.arg(result, list.at(size - 1));
return result;
}
/*!
@ -2251,18 +2222,10 @@ QString QLocale::dateFormat(FormatType format) const
}
#endif
quint32 idx, size;
switch (format) {
case LongFormat:
idx = d->m_data->m_long_date_format_idx;
size = d->m_data->m_long_date_format_size;
break;
default:
idx = d->m_data->m_short_date_format_idx;
size = d->m_data->m_short_date_format_size;
break;
}
return getLocaleData(date_format_data + idx, size);
return (format == LongFormat
? d->m_data->longDateFormat()
: d->m_data->shortDateFormat()
).getData(date_format_data);
}
/*!
@ -2289,18 +2252,10 @@ QString QLocale::timeFormat(FormatType format) const
}
#endif
quint32 idx, size;
switch (format) {
case LongFormat:
idx = d->m_data->m_long_time_format_idx;
size = d->m_data->m_long_time_format_size;
break;
default:
idx = d->m_data->m_short_time_format_idx;
size = d->m_data->m_short_time_format_size;
break;
}
return getLocaleData(time_format_data + idx, size);
return (format == LongFormat
? d->m_data->longTimeFormat()
: d->m_data->shortTimeFormat()
).getData(time_format_data);
}
/*!
@ -2869,24 +2824,21 @@ static QString rawMonthName(const QCalendarLocale &localeData,
const ushort *monthsData, int month,
QLocale::FormatType type)
{
quint32 idx, size;
QLocaleData::DataRange range;
switch (type) {
case QLocale::LongFormat:
idx = localeData.m_long.index;
size = localeData.m_long.size;
break;
range = localeData.longMonth();
break;
case QLocale::ShortFormat:
idx = localeData.m_short.index;
size = localeData.m_short.size;
break;
range = localeData.shortMonth();
break;
case QLocale::NarrowFormat:
idx = localeData.m_narrow.index;
size = localeData.m_narrow.size;
break;
range = localeData.narrowMonth();
break;
default:
return QString();
return QString();
}
return getLocaleListData(monthsData + idx, size, month - 1);
return range.getListEntry(monthsData, month - 1);
}
/*!
@ -2897,24 +2849,21 @@ static QString rawStandaloneMonthName(const QCalendarLocale &localeData,
const ushort *monthsData, int month,
QLocale::FormatType type)
{
quint32 idx, size;
QLocaleData::DataRange range;
switch (type) {
case QLocale::LongFormat:
idx = localeData.m_standalone_long.index;
size = localeData.m_standalone_long.size;
range = localeData.longMonthStandalone();
break;
case QLocale::ShortFormat:
idx = localeData.m_standalone_short.index;
size = localeData.m_standalone_short.size;
range = localeData.shortMonthStandalone();
break;
case QLocale::NarrowFormat:
idx = localeData.m_standalone_narrow.index;
size = localeData.m_standalone_narrow.size;
range = localeData.narrowMonthStandalone();
break;
default:
return QString();
}
QString name = getLocaleListData(monthsData + idx, size, month - 1);
QString name = range.getListEntry(monthsData, month - 1);
return name.isEmpty() ? rawMonthName(localeData, monthsData, month, type) : name;
}
@ -2925,24 +2874,21 @@ static QString rawStandaloneMonthName(const QCalendarLocale &localeData,
static QString rawWeekDayName(const QLocaleData *data, const int day,
QLocale::FormatType type)
{
quint32 idx, size;
QLocaleData::DataRange range;
switch (type) {
case QLocale::LongFormat:
idx = data->m_long_day_names_idx;
size = data->m_long_day_names_size;
range = data->longDayNames();
break;
case QLocale::ShortFormat:
idx = data->m_short_day_names_idx;
size = data->m_short_day_names_size;
range = data->shortDayNames();
break;
case QLocale::NarrowFormat:
idx = data->m_narrow_day_names_idx;
size = data->m_narrow_day_names_size;
range = data->narrowDayNames();
break;
default:
return QString();
}
return getLocaleListData(days_data + idx, size, day == 7 ? 0 : day);
return range.getListEntry(days_data, day == 7 ? 0 : day);
}
/*!
@ -2952,24 +2898,21 @@ static QString rawWeekDayName(const QLocaleData *data, const int day,
static QString rawStandaloneWeekDayName(const QLocaleData *data, const int day,
QLocale::FormatType type)
{
quint32 idx, size;
QLocaleData::DataRange range;
switch (type) {
case QLocale::LongFormat:
idx = data->m_standalone_long_day_names_idx;
size = data->m_standalone_long_day_names_size;
range =data->longDayNamesStandalone();
break;
case QLocale::ShortFormat:
idx = data->m_standalone_short_day_names_idx;
size = data->m_standalone_short_day_names_size;
range = data->shortDayNamesStandalone();
break;
case QLocale::NarrowFormat:
idx = data->m_standalone_narrow_day_names_idx;
size = data->m_standalone_narrow_day_names_size;
range = data->narrowDayNamesStandalone();
break;
default:
return QString();
}
QString name = getLocaleListData(days_data + idx, size, day == 7 ? 0 : day);
QString name = range.getListEntry(days_data, day == 7 ? 0 : day);
if (name.isEmpty())
return rawWeekDayName(data, day, type);
return name;
@ -3253,7 +3196,7 @@ QString QLocale::amText() const
return res.toString();
}
#endif
return getLocaleData(am_data + d->m_data->m_am_idx, d->m_data->m_am_size);
return d->m_data->anteMeridiem().getData(am_data);
}
/*!
@ -3273,7 +3216,7 @@ QString QLocale::pmText() const
return res.toString();
}
#endif
return getLocaleData(pm_data + d->m_data->m_pm_idx, d->m_data->m_pm_size);
return d->m_data->postMeridiem().getData(pm_data);
}
// Another intrusion from QCalendar, using some of the tools above:
@ -3885,7 +3828,7 @@ bool QLocaleData::numberToCLocale(QStringView s, QLocale::NumberOptions number_o
if (decpt_idx != -1 || exponent_idx != -1)
return false;
decpt_idx = idx;
} else if (out == 'e' || out == 'E') {
} else if (out == 'e') {
exponent_idx = idx;
}
@ -3932,7 +3875,7 @@ bool QLocaleData::numberToCLocale(QStringView s, QLocale::NumberOptions number_o
// don't add the group separator
++idx;
continue;
} else if (out == '.' || out == 'e' || out == 'E') {
} else if (out == '.' || idx == exponent_idx) {
// check distance from the last separator
// ### FIXME: Some locales allow other groupings!
// See https://en.wikipedia.org/wiki/Thousands_separator
@ -4215,23 +4158,16 @@ QString QLocale::currencySymbol(QLocale::CurrencySymbolFormat format) const
return res.toString();
}
#endif
quint32 idx, size;
switch (format) {
case CurrencySymbol:
idx = d->m_data->m_currency_symbol_idx;
size = d->m_data->m_currency_symbol_size;
return getLocaleData(currency_symbol_data + idx, size);
return d->m_data->currencySymbol().getData(currency_symbol_data);
case CurrencyDisplayName:
idx = d->m_data->m_currency_display_name_idx;
size = d->m_data->m_currency_display_name_size;
return getLocaleListData(currency_display_name_data + idx, size, 0);
return d->m_data->currencyDisplayName().getListEntry(currency_display_name_data, 0);
case CurrencyIsoCode: {
int len = 0;
const QLocaleData *data = this->d->m_data;
for (; len < 3; ++len)
if (!data->m_currency_iso_code[len])
break;
return len ? QString::fromLatin1(data->m_currency_iso_code, len) : QString();
const char *code = d->m_data->m_currency_iso_code;
if (int len = qstrnlen(code, 3))
return QString::fromLatin1(code, len);
break;
}
}
return QString();
@ -4257,19 +4193,16 @@ QString QLocale::toCurrencyString(qlonglong value, const QString &symbol) const
}
#endif
const QLocalePrivate *d = this->d;
quint8 idx = d->m_data->m_currency_format_idx;
quint8 size = d->m_data->m_currency_format_size;
if (d->m_data->m_currency_negative_format_size && value < 0) {
idx = d->m_data->m_currency_negative_format_idx;
size = d->m_data->m_currency_negative_format_size;
QLocaleData::DataRange range = d->m_data->currencyFormatNegative();
if (!range.size || value >= 0)
range = d->m_data->currencyFormat();
else
value = -value;
}
QString str = toString(value);
QString sym = symbol.isNull() ? currencySymbol() : symbol;
if (sym.isEmpty())
sym = currencySymbol(QLocale::CurrencyIsoCode);
QString format = getLocaleData(currency_format_data + idx, size);
return format.arg(str, sym);
return range.getData(currency_format_data).arg(str, sym);
}
/*!
@ -4287,15 +4220,11 @@ QString QLocale::toCurrencyString(qulonglong value, const QString &symbol) const
return res.toString();
}
#endif
const QLocaleData *data = this->d->m_data;
quint8 idx = data->m_currency_format_idx;
quint8 size = data->m_currency_format_size;
QString str = toString(value);
QString sym = symbol.isNull() ? currencySymbol() : symbol;
if (sym.isEmpty())
sym = currencySymbol(QLocale::CurrencyIsoCode);
QString format = getLocaleData(currency_format_data + idx, size);
return format.arg(str, sym);
return d->m_data->currencyFormat().getData(currency_format_data).arg(str, sym);
}
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
@ -4330,20 +4259,16 @@ QString QLocale::toCurrencyString(double value, const QString &symbol, int preci
return res.toString();
}
#endif
const QLocaleData *data = this->d->m_data;
quint8 idx = data->m_currency_format_idx;
quint8 size = data->m_currency_format_size;
if (data->m_currency_negative_format_size && value < 0) {
idx = data->m_currency_negative_format_idx;
size = data->m_currency_negative_format_size;
QLocaleData::DataRange range = d->m_data->currencyFormatNegative();
if (!range.size || value >= 0)
range = d->m_data->currencyFormat();
else
value = -value;
}
QString str = toString(value, 'f', precision == -1 ? d->m_data->m_currency_digits : precision);
QString sym = symbol.isNull() ? currencySymbol() : symbol;
if (sym.isEmpty())
sym = currencySymbol(QLocale::CurrencyIsoCode);
QString format = getLocaleData(currency_format_data + idx, size);
return format.arg(str, sym);
return range.getData(currency_format_data).arg(str, sym);
}
/*!
@ -4418,17 +4343,11 @@ QString QLocale::formattedDataSize(qint64 bytes, int precision, DataSizeFormats
Q_ASSERT(power <= 6 && power >= 0);
QString unit;
if (power > 0) {
quint16 index, size;
if (format & DataSizeSIQuantifiers) {
index = d->m_data->m_byte_si_quantified_idx;
size = d->m_data->m_byte_si_quantified_size;
} else {
index = d->m_data->m_byte_iec_quantified_idx;
size = d->m_data->m_byte_iec_quantified_size;
}
unit = getLocaleListData(byte_unit_data + index, size, power - 1);
QLocaleData::DataRange range = (format & DataSizeSIQuantifiers)
? d->m_data->byteAmountSI() : d->m_data->byteAmountIEC();
unit = range.getListEntry(byte_unit_data, power - 1);
} else {
unit = getLocaleData(byte_unit_data + d->m_data->m_byte_idx, d->m_data->m_byte_size);
unit = d->m_data->byteCount().getData(byte_unit_data);
}
return number + QLatin1Char(' ') + unit;
@ -4554,8 +4473,7 @@ QString QLocale::nativeLanguageName() const
return res.toString();
}
#endif
return getLocaleData(endonyms_data + d->m_data->m_language_endonym_idx,
d->m_data->m_language_endonym_size);
return d->m_data->endonymLanguage().getData(endonyms_data);
}
/*!
@ -4575,8 +4493,7 @@ QString QLocale::nativeCountryName() const
return res.toString();
}
#endif
return getLocaleData(endonyms_data + d->m_data->m_country_endonym_idx,
d->m_data->m_country_endonym_size);
return d->m_data->endonymCountry().getData(endonyms_data);
}
#ifndef QT_NO_DEBUG_STREAM

View File

@ -614,6 +614,7 @@ public:
LastScript = JamoScript
};
enum Country {
AnyCountry = 0,
Afghanistan = 1,

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@ -288,6 +288,62 @@ public:
Q_CORE_EXPORT bool validateChars(QStringView str, NumberMode numMode, QByteArray *buff, int decDigits = -1,
QLocale::NumberOptions number_options = QLocale::DefaultNumberOptions) const;
struct DataRange
{
quint16 offset;
quint16 size;
QString getData(const ushort *table) const
{
return size > 0
? QString::fromRawData(reinterpret_cast<const QChar *>(table + offset), size)
: QString();
}
QStringView viewData(const ushort *table) const
{
return { reinterpret_cast<const QChar *>(table + offset), size };
}
QString getListEntry(const ushort *table, int index) const
{
return listEntry(table, index).getData(table);
}
QStringView viewListEntry(const ushort *table, int index) const
{
return listEntry(table, index).viewData(table);
}
private:
DataRange listEntry(const ushort *table, int index) const
{
const ushort separator = ';';
quint16 i = 0;
while (index > 0 && i < size) {
if (table[offset + i] == separator)
index--;
i++;
}
quint16 end = i;
while (end < size && table[offset + end] != separator)
end++;
return { quint16(offset + i), quint16(end - i) };
}
};
#define ForEachQLocaleRange(X) \
X(startListPattern) X(midListPattern) X(endListPattern) X(pairListPattern) \
X(longDateFormat) X(shortDateFormat) X(longTimeFormat) X(shortTimeFormat) \
X(longDayNamesStandalone) X(longDayNames) \
X(shortDayNamesStandalone) X(shortDayNames) \
X(narrowDayNamesStandalone) X(narrowDayNames) \
X(anteMeridiem) X(postMeridiem) \
X(byteCount) X(byteAmountSI) X(byteAmountIEC) \
X(currencySymbol) X(currencyDisplayName) \
X(currencyFormat) X(currencyFormatNegative) \
X(endonymLanguage) X(endonymCountry)
#define rangeGetter(name) \
DataRange name() const { return { m_ ## name ## _idx, m_ ## name ## _size }; }
ForEachQLocaleRange(rangeGetter)
#undef rangeGetter
public:
quint16 m_language_id, m_script_id, m_country_id;
@ -296,34 +352,20 @@ public:
char16_t m_quotation_start, m_quotation_end;
char16_t m_alternate_quotation_start, m_alternate_quotation_end;
quint16 m_list_pattern_part_start_idx, m_list_pattern_part_start_size;
quint16 m_list_pattern_part_mid_idx, m_list_pattern_part_mid_size;
quint16 m_list_pattern_part_end_idx, m_list_pattern_part_end_size;
quint16 m_list_pattern_part_two_idx, m_list_pattern_part_two_size;
quint16 m_short_date_format_idx, m_short_date_format_size;
quint16 m_long_date_format_idx, m_long_date_format_size;
quint16 m_short_time_format_idx, m_short_time_format_size;
quint16 m_long_time_format_idx, m_long_time_format_size;
quint16 m_standalone_short_day_names_idx, m_standalone_short_day_names_size;
quint16 m_standalone_long_day_names_idx, m_standalone_long_day_names_size;
quint16 m_standalone_narrow_day_names_idx, m_standalone_narrow_day_names_size;
quint16 m_short_day_names_idx, m_short_day_names_size;
quint16 m_long_day_names_idx, m_long_day_names_size;
quint16 m_narrow_day_names_idx, m_narrow_day_names_size;
quint16 m_am_idx, m_am_size;
quint16 m_pm_idx, m_pm_size;
quint16 m_byte_idx, m_byte_size;
quint16 m_byte_si_quantified_idx, m_byte_si_quantified_size;
quint16 m_byte_iec_quantified_idx, m_byte_iec_quantified_size;
// Offsets, then sizes, for each range:
#define rangeIndex(name) quint16 m_ ## name ## _idx;
ForEachQLocaleRange(rangeIndex)
#undef rangeIndex
#define Size(name) quint8 m_ ## name ## _size;
ForEachQLocaleRange(Size)
#undef Size
#undef ForEachQLocaleRange
// Strays:
char m_currency_iso_code[3];
quint16 m_currency_symbol_idx, m_currency_symbol_size;
quint16 m_currency_display_name_idx, m_currency_display_name_size;
quint8 m_currency_format_idx, m_currency_format_size;
quint8 m_currency_negative_format_idx, m_currency_negative_format_size;
quint16 m_language_endonym_idx, m_language_endonym_size;
quint16 m_country_endonym_idx, m_country_endonym_size;
quint16 m_currency_digits : 2;
quint16 m_currency_rounding : 3;
quint16 m_currency_rounding : 3; // (not yet used !)
quint16 m_first_day_of_week : 3;
quint16 m_weekend_start : 3;
quint16 m_weekend_end : 3;
@ -417,7 +459,7 @@ inline char QLocaleData::digitToCLocale(QChar in) const
if (in == m_group)
return ',';
if (in == m_exponential || in == QChar(QChar::toUpper(m_exponential)))
if (in == m_exponential || in.toCaseFolded().unicode() == QChar::toCaseFolded(m_exponential))
return 'e';
// In several languages group() is a non-breaking space (U+00A0) or its thin

View File

@ -43,7 +43,6 @@ QT_BEGIN_NAMESPACE
QRunnable::~QRunnable()
{
// Must be empty until ### Qt 6
}
/*!

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@ -56,23 +56,33 @@
#include <QtCore/qstringlist.h>
#include <QtCore/qstring.h>
#include <QtCore/qmap.h>
#include <QtCore/private/qlocale_p.h>
QT_BEGIN_NAMESPACE
// Locale-related parts, mostly handled in ../text/qlocale.cpp
struct QLocaleDataEntry {
quint16 index, size;
};
struct QCalendarLocale {
quint16 m_language_id, m_script_id, m_country_id;
#define rangeGetter(name) \
QLocaleData::DataRange name() const { return { m_ ## name ## _idx, m_ ## name ## _size }; }
rangeGetter(longMonthStandalone) rangeGetter(longMonth)
rangeGetter(shortMonthStandalone) rangeGetter(shortMonth)
rangeGetter(narrowMonthStandalone) rangeGetter(narrowMonth)
#undef rangeGetter
// Month name indexes:
QLocaleDataEntry m_standalone_short;
QLocaleDataEntry m_standalone_long;
QLocaleDataEntry m_standalone_narrow;
QLocaleDataEntry m_short;
QLocaleDataEntry m_long;
QLocaleDataEntry m_narrow;
quint16 m_longMonthStandalone_idx, m_longMonth_idx;
quint16 m_shortMonthStandalone_idx, m_shortMonth_idx;
quint16 m_narrowMonthStandalone_idx, m_narrowMonth_idx;
// Twelve long month names (separated by commas) can add up to more than 256
// QChars - e.g. kde_TZ gets to 264.
quint16 m_longMonthStandalone_size, m_longMonth_size;
quint8 m_shortMonthStandalone_size, m_shortMonth_size;
quint8 m_narrowMonthStandalone_size, m_narrowMonth_size;
};
// Partial implementation, of methods with common forms, in qcalendar.cpp

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -117,6 +117,9 @@ struct QPodArrayOps
this->size += int(n);
}
template <typename ...Args>
void emplaceBack(Args&&... args) { this->emplace(this->end(), T(std::forward<Args>(args)...)); }
void truncate(size_t newSize)
{
Q_ASSERT(this->isMutable());
@ -163,16 +166,28 @@ struct QPodArrayOps
*where++ = t;
}
void insert(T *where, T &&t)
template <typename ...Args>
void createInPlace(T *where, Args&&... args) { new (where) T(std::forward<Args>(args)...); }
template <typename ...Args>
void emplace(T *where, Args&&... args)
{
Q_ASSERT(!this->isShared());
Q_ASSERT(where >= this->begin() && where <= this->end());
Q_ASSERT(this->allocatedCapacity() - this->size >= 1);
::memmove(static_cast<void *>(where + 1), static_cast<void *>(where),
(static_cast<const T*>(this->end()) - where) * sizeof(T));
this->size += 1;
new (where) T(std::move(t));
if (where == this->end()) {
new (this->end()) T(std::forward<Args>(args)...);
} else {
// Preserve the value, because it might be a reference to some part of the moved chunk
T t(std::forward<Args>(args)...);
::memmove(static_cast<void *>(where + 1), static_cast<void *>(where),
(static_cast<const T*>(this->end()) - where) * sizeof(T));
*where = t;
}
++this->size;
}
@ -289,6 +304,12 @@ struct QGenericArrayOps
}
}
template <typename ...Args>
void emplaceBack(Args&&... args)
{
this->emplace(this->end(), std::forward<Args>(args)...);
}
void truncate(size_t newSize)
{
Q_ASSERT(this->isMutable());
@ -444,31 +465,20 @@ struct QGenericArrayOps
}
}
void insert(T *where, T &&t)
template <typename ...Args>
void createInPlace(T *where, Args&&... args) { new (where) T(std::forward<Args>(args)...); }
template <typename iterator, typename ...Args>
void emplace(iterator where, Args&&... args)
{
Q_ASSERT(!this->isShared());
Q_ASSERT(where >= this->begin() && where <= this->end());
Q_ASSERT(this->allocatedCapacity() - this->size >= 1);
// Array may be truncated at where in case of exceptions
T *const end = this->end();
if (where != end) {
// Move elements in array
T *readIter = end - 1;
T *writeIter = end;
new (writeIter) T(std::move(*readIter));
while (readIter > where) {
--readIter;
--writeIter;
*writeIter = std::move(*readIter);
}
*where = std::move(t);
} else {
new (where) T(std::move(t));
}
createInPlace(this->end(), std::forward<Args>(args)...);
++this->size;
std::rotate(where, this->end() - 1, this->end());
}
void erase(T *b, T *e)

View File

@ -56,8 +56,6 @@ struct Q_CORE_EXPORT QContiguousCacheData
int count;
int start;
int offset;
uint sharable : 1;
uint reserved : 31;
// total is 24 bytes (HP-UX aCC: 40 bytes)
// the next entry is already aligned to 8 bytes
@ -96,7 +94,7 @@ public:
typedef int size_type;
explicit QContiguousCache(int capacity = 0);
QContiguousCache(const QContiguousCache<T> &v) : d(v.d) { d->ref.ref(); if (!d->sharable) detach_helper(); }
QContiguousCache(const QContiguousCache<T> &v) : d(v.d) { d->ref.ref(); }
inline ~QContiguousCache() { if (!d) return; if (!d->ref.deref()) freeData(p); }
@ -178,8 +176,6 @@ void QContiguousCache<T>::detach_helper()
x.d->start = d->start;
x.d->offset = d->offset;
x.d->alloc = d->alloc;
x.d->sharable = true;
x.d->reserved = 0;
T *dest = x.p->array + x.d->start;
T *src = p->array + d->start;
@ -267,7 +263,6 @@ void QContiguousCache<T>::clear()
x.d->ref.storeRelaxed(1);
x.d->alloc = d->alloc;
x.d->count = x.d->start = x.d->offset = 0;
x.d->sharable = true;
if (!d->ref.deref()) freeData(p);
d = x.d;
}
@ -287,7 +282,6 @@ QContiguousCache<T>::QContiguousCache(int cap)
d->ref.storeRelaxed(1);
d->alloc = cap;
d->count = d->start = d->offset = 0;
d->sharable = true;
}
template <typename T>
@ -297,8 +291,6 @@ QContiguousCache<T> &QContiguousCache<T>::operator=(const QContiguousCache<T> &o
if (!d->ref.deref())
freeData(p);
d = other.d;
if (!d->sharable)
detach_helper();
return *this;
}

View File

@ -359,53 +359,67 @@ void QCryptographicHash::reset()
Adds the first \a length chars of \a data to the cryptographic
hash.
*/
void QCryptographicHash::addData(const char *data, int length)
void QCryptographicHash::addData(const char *data, qsizetype length)
{
switch (d->method) {
case Sha1:
sha1Update(&d->sha1Context, (const unsigned char *)data, length);
break;
#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
default:
Q_ASSERT_X(false, "QCryptographicHash", "Method not compiled in");
Q_UNREACHABLE();
break;
Q_ASSERT(length >= 0);
#if QT_POINTER_SIZE == 8
// feed the data UINT_MAX bytes at a time, as some of the methods below
// take a uint (of course, feeding more than 4G of data into the hashing
// functions will be pretty slow anyway)
qsizetype remaining = length;
while (remaining) {
length = qMin(qsizetype(std::numeric_limits<uint>::max()), remaining);
remaining -= length;
#else
case Md4:
md4_update(&d->md4Context, (const unsigned char *)data, length);
break;
case Md5:
MD5Update(&d->md5Context, (const unsigned char *)data, length);
break;
case Sha224:
SHA224Input(&d->sha224Context, reinterpret_cast<const unsigned char *>(data), length);
break;
case Sha256:
SHA256Input(&d->sha256Context, reinterpret_cast<const unsigned char *>(data), length);
break;
case Sha384:
SHA384Input(&d->sha384Context, reinterpret_cast<const unsigned char *>(data), length);
break;
case Sha512:
SHA512Input(&d->sha512Context, reinterpret_cast<const unsigned char *>(data), length);
break;
case RealSha3_224:
case Keccak_224:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), quint64(length) * 8);
break;
case RealSha3_256:
case Keccak_256:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), quint64(length) * 8);
break;
case RealSha3_384:
case Keccak_384:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), quint64(length) * 8);
break;
case RealSha3_512:
case Keccak_512:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), quint64(length) * 8);
break;
{
#endif
switch (d->method) {
case Sha1:
sha1Update(&d->sha1Context, (const unsigned char *)data, length);
break;
#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
default:
Q_ASSERT_X(false, "QCryptographicHash", "Method not compiled in");
Q_UNREACHABLE();
break;
#else
case Md4:
md4_update(&d->md4Context, (const unsigned char *)data, length);
break;
case Md5:
MD5Update(&d->md5Context, (const unsigned char *)data, length);
break;
case Sha224:
SHA224Input(&d->sha224Context, reinterpret_cast<const unsigned char *>(data), length);
break;
case Sha256:
SHA256Input(&d->sha256Context, reinterpret_cast<const unsigned char *>(data), length);
break;
case Sha384:
SHA384Input(&d->sha384Context, reinterpret_cast<const unsigned char *>(data), length);
break;
case Sha512:
SHA512Input(&d->sha512Context, reinterpret_cast<const unsigned char *>(data), length);
break;
case RealSha3_224:
case Keccak_224:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), quint64(length) * 8);
break;
case RealSha3_256:
case Keccak_256:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), quint64(length) * 8);
break;
case RealSha3_384:
case Keccak_384:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), quint64(length) * 8);
break;
case RealSha3_512:
case Keccak_512:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), quint64(length) * 8);
break;
#endif
}
}
d->result.clear();
}

View File

@ -94,7 +94,7 @@ public:
void reset();
void addData(const char *data, int length);
void addData(const char *data, qsizetype length);
void addData(const QByteArray &data);
bool addData(QIODevice* device);

View File

@ -105,11 +105,7 @@ public:
friend class QSet<T>;
public:
#if QT_DEPRECATED_SINCE(5, 15)
typedef std::bidirectional_iterator_tag iterator_category;
#else
typedef std::forward_iterator_tag iterator_category;
#endif
typedef qptrdiff difference_type;
typedef T value_type;
typedef const T *pointer;
@ -129,15 +125,6 @@ public:
{ return i != o.i; }
inline iterator &operator++() { ++i; return *this; }
inline iterator operator++(int) { iterator r = *this; ++i; return r; }
#if QT_DEPRECATED_SINCE(5, 15)
inline QT_DEPRECATED iterator &operator--() { --i; return *this; }
inline QT_DEPRECATED iterator operator--(int) { iterator r = *this; --i; return r; }
inline QT_DEPRECATED iterator operator+(int j) const { return i + j; }
inline QT_DEPRECATED iterator operator-(int j) const { return i - j; }
friend inline QT_DEPRECATED iterator operator+(int j, iterator k) { return k + j; }
inline QT_DEPRECATED iterator &operator+=(int j) { i += j; return *this; }
inline QT_DEPRECATED iterator &operator-=(int j) { i -= j; return *this; }
#endif
};
class const_iterator
@ -148,11 +135,7 @@ public:
friend class QSet<T>;
public:
#if QT_DEPRECATED_SINCE(5, 15)
typedef std::bidirectional_iterator_tag iterator_category;
#else
typedef std::forward_iterator_tag iterator_category;
#endif
typedef qptrdiff difference_type;
typedef T value_type;
typedef const T *pointer;
@ -170,15 +153,6 @@ public:
inline bool operator!=(const const_iterator &o) const { return i != o.i; }
inline const_iterator &operator++() { ++i; return *this; }
inline const_iterator operator++(int) { const_iterator r = *this; ++i; return r; }
#if QT_DEPRECATED_SINCE(5, 15)
inline QT_DEPRECATED const_iterator &operator--() { --i; return *this; }
inline QT_DEPRECATED const_iterator operator--(int) { const_iterator r = *this; --i; return r; }
inline QT_DEPRECATED const_iterator operator+(int j) const { return i + j; }
inline QT_DEPRECATED const_iterator operator-(int j) const { return i - j; }
friend inline QT_DEPRECATED const_iterator operator+(int j, const_iterator k) { return k + j; }
inline QT_DEPRECATED const_iterator &operator+=(int j) { i += j; return *this; }
inline QT_DEPRECATED const_iterator &operator-=(int j) { i -= j; return *this; }
#endif
};
// STL style
@ -191,23 +165,10 @@ public:
inline const_iterator cend() const noexcept { return q_hash.end(); }
inline const_iterator constEnd() const noexcept { return q_hash.constEnd(); }
#if QT_DEPRECATED_SINCE(5, 15)
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
reverse_iterator QT_DEPRECATED rbegin() { return reverse_iterator(end()); }
reverse_iterator QT_DEPRECATED rend() { return reverse_iterator(begin()); }
const_reverse_iterator QT_DEPRECATED rbegin() const noexcept { return const_reverse_iterator(end()); }
const_reverse_iterator QT_DEPRECATED rend() const noexcept { return const_reverse_iterator(begin()); }
const_reverse_iterator QT_DEPRECATED crbegin() const noexcept { return const_reverse_iterator(end()); }
const_reverse_iterator QT_DEPRECATED crend() const noexcept { return const_reverse_iterator(begin()); }
#endif
iterator erase(iterator i)
{ return erase(m2c(i)); }
iterator erase(const_iterator i)
{
Q_ASSERT_X(isValidIterator(i), "QSet::erase", "The specified const_iterator argument 'i' is invalid");
return q_hash.erase(reinterpret_cast<typename Hash::const_iterator &>(i));
}
@ -263,15 +224,6 @@ private:
static const_iterator m2c(iterator it) noexcept
{ return const_iterator(typename Hash::const_iterator(it.i.i)); }
bool isValidIterator(const iterator &i) const
{
return q_hash.isValidIterator(reinterpret_cast<const typename Hash::iterator&>(i));
}
bool isValidIterator(const const_iterator &i) const noexcept
{
return q_hash.isValidIterator(reinterpret_cast<const typename Hash::const_iterator&>(i));
}
};
#if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201606
@ -415,14 +367,6 @@ public:
inline const T &value() const { Q_ASSERT(item_exists()); return *n; }
inline bool findNext(const T &t)
{ while (c->constEnd() != (n = i)) if (*i++ == t) return true; return false; }
#if QT_DEPRECATED_SINCE(5, 15)
inline QT_DEPRECATED bool hasPrevious() const { return c->constBegin() != i; }
inline QT_DEPRECATED const T &previous() { n = --i; return *n; }
inline QT_DEPRECATED const T &peekPrevious() const { iterator p = i; return *--p; }
inline QT_DEPRECATED bool findPrevious(const T &t)
{ while (c->constBegin() != i) if (*(n = --i) == t) return true;
n = c->end(); return false; }
#endif
};
#endif // QT_NO_JAVA_STYLE_ITERATORS

View File

@ -242,10 +242,14 @@ public:
void append(const_reference t)
{ append(const_iterator(std::addressof(t)), const_iterator(std::addressof(t)) + 1); }
void append(const_iterator i1, const_iterator i2);
void append(value_type &&t);
void append(rvalue_ref t) { emplaceBack(std::move(t)); }
void append(const QVector<T> &l) { append(l.constBegin(), l.constEnd()); }
void prepend(rvalue_ref t);
void prepend(const T &t);
template <typename ...Args>
reference emplaceBack(Args&&... args) { return *emplace(count(), std::forward<Args>(args)...); }
iterator insert(int i, parameter_type t)
{ return insert(i, 1, t); }
iterator insert(int i, int n, parameter_type t);
@ -264,7 +268,17 @@ public:
Q_ASSERT_X(isValidIterator(before), "QVector::insert", "The specified iterator argument 'before' is invalid");
return insert(std::distance(constBegin(), before), std::move(t));
}
iterator insert(int i, rvalue_ref t);
iterator insert(int i, rvalue_ref t) { return emplace(i, std::move(t)); }
template <typename ...Args>
iterator emplace(const_iterator before, Args&&... args)
{
Q_ASSERT_X(isValidIterator(before), "QVector::emplace", "The specified iterator argument 'before' is invalid");
return emplace(std::distance(constBegin(), before), std::forward<Args>(args)...);
}
template <typename ...Args>
iterator emplace(int i, Args&&... args);
#if 0
template< class InputIt >
iterator insert( const_iterator pos, InputIt first, InputIt last );
@ -388,6 +402,10 @@ public:
inline void push_front(const T &t) { prepend(t); }
void pop_back() { removeLast(); }
void pop_front() { removeFirst(); }
template <typename ...Args>
reference emplace_back(Args&&... args) { return emplaceBack(std::forward<Args>(args)...); }
inline bool empty() const
{ return d->size == 0; }
inline reference front() { return first(); }
@ -537,27 +555,6 @@ inline void QVector<T>::append(const_iterator i1, const_iterator i2)
}
}
template <typename T>
inline void QVector<T>::append(value_type &&t)
{
const size_t newSize = size() + 1;
const bool isTooSmall = newSize > d->allocatedCapacity();
const bool isOverlapping = std::addressof(*d->begin()) <= std::addressof(t)
&& std::addressof(t) < std::addressof(*d->end());
if (isTooSmall || d->needsDetach() || Q_UNLIKELY(isOverlapping)) {
typename Data::ArrayOptions flags = d->detachFlags();
if (isTooSmall)
flags |= Data::GrowsForward;
DataPointer detached(Data::allocate(d->detachCapacity(newSize), flags));
detached->copyAppend(constBegin(), constEnd());
detached->moveAppend(std::addressof(t), std::addressof(t) + 1);
d.swap(detached);
} else {
// we're detached and we can just move data around
d->moveAppend(std::addressof(t), std::addressof(t) + 1);
}
}
template <typename T>
inline typename QVector<T>::iterator
QVector<T>::insert(int i, int n, parameter_type t)
@ -592,10 +589,11 @@ QVector<T>::insert(int i, int n, parameter_type t)
}
template <typename T>
template <typename ...Args>
typename QVector<T>::iterator
QVector<T>::insert(int i, rvalue_ref t)
QVector<T>::emplace(int i, Args&&... args)
{
Q_ASSERT_X(size_t(i) <= size_t(d->size), "QVector<T>::insert", "index out of range");
Q_ASSERT_X(i >= 0 && i <= d->size, "QVector<T>::insert", "index out of range");
const size_t newSize = size() + 1;
if (d->needsDetach() || newSize > d->allocatedCapacity()) {
@ -605,12 +603,24 @@ QVector<T>::insert(int i, rvalue_ref t)
DataPointer detached(Data::allocate(d->detachCapacity(newSize), flags));
const_iterator where = constBegin() + i;
// First, create an element to handle cases, when a user moves
// the element from a container to the same container
detached->createInPlace(detached.begin() + i, std::forward<Args>(args)...);
// Then, put the first part of the elements to the new location
detached->copyAppend(constBegin(), where);
detached->moveAppend(std::addressof(t), std::addressof(t) + 1);
// After that, increase the actual size, because we created
// one extra element
++detached.size;
// Finally, put the rest of the elements to the new location
detached->copyAppend(where, constEnd());
d.swap(detached);
} else {
d->insert(d.begin() + i, std::move(t));
d->emplace(d.begin() + i, std::forward<Args>(args)...);
}
return d.begin() + i;
}

View File

@ -646,6 +646,28 @@
\sa append(), insert()
*/
/*!
\fn template <typename T> template <typename ...Args> T &QVector<T>::emplaceBack(Args&&... args)
\fn template <typename T> template <typename ...Args> T &QVector<T>::emplace_back(Args&&... args)
Adds a new element to the end for the container. This new element
is constructed in-place using \a args as the arguments for its
construction.
Returns a reference to the new element.
Example:
\snippet code/src_corelib_tools_qvector.cpp emplace-back
It is also possible to access a newly created object by using
returned reference:
\snippet code/src_corelib_tools_qvector.cpp emplace-back-ref
This is the same as vector.emplace(vector.size(), \a args).
\sa emplace
*/
/*! \fn template <typename T> void QVector<T>::insert(int i, const T &value)
\fn template <typename T> void QVector<T>::insert(int i, T &&value)
@ -693,6 +715,26 @@
first of the inserted items.
*/
/*!
\fn template <typename T> template <typename ...Args> QVector<T>::iterator QVector<T>::emplace(int i, Args&&... args)
Extends the container by inserting a new element at position \a i.
This new element is constructed in-place using \a args as the
arguments for its construction.
Returns an iterator to the new element.
Example:
\snippet code/src_corelib_tools_qvector.cpp emplace
\note It is garanteed that the element will be created in place
at the beginning, but after that it might be copied or
moved to the right position.
\sa emplaceBack
*/
/*! \fn template <typename T> void QVector<T>::replace(int i, const T &value)
Replaces the item at index position \a i with \a value.
@ -838,6 +880,17 @@
\sa takeFirst(), removeLast()
*/
/*!
\fn template <typename T> template <typename ...Args> QVector<T>::iterator QVector<T>::emplace(QVector<T>::iterator before, Args&&... args)
\overload
Creates a new element in front of the item pointed to by the
iterator \a before. This new element is constructed in-place
using \a args as the arguments for its construction.
Returns an iterator to the new element.
*/
/*! \fn template <typename T> QVector<T> &QVector<T>::fill(const T &value, int size = -1)

View File

@ -556,5 +556,199 @@ uint qHash(const QVersionNumber &key, uint seed)
return seed;
}
QT_END_NAMESPACE
/*!
\class QTypeRevision
\inmodule QtCore
\since 6.0
\brief The QTypeRevision class contains a lightweight representation of
a version number with two 8-bit segments, major and minor, either
of which can be unknown.
Use this class to describe revisions of a type. Compatible revisions can be
expressed as increments of the minor version. Breaking changes can be
expressed as increments of the major version. The return values of
\l QMetaMethod::revision() and \l QMetaProperty::revision() can be passed to
\l QTypeRevision::fromEncodedVersion(). The resulting major and minor versions
specify in which Qt versions the properties and methods were added.
\sa QMetaMethod::revision(), QMetaProperty::revision()
*/
/*!
\fn template<typename Integer> static bool QTypeRevision::isValidSegment(Integer segment)
Returns true if the given number can be used as either major or minor
version in a QTypeRevision. Valid segments need to be \c {>= 0} and \c {< 255}.
*/
/*!
\fn QTypeRevision::QTypeRevision()
Produces an invalid revision.
\sa isValid()
*/
/*!
\fn template <typename Major, typename Minor> static QTypeRevision QTypeRevision::fromVersion(Major majorVersion, Minor minorVersion)
Produces a QTypeRevision from the given \a majorVersion and \a minorVersion,
both of which need to be a valid segments.
\sa isValidSegment()
*/
/*!
\fn template <typename Major> static QTypeRevision QTypeRevision::fromMajorVersion(Major majorVersion)
Produces a QTypeRevision from the given \a majorVersion with an invalid minor
version. \a majorVersion needs to be a valid segment.
\sa isValidSegment()
*/
/*!
\fn template <typename Minor> static QTypeRevision QTypeRevision::fromMinorVersion(Minor minorVersion)
Produces a QTypeRevision from the given \a minorVersion with an invalid major
version. \a minorVersion needs to be a valid segment.
\sa isValidSegment()
*/
/*!
\fn template <typename Integer> static QTypeRevision QTypeRevision::fromEncodedVersion(Integer value)
Produces a QTypeRevision from the given \a value. \a value encodes both the
minor and major versions in the least significant and second least
significant byte, respectively.
\a value must not have any bits outside the least significant two bytes set.
\c Integer needs to be at least 16 bits wide, and must not have a sign bit
in the least significant 16 bits.
\sa toEncodedVersion()
*/
/*!
\fn static QTypeRevision QTypeRevision::zero()
Produces a QTypeRevision with major and minor version \c{0}.
*/
/*!
\fn bool QTypeRevision::hasMajorVersion() const
Returns true if the major version is known, otherwise false.
\sa majorVersion(), hasMinorVersion()
*/
/*!
\fn quint8 QTypeRevision::majorVersion() const
Returns the major version encoded in the revision.
\sa hasMajorVersion(), minorVersion()
*/
/*!
\fn bool QTypeRevision::hasMinorVersion() const
Returns true if the minor version is known, otherwise false.
\sa minorVersion(), hasMajorVersion()
*/
/*!
\fn quint8 QTypeRevision::minorVersion() const
Returns the minor version encoded in the revision.
\sa hasMinorVersion(), majorVersion()
*/
/*!
\fn bool QTypeRevision::isValid() const
Returns true if the major version or the minor version is known,
otherwise false.
\sa hasMajorVersion(), hasMinorVersion()
*/
/*!
\fn template<typename Integer> Integer QTypeRevision::toEncodedVersion() const
Transforms the revision into an integer value, encoding the minor
version into the least significant byte, and the major version into
the second least significant byte.
\c Integer needs to be at least 16 bits wide, and must not have a sign bit
in the least significant 16 bits.
\sa fromEncodedVersion()
*/
#ifndef QT_NO_DATASTREAM
/*!
\fn QDataStream& operator<<(QDataStream &out, const QTypeRevision &revision)
\relates QTypeRevision
\since 6.0
Writes the revision \a revision to stream \a out.
*/
QDataStream& operator<<(QDataStream &out, const QTypeRevision &revision)
{
return out << revision.toEncodedVersion<quint16>();
}
/*!
\fn QDataStream& operator>>(QDataStream &in, QTypeRevision &revision)
\relates QTypeRevision
\since 6.0
Reads a revision from stream \a in and stores it in \a revision.
*/
QDataStream& operator>>(QDataStream &in, QTypeRevision &revision)
{
quint16 value;
in >> value;
revision = QTypeRevision::fromEncodedVersion(value);
return in;
}
#endif
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QTypeRevision &revision)
{
QDebugStateSaver saver(debug);
if (revision.hasMajorVersion()) {
if (revision.hasMinorVersion())
debug.nospace() << revision.majorVersion() << '.' << revision.minorVersion();
else
debug.nospace().noquote() << revision.majorVersion() << ".x";
} else {
if (revision.hasMinorVersion())
debug << revision.minorVersion();
else
debug.noquote() << "invalid";
}
return debug;
}
#endif
/*!
\fn uint qHash(const QTypeRevision &key, uint seed)
\relates QHash
\since 6.0
Returns the hash value for the \a key, using \a seed to seed the
calculation.
*/
uint qHash(const QTypeRevision &key, uint seed)
{
return qHash(key.toEncodedVersion<quint16>(), seed);
}
QT_END_NAMESPACE

View File

@ -309,8 +309,159 @@ Q_REQUIRED_RESULT inline bool operator==(const QVersionNumber &lhs, const QVersi
Q_REQUIRED_RESULT inline bool operator!=(const QVersionNumber &lhs, const QVersionNumber &rhs) noexcept
{ return QVersionNumber::compare(lhs, rhs) != 0; }
class QTypeRevision;
Q_CORE_EXPORT uint qHash(const QTypeRevision &key, uint seed = 0);
#ifndef QT_NO_DATASTREAM
Q_CORE_EXPORT QDataStream& operator<<(QDataStream &out, const QTypeRevision &revision);
Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QTypeRevision &revision);
#endif
class QTypeRevision
{
public:
template<typename Integer>
using if_valid_segment_type = typename std::enable_if<
std::is_integral<Integer>::value, bool>::type;
template<typename Integer>
using if_valid_value_type = typename std::enable_if<
std::is_integral<Integer>::value
&& (sizeof(Integer) > sizeof(quint16)
|| (sizeof(Integer) == sizeof(quint16)
&& !std::is_signed<Integer>::value)), bool>::type;
template<typename Integer, if_valid_segment_type<Integer> = true>
static constexpr bool isValidSegment(Integer segment)
{
return segment >= Integer(0) && segment < Integer(SegmentUnknown);
}
static constexpr bool isValidSegment(qint8 segment) { return segment >= 0; }
template<typename Major, typename Minor,
if_valid_segment_type<Major> = true,
if_valid_segment_type<Minor> = true>
static constexpr QTypeRevision fromVersion(Major majorVersion, Minor minorVersion)
{
return Q_ASSERT(isValidSegment(majorVersion)),
Q_ASSERT(isValidSegment(minorVersion)),
QTypeRevision(quint8(majorVersion), quint8(minorVersion));
}
template<typename Major, if_valid_segment_type<Major> = true>
static constexpr QTypeRevision fromMajorVersion(Major majorVersion)
{
return Q_ASSERT(isValidSegment(majorVersion)),
QTypeRevision(quint8(majorVersion), SegmentUnknown);
}
template<typename Minor, if_valid_segment_type<Minor> = true>
static constexpr QTypeRevision fromMinorVersion(Minor minorVersion)
{
return Q_ASSERT(isValidSegment(minorVersion)),
QTypeRevision(SegmentUnknown, quint8(minorVersion));
}
template<typename Integer, if_valid_value_type<Integer> = true>
static constexpr QTypeRevision fromEncodedVersion(Integer value)
{
return Q_ASSERT((value & ~Integer(0xffff)) == Integer(0)),
QTypeRevision((value & Integer(0xff00)) >> 8, value & Integer(0xff));
}
static constexpr QTypeRevision zero() { return QTypeRevision(0, 0); }
constexpr QTypeRevision() = default;
constexpr bool hasMajorVersion() const { return m_majorVersion != SegmentUnknown; }
constexpr quint8 majorVersion() const { return m_majorVersion; }
constexpr bool hasMinorVersion() const { return m_minorVersion != SegmentUnknown; }
constexpr quint8 minorVersion() const { return m_minorVersion; }
constexpr bool isValid() const { return hasMajorVersion() || hasMinorVersion(); }
template<typename Integer, if_valid_value_type<Integer> = true>
constexpr Integer toEncodedVersion() const
{
return Integer(m_majorVersion << 8) | Integer(m_minorVersion);
}
private:
enum { SegmentUnknown = quint8(~0U) };
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
constexpr QTypeRevision(quint8 major, quint8 minor)
: m_minorVersion(minor), m_majorVersion(major) {}
quint8 m_minorVersion = SegmentUnknown;
quint8 m_majorVersion = SegmentUnknown;
#else
constexpr QTypeRevision(quint8 major, quint8 minor)
: m_majorVersion(major), m_minorVersion(minor) {}
quint8 m_majorVersion = SegmentUnknown;
quint8 m_minorVersion = SegmentUnknown;
#endif
};
inline constexpr bool operator==(QTypeRevision lhs, QTypeRevision rhs)
{
return lhs.toEncodedVersion<quint16>() == rhs.toEncodedVersion<quint16>();
}
inline constexpr bool operator!=(QTypeRevision lhs, QTypeRevision rhs)
{
return lhs.toEncodedVersion<quint16>() != rhs.toEncodedVersion<quint16>();
}
inline constexpr bool operator<(QTypeRevision lhs, QTypeRevision rhs)
{
return (!lhs.hasMajorVersion() && rhs.hasMajorVersion())
// non-0 major > unspecified major > major 0
? rhs.majorVersion() != 0
: ((lhs.hasMajorVersion() && !rhs.hasMajorVersion())
// major 0 < unspecified major < non-0 major
? lhs.majorVersion() == 0
: (lhs.majorVersion() != rhs.majorVersion()
// both majors specified and non-0
? lhs.majorVersion() < rhs.majorVersion()
: ((!lhs.hasMinorVersion() && rhs.hasMinorVersion())
// non-0 minor > unspecified minor > minor 0
? rhs.minorVersion() != 0
: ((lhs.hasMinorVersion() && !rhs.hasMinorVersion())
// minor 0 < unspecified minor < non-0 minor
? lhs.minorVersion() == 0
// both minors specified and non-0
: lhs.minorVersion() < rhs.minorVersion()))));
}
inline constexpr bool operator>(QTypeRevision lhs, QTypeRevision rhs)
{
return lhs != rhs && !(lhs < rhs);
}
inline constexpr bool operator<=(QTypeRevision lhs, QTypeRevision rhs)
{
return lhs == rhs || lhs < rhs;
}
inline constexpr bool operator>=(QTypeRevision lhs, QTypeRevision rhs)
{
return lhs == rhs || !(lhs < rhs);
}
Q_STATIC_ASSERT(sizeof(QTypeRevision) == 2);
Q_DECLARE_TYPEINFO(QTypeRevision, Q_MOVABLE_TYPE);
#ifndef QT_NO_DEBUG_STREAM
Q_CORE_EXPORT QDebug operator<<(QDebug, const QTypeRevision &revision);
#endif
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QVersionNumber)
Q_DECLARE_METATYPE(QTypeRevision)
#endif //QVERSIONNUMBER_H

View File

@ -908,9 +908,10 @@ void QDBusArgument::endArray()
\snippet code/src_qdbus_qdbusargument.cpp 7
If the type you want to marshall is a QMap or QHash, you need not
declare an \c{operator<<} function for it, since Qt D-Bus provides
generic templates to do the job of marshalling the data.
You usually don't need to provide an \c{operator<<} or \c{operator>>}
function for associative containers such as QHash or std::map,
since Qt D-Bus provides generic templates to do the job of marshalling
the data.
\sa endMap(), beginStructure(), beginArray(), beginMapEntry()
*/

View File

@ -224,7 +224,8 @@ Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QLineF &li
Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QLineF &line);
#endif
template<template <typename> class Container, typename T>
template<template <typename> class Container, typename T,
typename = typename Container<T>::iterator>
inline QDBusArgument &operator<<(QDBusArgument &arg, const Container<T> &list)
{
int id = qMetaTypeId<T>();
@ -237,7 +238,8 @@ inline QDBusArgument &operator<<(QDBusArgument &arg, const Container<T> &list)
return arg;
}
template<template <typename> class Container, typename T>
template<template <typename> class Container, typename T,
typename = typename Container<T>::iterator>
inline const QDBusArgument &operator>>(const QDBusArgument &arg, Container<T> &list)
{
arg.beginArray();
@ -252,35 +254,6 @@ inline const QDBusArgument &operator>>(const QDBusArgument &arg, Container<T> &l
return arg;
}
// QList specializations
template<typename T>
inline QDBusArgument &operator<<(QDBusArgument &arg, const QList<T> &list)
{
int id = qMetaTypeId<T>();
arg.beginArray(id);
typename QList<T>::ConstIterator it = list.constBegin();
typename QList<T>::ConstIterator end = list.constEnd();
for ( ; it != end; ++it)
arg << *it;
arg.endArray();
return arg;
}
template<typename T>
inline const QDBusArgument &operator>>(const QDBusArgument &arg, QList<T> &list)
{
arg.beginArray();
list.clear();
while (!arg.atEnd()) {
T item;
arg >> item;
list.push_back(item);
}
arg.endArray();
return arg;
}
inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantList &list)
{
int id = qMetaTypeId<QDBusVariant>();
@ -293,15 +266,16 @@ inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantList &list)
return arg;
}
// QMap specializations
template<typename Key, typename T>
inline QDBusArgument &operator<<(QDBusArgument &arg, const QMap<Key, T> &map)
// Specializations for associative containers
template <template <typename, typename> class Container, typename Key, typename T,
QtPrivate::IfAssociativeIteratorHasKeyAndValue<typename Container<Key, T>::iterator> = true>
inline QDBusArgument &operator<<(QDBusArgument &arg, const Container<Key, T> &map)
{
int kid = qMetaTypeId<Key>();
int vid = qMetaTypeId<T>();
arg.beginMap(kid, vid);
typename QMap<Key, T>::ConstIterator it = map.constBegin();
typename QMap<Key, T>::ConstIterator end = map.constEnd();
auto it = map.begin();
auto end = map.end();
for ( ; it != end; ++it) {
arg.beginMapEntry();
arg << it.key() << it.value();
@ -311,8 +285,27 @@ inline QDBusArgument &operator<<(QDBusArgument &arg, const QMap<Key, T> &map)
return arg;
}
template<typename Key, typename T>
inline const QDBusArgument &operator>>(const QDBusArgument &arg, QMap<Key, T> &map)
template <template <typename, typename> class Container, typename Key, typename T,
QtPrivate::IfAssociativeIteratorHasFirstAndSecond<typename Container<Key, T>::iterator> = true>
inline QDBusArgument &operator<<(QDBusArgument &arg, const Container<Key, T> &map)
{
int kid = qMetaTypeId<Key>();
int vid = qMetaTypeId<T>();
arg.beginMap(kid, vid);
auto it = map.begin();
auto end = map.end();
for ( ; it != end; ++it) {
arg.beginMapEntry();
arg << it->first << it->second;
arg.endMapEntry();
}
arg.endMap();
return arg;
}
template <template <typename, typename> class Container, typename Key, typename T,
typename = typename Container<Key, T>::iterator>
inline const QDBusArgument &operator>>(const QDBusArgument &arg, Container<Key, T> &map)
{
arg.beginMap();
map.clear();
@ -321,7 +314,7 @@ inline const QDBusArgument &operator>>(const QDBusArgument &arg, QMap<Key, T> &m
T value;
arg.beginMapEntry();
arg >> key >> value;
static_cast<QMultiMap<Key, T> &>(map).insert(key, value);
map.insert(key, value);
arg.endMapEntry();
}
arg.endMap();
@ -342,41 +335,6 @@ inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantMap &map)
return arg;
}
// QHash specializations
template<typename Key, typename T>
inline QDBusArgument &operator<<(QDBusArgument &arg, const QHash<Key, T> &map)
{
int kid = qMetaTypeId<Key>();
int vid = qMetaTypeId<T>();
arg.beginMap(kid, vid);
typename QHash<Key, T>::ConstIterator it = map.constBegin();
typename QHash<Key, T>::ConstIterator end = map.constEnd();
for ( ; it != end; ++it) {
arg.beginMapEntry();
arg << it.key() << it.value();
arg.endMapEntry();
}
arg.endMap();
return arg;
}
template<typename Key, typename T>
inline const QDBusArgument &operator>>(const QDBusArgument &arg, QHash<Key, T> &map)
{
arg.beginMap();
map.clear();
while (!arg.atEnd()) {
Key key;
T value;
arg.beginMapEntry();
arg >> key >> value;
static_cast<QMultiHash<Key, T> &>(map).insert(key, value);
arg.endMapEntry();
}
arg.endMap();
return arg;
}
inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantHash &map)
{
arg.beginMap(QMetaType::QString, qMetaTypeId<QDBusVariant>());

View File

@ -262,7 +262,6 @@ qt_extend_target(Gui CONDITION QT_FEATURE_opengl
opengl/qopenglfunctions.cpp opengl/qopenglfunctions.h
opengl/qopenglprogrambinarycache.cpp opengl/qopenglprogrambinarycache_p.h
opengl/qopenglshaderprogram.cpp opengl/qopenglshaderprogram.h
opengl/qopengltextureblitter.cpp opengl/qopengltextureblitter.h
opengl/qopenglversionfunctions.cpp opengl/qopenglversionfunctions.h
opengl/qopenglversionfunctionsfactory.cpp opengl/qopenglversionfunctionsfactory_p.h
opengl/qopenglvertexarrayobject.cpp opengl/qopenglvertexarrayobject.h

View File

@ -344,7 +344,6 @@ qt_extend_target(Gui CONDITION QT_FEATURE_opengl
opengl/qopenglfunctions.cpp opengl/qopenglfunctions.h
opengl/qopenglprogrambinarycache.cpp opengl/qopenglprogrambinarycache_p.h
opengl/qopenglshaderprogram.cpp opengl/qopenglshaderprogram.h
opengl/qopengltextureblitter.cpp opengl/qopengltextureblitter.h
opengl/qopenglversionfunctions.cpp opengl/qopenglversionfunctions.h
opengl/qopenglversionfunctionsfactory.cpp opengl/qopenglversionfunctionsfactory_p.h
opengl/qopenglvertexarrayobject.cpp opengl/qopenglvertexarrayobject.h

View File

@ -619,7 +619,6 @@ QAccessible::RootObjectHandler QAccessible::installRootObjectHandler(RootObjectH
QAccessible::ActivationObserver::~ActivationObserver()
{
// must be empty until ### Qt 6
}
/*!
@ -1334,7 +1333,6 @@ QColor QAccessibleInterface::backgroundColor() const
*/
QAccessibleEvent::~QAccessibleEvent()
{
// must be empty until ### Qt 6
}
/*! \fn QAccessible::Event QAccessibleEvent::type() const
@ -1414,7 +1412,6 @@ QAccessible::Id QAccessibleEvent::uniqueId() const
*/
QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent()
{
// must be empty until ### Qt 6
}
/*!
@ -1458,7 +1455,6 @@ QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent()
*/
QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent()
{
// must be empty until ### Qt 6
}
/*!
@ -1538,7 +1534,6 @@ QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent()
*/
QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent()
{
// must be empty until ### Qt 6
}
/*!
\class QAccessibleTextCursorEvent
@ -1567,7 +1562,6 @@ QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent()
*/
QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent()
{
// must be empty until ### Qt 6
}
@ -1608,7 +1602,6 @@ QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent()
*/
QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent()
{
// must be empty until ### Qt 6
}
@ -1651,7 +1644,6 @@ QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent()
*/
QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent()
{
// must be empty until ### Qt 6
}
/*!
@ -1713,7 +1705,6 @@ QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent()
*/
QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent()
{
// must be empty until ### Qt 6
}
@ -1748,7 +1739,6 @@ QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent()
*/
QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent()
{
// must be empty until ### Qt 6
}
@ -1978,7 +1968,6 @@ QDebug operator<<(QDebug d, const QAccessibleEvent &ev)
*/
QAccessibleTextInterface::~QAccessibleTextInterface()
{
// must be empty until ### Qt 6
}
/*!
@ -2367,7 +2356,6 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun
*/
QAccessibleEditableTextInterface::~QAccessibleEditableTextInterface()
{
// must be empty until ### Qt 6
}
/*!
@ -2412,7 +2400,6 @@ QAccessibleEditableTextInterface::~QAccessibleEditableTextInterface()
*/
QAccessibleValueInterface::~QAccessibleValueInterface()
{
// must be empty until ### Qt 6
}
/*!
@ -2476,7 +2463,6 @@ QAccessibleValueInterface::~QAccessibleValueInterface()
*/
QAccessibleImageInterface::~QAccessibleImageInterface()
{
// must be empty until ### Qt 6
}
/*!
@ -2496,7 +2482,6 @@ QAccessibleImageInterface::~QAccessibleImageInterface()
*/
QAccessibleTableCellInterface::~QAccessibleTableCellInterface()
{
// must be empty until ### Qt 6
}
/*!
@ -2564,7 +2549,6 @@ QAccessibleTableCellInterface::~QAccessibleTableCellInterface()
*/
QAccessibleTableInterface::~QAccessibleTableInterface()
{
// must be empty until ### Qt 6
}
/*!
@ -2740,7 +2724,6 @@ QAccessibleTableInterface::~QAccessibleTableInterface()
*/
QAccessibleActionInterface::~QAccessibleActionInterface()
{
// must be empty until ### Qt 6
}
/*!

View File

@ -557,6 +557,11 @@ qt_feature("directwrite1" PRIVATE
CONDITION libs.dwrite_1 OR FIXME
EMIT_IF WIN32
)
qt_feature("directwrite3" PRIVATE
LABEL "DirectWrite 3"
CONDITION QT_FEATURE_directwrite1 AND libs.dwrite_3 OR FIXME
EMIT_IF WIN32
)
qt_feature("directwrite2" PRIVATE
LABEL "DirectWrite 2"
CONDITION QT_FEATURE_directwrite1 AND libs.dwrite_2 OR FIXME

View File

@ -189,6 +189,20 @@
"-ldwrite"
]
},
"dwrite_3": {
"label": "DirectWrite 3",
"test": {
"main": [
"IUnknown *factory = 0;",
"DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory3),",
" &factory);"
]
},
"headers": "dwrite_3.h",
"sources": [
"-ldwrite"
]
},
"drm": {
"label": "KMS",
"test": {
@ -1145,6 +1159,12 @@
"condition": "libs.dwrite_1",
"output": [ "privateFeature" ]
},
"directwrite3": {
"label": "DirectWrite 3",
"emitIf": "config.win32",
"condition": "features.directwrite1 && libs.dwrite_3",
"output": [ "privateFeature" ]
},
"directwrite2": {
"label": "DirectWrite 2",
"emitIf": "config.win32",

View File

@ -2063,7 +2063,6 @@ QInputMethodEvent::QInputMethodEvent(const QInputMethodEvent &other)
QInputMethodEvent::~QInputMethodEvent()
{
// must be empty until ### Qt 6
}
/*!

View File

@ -613,6 +613,13 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME
\li \c {dpiawareness=[0|1|2} Sets the DPI awareness of the process
(see \l{High DPI Displays}, since Qt 5.4).
\li \c {fontengine=freetype}, uses the FreeType font engine.
\li \c {fontengine=directwrite}, uses the experimental DirectWrite
font database and defaults to using the DirectWrite font
engine (which is otherwise only used for some font types
or font properties.) This affects font selection and aims
to provide font naming more consistent with other platforms,
but does not support all font formats, such as Postscript
Type-1 or Microsoft FNT fonts.
\li \c {menus=[native|none]}, controls the use of native menus.
Native menus are implemented using Win32 API and are simpler than

View File

@ -623,7 +623,6 @@ bool QOpenGLContext::create()
*/
void QOpenGLContext::destroy()
{
deleteQGLContext();
Q_D(QOpenGLContext);
if (d->platformGLContext)
emit aboutToBeDestroyed();
@ -1176,44 +1175,6 @@ QScreen *QOpenGLContext::screen() const
return d->screen;
}
/*!
internal: Needs to have a pointer to qGLContext. But since this is in Qt GUI we can't
have any type information.
\internal
*/
void *QOpenGLContext::qGLContextHandle() const
{
Q_D(const QOpenGLContext);
return d->qGLContextHandle;
}
/*!
internal: If the delete function is specified QOpenGLContext "owns"
the passed context handle and will use the delete function to destroy it.
\internal
*/
void QOpenGLContext::setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *))
{
Q_D(QOpenGLContext);
d->qGLContextHandle = handle;
d->qGLContextDeleteFunction = qGLContextDeleteFunction;
}
/*!
\internal
*/
void QOpenGLContext::deleteQGLContext()
{
Q_D(QOpenGLContext);
if (d->qGLContextDeleteFunction && d->qGLContextHandle) {
d->qGLContextDeleteFunction(d->qGLContextHandle);
d->qGLContextDeleteFunction = nullptr;
d->qGLContextHandle = nullptr;
}
}
/*!
Returns the platform-specific handle for the OpenGL implementation that
is currently in use. (for example, a HMODULE on Windows)

View File

@ -218,8 +218,6 @@ Q_SIGNALS:
void aboutToBeDestroyed();
private:
friend class QGLContext;
friend class QGLPixelBuffer;
friend class QOpenGLContextResourceBase;
friend class QOpenGLPaintDevice;
friend class QOpenGLGlyphTexture;
@ -234,10 +232,6 @@ private:
friend class QAbstractOpenGLFunctionsPrivate;
friend class QOpenGLTexturePrivate;
void *qGLContextHandle() const;
void setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *));
void deleteQGLContext();
QOpenGLVersionFunctionsStorage* functionsBackendStorage() const;
void insertExternalFunctions(QAbstractOpenGLFunctions *f);
void removeExternalFunctions(QAbstractOpenGLFunctions *f);

View File

@ -197,9 +197,7 @@ class Q_GUI_EXPORT QOpenGLContextPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QOpenGLContext)
public:
QOpenGLContextPrivate()
: qGLContextHandle(nullptr)
, qGLContextDeleteFunction(nullptr)
, platformGLContext(nullptr)
: platformGLContext(nullptr)
, shareContext(nullptr)
, shareGroup(nullptr)
, screen(nullptr)
@ -228,9 +226,6 @@ public:
mutable QOpenGLVersionFunctionsStorage versionFunctionsStorage;
mutable QSet<QAbstractOpenGLFunctions *> externalVersionFunctions;
void *qGLContextHandle;
void (*qGLContextDeleteFunction)(void *handle);
QSurfaceFormat requestedFormat;
QPlatformOpenGLContext *platformGLContext;
QOpenGLContext *shareContext;

View File

@ -46,7 +46,7 @@
QT_BEGIN_NAMESPACE
namespace QPlatformGraphicsBufferHelper {
bool lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB, bool *premultipliedB, const QRect &rect = QRect());
Q_GUI_EXPORT bool lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB, bool *premultipliedB, const QRect &rect = QRect());
bool bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB = nullptr, bool *premultipliedB = nullptr, const QRect &rect = QRect());
}

View File

@ -16,7 +16,6 @@ qtConfig(opengl) {
opengl/qopenglversionfunctions.h \
opengl/qopenglversionfunctionsfactory_p.h \
opengl/qopenglvertexarrayobject.h \
opengl/qopengltextureblitter.h \
opengl/qopenglextrafunctions.h \
opengl/qopenglprogrambinarycache_p.h
@ -28,7 +27,6 @@ qtConfig(opengl) {
opengl/qopenglversionfunctions.cpp \
opengl/qopenglversionfunctionsfactory.cpp \
opengl/qopenglvertexarrayobject.cpp \
opengl/qopengltextureblitter.cpp \
opengl/qopenglprogrambinarycache.cpp
!qtConfig(opengles2) {

View File

@ -90,7 +90,7 @@ public:
void setStyle(Qt::BrushStyle);
#if QT_DEPRECATED_SINCE(5, 15)
QT_DEPRECATED_X("Use transform()") inline const QMatrix &matrix() const;
QT_DEPRECATED_X("Use transform()") inline QMatrix matrix() const;
QT_DEPRECATED_X("Use setTransform()") void setMatrix(const QMatrix &mat);
#endif // QT_DEPRECATED_SINCE(5, 15)
@ -161,7 +161,7 @@ inline Qt::BrushStyle QBrush::style() const { return d->style; }
inline const QColor &QBrush::color() const { return d->color; }
#if QT_DEPRECATED_SINCE(5, 15)
QT_DEPRECATED_X("Use transform()")
inline const QMatrix &QBrush::matrix() const { return d->transform.toAffine(); }
inline QMatrix QBrush::matrix() const { return d->transform.toAffine(); }
#endif // QT_DEPRECATED_SINCE(5, 15)
inline QTransform QBrush::transform() const { return d->transform; }
inline bool QBrush::isDetached() const { return d->ref.loadRelaxed() == 1; }

View File

@ -96,10 +96,15 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
QTextItem::RenderFlags flags, qreal width,
const QTextCharFormat &charFormat);
// Helper function to calculate left most position, width and flags for decoration drawing
Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
const QFixedPoint *positions, int glyphCount,
QFontEngine *fontEngine, const QFont &font,
const QTextCharFormat &charFormat);
static void qt_draw_decoration_for_glyphs(QPainter *painter,
const QPointF &decorationPosition,
const glyph_t *glyphArray,
const QFixedPoint *positions,
int glyphCount,
QFontEngine *fontEngine,
bool underline,
bool overline,
bool strikeOut);
static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush)
{
@ -2953,7 +2958,7 @@ void QPainter::setWorldMatrix(const QMatrix &matrix, bool combine)
{Coordinate System}
*/
const QMatrix &QPainter::worldMatrix() const
QMatrix QPainter::worldMatrix() const
{
Q_D(const QPainter);
if (!d->engine) {
@ -2984,7 +2989,7 @@ void QPainter::setMatrix(const QMatrix &matrix, bool combine)
\sa worldTransform()
*/
const QMatrix &QPainter::matrix() const
QMatrix QPainter::matrix() const
{
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
@ -3030,7 +3035,7 @@ QMatrix QPainter::combinedMatrix() const
\sa worldMatrix(), QPaintEngine::hasFeature(),
*/
const QMatrix &QPainter::deviceMatrix() const
QMatrix QPainter::deviceMatrix() const
{
Q_D(const QPainter);
if (!d->engine) {
@ -5607,40 +5612,31 @@ void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun)
fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition);
}
d->drawGlyphs(glyphIndexes, fixedPointPositions.data(), count, fontD->fontEngine,
glyphRun.overline(), glyphRun.underline(), glyphRun.strikeOut());
d->drawGlyphs(engineRequiresPretransformedGlyphPositions
? d->state->transform().map(position)
: position,
glyphIndexes,
fixedPointPositions.data(),
count,
fontD->fontEngine,
glyphRun.overline(),
glyphRun.underline(),
glyphRun.strikeOut());
}
void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positions,
void QPainterPrivate::drawGlyphs(const QPointF &decorationPosition,
const quint32 *glyphArray,
QFixedPoint *positions,
int glyphCount,
QFontEngine *fontEngine, bool overline, bool underline,
QFontEngine *fontEngine,
bool overline,
bool underline,
bool strikeOut)
{
Q_Q(QPainter);
updateState(state);
QFixed leftMost;
QFixed rightMost;
QFixed baseLine;
for (int i=0; i<glyphCount; ++i) {
glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]);
if (i == 0 || leftMost > positions[i].x)
leftMost = positions[i].x;
// We don't support glyphs that do not share a common baseline. If this turns out to
// be a relevant use case, then we need to find clusters of glyphs that share a baseline
// and do a drawTextItemDecorations call per cluster.
if (i == 0 || baseLine < positions[i].y)
baseLine = positions[i].y;
// We use the advance rather than the actual bounds to match the algorithm in drawText()
if (i == 0 || rightMost < positions[i].x + gm.xoff)
rightMost = positions[i].x + gm.xoff;
}
QFixed width = rightMost - leftMost;
if (extended != nullptr && state->matrix.isAffine()) {
QStaticTextItem staticTextItem;
staticTextItem.color = state->pen.color();
@ -5674,21 +5670,15 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positio
engine->drawTextItem(QPointF(0, 0), textItem);
}
QTextItemInt::RenderFlags flags;
if (underline)
flags |= QTextItemInt::Underline;
if (overline)
flags |= QTextItemInt::Overline;
if (strikeOut)
flags |= QTextItemInt::StrikeOut;
drawTextItemDecoration(q, QPointF(leftMost.toReal(), baseLine.toReal()),
fontEngine,
nullptr, // textEngine
(underline
? QTextCharFormat::SingleUnderline
: QTextCharFormat::NoUnderline),
flags, width.toReal(), QTextCharFormat());
qt_draw_decoration_for_glyphs(q,
decorationPosition,
glyphArray,
positions,
glyphCount,
fontEngine,
underline,
overline,
strikeOut);
}
#endif // QT_NO_RAWFONT
@ -5868,9 +5858,15 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
}
d->extended->drawStaticTextItem(item);
qt_draw_decoration_for_glyphs(this, item->glyphs, item->glyphPositions,
item->numGlyphs, item->fontEngine(), staticText_d->font,
QTextCharFormat());
qt_draw_decoration_for_glyphs(this,
topLeftPosition,
item->glyphs,
item->glyphPositions,
item->numGlyphs,
item->fontEngine(),
staticText_d->font.underline(),
staticText_d->font.overline(),
staticText_d->font.strikeOut());
}
if (currentColor != oldPen.color())
setPen(oldPen);
@ -6375,49 +6371,44 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
painter->setRenderHint(QPainter::Qt4CompatiblePainting);
}
Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
const QFixedPoint *positions, int glyphCount,
QFontEngine *fontEngine, const QFont &font,
const QTextCharFormat &charFormat)
static void qt_draw_decoration_for_glyphs(QPainter *painter,
const QPointF &decorationPosition,
const glyph_t *glyphArray,
const QFixedPoint *positions,
int glyphCount,
QFontEngine *fontEngine,
bool underline,
bool overline,
bool strikeOut)
{
if (!(font.underline() || font.strikeOut() || font.overline()))
if (!underline && !overline && !strikeOut)
return;
QFixed leftMost;
QFixed rightMost;
QFixed baseLine;
for (int i=0; i<glyphCount; ++i) {
glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]);
if (i == 0 || leftMost > positions[i].x)
leftMost = positions[i].x;
// We don't support glyphs that do not share a common baseline. If this turns out to
// be a relevant use case, then we need to find clusters of glyphs that share a baseline
// and do a drawTextItemDecoration call per cluster.
if (i == 0 || baseLine < positions[i].y)
baseLine = positions[i].y;
// We use the advance rather than the actual bounds to match the algorithm in drawText()
if (i == 0 || rightMost < positions[i].x + gm.xoff)
rightMost = positions[i].x + gm.xoff;
}
QFixed width = rightMost - leftMost;
QTextItem::RenderFlags flags;
if (font.underline())
if (underline)
flags |= QTextItem::Underline;
if (font.overline())
if (overline)
flags |= QTextItem::Overline;
if (font.strikeOut())
if (strikeOut)
flags |= QTextItem::StrikeOut;
drawTextItemDecoration(painter, QPointF(leftMost.toReal(), baseLine.toReal()),
bool rtl = positions[glyphCount - 1].x < positions[0].x;
QFixed baseline = positions[0].y;
glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[rtl ? 0 : glyphCount - 1]);
qreal width = rtl
? (positions[0].x + gm.xoff - positions[glyphCount - 1].x).toReal()
: (positions[glyphCount - 1].x + gm.xoff - positions[0].x).toReal();
drawTextItemDecoration(painter,
QPointF(decorationPosition.x(), baseline.toReal()),
fontEngine,
nullptr, // textEngine
font.underline() ? QTextCharFormat::SingleUnderline
: QTextCharFormat::NoUnderline, flags,
width.toReal(), charFormat);
underline ? QTextCharFormat::SingleUnderline
: QTextCharFormat::NoUnderline,
flags,
width,
QTextCharFormat());
}
void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti)

View File

@ -240,9 +240,9 @@ public:
QT_DEPRECATED_X("Use setTransform() instead")
void setMatrix(const QMatrix &matrix, bool combine = false);
QT_DEPRECATED_X("Use transform() instead")
const QMatrix &matrix() const;
QMatrix matrix() const;
QT_DEPRECATED_X("Use deviceTransform() instead")
const QMatrix &deviceMatrix() const;
QMatrix deviceMatrix() const;
QT_DEPRECATED_X("Use resetTransform() instead")
void resetMatrix();
#endif
@ -256,7 +256,7 @@ public:
QT_DEPRECATED_X("Use setWorldTransform() instead")
void setWorldMatrix(const QMatrix &matrix, bool combine = false);
QT_DEPRECATED_X("Use worldTransform() instead")
const QMatrix &worldMatrix() const;
QMatrix worldMatrix() const;
QT_DEPRECATED_X("Use combinedTransform() instead")
QMatrix combinedMatrix() const;
QT_DEPRECATED_X("Use setWorldMatrixEnabled() instead")

View File

@ -235,7 +235,7 @@ public:
void drawTextItem(const QPointF &p, const QTextItem &_ti, QTextEngine *textEngine);
#if !defined(QT_NO_RAWFONT)
void drawGlyphs(const quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount,
void drawGlyphs(const QPointF &decorationPosition, const quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount,
QFontEngine *fontEngine, bool overline = false, bool underline = false,
bool strikeOut = false);
#endif

View File

@ -40,43 +40,8 @@
#include "qplatformbackingstore.h"
#include <qwindow.h>
#include <qpixmap.h>
#include <private/qwindow_p.h>
#include <qopengl.h>
#include <qopenglcontext.h>
#include <QtGui/QMatrix4x4>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFunctions>
#ifndef QT_NO_OPENGL
#include <QtGui/qopengltextureblitter.h>
#include <QtGui/qoffscreensurface.h>
#endif
#include <qpa/qplatformgraphicsbuffer.h>
#include <qpa/qplatformgraphicsbufferhelper.h>
#ifndef GL_TEXTURE_BASE_LEVEL
#define GL_TEXTURE_BASE_LEVEL 0x813C
#endif
#ifndef GL_TEXTURE_MAX_LEVEL
#define GL_TEXTURE_MAX_LEVEL 0x813D
#endif
#ifndef GL_UNPACK_ROW_LENGTH
#define GL_UNPACK_ROW_LENGTH 0x0CF2
#endif
#ifndef GL_RGB10_A2
#define GL_RGB10_A2 0x8059
#endif
#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
#endif
#ifndef GL_FRAMEBUFFER_SRGB
#define GL_FRAMEBUFFER_SRGB 0x8DB9
#endif
#ifndef GL_FRAMEBUFFER_SRGB_CAPABLE
#define GL_FRAMEBUFFER_SRGB_CAPABLE 0x8DBA
#endif
#include <QtCore/private/qobject_p.h>
QT_BEGIN_NAMESPACE
@ -88,38 +53,19 @@ public:
QPlatformBackingStorePrivate(QWindow *w)
: window(w)
, backingStore(nullptr)
#ifndef QT_NO_OPENGL
, textureId(0)
, blitter(nullptr)
#endif
{
}
~QPlatformBackingStorePrivate()
{
#ifndef QT_NO_OPENGL
if (context) {
QOffscreenSurface offscreenSurface;
offscreenSurface.setFormat(context->format());
offscreenSurface.create();
context->makeCurrent(&offscreenSurface);
if (textureId)
context->functions()->glDeleteTextures(1, &textureId);
if (blitter)
blitter->destroy();
}
delete blitter;
delete openGLSupport;
#endif
}
QWindow *window;
QBackingStore *backingStore;
#ifndef QT_NO_OPENGL
QScopedPointer<QOpenGLContext> context;
mutable GLuint textureId;
mutable QSize textureSize;
mutable bool needsSwizzle;
mutable bool premultiplied;
QOpenGLTextureBlitter *blitter;
QPlatformBackingStoreOpenGLSupportBase *openGLSupport = nullptr;
#endif
};
@ -240,83 +186,20 @@ void QPlatformTextureList::clear()
*/
#ifndef QT_NO_OPENGL
static inline QRect deviceRect(const QRect &rect, QWindow *window)
{
QRect deviceRect(rect.topLeft() * window->devicePixelRatio(),
rect.size() * window->devicePixelRatio());
return deviceRect;
}
static inline QPoint deviceOffset(const QPoint &pt, QWindow *window)
{
return pt * window->devicePixelRatio();
}
static QRegion deviceRegion(const QRegion &region, QWindow *window, const QPoint &offset)
{
if (offset.isNull() && window->devicePixelRatio() <= 1)
return region;
QVector<QRect> rects;
rects.reserve(region.rectCount());
for (const QRect &rect : region)
rects.append(deviceRect(rect.translated(offset), window));
QRegion deviceRegion;
deviceRegion.setRects(rects.constData(), rects.count());
return deviceRegion;
}
static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
{
return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1,
topLeftRect.width(), topLeftRect.height());
}
static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect,
QOpenGLTextureBlitter *blitter, const QPoint &offset, bool canUseSrgb)
{
const QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty())
return;
QRect rectInWindow = textures->geometry(idx);
// relative to the TLW, not necessarily our window (if the flush is for a native child widget), have to adjust
rectInWindow.translate(-offset);
const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(deviceRect(clippedRectInWindow, window),
deviceWindowRect);
const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(deviceRect(srcRect, window),
deviceRect(rectInWindow, window).size(),
QOpenGLTextureBlitter::OriginBottomLeft);
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
const bool srgb = textures->flags(idx).testFlag(QPlatformTextureList::TextureIsSrgb);
if (srgb && canUseSrgb)
funcs->glEnable(GL_FRAMEBUFFER_SRGB);
blitter->blit(textures->textureId(idx), target, source);
if (srgb && canUseSrgb)
funcs->glDisable(GL_FRAMEBUFFER_SRGB);
}
/*!
Flushes the given \a region from the specified \a window onto the
screen, and composes it with the specified \a textures.
The default implementation retrieves the contents using toTexture()
If OpenGLSupport has been enabled using \c setOpenGLSupport,
the default implementation retrieves the contents using toTexture()
and composes using OpenGL. May be reimplemented in subclasses if there
is a more efficient native way to do it.
\note \a region is relative to the window which may not be top-level in case
\a window corresponds to a native child widget. \a offset is the position of
the native child relative to the top-level window.
\sa setOpenGLSupport()
*/
void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &region,
@ -324,162 +207,13 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
QPlatformTextureList *textures,
bool translucentBackground)
{
if (!qt_window_private(window)->receivedExpose)
return;
if (!d_ptr->context) {
d_ptr->context.reset(new QOpenGLContext);
d_ptr->context->setFormat(d_ptr->window->requestedFormat());
d_ptr->context->setScreen(d_ptr->window->screen());
d_ptr->context->setShareContext(qt_window_private(d_ptr->window)->shareContext());
if (!d_ptr->context->create()) {
qCWarning(lcQpaBackingStore, "composeAndFlush: QOpenGLContext creation failed");
return;
}
}
bool current = d_ptr->context->makeCurrent(window);
if (!current && !d_ptr->context->isValid()) {
delete d_ptr->blitter;
d_ptr->blitter = nullptr;
d_ptr->textureId = 0;
current = d_ptr->context->create() && d_ptr->context->makeCurrent(window);
}
if (!current) {
qCWarning(lcQpaBackingStore, "composeAndFlush: makeCurrent() failed");
return;
}
qCDebug(lcQpaBackingStore) << "Composing and flushing" << region << "of" << window
<< "at offset" << offset << "with" << textures->count() << "texture(s) in" << textures;
QWindowPrivate::get(window)->lastComposeTime.start();
QOpenGLFunctions *funcs = d_ptr->context->functions();
funcs->glViewport(0, 0, qRound(window->width() * window->devicePixelRatio()), qRound(window->height() * window->devicePixelRatio()));
funcs->glClearColor(0, 0, 0, translucentBackground ? 0 : 1);
funcs->glClear(GL_COLOR_BUFFER_BIT);
if (!d_ptr->blitter) {
d_ptr->blitter = new QOpenGLTextureBlitter;
d_ptr->blitter->create();
}
d_ptr->blitter->bind();
const QRect deviceWindowRect = deviceRect(QRect(QPoint(), window->size()), window);
const QPoint deviceWindowOffset = deviceOffset(offset, window);
bool canUseSrgb = false;
// If there are any sRGB textures in the list, check if the destination
// framebuffer is sRGB capable.
for (int i = 0; i < textures->count(); ++i) {
if (textures->flags(i).testFlag(QPlatformTextureList::TextureIsSrgb)) {
GLint cap = 0;
funcs->glGetIntegerv(GL_FRAMEBUFFER_SRGB_CAPABLE, &cap);
if (cap)
canUseSrgb = true;
break;
}
}
// Textures for renderToTexture widgets.
for (int i = 0; i < textures->count(); ++i) {
if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset, canUseSrgb);
}
// Backingstore texture with the normal widgets.
GLuint textureId = 0;
QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft;
if (QPlatformGraphicsBuffer *graphicsBuffer = this->graphicsBuffer()) {
if (graphicsBuffer->size() != d_ptr->textureSize) {
if (d_ptr->textureId)
funcs->glDeleteTextures(1, &d_ptr->textureId);
funcs->glGenTextures(1, &d_ptr->textureId);
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
QOpenGLContext *ctx = QOpenGLContext::currentContext();
if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
}
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle, &d_ptr->premultiplied)) {
d_ptr->textureSize = graphicsBuffer->size();
} else {
d_ptr->textureSize = QSize(0,0);
}
graphicsBuffer->unlock();
} else if (!region.isEmpty()){
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle, &d_ptr->premultiplied);
graphicsBuffer->unlock();
}
if (graphicsBuffer->origin() == QPlatformGraphicsBuffer::OriginBottomLeft)
origin = QOpenGLTextureBlitter::OriginBottomLeft;
textureId = d_ptr->textureId;
} else {
TextureFlags flags;
textureId = toTexture(deviceRegion(region, window, offset), &d_ptr->textureSize, &flags);
d_ptr->needsSwizzle = (flags & TextureSwizzle) != 0;
d_ptr->premultiplied = (flags & TexturePremultiplied) != 0;
if (flags & TextureFlip)
origin = QOpenGLTextureBlitter::OriginBottomLeft;
}
funcs->glEnable(GL_BLEND);
if (d_ptr->premultiplied)
funcs->glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
if (auto *c = d_ptr->openGLSupport)
c->composeAndFlush(window, region, offset, textures, translucentBackground);
else
funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
if (textureId) {
if (d_ptr->needsSwizzle)
d_ptr->blitter->setRedBlueSwizzle(true);
// The backingstore is for the entire tlw.
// In case of native children offset tells the position relative to the tlw.
const QRect srcRect = toBottomLeftRect(deviceWindowRect.translated(deviceWindowOffset), d_ptr->textureSize.height());
const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(srcRect,
d_ptr->textureSize,
origin);
d_ptr->blitter->blit(textureId, QMatrix4x4(), source);
if (d_ptr->needsSwizzle)
d_ptr->blitter->setRedBlueSwizzle(false);
}
// Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
bool blendIsPremultiplied = d_ptr->premultiplied;
for (int i = 0; i < textures->count(); ++i) {
const QPlatformTextureList::Flags flags = textures->flags(i);
if (flags.testFlag(QPlatformTextureList::NeedsPremultipliedAlphaBlending)) {
if (!blendIsPremultiplied) {
funcs->glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
blendIsPremultiplied = true;
}
} else {
if (blendIsPremultiplied) {
funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
blendIsPremultiplied = false;
}
}
if (flags.testFlag(QPlatformTextureList::StacksOnTop))
blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset, canUseSrgb);
}
funcs->glDisable(GL_BLEND);
d_ptr->blitter->release();
d_ptr->context->swapBuffers(window);
qWarning() << Q_FUNC_INFO << "no opengl support set";
}
#endif
/*!
Implemented in subclasses to return the content of the backingstore as a QImage.
@ -504,7 +238,8 @@ QImage QPlatformBackingStore::toImage() const
The ownership of the texture is not transferred. The caller must not store
the return value between calls, but instead call this function before each use.
The default implementation returns a cached texture if \a dirtyRegion is empty and
If OpenGLSupport has been enabled using \c setOpenGLSupport,
the default implementation returns a cached texture if \a dirtyRegion is empty and
\a textureSize matches the backingstore size, otherwise it retrieves the content using
toImage() and performs a texture upload. This works only if the value of \a textureSize
is preserved between the calls to this function.
@ -520,141 +255,17 @@ QImage QPlatformBackingStore::toImage() const
flags will be set to include \c TextureFlip.
\note \a dirtyRegion is relative to the backingstore so no adjustment is needed.
\sa setOpenGLSupport()
*/
GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const
{
Q_ASSERT(textureSize);
Q_ASSERT(flags);
QImage image = toImage();
QSize imageSize = image.size();
QOpenGLContext *ctx = QOpenGLContext::currentContext();
GLenum internalFormat = GL_RGBA;
GLuint pixelType = GL_UNSIGNED_BYTE;
bool needsConversion = false;
*flags = { };
switch (image.format()) {
case QImage::Format_ARGB32_Premultiplied:
*flags |= TexturePremultiplied;
Q_FALLTHROUGH();
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
*flags |= TextureSwizzle;
break;
case QImage::Format_RGBA8888_Premultiplied:
*flags |= TexturePremultiplied;
Q_FALLTHROUGH();
case QImage::Format_RGBX8888:
case QImage::Format_RGBA8888:
break;
case QImage::Format_BGR30:
case QImage::Format_A2BGR30_Premultiplied:
if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
internalFormat = GL_RGB10_A2;
*flags |= TexturePremultiplied;
} else {
needsConversion = true;
}
break;
case QImage::Format_RGB30:
case QImage::Format_A2RGB30_Premultiplied:
if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
internalFormat = GL_RGB10_A2;
*flags |= TextureSwizzle | TexturePremultiplied;
} else {
needsConversion = true;
}
break;
default:
needsConversion = true;
break;
}
if (imageSize.isEmpty()) {
*textureSize = imageSize;
if (auto *c = d_ptr->openGLSupport)
return c->toTexture(dirtyRegion, textureSize, flags);
else {
qWarning() << Q_FUNC_INFO << "no opengl support set";
return 0;
}
// Must rely on the input only, not d_ptr.
// With the default composeAndFlush() textureSize is &d_ptr->textureSize.
bool resized = *textureSize != imageSize;
if (dirtyRegion.isEmpty() && !resized)
return d_ptr->textureId;
*textureSize = imageSize;
if (needsConversion)
image = image.convertToFormat(QImage::Format_RGBA8888);
// The image provided by the backingstore may have a stride larger than width * 4, for
// instance on platforms that manually implement client-side decorations.
static const int bytesPerPixel = 4;
const int strideInPixels = image.bytesPerLine() / bytesPerPixel;
const bool hasUnpackRowLength = !ctx->isOpenGLES() || ctx->format().majorVersion() >= 3;
QOpenGLFunctions *funcs = ctx->functions();
if (hasUnpackRowLength) {
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, strideInPixels);
} else if (strideInPixels != image.width()) {
// No UNPACK_ROW_LENGTH on ES 2.0 and yet we would need it. This case is typically
// hit with QtWayland which is rarely used in combination with a ES2.0-only GL
// implementation. Therefore, accept the performance hit and do a copy.
image = image.copy();
}
if (resized) {
if (d_ptr->textureId)
funcs->glDeleteTextures(1, &d_ptr->textureId);
funcs->glGenTextures(1, &d_ptr->textureId);
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
}
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, imageSize.width(), imageSize.height(), 0, GL_RGBA, pixelType,
const_cast<uchar*>(image.constBits()));
} else {
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
QRect imageRect = image.rect();
QRect rect = dirtyRegion.boundingRect() & imageRect;
if (hasUnpackRowLength) {
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.constScanLine(rect.y()) + rect.x() * bytesPerPixel);
} else {
// if the rect is wide enough it's cheaper to just
// extend it instead of doing an image copy
if (rect.width() >= imageRect.width() / 2) {
rect.setX(0);
rect.setWidth(imageRect.width());
}
// if the sub-rect is full-width we can pass the image data directly to
// OpenGL instead of copying, since there's no gap between scanlines
if (rect.width() == imageRect.width()) {
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.constScanLine(rect.y()));
} else {
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.copy(rect).constBits());
}
}
}
if (hasUnpackRowLength)
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
return d_ptr->textureId;
}
#endif // QT_NO_OPENGL
@ -706,6 +317,18 @@ QBackingStore *QPlatformBackingStore::backingStore() const
return d_ptr->backingStore;
}
#ifndef QT_NO_OPENGL
/*!
Injects an OpenGL implementation helper. Platform integrations need to
call this if they intend to use the default OpenGL implementations of
composeAndFlush or toTexture.
*/
void QPlatformBackingStore::setOpenGLSupport(QPlatformBackingStoreOpenGLSupportBase *openGLSupport)
{
d_ptr->openGLSupport = openGLSupport;
}
#endif // QT_NO_OPENGL
/*!
This function is called before painting onto the surface begins,
with the \a region in which the painting will occur.

View File

@ -67,11 +67,10 @@ class QRect;
class QPoint;
class QImage;
class QPlatformBackingStorePrivate;
class QPlatformWindow;
class QPlatformTextureList;
class QPlatformTextureListPrivate;
class QOpenGLContext;
class QPlatformGraphicsBuffer;
class QPlatformBackingStoreOpenGLSupportBase;
#ifndef QT_NO_OPENGL
class Q_GUI_EXPORT QPlatformTextureList : public QObject
@ -118,6 +117,8 @@ public:
QWindow *window() const;
QBackingStore *backingStore() const;
void setOpenGLSupport(QPlatformBackingStoreOpenGLSupportBase *openGLSupport);
virtual QPaintDevice *paintDevice() = 0;
virtual void flush(QWindow *window, const QRegion &region, const QPoint &offset) = 0;
@ -153,6 +154,17 @@ private:
friend class QBackingStore;
};
#ifndef QT_NO_OPENGL
class Q_GUI_EXPORT QPlatformBackingStoreOpenGLSupportBase // pure interface
{
public:
virtual void composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
QPlatformTextureList *textures, bool translucentBackground) = 0;
virtual GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize, QPlatformBackingStore::TextureFlags *flags) const = 0;
virtual ~QPlatformBackingStoreOpenGLSupportBase() {}
};
#endif // QT_NO_OPENGL
#ifndef QT_NO_OPENGL
Q_DECLARE_OPERATORS_FOR_FLAGS(QPlatformBackingStore::TextureFlags)
#endif

View File

@ -76,20 +76,20 @@ static void nanWarning(const char *func)
ny = FY_; \
break; \
case TxTranslate: \
nx = FX_ + affine._dx; \
ny = FY_ + affine._dy; \
nx = FX_ + m_matrix[2][0]; \
ny = FY_ + m_matrix[2][1]; \
break; \
case TxScale: \
nx = affine._m11 * FX_ + affine._dx; \
ny = affine._m22 * FY_ + affine._dy; \
nx = m_matrix[0][0] * FX_ + m_matrix[2][0]; \
ny = m_matrix[1][1] * FY_ + m_matrix[2][1]; \
break; \
case TxRotate: \
case TxShear: \
case TxProject: \
nx = affine._m11 * FX_ + affine._m21 * FY_ + affine._dx; \
ny = affine._m12 * FX_ + affine._m22 * FY_ + affine._dy; \
nx = m_matrix[0][0] * FX_ + m_matrix[1][0] * FY_ + m_matrix[2][0]; \
ny = m_matrix[0][1] * FX_ + m_matrix[1][1] * FY_ + m_matrix[2][1]; \
if (t == TxProject) { \
qreal w = (m_13 * FX_ + m_23 * FY_ + m_33); \
qreal w = (m_matrix[0][2] * FX_ + m_matrix[1][2] * FY_ + m_matrix[2][2]); \
if (w < qreal(Q_NEAR_CLIP)) w = qreal(Q_NEAR_CLIP); \
w = 1./w; \
nx *= w; \
@ -261,8 +261,7 @@ static void nanWarning(const char *func)
\sa reset()
*/
QTransform::QTransform()
: affine(true)
, m_13(0), m_23(0), m_33(1)
: m_matrix{ {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }
, m_type(TxNone)
, m_dirty(TxNone)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@ -282,8 +281,7 @@ QTransform::QTransform()
QTransform::QTransform(qreal h11, qreal h12, qreal h13,
qreal h21, qreal h22, qreal h23,
qreal h31, qreal h32, qreal h33)
: affine(h11, h12, h21, h22, h31, h32, true)
, m_13(h13), m_23(h23), m_33(h33)
: m_matrix{ {h11, h12, h13}, {h21, h22, h23}, {h31, h32, h33} }
, m_type(TxNone)
, m_dirty(TxProject)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@ -301,8 +299,7 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h13,
*/
QTransform::QTransform(qreal h11, qreal h12, qreal h21,
qreal h22, qreal dx, qreal dy)
: affine(h11, h12, h21, h22, dx, dy, true)
, m_13(0), m_23(0), m_33(1)
: m_matrix{ {h11, h12, 0}, {h21, h22, 0}, {dx, dy, 1} }
, m_type(TxNone)
, m_dirty(TxShear)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@ -321,8 +318,7 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h21,
and 1 respectively.
*/
QTransform::QTransform(const QMatrix &mtx)
: affine(mtx._m11, mtx._m12, mtx._m21, mtx._m22, mtx._dx, mtx._dy, true),
m_13(0), m_23(0), m_33(1)
: m_matrix{ {mtx._m11, mtx._m12, 0}, {mtx._m21, mtx._m22, 0}, {mtx._dx, mtx._dy, 1} }
, m_type(TxNone)
, m_dirty(TxShear)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@ -338,17 +334,17 @@ QTransform::QTransform(const QMatrix &mtx)
QTransform QTransform::adjoint() const
{
qreal h11, h12, h13,
h21, h22, h23,
h31, h32, h33;
h11 = affine._m22*m_33 - m_23*affine._dy;
h21 = m_23*affine._dx - affine._m21*m_33;
h31 = affine._m21*affine._dy - affine._m22*affine._dx;
h12 = m_13*affine._dy - affine._m12*m_33;
h22 = affine._m11*m_33 - m_13*affine._dx;
h32 = affine._m12*affine._dx - affine._m11*affine._dy;
h13 = affine._m12*m_23 - m_13*affine._m22;
h23 = m_13*affine._m21 - affine._m11*m_23;
h33 = affine._m11*affine._m22 - affine._m12*affine._m21;
h21, h22, h23,
h31, h32, h33;
h11 = m_matrix[1][1] * m_matrix[2][2] - m_matrix[1][2] * m_matrix[2][1];
h21 = m_matrix[1][2] * m_matrix[2][0] - m_matrix[1][0] * m_matrix[2][2];
h31 = m_matrix[1][0] * m_matrix[2][1] - m_matrix[1][1] * m_matrix[2][0];
h12 = m_matrix[0][2] * m_matrix[2][1] - m_matrix[0][1] * m_matrix[2][2];
h22 = m_matrix[0][0] * m_matrix[2][2] - m_matrix[0][2] * m_matrix[2][0];
h32 = m_matrix[0][1] * m_matrix[2][0] - m_matrix[0][0] * m_matrix[2][1];
h13 = m_matrix[0][1] * m_matrix[1][2] - m_matrix[0][2] * m_matrix[1][1];
h23 = m_matrix[0][2] * m_matrix[1][0] - m_matrix[0][0] * m_matrix[1][2];
h33 = m_matrix[0][0] * m_matrix[1][1] - m_matrix[0][1] * m_matrix[1][0];
return QTransform(h11, h12, h13,
h21, h22, h23,
@ -360,9 +356,9 @@ QTransform QTransform::adjoint() const
*/
QTransform QTransform::transposed() const
{
QTransform t(affine._m11, affine._m21, affine._dx,
affine._m12, affine._m22, affine._dy,
m_13, m_23, m_33, true);
QTransform t(m_matrix[0][0], m_matrix[1][0], m_matrix[2][0],
m_matrix[0][1], m_matrix[1][1], m_matrix[2][1],
m_matrix[0][2], m_matrix[1][2], m_matrix[2][2], true);
return t;
}
@ -385,23 +381,23 @@ QTransform QTransform::inverted(bool *invertible) const
case TxNone:
break;
case TxTranslate:
invert.affine._dx = -affine._dx;
invert.affine._dy = -affine._dy;
invert.m_matrix[2][0] = -m_matrix[2][0];
invert.m_matrix[2][1] = -m_matrix[2][1];
break;
case TxScale:
inv = !qFuzzyIsNull(affine._m11);
inv &= !qFuzzyIsNull(affine._m22);
inv = !qFuzzyIsNull(m_matrix[0][0]);
inv &= !qFuzzyIsNull(m_matrix[1][1]);
if (inv) {
invert.affine._m11 = 1. / affine._m11;
invert.affine._m22 = 1. / affine._m22;
invert.affine._dx = -affine._dx * invert.affine._m11;
invert.affine._dy = -affine._dy * invert.affine._m22;
invert.m_matrix[0][0] = 1. / m_matrix[0][0];
invert.m_matrix[1][1] = 1. / m_matrix[1][1];
invert.m_matrix[2][0] = -m_matrix[2][0] * invert.m_matrix[0][0];
invert.m_matrix[2][1] = -m_matrix[2][1] * invert.m_matrix[1][1];
}
break;
case TxRotate:
case TxShear:
invert.affine = affine.inverted(&inv);
break;
// case TxRotate:
// case TxShear:
// invert.affine = affine.inverted(&inv);
// break;
default:
// general case
qreal det = determinant();
@ -442,24 +438,24 @@ QTransform &QTransform::translate(qreal dx, qreal dy)
switch(inline_type()) {
case TxNone:
affine._dx = dx;
affine._dy = dy;
m_matrix[2][0] = dx;
m_matrix[2][1] = dy;
break;
case TxTranslate:
affine._dx += dx;
affine._dy += dy;
m_matrix[2][0] += dx;
m_matrix[2][1] += dy;
break;
case TxScale:
affine._dx += dx*affine._m11;
affine._dy += dy*affine._m22;
m_matrix[2][0] += dx * m_matrix[0][0];
m_matrix[2][1] += dy * m_matrix[1][1];
break;
case TxProject:
m_33 += dx*m_13 + dy*m_23;
m_matrix[2][2] += dx * m_matrix[0][2] + dy * m_matrix[1][2];
Q_FALLTHROUGH();
case TxShear:
case TxRotate:
affine._dx += dx*affine._m11 + dy*affine._m21;
affine._dy += dy*affine._m22 + dx*affine._m12;
m_matrix[2][0] += dx * m_matrix[0][0] + dy * m_matrix[1][0];
m_matrix[2][1] += dy * m_matrix[1][1] + dx * m_matrix[0][1];
break;
}
if (m_dirty < TxTranslate)
@ -511,21 +507,21 @@ QTransform & QTransform::scale(qreal sx, qreal sy)
switch(inline_type()) {
case TxNone:
case TxTranslate:
affine._m11 = sx;
affine._m22 = sy;
m_matrix[0][0] = sx;
m_matrix[1][1] = sy;
break;
case TxProject:
m_13 *= sx;
m_23 *= sy;
m_matrix[0][2] *= sx;
m_matrix[1][2] *= sy;
Q_FALLTHROUGH();
case TxRotate:
case TxShear:
affine._m12 *= sx;
affine._m21 *= sy;
m_matrix[0][1] *= sx;
m_matrix[1][0] *= sy;
Q_FALLTHROUGH();
case TxScale:
affine._m11 *= sx;
affine._m22 *= sy;
m_matrix[0][0] *= sx;
m_matrix[1][1] *= sy;
break;
}
if (m_dirty < TxScale)
@ -577,28 +573,30 @@ QTransform & QTransform::shear(qreal sh, qreal sv)
switch(inline_type()) {
case TxNone:
case TxTranslate:
affine._m12 = sv;
affine._m21 = sh;
m_matrix[0][1] = sv;
m_matrix[1][0] = sh;
break;
case TxScale:
affine._m12 = sv*affine._m22;
affine._m21 = sh*affine._m11;
m_matrix[0][1] = sv*m_matrix[1][1];
m_matrix[1][0] = sh*m_matrix[0][0];
break;
case TxProject: {
qreal tm13 = sv*m_23;
qreal tm23 = sh*m_13;
m_13 += tm13;
m_23 += tm23;
qreal tm13 = sv * m_matrix[1][2];
qreal tm23 = sh * m_matrix[0][2];
m_matrix[0][2] += tm13;
m_matrix[1][2] += tm23;
}
Q_FALLTHROUGH();
case TxRotate:
case TxShear: {
qreal tm11 = sv*affine._m21;
qreal tm22 = sh*affine._m12;
qreal tm12 = sv*affine._m22;
qreal tm21 = sh*affine._m11;
affine._m11 += tm11; affine._m12 += tm12;
affine._m21 += tm21; affine._m22 += tm22;
qreal tm11 = sv * m_matrix[1][0];
qreal tm22 = sh * m_matrix[0][1];
qreal tm12 = sv * m_matrix[1][1];
qreal tm21 = sh * m_matrix[0][0];
m_matrix[0][0] += tm11;
m_matrix[0][1] += tm12;
m_matrix[1][0] += tm21;
m_matrix[1][1] += tm22;
break;
}
}
@ -653,35 +651,39 @@ QTransform & QTransform::rotate(qreal a, Qt::Axis axis)
switch(inline_type()) {
case TxNone:
case TxTranslate:
affine._m11 = cosa;
affine._m12 = sina;
affine._m21 = -sina;
affine._m22 = cosa;
m_matrix[0][0] = cosa;
m_matrix[0][1] = sina;
m_matrix[1][0] = -sina;
m_matrix[1][1] = cosa;
break;
case TxScale: {
qreal tm11 = cosa*affine._m11;
qreal tm12 = sina*affine._m22;
qreal tm21 = -sina*affine._m11;
qreal tm22 = cosa*affine._m22;
affine._m11 = tm11; affine._m12 = tm12;
affine._m21 = tm21; affine._m22 = tm22;
qreal tm11 = cosa * m_matrix[0][0];
qreal tm12 = sina * m_matrix[1][1];
qreal tm21 = -sina * m_matrix[0][0];
qreal tm22 = cosa * m_matrix[1][1];
m_matrix[0][0] = tm11;
m_matrix[0][1] = tm12;
m_matrix[1][0] = tm21;
m_matrix[1][1] = tm22;
break;
}
case TxProject: {
qreal tm13 = cosa*m_13 + sina*m_23;
qreal tm23 = -sina*m_13 + cosa*m_23;
m_13 = tm13;
m_23 = tm23;
qreal tm13 = cosa * m_matrix[0][2] + sina * m_matrix[1][2];
qreal tm23 = -sina * m_matrix[0][2] + cosa * m_matrix[1][2];
m_matrix[0][2] = tm13;
m_matrix[1][2] = tm23;
Q_FALLTHROUGH();
}
case TxRotate:
case TxShear: {
qreal tm11 = cosa*affine._m11 + sina*affine._m21;
qreal tm12 = cosa*affine._m12 + sina*affine._m22;
qreal tm21 = -sina*affine._m11 + cosa*affine._m21;
qreal tm22 = -sina*affine._m12 + cosa*affine._m22;
affine._m11 = tm11; affine._m12 = tm12;
affine._m21 = tm21; affine._m22 = tm22;
qreal tm11 = cosa * m_matrix[0][0] + sina * m_matrix[1][0];
qreal tm12 = cosa * m_matrix[0][1] + sina * m_matrix[1][1];
qreal tm21 = -sina * m_matrix[0][0] + cosa * m_matrix[1][0];
qreal tm22 = -sina * m_matrix[0][1] + cosa * m_matrix[1][1];
m_matrix[0][0] = tm11;
m_matrix[0][1] = tm12;
m_matrix[1][0] = tm21;
m_matrix[1][1] = tm22;
break;
}
}
@ -690,11 +692,11 @@ QTransform & QTransform::rotate(qreal a, Qt::Axis axis)
} else {
QTransform result;
if (axis == Qt::YAxis) {
result.affine._m11 = cosa;
result.m_13 = -sina * inv_dist_to_plane;
result.m_matrix[0][0] = cosa;
result.m_matrix[0][2] = -sina * inv_dist_to_plane;
} else {
result.affine._m22 = cosa;
result.m_23 = -sina * inv_dist_to_plane;
result.m_matrix[1][1] = cosa;
result.m_matrix[1][2] = -sina * inv_dist_to_plane;
}
result.m_type = TxProject;
*this = result * *this;
@ -732,35 +734,39 @@ QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis)
switch(inline_type()) {
case TxNone:
case TxTranslate:
affine._m11 = cosa;
affine._m12 = sina;
affine._m21 = -sina;
affine._m22 = cosa;
m_matrix[0][0] = cosa;
m_matrix[0][1] = sina;
m_matrix[1][0] = -sina;
m_matrix[1][1] = cosa;
break;
case TxScale: {
qreal tm11 = cosa*affine._m11;
qreal tm12 = sina*affine._m22;
qreal tm21 = -sina*affine._m11;
qreal tm22 = cosa*affine._m22;
affine._m11 = tm11; affine._m12 = tm12;
affine._m21 = tm21; affine._m22 = tm22;
qreal tm11 = cosa * m_matrix[0][0];
qreal tm12 = sina * m_matrix[1][1];
qreal tm21 = -sina * m_matrix[0][0];
qreal tm22 = cosa * m_matrix[1][1];
m_matrix[0][0] = tm11;
m_matrix[0][1] = tm12;
m_matrix[1][0] = tm21;
m_matrix[1][1] = tm22;
break;
}
case TxProject: {
qreal tm13 = cosa*m_13 + sina*m_23;
qreal tm23 = -sina*m_13 + cosa*m_23;
m_13 = tm13;
m_23 = tm23;
qreal tm13 = cosa * m_matrix[0][2] + sina * m_matrix[1][2];
qreal tm23 = -sina * m_matrix[0][2] + cosa * m_matrix[1][2];
m_matrix[0][2] = tm13;
m_matrix[1][2] = tm23;
Q_FALLTHROUGH();
}
case TxRotate:
case TxShear: {
qreal tm11 = cosa*affine._m11 + sina*affine._m21;
qreal tm12 = cosa*affine._m12 + sina*affine._m22;
qreal tm21 = -sina*affine._m11 + cosa*affine._m21;
qreal tm22 = -sina*affine._m12 + cosa*affine._m22;
affine._m11 = tm11; affine._m12 = tm12;
affine._m21 = tm21; affine._m22 = tm22;
qreal tm11 = cosa * m_matrix[0][0] + sina * m_matrix[1][0];
qreal tm12 = cosa * m_matrix[0][1] + sina * m_matrix[1][1];
qreal tm21 = -sina * m_matrix[0][0] + cosa * m_matrix[1][0];
qreal tm22 = -sina * m_matrix[0][1] + cosa * m_matrix[1][1];
m_matrix[0][0] = tm11;
m_matrix[0][1] = tm12;
m_matrix[1][0] = tm21;
m_matrix[1][1] = tm22;
break;
}
}
@ -769,11 +775,11 @@ QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis)
} else {
QTransform result;
if (axis == Qt::YAxis) {
result.affine._m11 = cosa;
result.m_13 = -sina * inv_dist_to_plane;
result.m_matrix[0][0] = cosa;
result.m_matrix[0][2] = -sina * inv_dist_to_plane;
} else {
result.affine._m22 = cosa;
result.m_23 = -sina * inv_dist_to_plane;
result.m_matrix[1][1] = cosa;
result.m_matrix[1][2] = -sina * inv_dist_to_plane;
}
result.m_type = TxProject;
*this = result * *this;
@ -788,15 +794,15 @@ QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis)
*/
bool QTransform::operator==(const QTransform &o) const
{
return affine._m11 == o.affine._m11 &&
affine._m12 == o.affine._m12 &&
affine._m21 == o.affine._m21 &&
affine._m22 == o.affine._m22 &&
affine._dx == o.affine._dx &&
affine._dy == o.affine._dy &&
m_13 == o.m_13 &&
m_23 == o.m_23 &&
m_33 == o.m_33;
return m_matrix[0][0] == o.m_matrix[0][0] &&
m_matrix[0][1] == o.m_matrix[0][1] &&
m_matrix[1][0] == o.m_matrix[1][0] &&
m_matrix[1][1] == o.m_matrix[1][1] &&
m_matrix[2][0] == o.m_matrix[2][0] &&
m_matrix[2][1] == o.m_matrix[2][1] &&
m_matrix[0][2] == o.m_matrix[0][2] &&
m_matrix[1][2] == o.m_matrix[1][2] &&
m_matrix[2][2] == o.m_matrix[2][2];
}
/*!
@ -854,56 +860,59 @@ QTransform & QTransform::operator*=(const QTransform &o)
case TxNone:
break;
case TxTranslate:
affine._dx += o.affine._dx;
affine._dy += o.affine._dy;
m_matrix[2][0] += o.m_matrix[2][0];
m_matrix[2][1] += o.m_matrix[2][1];
break;
case TxScale:
{
qreal m11 = affine._m11*o.affine._m11;
qreal m22 = affine._m22*o.affine._m22;
qreal m11 = m_matrix[0][0] * o.m_matrix[0][0];
qreal m22 = m_matrix[1][1] * o.m_matrix[1][1];
qreal m31 = affine._dx*o.affine._m11 + o.affine._dx;
qreal m32 = affine._dy*o.affine._m22 + o.affine._dy;
qreal m31 = m_matrix[2][0] * o.m_matrix[0][0] + o.m_matrix[2][0];
qreal m32 = m_matrix[2][1] * o.m_matrix[1][1] + o.m_matrix[2][1];
affine._m11 = m11;
affine._m22 = m22;
affine._dx = m31; affine._dy = m32;
m_matrix[0][0] = m11;
m_matrix[1][1] = m22;
m_matrix[2][0] = m31; m_matrix[2][1] = m32;
break;
}
case TxRotate:
case TxShear:
{
qreal m11 = affine._m11*o.affine._m11 + affine._m12*o.affine._m21;
qreal m12 = affine._m11*o.affine._m12 + affine._m12*o.affine._m22;
qreal m11 = m_matrix[0][0] * o.m_matrix[0][0] + m_matrix[0][1] * o.m_matrix[1][0];
qreal m12 = m_matrix[0][0] * o.m_matrix[0][1] + m_matrix[0][1] * o.m_matrix[1][1];
qreal m21 = affine._m21*o.affine._m11 + affine._m22*o.affine._m21;
qreal m22 = affine._m21*o.affine._m12 + affine._m22*o.affine._m22;
qreal m21 = m_matrix[1][0] * o.m_matrix[0][0] + m_matrix[1][1] * o.m_matrix[1][0];
qreal m22 = m_matrix[1][0] * o.m_matrix[0][1] + m_matrix[1][1] * o.m_matrix[1][1];
qreal m31 = affine._dx*o.affine._m11 + affine._dy*o.affine._m21 + o.affine._dx;
qreal m32 = affine._dx*o.affine._m12 + affine._dy*o.affine._m22 + o.affine._dy;
qreal m31 = m_matrix[2][0] * o.m_matrix[0][0] + m_matrix[2][1] * o.m_matrix[1][0] + o.m_matrix[2][0];
qreal m32 = m_matrix[2][0] * o.m_matrix[0][1] + m_matrix[2][1] * o.m_matrix[1][1] + o.m_matrix[2][1];
affine._m11 = m11; affine._m12 = m12;
affine._m21 = m21; affine._m22 = m22;
affine._dx = m31; affine._dy = m32;
m_matrix[0][0] = m11;
m_matrix[0][1] = m12;
m_matrix[1][0] = m21;
m_matrix[1][1] = m22;
m_matrix[2][0] = m31;
m_matrix[2][1] = m32;
break;
}
case TxProject:
{
qreal m11 = affine._m11*o.affine._m11 + affine._m12*o.affine._m21 + m_13*o.affine._dx;
qreal m12 = affine._m11*o.affine._m12 + affine._m12*o.affine._m22 + m_13*o.affine._dy;
qreal m13 = affine._m11*o.m_13 + affine._m12*o.m_23 + m_13*o.m_33;
qreal m11 = m_matrix[0][0] * o.m_matrix[0][0] + m_matrix[0][1] * o.m_matrix[1][0] + m_matrix[0][2] * o.m_matrix[2][0];
qreal m12 = m_matrix[0][0] * o.m_matrix[0][1] + m_matrix[0][1] * o.m_matrix[1][1] + m_matrix[0][2] * o.m_matrix[2][1];
qreal m13 = m_matrix[0][0] * o.m_matrix[0][2] + m_matrix[0][1] * o.m_matrix[1][2] + m_matrix[0][2] * o.m_matrix[2][2];
qreal m21 = affine._m21*o.affine._m11 + affine._m22*o.affine._m21 + m_23*o.affine._dx;
qreal m22 = affine._m21*o.affine._m12 + affine._m22*o.affine._m22 + m_23*o.affine._dy;
qreal m23 = affine._m21*o.m_13 + affine._m22*o.m_23 + m_23*o.m_33;
qreal m21 = m_matrix[1][0] * o.m_matrix[0][0] + m_matrix[1][1] * o.m_matrix[1][0] + m_matrix[1][2] * o.m_matrix[2][0];
qreal m22 = m_matrix[1][0] * o.m_matrix[0][1] + m_matrix[1][1] * o.m_matrix[1][1] + m_matrix[1][2] * o.m_matrix[2][1];
qreal m23 = m_matrix[1][0] * o.m_matrix[0][2] + m_matrix[1][1] * o.m_matrix[1][2] + m_matrix[1][2] * o.m_matrix[2][2];
qreal m31 = affine._dx*o.affine._m11 + affine._dy*o.affine._m21 + m_33*o.affine._dx;
qreal m32 = affine._dx*o.affine._m12 + affine._dy*o.affine._m22 + m_33*o.affine._dy;
qreal m33 = affine._dx*o.m_13 + affine._dy*o.m_23 + m_33*o.m_33;
qreal m31 = m_matrix[2][0] * o.m_matrix[0][0] + m_matrix[2][1] * o.m_matrix[1][0] + m_matrix[2][2] * o.m_matrix[2][0];
qreal m32 = m_matrix[2][0] * o.m_matrix[0][1] + m_matrix[2][1] * o.m_matrix[1][1] + m_matrix[2][2] * o.m_matrix[2][1];
qreal m33 = m_matrix[2][0] * o.m_matrix[0][2] + m_matrix[2][1] * o.m_matrix[1][2] + m_matrix[2][2] * o.m_matrix[2][2];
affine._m11 = m11; affine._m12 = m12; m_13 = m13;
affine._m21 = m21; affine._m22 = m22; m_23 = m23;
affine._dx = m31; affine._dy = m32; m_33 = m33;
m_matrix[0][0] = m11; m_matrix[0][1] = m12; m_matrix[0][2] = m13;
m_matrix[1][0] = m21; m_matrix[1][1] = m22; m_matrix[1][2] = m23;
m_matrix[2][0] = m31; m_matrix[2][1] = m32; m_matrix[2][2] = m33;
}
}
@ -937,56 +946,57 @@ QTransform QTransform::operator*(const QTransform &m) const
case TxNone:
break;
case TxTranslate:
t.affine._dx = affine._dx + m.affine._dx;
t.affine._dy += affine._dy + m.affine._dy;
t.m_matrix[2][0] = m_matrix[2][0] + m.m_matrix[2][0];
t.m_matrix[2][1] = m_matrix[2][1] + m.m_matrix[2][1];
break;
case TxScale:
{
qreal m11 = affine._m11*m.affine._m11;
qreal m22 = affine._m22*m.affine._m22;
qreal m11 = m_matrix[0][0] * m.m_matrix[0][0];
qreal m22 = m_matrix[1][1] * m.m_matrix[1][1];
qreal m31 = affine._dx*m.affine._m11 + m.affine._dx;
qreal m32 = affine._dy*m.affine._m22 + m.affine._dy;
qreal m31 = m_matrix[2][0] * m.m_matrix[0][0] + m.m_matrix[2][0];
qreal m32 = m_matrix[2][1] * m.m_matrix[1][1] + m.m_matrix[2][1];
t.affine._m11 = m11;
t.affine._m22 = m22;
t.affine._dx = m31; t.affine._dy = m32;
t.m_matrix[0][0] = m11;
t.m_matrix[1][1] = m22;
t.m_matrix[2][0] = m31;
t.m_matrix[2][1] = m32;
break;
}
case TxRotate:
case TxShear:
{
qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21;
qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22;
qreal m11 = m_matrix[0][0] * m.m_matrix[0][0] + m_matrix[0][1] * m.m_matrix[1][0];
qreal m12 = m_matrix[0][0] * m.m_matrix[0][1] + m_matrix[0][1] * m.m_matrix[1][1];
qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21;
qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22;
qreal m21 = m_matrix[1][0] * m.m_matrix[0][0] + m_matrix[1][1] * m.m_matrix[1][0];
qreal m22 = m_matrix[1][0] * m.m_matrix[0][1] + m_matrix[1][1] * m.m_matrix[1][1];
qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m.affine._dx;
qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m.affine._dy;
qreal m31 = m_matrix[2][0] * m.m_matrix[0][0] + m_matrix[2][1] * m.m_matrix[1][0] + m.m_matrix[2][0];
qreal m32 = m_matrix[2][0] * m.m_matrix[0][1] + m_matrix[2][1] * m.m_matrix[1][1] + m.m_matrix[2][1];
t.affine._m11 = m11; t.affine._m12 = m12;
t.affine._m21 = m21; t.affine._m22 = m22;
t.affine._dx = m31; t.affine._dy = m32;
t.m_matrix[0][0] = m11; t.m_matrix[0][1] = m12;
t.m_matrix[1][0] = m21; t.m_matrix[1][1] = m22;
t.m_matrix[2][0] = m31; t.m_matrix[2][1] = m32;
break;
}
case TxProject:
{
qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21 + m_13*m.affine._dx;
qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22 + m_13*m.affine._dy;
qreal m13 = affine._m11*m.m_13 + affine._m12*m.m_23 + m_13*m.m_33;
qreal m11 = m_matrix[0][0] * m.m_matrix[0][0] + m_matrix[0][1] * m.m_matrix[1][0] + m_matrix[0][2] * m.m_matrix[2][0];
qreal m12 = m_matrix[0][0] * m.m_matrix[0][1] + m_matrix[0][1] * m.m_matrix[1][1] + m_matrix[0][2] * m.m_matrix[2][1];
qreal m13 = m_matrix[0][0] * m.m_matrix[0][2] + m_matrix[0][1] * m.m_matrix[1][2] + m_matrix[0][2] * m.m_matrix[2][2];
qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21 + m_23*m.affine._dx;
qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22 + m_23*m.affine._dy;
qreal m23 = affine._m21*m.m_13 + affine._m22*m.m_23 + m_23*m.m_33;
qreal m21 = m_matrix[1][0] * m.m_matrix[0][0] + m_matrix[1][1] * m.m_matrix[1][0] + m_matrix[1][2] * m.m_matrix[2][0];
qreal m22 = m_matrix[1][0] * m.m_matrix[0][1] + m_matrix[1][1] * m.m_matrix[1][1] + m_matrix[1][2] * m.m_matrix[2][1];
qreal m23 = m_matrix[1][0] * m.m_matrix[0][2] + m_matrix[1][1] * m.m_matrix[1][2] + m_matrix[1][2] * m.m_matrix[2][2];
qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m_33*m.affine._dx;
qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m_33*m.affine._dy;
qreal m33 = affine._dx*m.m_13 + affine._dy*m.m_23 + m_33*m.m_33;
qreal m31 = m_matrix[2][0] * m.m_matrix[0][0] + m_matrix[2][1] * m.m_matrix[1][0] + m_matrix[2][2] * m.m_matrix[2][0];
qreal m32 = m_matrix[2][0] * m.m_matrix[0][1] + m_matrix[2][1] * m.m_matrix[1][1] + m_matrix[2][2] * m.m_matrix[2][1];
qreal m33 = m_matrix[2][0] * m.m_matrix[0][2] + m_matrix[2][1] * m.m_matrix[1][2] + m_matrix[2][2] * m.m_matrix[2][2];
t.affine._m11 = m11; t.affine._m12 = m12; t.m_13 = m13;
t.affine._m21 = m21; t.affine._m22 = m22; t.m_23 = m23;
t.affine._dx = m31; t.affine._dy = m32; t.m_33 = m33;
t.m_matrix[0][0] = m11; t.m_matrix[0][1] = m12; t.m_matrix[0][2] = m13;
t.m_matrix[1][0] = m21; t.m_matrix[1][1] = m22; t.m_matrix[1][2] = m23;
t.m_matrix[2][0] = m31; t.m_matrix[2][1] = m32; t.m_matrix[2][2] = m33;
}
}
@ -1034,15 +1044,15 @@ QTransform QTransform::operator*(const QTransform &m) const
*/
QTransform & QTransform::operator=(const QTransform &matrix) noexcept
{
affine._m11 = matrix.affine._m11;
affine._m12 = matrix.affine._m12;
affine._m21 = matrix.affine._m21;
affine._m22 = matrix.affine._m22;
affine._dx = matrix.affine._dx;
affine._dy = matrix.affine._dy;
m_13 = matrix.m_13;
m_23 = matrix.m_23;
m_33 = matrix.m_33;
m_matrix[0][0] = matrix.m_matrix[0][0];
m_matrix[0][1] = matrix.m_matrix[0][1];
m_matrix[1][0] = matrix.m_matrix[1][0];
m_matrix[1][1] = matrix.m_matrix[1][1];
m_matrix[2][0] = matrix.m_matrix[2][0];
m_matrix[2][1] = matrix.m_matrix[2][1];
m_matrix[0][2] = matrix.m_matrix[0][2];
m_matrix[1][2] = matrix.m_matrix[1][2];
m_matrix[2][2] = matrix.m_matrix[2][2];
m_type = matrix.m_type;
m_dirty = matrix.m_dirty;
@ -1060,8 +1070,8 @@ QTransform & QTransform::operator=(const QTransform &matrix) noexcept
*/
void QTransform::reset()
{
affine._m11 = affine._m22 = m_33 = 1.0;
affine._m12 = m_13 = affine._m21 = m_23 = affine._dx = affine._dy = 0;
m_matrix[0][0] = m_matrix[1][1] = m_matrix[2][2] = 1.0;
m_matrix[0][1] = m_matrix[0][2] = m_matrix[1][0] = m_matrix[1][2] = m_matrix[2][0] = m_matrix[2][1] = 0;
m_type = TxNone;
m_dirty = TxNone;
}
@ -1179,20 +1189,20 @@ QPoint QTransform::map(const QPoint &p) const
y = fy;
break;
case TxTranslate:
x = fx + affine._dx;
y = fy + affine._dy;
x = fx + m_matrix[2][0];
y = fy + m_matrix[2][1];
break;
case TxScale:
x = affine._m11 * fx + affine._dx;
y = affine._m22 * fy + affine._dy;
x = m_matrix[0][0] * fx + m_matrix[2][0];
y = m_matrix[1][1] * fy + m_matrix[2][1];
break;
case TxRotate:
case TxShear:
case TxProject:
x = affine._m11 * fx + affine._m21 * fy + affine._dx;
y = affine._m12 * fx + affine._m22 * fy + affine._dy;
x = m_matrix[0][0] * fx + m_matrix[1][0] * fy + m_matrix[2][0];
y = m_matrix[0][1] * fx + m_matrix[1][1] * fy + m_matrix[2][1];
if (t == TxProject) {
qreal w = 1./(m_13 * fx + m_23 * fy + m_33);
qreal w = 1./(m_matrix[0][2] * fx + m_matrix[1][2] * fy + m_matrix[2][2]);
x *= w;
y *= w;
}
@ -1230,20 +1240,20 @@ QPointF QTransform::map(const QPointF &p) const
y = fy;
break;
case TxTranslate:
x = fx + affine._dx;
y = fy + affine._dy;
x = fx + m_matrix[2][0];
y = fy + m_matrix[2][1];
break;
case TxScale:
x = affine._m11 * fx + affine._dx;
y = affine._m22 * fy + affine._dy;
x = m_matrix[0][0] * fx + m_matrix[2][0];
y = m_matrix[1][1] * fy + m_matrix[2][1];
break;
case TxRotate:
case TxShear:
case TxProject:
x = affine._m11 * fx + affine._m21 * fy + affine._dx;
y = affine._m12 * fx + affine._m22 * fy + affine._dy;
x = m_matrix[0][0] * fx + m_matrix[1][0] * fy + m_matrix[2][0];
y = m_matrix[0][1] * fx + m_matrix[1][1] * fy + m_matrix[2][1];
if (t == TxProject) {
qreal w = 1./(m_13 * fx + m_23 * fy + m_33);
qreal w = 1./(m_matrix[0][2] * fx + m_matrix[1][2] * fy + m_matrix[2][2]);
x *= w;
y *= w;
}
@ -1303,29 +1313,29 @@ QLine QTransform::map(const QLine &l) const
y2 = fy2;
break;
case TxTranslate:
x1 = fx1 + affine._dx;
y1 = fy1 + affine._dy;
x2 = fx2 + affine._dx;
y2 = fy2 + affine._dy;
x1 = fx1 + m_matrix[2][0];
y1 = fy1 + m_matrix[2][1];
x2 = fx2 + m_matrix[2][0];
y2 = fy2 + m_matrix[2][1];
break;
case TxScale:
x1 = affine._m11 * fx1 + affine._dx;
y1 = affine._m22 * fy1 + affine._dy;
x2 = affine._m11 * fx2 + affine._dx;
y2 = affine._m22 * fy2 + affine._dy;
x1 = m_matrix[0][0] * fx1 + m_matrix[2][0];
y1 = m_matrix[1][1] * fy1 + m_matrix[2][1];
x2 = m_matrix[0][0] * fx2 + m_matrix[2][0];
y2 = m_matrix[1][1] * fy2 + m_matrix[2][1];
break;
case TxRotate:
case TxShear:
case TxProject:
x1 = affine._m11 * fx1 + affine._m21 * fy1 + affine._dx;
y1 = affine._m12 * fx1 + affine._m22 * fy1 + affine._dy;
x2 = affine._m11 * fx2 + affine._m21 * fy2 + affine._dx;
y2 = affine._m12 * fx2 + affine._m22 * fy2 + affine._dy;
x1 = m_matrix[0][0] * fx1 + m_matrix[1][0] * fy1 + m_matrix[2][0];
y1 = m_matrix[0][1] * fx1 + m_matrix[1][1] * fy1 + m_matrix[2][1];
x2 = m_matrix[0][0] * fx2 + m_matrix[1][0] * fy2 + m_matrix[2][0];
y2 = m_matrix[0][1] * fx2 + m_matrix[1][1] * fy2 + m_matrix[2][1];
if (t == TxProject) {
qreal w = 1./(m_13 * fx1 + m_23 * fy1 + m_33);
qreal w = 1./(m_matrix[0][2] * fx1 + m_matrix[1][2] * fy1 + m_matrix[2][2]);
x1 *= w;
y1 *= w;
w = 1./(m_13 * fx2 + m_23 * fy2 + m_33);
w = 1./(m_matrix[0][2] * fx2 + m_matrix[1][2] * fy2 + m_matrix[2][2]);
x2 *= w;
y2 *= w;
}
@ -1362,29 +1372,29 @@ QLineF QTransform::map(const QLineF &l) const
y2 = fy2;
break;
case TxTranslate:
x1 = fx1 + affine._dx;
y1 = fy1 + affine._dy;
x2 = fx2 + affine._dx;
y2 = fy2 + affine._dy;
x1 = fx1 + m_matrix[2][0];
y1 = fy1 + m_matrix[2][1];
x2 = fx2 + m_matrix[2][0];
y2 = fy2 + m_matrix[2][1];
break;
case TxScale:
x1 = affine._m11 * fx1 + affine._dx;
y1 = affine._m22 * fy1 + affine._dy;
x2 = affine._m11 * fx2 + affine._dx;
y2 = affine._m22 * fy2 + affine._dy;
x1 = m_matrix[0][0] * fx1 + m_matrix[2][0];
y1 = m_matrix[1][1] * fy1 + m_matrix[2][1];
x2 = m_matrix[0][0] * fx2 + m_matrix[2][0];
y2 = m_matrix[1][1] * fy2 + m_matrix[2][1];
break;
case TxRotate:
case TxShear:
case TxProject:
x1 = affine._m11 * fx1 + affine._m21 * fy1 + affine._dx;
y1 = affine._m12 * fx1 + affine._m22 * fy1 + affine._dy;
x2 = affine._m11 * fx2 + affine._m21 * fy2 + affine._dx;
y2 = affine._m12 * fx2 + affine._m22 * fy2 + affine._dy;
x1 = m_matrix[0][0] * fx1 + m_matrix[1][0] * fy1 + m_matrix[2][0];
y1 = m_matrix[0][1] * fx1 + m_matrix[1][1] * fy1 + m_matrix[2][1];
x2 = m_matrix[0][0] * fx2 + m_matrix[1][0] * fy2 + m_matrix[2][0];
y2 = m_matrix[0][1] * fx2 + m_matrix[1][1] * fy2 + m_matrix[2][1];
if (t == TxProject) {
qreal w = 1./(m_13 * fx1 + m_23 * fy1 + m_33);
qreal w = 1./(m_matrix[0][2] * fx1 + m_matrix[1][2] * fy1 + m_matrix[2][2]);
x1 *= w;
y1 *= w;
w = 1./(m_13 * fx2 + m_23 * fy2 + m_33);
w = 1./(m_matrix[0][2] * fx2 + m_matrix[1][2] * fy2 + m_matrix[2][2]);
x2 *= w;
y2 *= w;
}
@ -1445,7 +1455,7 @@ QPolygonF QTransform::map(const QPolygonF &a) const
{
TransformationType t = inline_type();
if (t <= TxTranslate)
return a.translated(affine._dx, affine._dy);
return a.translated(m_matrix[2][0], m_matrix[2][1]);
if (t >= QTransform::TxProject)
return mapProjective(*this, a);
@ -1475,7 +1485,7 @@ QPolygon QTransform::map(const QPolygon &a) const
{
TransformationType t = inline_type();
if (t <= TxTranslate)
return a.translated(qRound(affine._dx), qRound(affine._dy));
return a.translated(qRound(m_matrix[2][0]), qRound(m_matrix[2][1]));
if (t >= QTransform::TxProject)
return mapProjective(*this, QPolygonF(a)).toPolygon();
@ -1524,7 +1534,7 @@ QRegion QTransform::map(const QRegion &r) const
if (t == TxTranslate) {
QRegion copy(r);
copy.translate(qRound(affine._dx), qRound(affine._dy));
copy.translate(qRound(m_matrix[2][0]), qRound(m_matrix[2][1]));
return copy;
}
@ -1703,7 +1713,7 @@ QPainterPath QTransform::map(const QPainterPath &path) const
QPainterPath copy = path;
if (t == TxTranslate) {
copy.translate(affine._dx, affine._dy);
copy.translate(m_matrix[2][0], m_matrix[2][1]);
} else {
copy.detach();
// Full xform
@ -1743,10 +1753,10 @@ QPolygon QTransform::mapToPolygon(const QRect &rect) const
QPolygon a(4);
qreal x[4] = { 0, 0, 0, 0 }, y[4] = { 0, 0, 0, 0 };
if (t <= TxScale) {
x[0] = affine._m11*rect.x() + affine._dx;
y[0] = affine._m22*rect.y() + affine._dy;
qreal w = affine._m11*rect.width();
qreal h = affine._m22*rect.height();
x[0] = m_matrix[0][0]*rect.x() + m_matrix[2][0];
y[0] = m_matrix[1][1]*rect.y() + m_matrix[2][1];
qreal w = m_matrix[0][0]*rect.width();
qreal h = m_matrix[1][1]*rect.height();
if (w < 0) {
w = -w;
x[0] -= w;
@ -1903,9 +1913,9 @@ void QTransform::setMatrix(qreal m11, qreal m12, qreal m13,
qreal m21, qreal m22, qreal m23,
qreal m31, qreal m32, qreal m33)
{
affine._m11 = m11; affine._m12 = m12; m_13 = m13;
affine._m21 = m21; affine._m22 = m22; m_23 = m23;
affine._dx = m31; affine._dy = m32; m_33 = m33;
m_matrix[0][0] = m11; m_matrix[0][1] = m12; m_matrix[0][2] = m13;
m_matrix[1][0] = m21; m_matrix[1][1] = m22; m_matrix[1][2] = m23;
m_matrix[2][0] = m31; m_matrix[2][1] = m32; m_matrix[2][2] = m33;
m_type = TxNone;
m_dirty = TxProject;
}
@ -1922,13 +1932,13 @@ QRect QTransform::mapRect(const QRect &rect) const
{
TransformationType t = inline_type();
if (t <= TxTranslate)
return rect.translated(qRound(affine._dx), qRound(affine._dy));
return rect.translated(qRound(m_matrix[2][0]), qRound(m_matrix[2][1]));
if (t <= TxScale) {
int x = qRound(affine._m11*rect.x() + affine._dx);
int y = qRound(affine._m22*rect.y() + affine._dy);
int w = qRound(affine._m11*rect.width());
int h = qRound(affine._m22*rect.height());
int x = qRound(m_matrix[0][0] * rect.x() + m_matrix[2][0]);
int y = qRound(m_matrix[1][1] * rect.y() + m_matrix[2][1]);
int w = qRound(m_matrix[0][0] * rect.width());
int h = qRound(m_matrix[1][1] * rect.height());
if (w < 0) {
w = -w;
x -= w;
@ -1992,13 +2002,13 @@ QRectF QTransform::mapRect(const QRectF &rect) const
{
TransformationType t = inline_type();
if (t <= TxTranslate)
return rect.translated(affine._dx, affine._dy);
return rect.translated(m_matrix[2][0], m_matrix[2][1]);
if (t <= TxScale) {
qreal x = affine._m11*rect.x() + affine._dx;
qreal y = affine._m22*rect.y() + affine._dy;
qreal w = affine._m11*rect.width();
qreal h = affine._m22*rect.height();
qreal x = m_matrix[0][0] * rect.x() + m_matrix[2][0];
qreal y = m_matrix[1][1] * rect.y() + m_matrix[2][1];
qreal w = m_matrix[0][0] * rect.width();
qreal h = m_matrix[1][1] * rect.height();
if (w < 0) {
w = -w;
x -= w;
@ -2093,9 +2103,11 @@ void QTransform::map(int x, int y, int *tx, int *ty) const
\warning If a perspective transformation has been specified,
then the conversion will cause loss of data.
*/
const QMatrix &QTransform::toAffine() const
QMatrix QTransform::toAffine() const
{
return affine;
return QMatrix(m_matrix[0][0], m_matrix[0][1],
m_matrix[1][0], m_matrix[1][1],
m_matrix[2][0], m_matrix[2][1]);
}
#endif // QT_DEPRECATED_SINCE(5, 15)
@ -2118,15 +2130,15 @@ QTransform::TransformationType QTransform::type() const
switch (static_cast<TransformationType>(m_dirty)) {
case TxProject:
if (!qFuzzyIsNull(m_13) || !qFuzzyIsNull(m_23) || !qFuzzyIsNull(m_33 - 1)) {
if (!qFuzzyIsNull(m_matrix[0][2]) || !qFuzzyIsNull(m_matrix[1][2]) || !qFuzzyIsNull(m_matrix[2][2] - 1)) {
m_type = TxProject;
break;
}
Q_FALLTHROUGH();
case TxShear:
case TxRotate:
if (!qFuzzyIsNull(affine._m12) || !qFuzzyIsNull(affine._m21)) {
const qreal dot = affine._m11 * affine._m12 + affine._m21 * affine._m22;
if (!qFuzzyIsNull(m_matrix[0][1]) || !qFuzzyIsNull(m_matrix[1][0])) {
const qreal dot = m_matrix[0][0] * m_matrix[0][1] + m_matrix[1][0] * m_matrix[1][1];
if (qFuzzyIsNull(dot))
m_type = TxRotate;
else
@ -2135,13 +2147,13 @@ QTransform::TransformationType QTransform::type() const
}
Q_FALLTHROUGH();
case TxScale:
if (!qFuzzyIsNull(affine._m11 - 1) || !qFuzzyIsNull(affine._m22 - 1)) {
if (!qFuzzyIsNull(m_matrix[0][0] - 1) || !qFuzzyIsNull(m_matrix[1][1] - 1)) {
m_type = TxScale;
break;
}
Q_FALLTHROUGH();
case TxTranslate:
if (!qFuzzyIsNull(affine._dx) || !qFuzzyIsNull(affine._dy)) {
if (!qFuzzyIsNull(m_matrix[2][0]) || !qFuzzyIsNull(m_matrix[2][1])) {
m_type = TxTranslate;
break;
}

View File

@ -66,7 +66,7 @@ public:
TxProject = 0x10
};
inline explicit QTransform(Qt::Initialization) : affine(Qt::Uninitialized) {}
inline explicit QTransform(Qt::Initialization) {}
QTransform();
QTransform(qreal h11, qreal h12, qreal h13,
qreal h21, qreal h22, qreal h23,
@ -161,7 +161,7 @@ public:
void map(qreal x, qreal y, qreal *tx, qreal *ty) const;
#if QT_DEPRECATED_SINCE(5, 15)
const QMatrix &toAffine() const;
QMatrix toAffine() const;
#endif // QT_DEPRECATED_SINCE(5, 15)
QTransform &operator*=(qreal div);
@ -176,8 +176,7 @@ private:
inline QTransform(qreal h11, qreal h12, qreal h13,
qreal h21, qreal h22, qreal h23,
qreal h31, qreal h32, qreal h33, bool)
: affine(h11, h12, h21, h22, h31, h32, true)
, m_13(h13), m_23(h23), m_33(h33)
: m_matrix{ {h11, h12, h13}, {h21, h22, h23}, {h31, h32, h33} }
, m_type(TxNone)
, m_dirty(TxProject)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@ -186,8 +185,7 @@ private:
{
}
inline QTransform(bool)
: affine(true)
, m_13(0), m_23(0), m_33(1)
: m_matrix{ {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }
, m_type(TxNone)
, m_dirty(TxNone)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@ -196,10 +194,7 @@ private:
{
}
inline TransformationType inline_type() const;
QMatrix affine;
qreal m_13;
qreal m_23;
qreal m_33;
qreal m_matrix[3][3];
mutable uint m_type : 5;
mutable uint m_dirty : 5;
@ -250,8 +245,9 @@ inline bool QTransform::isTranslating() const
inline qreal QTransform::determinant() const
{
return affine._m11*(m_33*affine._m22-affine._dy*m_23) -
affine._m21*(m_33*affine._m12-affine._dy*m_13)+affine._dx*(m_23*affine._m12-affine._m22*m_13);
return m_matrix[0][0] * (m_matrix[2][2] * m_matrix[1][1] - m_matrix[2][1] * m_matrix[1][2]) -
m_matrix[1][0] * (m_matrix[2][2] * m_matrix[0][1] - m_matrix[2][1] * m_matrix[0][2]) +
m_matrix[2][0] * (m_matrix[1][2] * m_matrix[0][1] - m_matrix[1][1] * m_matrix[0][2]);
}
#if QT_DEPRECATED_SINCE(5, 13)
inline qreal QTransform::det() const
@ -261,47 +257,47 @@ inline qreal QTransform::det() const
#endif
inline qreal QTransform::m11() const
{
return affine._m11;
return m_matrix[0][0];
}
inline qreal QTransform::m12() const
{
return affine._m12;
return m_matrix[0][1];
}
inline qreal QTransform::m13() const
{
return m_13;
return m_matrix[0][2];
}
inline qreal QTransform::m21() const
{
return affine._m21;
return m_matrix[1][0];
}
inline qreal QTransform::m22() const
{
return affine._m22;
return m_matrix[1][1];
}
inline qreal QTransform::m23() const
{
return m_23;
return m_matrix[1][2];
}
inline qreal QTransform::m31() const
{
return affine._dx;
return m_matrix[2][0];
}
inline qreal QTransform::m32() const
{
return affine._dy;
return m_matrix[2][1];
}
inline qreal QTransform::m33() const
{
return m_33;
return m_matrix[2][2];
}
inline qreal QTransform::dx() const
{
return affine._dx;
return m_matrix[2][0];
}
inline qreal QTransform::dy() const
{
return affine._dy;
return m_matrix[2][1];
}
QT_WARNING_PUSH
@ -313,15 +309,15 @@ inline QTransform &QTransform::operator*=(qreal num)
{
if (num == 1.)
return *this;
affine._m11 *= num;
affine._m12 *= num;
m_13 *= num;
affine._m21 *= num;
affine._m22 *= num;
m_23 *= num;
affine._dx *= num;
affine._dy *= num;
m_33 *= num;
m_matrix[0][0] *= num;
m_matrix[0][1] *= num;
m_matrix[0][2] *= num;
m_matrix[1][0] *= num;
m_matrix[1][1] *= num;
m_matrix[1][2] *= num;
m_matrix[2][0] *= num;
m_matrix[2][1] *= num;
m_matrix[2][2] *= num;
if (m_dirty < TxScale)
m_dirty = TxScale;
return *this;
@ -337,15 +333,15 @@ inline QTransform &QTransform::operator+=(qreal num)
{
if (num == 0)
return *this;
affine._m11 += num;
affine._m12 += num;
m_13 += num;
affine._m21 += num;
affine._m22 += num;
m_23 += num;
affine._dx += num;
affine._dy += num;
m_33 += num;
m_matrix[0][0] += num;
m_matrix[0][1] += num;
m_matrix[0][2] += num;
m_matrix[1][0] += num;
m_matrix[1][1] += num;
m_matrix[1][2] += num;
m_matrix[2][0] += num;
m_matrix[2][1] += num;
m_matrix[2][2] += num;
m_dirty = TxProject;
return *this;
}
@ -353,15 +349,15 @@ inline QTransform &QTransform::operator-=(qreal num)
{
if (num == 0)
return *this;
affine._m11 -= num;
affine._m12 -= num;
m_13 -= num;
affine._m21 -= num;
affine._m22 -= num;
m_23 -= num;
affine._dx -= num;
affine._dy -= num;
m_33 -= num;
m_matrix[0][0] -= num;
m_matrix[0][1] -= num;
m_matrix[0][2] -= num;
m_matrix[1][0] -= num;
m_matrix[1][1] -= num;
m_matrix[1][2] -= num;
m_matrix[2][0] -= num;
m_matrix[2][1] -= num;
m_matrix[2][2] -= num;
m_dirty = TxProject;
return *this;
}

View File

@ -53,7 +53,6 @@ QAbstractTextDocumentLayoutPrivate::~QAbstractTextDocumentLayoutPrivate()
QTextObjectInterface::~QTextObjectInterface()
{
// must be empty until ### Qt 6
}
/*!

View File

@ -17,6 +17,7 @@ qt_add_module(OpenGL
qopenglpixeltransferoptions.cpp qopenglpixeltransferoptions.h
qopenglshadercache_p.h
qopengltexture.cpp qopengltexture.h qopengltexture_p.h
qopengltextureblitter.cpp qopengltextureblitter.h
qopengltexturecache.cpp qopengltexturecache_p.h
qopengltextureglyphcache.cpp qopengltextureglyphcache_p.h
qopengltexturehelper.cpp qopengltexturehelper_p.h

View File

@ -24,6 +24,7 @@ HEADERS += \
qopengltexture.h \
qopengltexture_p.h \
qopengltexturehelper_p.h \
qopengltextureblitter.h \
qopengltexturecache_p.h \
qopengltextureglyphcache_p.h \
qopengltextureuploader_p.h \
@ -40,6 +41,7 @@ SOURCES += \
qopenglpixeltransferoptions.cpp \
qopengltexture.cpp \
qopengltexturehelper.cpp \
qopengltextureblitter.cpp \
qopengltexturecache.cpp \
qopengltextureglyphcache.cpp \
qopengltextureuploader.cpp \

View File

@ -3,7 +3,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
\brief The QOpenGLTextureBlitter class provides a convenient way to draw textured quads via OpenGL.
\since 5.8
\ingroup painting-3D
\inmodule QtGui
\inmodule QtOpenGL
Drawing textured quads, in order to get the contents of a texture
onto the screen, is a common operation when developing 2D user

View File

@ -3,7 +3,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@ -40,9 +40,7 @@
#ifndef QOPENGLTEXTUREBLITTER_H
#define QOPENGLTEXTUREBLITTER_H
#include <QtGui/qtguiglobal.h>
#ifndef QT_NO_OPENGL
#include <QtOpenGL/qtopenglglobal.h>
#include <QtGui/qopengl.h>
#include <QtGui/QMatrix3x3>
@ -52,7 +50,7 @@ QT_BEGIN_NAMESPACE
class QOpenGLTextureBlitterPrivate;
class Q_GUI_EXPORT QOpenGLTextureBlitter
class Q_OPENGL_EXPORT QOpenGLTextureBlitter
{
public:
QOpenGLTextureBlitter();
@ -89,6 +87,4 @@ private:
QT_END_NAMESPACE
#endif
#endif //QOPENGLTEXTUREBLITTER_H

View File

@ -40,12 +40,12 @@
#include "qopenglwindow.h"
#include <QtGui/QOpenGLFramebufferObject>
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QOpenGLTextureBlitter>
#include <QtGui/private/qpaintdevicewindow_p.h>
#include <QtGui/private/qopenglextensions_p.h>
#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/QMatrix4x4>
#include <QtGui/QOffscreenSurface>
#include <QtOpenGL/QOpenGLTextureBlitter>
#include <QtOpenGL/QOpenGLPaintDevice>
QT_BEGIN_NAMESPACE

View File

@ -67,6 +67,7 @@ qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_fontconfig
qt_extend_target(FontDatabaseSupport CONDITION WIN32 AND NOT WINRT
SOURCES
windows/qwindowsfontdatabase.cpp windows/qwindowsfontdatabase_p.h
windows/qwindowsfontdatabasebase.cpp windows/qwindowsfontdatabasebase_p.h
windows/qwindowsfontengine.cpp windows/qwindowsfontengine_p.h
windows/qwindowsnativeimage.cpp windows/qwindowsnativeimage_p.h
LIBRARIES
@ -90,14 +91,24 @@ qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATUR
d2d1
)
qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND QT_FEATURE_directwrite2 AND WIN32 AND NOT WINRT
qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND QT_FEATURE_directwrite3 AND WIN32 AND NOT WINRT
SOURCES
windows/qwindowsdirectwritefontdatabase.cpp windows/qwindowsdirectwritefontdatabase_p.h
DEFINES
QT_USE_DIRECTWRITE2
QT_USE_DIRECTWRITE3
LIBRARIES
dwrite_3
)
qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND QT_FEATURE_directwrite2 AND WIN32 AND NOT QT_FEATURE_directwrite3 AND NOT WINRT
DEFINES
QT_USE_DIRECTWRITE2
LIBRARIES
dwrite_2
)
qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND WIN32 AND NOT QT_FEATURE_directwrite2 AND NOT WINRT
qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND WIN32 AND NOT QT_FEATURE_directwrite2 AND NOT QT_FEATURE_directwrite3 AND NOT WINRT
LIBRARIES
dwrite
)

View File

@ -70,6 +70,7 @@ qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_fontconfig
qt_extend_target(FontDatabaseSupport CONDITION WIN32 AND NOT WINRT
SOURCES
windows/qwindowsfontdatabase.cpp windows/qwindowsfontdatabase_p.h
windows/qwindowsfontdatabasebase.cpp windows/qwindowsfontdatabasebase_p.h
windows/qwindowsfontengine.cpp windows/qwindowsfontengine_p.h
windows/qwindowsnativeimage.cpp windows/qwindowsnativeimage_p.h
LIBRARIES
@ -93,14 +94,24 @@ qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATUR
d2d1
)
qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND QT_FEATURE_directwrite2 AND WIN32 AND NOT WINRT
qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND QT_FEATURE_directwrite3 AND WIN32 AND NOT WINRT
SOURCES
windows/qwindowsdirectwritefontdatabase.cpp windows/qwindowsdirectwritefontdatabase_p.h
DEFINES
QT_USE_DIRECTWRITE2
QT_USE_DIRECTWRITE3
LIBRARIES
dwrite_3
)
qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND QT_FEATURE_directwrite2 AND WIN32 AND NOT QT_FEATURE_directwrite3 AND NOT WINRT
DEFINES
QT_USE_DIRECTWRITE2
LIBRARIES
dwrite_2
)
qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND WIN32 AND NOT QT_FEATURE_directwrite2 AND NOT WINRT
qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND WIN32 AND NOT QT_FEATURE_directwrite2 AND NOT QT_FEATURE_directwrite3 AND NOT WINRT
LIBRARIES
dwrite
)

View File

@ -0,0 +1,465 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwindowsdirectwritefontdatabase_p.h"
#include "qwindowsfontenginedirectwrite_p.h"
#include <QtCore/qstringbuilder.h>
#include <QtCore/qvarlengtharray.h>
#include <dwrite_3.h>
#include <d2d1.h>
QT_BEGIN_NAMESPACE
#ifdef QT_USE_DIRECTWRITE3
QWindowsDirectWriteFontDatabase::QWindowsDirectWriteFontDatabase()
{
qCDebug(lcQpaFonts) << "Creating DirectWrite database";
}
QWindowsDirectWriteFontDatabase::~QWindowsDirectWriteFontDatabase()
{
for (auto it = m_populatedFonts.begin(); it != m_populatedFonts.end(); ++it)
it.value()->Release();
}
QString QWindowsDirectWriteFontDatabase::localeString(IDWriteLocalizedStrings *names,
wchar_t localeName[])
{
uint index;
BOOL exists;
if (SUCCEEDED(names->FindLocaleName(localeName, &index, &exists)) && exists) {
uint length;
if (SUCCEEDED(names->GetStringLength(index, &length)) && length > 0) {
QVarLengthArray<wchar_t> buffer(int(length) + 1);
if (SUCCEEDED(names->GetString(index, buffer.data(), length + 1)))
return QString::fromWCharArray(buffer.data());
}
}
return QString();
}
static QFont::Stretch fromDirectWriteStretch(DWRITE_FONT_STRETCH stretch)
{
switch (stretch) {
case DWRITE_FONT_STRETCH_ULTRA_CONDENSED: return QFont::UltraCondensed;
case DWRITE_FONT_STRETCH_EXTRA_CONDENSED: return QFont::ExtraCondensed;
case DWRITE_FONT_STRETCH_CONDENSED: return QFont::Condensed;
case DWRITE_FONT_STRETCH_SEMI_CONDENSED: return QFont::SemiCondensed;
case DWRITE_FONT_STRETCH_NORMAL: return QFont::Unstretched;
case DWRITE_FONT_STRETCH_SEMI_EXPANDED: return QFont::SemiExpanded;
case DWRITE_FONT_STRETCH_EXPANDED: return QFont::Expanded;
case DWRITE_FONT_STRETCH_EXTRA_EXPANDED: return QFont::ExtraExpanded;
case DWRITE_FONT_STRETCH_ULTRA_EXPANDED: return QFont::UltraExpanded;
default: return QFont::AnyStretch;
}
}
static QFont::Weight fromDirectWriteWeight(DWRITE_FONT_WEIGHT weight)
{
return QPlatformFontDatabase::weightFromInteger(int(weight));
}
static DWRITE_FONT_STYLE toDirectWriteStyle(QFont::Style style)
{
switch (style) {
case QFont::StyleNormal: return DWRITE_FONT_STYLE_NORMAL;
case QFont::StyleOblique: return DWRITE_FONT_STYLE_OBLIQUE;
case QFont::StyleItalic: return DWRITE_FONT_STYLE_ITALIC;
default: return DWRITE_FONT_STYLE_NORMAL;
}
}
static QFont::Style fromDirectWriteStyle(DWRITE_FONT_STYLE style)
{
switch (style) {
case DWRITE_FONT_STYLE_NORMAL: return QFont::StyleNormal;
case DWRITE_FONT_STYLE_OBLIQUE: return QFont::StyleOblique;
case DWRITE_FONT_STYLE_ITALIC: return QFont::StyleItalic;
default: return QFont::StyleNormal;
}
}
void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName)
{
auto it = m_populatedFonts.find(familyName);
IDWriteFontFamily *fontFamily = it != m_populatedFonts.end() ? it.value() : nullptr;
if (fontFamily == nullptr) {
qCWarning(lcQpaFonts) << "Cannot find" << familyName << "in list of fonts";
return;
}
qCDebug(lcQpaFonts) << "Populate family:" << familyName;
wchar_t defaultLocale[LOCALE_NAME_MAX_LENGTH];
bool hasDefaultLocale = GetUserDefaultLocaleName(defaultLocale, LOCALE_NAME_MAX_LENGTH) != 0;
wchar_t englishLocale[] = L"en-us";
static const int SMOOTH_SCALABLE = 0xffff;
const QString foundryName; // No such concept.
const bool scalable = true;
const bool antialias = false;
const int size = SMOOTH_SCALABLE;
IDWriteFontList *matchingFonts;
if (SUCCEEDED(fontFamily->GetMatchingFonts(DWRITE_FONT_WEIGHT_REGULAR,
DWRITE_FONT_STRETCH_NORMAL,
DWRITE_FONT_STYLE_NORMAL,
&matchingFonts))) {
for (uint j = 0; j < matchingFonts->GetFontCount(); ++j) {
IDWriteFont *font;
if (SUCCEEDED(matchingFonts->GetFont(j, &font))) {
IDWriteFont1 *font1 = nullptr;
if (!SUCCEEDED(font->QueryInterface(__uuidof(IDWriteFont1),
reinterpret_cast<void **>(&font1)))) {
qCWarning(lcQpaFonts) << "COM object does not support IDWriteFont1";
continue;
}
QString defaultLocaleFamilyName;
QString englishLocaleFamilyName;
IDWriteFontFamily *fontFamily2;
if (SUCCEEDED(font1->GetFontFamily(&fontFamily2))) {
IDWriteLocalizedStrings *names;
if (SUCCEEDED(fontFamily2->GetFamilyNames(&names))) {
defaultLocaleFamilyName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
englishLocaleFamilyName = localeString(names, englishLocale);
names->Release();
}
fontFamily2->Release();
}
if (defaultLocaleFamilyName.isEmpty() && englishLocaleFamilyName.isEmpty())
englishLocaleFamilyName = familyName;
QVarLengthArray<DWRITE_UNICODE_RANGE, 64> ranges(QFontDatabase::WritingSystemsCount);
uint count = 0;
if (SUCCEEDED(font1->GetUnicodeRanges(QFontDatabase::WritingSystemsCount, ranges.data(), &count))) {
// ###
}
QSupportedWritingSystems writingSystems;
writingSystems.setSupported(QFontDatabase::Any);
writingSystems.setSupported(QFontDatabase::Latin);
{
IDWriteLocalizedStrings *names;
if (SUCCEEDED(font1->GetFaceNames(&names))) {
QString defaultLocaleStyleName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
QString englishLocaleStyleName = localeString(names, englishLocale);
QFont::Stretch stretch = fromDirectWriteStretch(font1->GetStretch());
QFont::Style style = fromDirectWriteStyle(font1->GetStyle());
QFont::Weight weight = fromDirectWriteWeight(font1->GetWeight());
bool fixed = font1->IsMonospacedFont();
qCDebug(lcQpaFonts) << "Family" << familyName << "has english variant" << englishLocaleStyleName << ", in default locale:" << defaultLocaleStyleName << stretch << style << weight << fixed;
IDWriteFontFace *face = nullptr;
if (SUCCEEDED(font->CreateFontFace(&face))) {
if (!englishLocaleStyleName.isEmpty() || defaultLocaleStyleName.isEmpty()) {
QPlatformFontDatabase::registerFont(englishLocaleFamilyName, englishLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face);
face->AddRef();
}
if (!defaultLocaleFamilyName.isEmpty() && defaultLocaleFamilyName != englishLocaleFamilyName) {
QPlatformFontDatabase::registerFont(defaultLocaleFamilyName, defaultLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face);
face->AddRef();
}
face->Release();
}
names->Release();
}
}
font1->Release();
font->Release();
}
}
matchingFonts->Release();
}
}
QFontEngine *QWindowsDirectWriteFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
{
IDWriteFontFace *face = reinterpret_cast<IDWriteFontFace *>(handle);
Q_ASSERT(face != nullptr);
QWindowsFontEngineDirectWrite *fontEngine = new QWindowsFontEngineDirectWrite(face, fontDef.pixelSize, data());
fontEngine->initFontInfo(fontDef, defaultVerticalDPI());
return fontEngine;
}
QStringList QWindowsDirectWriteFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
Q_UNUSED(styleHint);
Q_UNUSED(script);
wchar_t defaultLocale[LOCALE_NAME_MAX_LENGTH];
bool hasDefaultLocale = GetUserDefaultLocaleName(defaultLocale, LOCALE_NAME_MAX_LENGTH) != 0;
wchar_t englishLocale[] = L"en-us";
QStringList ret;
auto it = m_populatedFonts.find(family);
IDWriteFontFamily *fontFamily = it != m_populatedFonts.end() ? it.value() : nullptr;
if (fontFamily != nullptr) {
IDWriteFontList *matchingFonts = nullptr;
if (SUCCEEDED(fontFamily->GetMatchingFonts(DWRITE_FONT_WEIGHT_REGULAR,
DWRITE_FONT_STRETCH_NORMAL,
toDirectWriteStyle(style),
&matchingFonts))) {
for (uint j = 0; j < matchingFonts->GetFontCount(); ++j) {
IDWriteFont *font = nullptr;
if (SUCCEEDED(matchingFonts->GetFont(j, &font))) {
IDWriteFontFamily *fontFamily2;
if (SUCCEEDED(font->GetFontFamily(&fontFamily2))) {
IDWriteLocalizedStrings *names;
if (SUCCEEDED(fontFamily2->GetFamilyNames(&names))) {
QString name = localeString(names, englishLocale);
if (name.isEmpty() && hasDefaultLocale)
name = localeString(names, defaultLocale);
if (!name.isEmpty() && m_populatedFonts.contains(name))
ret.append(name);
names->Release();
}
fontFamily2->Release();
}
font->Release();
}
}
matchingFonts->Release();
}
}
qDebug(lcQpaFonts) << "fallbacks for" << family << "is" << ret;
return ret;
}
QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
{
qCDebug(lcQpaFonts) << "Adding application font" << fileName;
QByteArray loadedData = fontData;
if (loadedData.isEmpty()) {
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
qCWarning(lcQpaFonts) << "Cannot open" << fileName << "for reading.";
return QStringList();
}
loadedData = file.readAll();
}
IDWriteFontFace *face = createDirectWriteFace(loadedData);
if (face == nullptr) {
qCWarning(lcQpaFonts) << "Failed to create DirectWrite face from font data. Font may be unsupported.";
return QStringList();
}
wchar_t defaultLocale[LOCALE_NAME_MAX_LENGTH];
bool hasDefaultLocale = GetUserDefaultLocaleName(defaultLocale, LOCALE_NAME_MAX_LENGTH) != 0;
wchar_t englishLocale[] = L"en-us";
static const int SMOOTH_SCALABLE = 0xffff;
const QString foundryName; // No such concept.
const bool scalable = true;
const bool antialias = false;
const int size = SMOOTH_SCALABLE;
QSupportedWritingSystems writingSystems;
writingSystems.setSupported(QFontDatabase::Any);
writingSystems.setSupported(QFontDatabase::Latin);
QStringList ret;
IDWriteFontFace3 *face3 = nullptr;
if (SUCCEEDED(face->QueryInterface(__uuidof(IDWriteFontFace3),
reinterpret_cast<void **>(&face3)))) {
QString defaultLocaleFamilyName;
QString englishLocaleFamilyName;
IDWriteLocalizedStrings *names;
if (SUCCEEDED(face3->GetFamilyNames(&names))) {
defaultLocaleFamilyName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
englishLocaleFamilyName = localeString(names, englishLocale);
names->Release();
}
QString defaultLocaleStyleName;
QString englishLocaleStyleName;
if (SUCCEEDED(face3->GetFaceNames(&names))) {
defaultLocaleStyleName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
englishLocaleStyleName = localeString(names, englishLocale);
names->Release();
}
QFont::Stretch stretch = fromDirectWriteStretch(face3->GetStretch());
QFont::Style style = fromDirectWriteStyle(face3->GetStyle());
QFont::Weight weight = fromDirectWriteWeight(face3->GetWeight());
bool fixed = face3->IsMonospacedFont();
qCDebug(lcQpaFonts) << "\tFont names:" << englishLocaleFamilyName << ", " << defaultLocaleFamilyName
<< ", style names:" << englishLocaleStyleName << ", " << defaultLocaleStyleName
<< ", stretch:" << stretch
<< ", style:" << style
<< ", weight:" << weight
<< ", fixed:" << fixed;
if (!englishLocaleFamilyName.isEmpty()) {
ret.append(englishLocaleFamilyName);
QPlatformFontDatabase::registerFont(englishLocaleFamilyName, englishLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face);
face->AddRef();
}
if (!defaultLocaleFamilyName.isEmpty() && defaultLocaleFamilyName != englishLocaleFamilyName) {
ret.append(defaultLocaleFamilyName);
QPlatformFontDatabase::registerFont(defaultLocaleFamilyName, defaultLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face);
face->AddRef();
}
face3->Release();
} else {
qCWarning(lcQpaFonts) << "Unable to query IDWriteFontFace3 interface from font face.";
}
face->Release();
return ret;
}
void QWindowsDirectWriteFontDatabase::releaseHandle(void *handle)
{
IDWriteFontFace *face = reinterpret_cast<IDWriteFontFace *>(handle);
face->Release();
}
bool QWindowsDirectWriteFontDatabase::fontsAlwaysScalable() const
{
return true;
}
bool QWindowsDirectWriteFontDatabase::isPrivateFontFamily(const QString &family) const
{
Q_UNUSED(family);
return false;
}
void QWindowsDirectWriteFontDatabase::populateFontDatabase()
{
wchar_t defaultLocale[LOCALE_NAME_MAX_LENGTH];
bool hasDefaultLocale = GetUserDefaultLocaleName(defaultLocale, LOCALE_NAME_MAX_LENGTH) != 0;
wchar_t englishLocale[] = L"en-us";
QString defaultFontName = defaultFont().family();
QString systemDefaultFontName = systemDefaultFont().family();
IDWriteFontCollection *fontCollection;
if (SUCCEEDED(data()->directWriteFactory->GetSystemFontCollection(&fontCollection))) {
for (uint i = 0; i < fontCollection->GetFontFamilyCount(); ++i) {
IDWriteFontFamily *fontFamily;
if (SUCCEEDED(fontCollection->GetFontFamily(i, &fontFamily))) {
QString defaultLocaleName;
QString englishLocaleName;
IDWriteLocalizedStrings *names;
if (SUCCEEDED(fontFamily->GetFamilyNames(&names))) {
if (hasDefaultLocale)
defaultLocaleName = localeString(names, defaultLocale);
englishLocaleName = localeString(names, englishLocale);
}
qCDebug(lcQpaFonts) << "Registering font, english name = " << englishLocaleName << ", name in current locale = " << defaultLocaleName;
if (!defaultLocaleName.isEmpty()) {
registerFontFamily(defaultLocaleName);
m_populatedFonts.insert(defaultLocaleName, fontFamily);
fontFamily->AddRef();
if (defaultLocaleName == defaultFontName && defaultFontName != systemDefaultFontName) {
qDebug(lcQpaFonts) << "Adding default font" << systemDefaultFontName << "as alternative to" << defaultLocaleName;
m_populatedFonts.insert(systemDefaultFontName, fontFamily);
fontFamily->AddRef();
}
}
if (!englishLocaleName.isEmpty() && englishLocaleName != defaultLocaleName) {
registerFontFamily(englishLocaleName);
m_populatedFonts.insert(englishLocaleName, fontFamily);
fontFamily->AddRef();
if (englishLocaleName == defaultFontName && defaultFontName != systemDefaultFontName) {
qDebug(lcQpaFonts) << "Adding default font" << systemDefaultFontName << "as alternative to" << englishLocaleName;
m_populatedFonts.insert(systemDefaultFontName, fontFamily);
fontFamily->AddRef();
}
}
fontFamily->Release();
}
}
}
}
QFont QWindowsDirectWriteFontDatabase::defaultFont() const
{
return QFont(QStringLiteral("Segoe UI"));
}
#endif // QT_USE_DIRECTWRITE3
QT_END_NAMESPACE

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -37,38 +37,60 @@
**
****************************************************************************/
#include <qsqldriverplugin.h>
#include <qstringlist.h>
#include "qsql_sqlite2_p.h"
#ifndef QWINDOWSDIRECTWRITEFONTDATABASE_P_H
#define QWINDOWSDIRECTWRITEFONTDATABASE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qwindowsfontdatabasebase_p.h"
#include <qpa/qplatformfontdatabase.h>
#include <QtCore/qloggingcategory.h>
struct IDWriteFactory;
struct IDWriteFont;
struct IDWriteFontFamily;
struct IDWriteLocalizedStrings;
QT_BEGIN_NAMESPACE
// ### Qt6: remove, obsolete since 5.14
class QSQLite2DriverPlugin : public QSqlDriverPlugin
#ifdef QT_USE_DIRECTWRITE3
class QWindowsDirectWriteFontDatabase : public QWindowsFontDatabaseBase
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QSqlDriverFactoryInterface" FILE "sqlite2.json")
Q_DISABLE_COPY_MOVE(QWindowsDirectWriteFontDatabase)
public:
QSQLite2DriverPlugin();
QWindowsDirectWriteFontDatabase();
~QWindowsDirectWriteFontDatabase() override;
QSqlDriver* create(const QString &);
void populateFontDatabase() override;
void populateFamily(const QString &familyName) override;
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override;
void releaseHandle(void *handle) override;
QFont defaultFont() const override;
bool fontsAlwaysScalable() const override;
bool isPrivateFontFamily(const QString &family) const override;
private:
static QString localeString(IDWriteLocalizedStrings *names, wchar_t localeName[]);
QHash<QString, IDWriteFontFamily *> m_populatedFonts;
};
QSQLite2DriverPlugin::QSQLite2DriverPlugin()
: QSqlDriverPlugin()
{
}
QSqlDriver* QSQLite2DriverPlugin::create(const QString &name)
{
if (name == QLatin1String("QSQLITE2")) {
QSQLite2Driver* driver = new QSQLite2Driver();
return driver;
}
return 0;
}
#endif // QT_USE_DIRECTWRITE3
QT_END_NAMESPACE
#include "smain.moc"
#endif // QWINDOWSDIRECTWRITEFONTDATABASE_P_H

Some files were not shown because too many files have changed in this diff Show More