Make QtQuick2 compile on QPA
Moved the logic to set pixel size into the font engines to avoid making the platform plugin interface too complex, and added a function in QPA to make an isolated font engine based on font data. Currently none of the QPA back-ends supports it, but it compiles and spits out a warning if you try to create a QRawFont from data there. This isn't used in QtQuick2 anyway. Reviewed-by: Jiang Jiang
This commit is contained in:
parent
9e57cd5e6a
commit
07fa0ccfc4
@ -2755,7 +2755,8 @@ QT_LICENSED_MODULE(DBus)
|
||||
|
||||
#if !(defined(Q_WS_WIN) && !defined(Q_WS_WINCE)) \
|
||||
&& !(defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) \
|
||||
&& !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE))
|
||||
&& !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE)) \
|
||||
&& !(defined(Q_WS_QPA))
|
||||
# define QT_NO_RAWFONT
|
||||
#endif
|
||||
|
||||
|
@ -837,6 +837,15 @@ QFixed QCoreTextFontEngine::emSquareSize() const
|
||||
return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
||||
}
|
||||
|
||||
QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
|
||||
{
|
||||
QFontDef newFontDef = fontDef;
|
||||
newFontDef.pixelSize = pixelSize;
|
||||
newFontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
|
||||
|
||||
return new QCoreTextFontEngine(cgFont, fontDef);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
|
||||
|
@ -91,6 +91,8 @@ public:
|
||||
virtual qreal minLeftBearing() const;
|
||||
virtual QFixed emSquareSize() const;
|
||||
|
||||
virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
|
||||
|
||||
private:
|
||||
friend class QRawFontPrivate;
|
||||
|
||||
|
@ -2069,6 +2069,41 @@ HB_Error QFontEngineFT::getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 p
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QFontEngineFT::initFromFontEngine(const QFontEngineFT *fe)
|
||||
{
|
||||
if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype))
|
||||
return false;
|
||||
|
||||
// Increase the reference of this QFreetypeFace since one more QFontEngineFT
|
||||
// will be using it
|
||||
freetype->ref.ref();
|
||||
|
||||
default_load_flags = fe->default_load_flags;
|
||||
default_hint_style = fe->default_hint_style;
|
||||
antialias = fe->antialias;
|
||||
transform = fe->transform;
|
||||
embolden = fe->embolden;
|
||||
subpixelType = fe->subpixelType;
|
||||
lcdFilterType = fe->lcdFilterType;
|
||||
canUploadGlyphsToServer = fe->canUploadGlyphsToServer;
|
||||
embeddedbitmap = fe->embeddedbitmap;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QFontEngine *QFontEngineFT::cloneWithSize(qreal pixelSize) const
|
||||
{
|
||||
QFontDef fontDef;
|
||||
fontDef.pixelSize = pixelSize;
|
||||
QFontEngineFT *fe = new QFontEngineFT(fontDef);
|
||||
if (!fe->initFromFontEngine(this)) {
|
||||
delete fe;
|
||||
return 0;
|
||||
} else {
|
||||
return fe;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_FREETYPE
|
||||
|
@ -122,7 +122,7 @@ struct QFreetypeFace
|
||||
static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool = false);
|
||||
|
||||
private:
|
||||
friend class QFontEngineFTRawFont;
|
||||
friend class QFontEngineFT;
|
||||
friend class QScopedPointerDeleter<QFreetypeFace>;
|
||||
QFreetypeFace() : _lock(QMutex::Recursive) {}
|
||||
~QFreetypeFace() {}
|
||||
@ -311,7 +311,12 @@ private:
|
||||
|
||||
virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints);
|
||||
|
||||
|
||||
virtual void setDefaultHintStyle(HintStyle style);
|
||||
|
||||
virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
|
||||
bool initFromFontEngine(const QFontEngineFT *fontEngine);
|
||||
|
||||
HintStyle defaultHintStyle() const { return default_hint_style; }
|
||||
protected:
|
||||
|
||||
|
@ -235,6 +235,8 @@ public:
|
||||
|
||||
virtual int glyphCount() const;
|
||||
|
||||
virtual QFontEngine *cloneWithSize(qreal /*pixelSize*/) const { return 0; }
|
||||
|
||||
HB_Font harfbuzzFont() const;
|
||||
HB_Face harfbuzzFace() const;
|
||||
|
||||
|
@ -1284,6 +1284,23 @@ QImage QFontEngineWin::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, co
|
||||
return rgbMask;
|
||||
}
|
||||
|
||||
// From qfontdatabase_win.cpp
|
||||
extern QFontEngine *qt_load_font_engine_win(const QFontDef &request);
|
||||
QFontEngine *QFontEngineWin::cloneWithSize(qreal pixelSize) const
|
||||
{
|
||||
QFontDef request = fontDef;
|
||||
QString actualFontName = request.family;
|
||||
if (!uniqueFamilyName.isEmpty())
|
||||
request.family = uniqueFamilyName;
|
||||
request.pixelSize = pixelSize;
|
||||
|
||||
QFontEngine *fontEngine = qt_load_font_engine_win(request);
|
||||
if (fontEngine != NULL)
|
||||
fontEngine->fontDef.family = actualFontName;
|
||||
|
||||
return fontEngine;
|
||||
}
|
||||
|
||||
// -------------------------------------- Multi font engine
|
||||
|
||||
QFontEngineMultiWin::QFontEngineMultiWin(QFontEngine *first, const QStringList &fallbacks)
|
||||
|
@ -106,6 +106,8 @@ public:
|
||||
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
|
||||
virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
|
||||
|
||||
virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
|
||||
|
||||
#ifndef Q_CC_MINGW
|
||||
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
|
||||
#endif
|
||||
@ -118,6 +120,7 @@ public:
|
||||
#endif
|
||||
|
||||
QString _name;
|
||||
QString uniqueFamilyName;
|
||||
HFONT hfont;
|
||||
LOGFONT logfont;
|
||||
uint stockFont : 1;
|
||||
|
@ -1196,6 +1196,20 @@ bool QFontEngineX11FT::uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *
|
||||
#endif
|
||||
}
|
||||
|
||||
QFontEngine *QFontEngineX11FT::cloneWithSize(qreal pixelSize) const
|
||||
{
|
||||
QFontDef fontDef;
|
||||
fontDef.pixelSize = pixelSize;
|
||||
QFontEngineX11FT *fe = new QFontEngineX11FT(fontDef);
|
||||
if (!fe->initFromFontEngine(this)) {
|
||||
delete fe;
|
||||
return 0;
|
||||
} else {
|
||||
fe->xglyph_format = xglyph_format;
|
||||
return fe;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // QT_NO_FONTCONFIG
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -161,6 +161,8 @@ public:
|
||||
explicit QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen);
|
||||
~QFontEngineX11FT();
|
||||
|
||||
QFontEngine *cloneWithSize(qreal pixelSize) const;
|
||||
|
||||
#ifndef QT_NO_XRENDER
|
||||
int xglyph_format;
|
||||
#endif
|
||||
|
@ -630,6 +630,17 @@ QFontEngine::Type QFontEngineDirectWrite::type() const
|
||||
return QFontEngine::DirectWrite;
|
||||
}
|
||||
|
||||
QFontEngine *QFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const
|
||||
{
|
||||
QFontEngine *fontEngine = new QFontEngineDirectWrite(m_directWriteFactory, m_directWriteFontFace,
|
||||
pixelSize);
|
||||
|
||||
fontEngine->fontDef = fontDef;
|
||||
fontEngine->fontDef.pixelSize = pixelSize;
|
||||
|
||||
return fontEngine;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_DIRECTWRITE
|
||||
|
@ -101,6 +101,8 @@ public:
|
||||
QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin,
|
||||
const QTransform &xform);
|
||||
|
||||
QFontEngine *cloneWithSize(qreal pixelSize) const;
|
||||
|
||||
bool canRender(const QChar *string, int len);
|
||||
Type type() const;
|
||||
|
||||
|
@ -218,6 +218,16 @@ QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicode
|
||||
return engine;
|
||||
}
|
||||
|
||||
QFontEngine *QPlatformFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize,
|
||||
QFont::HintingPreference hintingPreference)
|
||||
{
|
||||
Q_UNUSED(fontData);
|
||||
Q_UNUSED(pixelSize);
|
||||
Q_UNUSED(hintingPreference);
|
||||
qWarning("This plugin does not support font engines created directly from font data");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
|
@ -92,6 +92,8 @@ public:
|
||||
virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
|
||||
virtual void releaseHandle(void *handle);
|
||||
|
||||
virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
|
||||
|
||||
virtual QString fontDir() const;
|
||||
|
||||
//callback
|
||||
|
@ -579,8 +579,19 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ
|
||||
*/
|
||||
void QRawFont::setPixelSize(int pixelSize)
|
||||
{
|
||||
if (d->fontEngine == 0)
|
||||
return;
|
||||
|
||||
detach();
|
||||
d->platformSetPixelSize(pixelSize);
|
||||
QFontEngine *oldFontEngine = d->fontEngine;
|
||||
|
||||
d->fontEngine = d->fontEngine->cloneWithSize(pixelSize);
|
||||
if (d->fontEngine != 0)
|
||||
d->fontEngine->ref.ref();
|
||||
|
||||
oldFontEngine->ref.deref();
|
||||
if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
|
||||
delete oldFontEngine;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -90,32 +90,6 @@ public:
|
||||
|
||||
return init(faceId, true, Format_None, fontData);
|
||||
}
|
||||
|
||||
bool initFromFontEngine(QFontEngine *oldFontEngine)
|
||||
{
|
||||
QFontEngineFT *fe = static_cast<QFontEngineFT *>(oldFontEngine);
|
||||
|
||||
// Increase the reference of this QFreetypeFace since one more QFontEngineFT
|
||||
// will be using it
|
||||
fe->freetype->ref.ref();
|
||||
if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype))
|
||||
return false;
|
||||
|
||||
default_load_flags = fe->default_load_flags;
|
||||
default_hint_style = fe->default_hint_style;
|
||||
antialias = fe->antialias;
|
||||
transform = fe->transform;
|
||||
embolden = fe->embolden;
|
||||
subpixelType = fe->subpixelType;
|
||||
lcdFilterType = fe->lcdFilterType;
|
||||
canUploadGlyphsToServer = fe->canUploadGlyphsToServer;
|
||||
embeddedbitmap = fe->embeddedbitmap;
|
||||
|
||||
#if defined(Q_WS_X11)
|
||||
xglyph_format = static_cast<QFontEngineX11FT *>(fe)->xglyph_format;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -159,31 +133,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixel
|
||||
fontEngine->ref.ref();
|
||||
}
|
||||
|
||||
void QRawFontPrivate::platformSetPixelSize(int pixelSize)
|
||||
{
|
||||
if (fontEngine == NULL)
|
||||
return;
|
||||
|
||||
QFontEngine *oldFontEngine = fontEngine;
|
||||
|
||||
QFontDef fontDef;
|
||||
fontDef.pixelSize = pixelSize;
|
||||
QFontEngineFTRawFont *fe = new QFontEngineFTRawFont(fontDef);
|
||||
if (!fe->initFromFontEngine(oldFontEngine)) {
|
||||
delete fe;
|
||||
return;
|
||||
}
|
||||
|
||||
fontEngine = fe;
|
||||
fontEngine->fontDef = oldFontEngine->fontDef;
|
||||
fontEngine->fontDef.pixelSize = pixelSize;
|
||||
fontEngine->ref.ref();
|
||||
Q_ASSERT(fontEngine != oldFontEngine);
|
||||
oldFontEngine->ref.deref();
|
||||
if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
|
||||
delete oldFontEngine;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_RAWFONT
|
||||
|
@ -78,28 +78,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData,
|
||||
}
|
||||
}
|
||||
|
||||
void QRawFontPrivate::platformSetPixelSize(int pixelSize)
|
||||
{
|
||||
if (fontEngine == NULL)
|
||||
return;
|
||||
|
||||
QFontEngine *oldFontEngine = fontEngine;
|
||||
|
||||
QFontDef fontDef = oldFontEngine->fontDef;
|
||||
fontDef.pixelSize = pixelSize;
|
||||
fontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
|
||||
|
||||
QCoreTextFontEngine *ctFontEngine = static_cast<QCoreTextFontEngine *>(oldFontEngine);
|
||||
Q_ASSERT(ctFontEngine->cgFont);
|
||||
|
||||
fontEngine = new QCoreTextFontEngine(ctFontEngine->cgFont, fontDef);
|
||||
fontEngine->ref.ref();
|
||||
Q_ASSERT(fontEngine != oldFontEngine);
|
||||
oldFontEngine->ref.deref();
|
||||
if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
|
||||
delete oldFontEngine;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_RAWFONT
|
||||
|
@ -83,7 +83,6 @@ public:
|
||||
, fontHandle(NULL)
|
||||
, ptrAddFontMemResourceEx(other.ptrAddFontMemResourceEx)
|
||||
, ptrRemoveFontMemResourceEx(other.ptrRemoveFontMemResourceEx)
|
||||
, uniqueFamilyName(other.uniqueFamilyName)
|
||||
#endif
|
||||
{
|
||||
fontEngine = other.fontEngine;
|
||||
@ -102,7 +101,6 @@ public:
|
||||
void platformLoadFromData(const QByteArray &fontData,
|
||||
int pixelSize,
|
||||
QFont::HintingPreference hintingPreference);
|
||||
void platformSetPixelSize(int pixelSize);
|
||||
|
||||
static QRawFontPrivate *get(const QRawFont &font) { return font.d.data(); }
|
||||
|
||||
@ -120,8 +118,6 @@ public:
|
||||
PtrAddFontMemResourceEx ptrAddFontMemResourceEx;
|
||||
PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx;
|
||||
|
||||
QString uniqueFamilyName;
|
||||
|
||||
#endif // Q_WS_WIN
|
||||
};
|
||||
|
||||
|
69
src/gui/text/qrawfont_qpa.cpp
Normal file
69
src/gui/text/qrawfont_qpa.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#if !defined(QT_NO_RAWFONT)
|
||||
|
||||
#include "qrawfont_p.h"
|
||||
#include <QtGui/qplatformfontdatabase_qpa.h>
|
||||
#include <private/qapplication_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
void QRawFontPrivate::platformCleanUp()
|
||||
{
|
||||
}
|
||||
|
||||
void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixelSize,
|
||||
QFont::HintingPreference hintingPreference)
|
||||
{
|
||||
Q_ASSERT(fontEngine == 0);
|
||||
|
||||
QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase();
|
||||
fontEngine = pfdb->fontEngine(fontData, pixelSize, hintingPreference);
|
||||
if (fontEngine != 0)
|
||||
fontEngine->ref.ref();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_RAWFONT
|
@ -559,7 +559,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
|
||||
GUID guid;
|
||||
CoCreateGuid(&guid);
|
||||
|
||||
uniqueFamilyName = QString::fromLatin1("f")
|
||||
QString uniqueFamilyName = QString::fromLatin1("f")
|
||||
+ QString::number(guid.Data1, 36) + QLatin1Char('-')
|
||||
+ QString::number(guid.Data2, 36) + QLatin1Char('-')
|
||||
+ QString::number(guid.Data3, 36) + QLatin1Char('-')
|
||||
@ -613,6 +613,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
|
||||
Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref == 0);
|
||||
|
||||
// Override the generated font name
|
||||
static_cast<QFontEngineWin *>(fontEngine)->uniqueFamilyName = uniqueFamilyName;
|
||||
fontEngine->fontDef.family = actualFontName;
|
||||
fontEngine->ref.ref();
|
||||
}
|
||||
@ -701,50 +702,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
|
||||
}
|
||||
}
|
||||
|
||||
void QRawFontPrivate::platformSetPixelSize(int pixelSize)
|
||||
{
|
||||
if (fontEngine == NULL)
|
||||
return;
|
||||
|
||||
QFontEngine *oldFontEngine = fontEngine;
|
||||
|
||||
#if !defined(QT_NO_DIRECTWRITE)
|
||||
if (fontEngine->type() == QFontEngine::Win)
|
||||
#endif
|
||||
|
||||
{
|
||||
QFontDef request = fontEngine->fontDef;
|
||||
QString actualFontName = request.family;
|
||||
if (!uniqueFamilyName.isEmpty())
|
||||
request.family = uniqueFamilyName;
|
||||
request.pixelSize = pixelSize;
|
||||
|
||||
fontEngine = qt_load_font_engine_win(request);
|
||||
if (fontEngine != NULL) {
|
||||
fontEngine->fontDef.family = actualFontName;
|
||||
fontEngine->ref.ref();
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(QT_NO_DIRECTWRITE)
|
||||
else {
|
||||
QFontEngineDirectWrite *dWriteFE = static_cast<QFontEngineDirectWrite *>(fontEngine);
|
||||
fontEngine = new QFontEngineDirectWrite(dWriteFE->m_directWriteFactory,
|
||||
dWriteFE->m_directWriteFontFace,
|
||||
pixelSize);
|
||||
|
||||
fontEngine->fontDef = dWriteFE->fontDef;
|
||||
fontEngine->fontDef.pixelSize = pixelSize;
|
||||
fontEngine->ref.ref();
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_ASSERT(fontEngine != oldFontEngine);
|
||||
oldFontEngine->ref.deref();
|
||||
if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
|
||||
delete oldFontEngine;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_RAWFONT
|
||||
|
@ -136,7 +136,8 @@ qpa {
|
||||
SOURCES += \
|
||||
text/qfont_qpa.cpp \
|
||||
text/qfontengine_qpa.cpp \
|
||||
text/qplatformfontdatabase_qpa.cpp
|
||||
text/qplatformfontdatabase_qpa.cpp \
|
||||
text/qrawfont_qpa.cpp
|
||||
|
||||
HEADERS += \
|
||||
text/qplatformfontdatabase_qpa.h
|
||||
|
Loading…
Reference in New Issue
Block a user