, elideMode(QQuickText::ElideNone), hAlign(QQuickText::AlignLeft), vAlign(QQuickText::AlignTop)
, format(QQuickText::AutoText), wrapMode(QQuickText::NoWrap)
, style(QQuickText::Normal)
+ , renderType(QQuickText::QtRendering)
, updateType(UpdatePaintNode)
, maximumLineCountValid(false), updateOnComponentComplete(true), richText(false)
, styledText(false), widthExceeded(false), heightExceeded(false), internalWidthUpdate(false)
return implicitHeight;
}
+/*!
+ \qmlproperty enumeration QtQuick2::Text::renderType
+
+ Override the default rendering type for this component.
+
+ Supported render types are:
+ \list
+ \li Text.QtRendering - the default
+ \li Text.NativeRendering
+ \endlist
+
+ Select Text.NativeRendering if you prefer text to look native on the target platform and do
+ not require advanced features such as transformation of the text. Using such features in
+ combination with the NativeRendering render type will lend poor and sometimes pixelated
+ results.
+*/
+QQuickText::RenderType QQuickText::renderType() const
+{
+ Q_D(const QQuickText);
+ return d->renderType;
+}
+
+void QQuickText::setRenderType(QQuickText::RenderType renderType)
+{
+ Q_D(QQuickText);
+ if (d->renderType == renderType)
+ return;
+
+ d->renderType = renderType;
+ emit renderTypeChanged();
+
+ if (isComponentComplete())
+ d->updateLayout();
+}
+
void QQuickText::q_imagesLoaded()
{
Q_D(QQuickText);
QTextOption option;
option.setAlignment((Qt::Alignment)int(horizontalAlignment | vAlign));
option.setWrapMode(QTextOption::WrapMode(wrapMode));
- option.setUseDesignMetrics(true);
+ option.setUseDesignMetrics(renderType != QQuickText::NativeRendering);
extra->doc->setDefaultTextOption(option);
qreal naturalWidth = 0;
if (requireImplicitSize && q->widthValid()) {
return QRectF(0, 0, 0, height);
}
+ bool shouldUseDesignMetrics = renderType != QQuickText::NativeRendering;
+
layout.setCacheEnabled(true);
QTextOption textOption = layout.textOption();
if (textOption.alignment() != q->effectiveHAlign()
|| textOption.wrapMode() != QTextOption::WrapMode(wrapMode)
- || !textOption.useDesignMetrics()) {
+ || textOption.useDesignMetrics() != shouldUseDesignMetrics) {
textOption.setAlignment(Qt::Alignment(q->effectiveHAlign()));
textOption.setWrapMode(QTextOption::WrapMode(wrapMode));
- textOption.setUseDesignMetrics(true);
+ textOption.setUseDesignMetrics(shouldUseDesignMetrics);
layout.setTextOption(textOption);
}
if (layout.font() != font)
node = static_cast<QQuickTextNode *>(oldNode);
}
+ node->setUseNativeRenderer(d->renderType == NativeRendering);
node->deleteContent();
node->setMatrix(QMatrix4x4());
Q_ENUMS(WrapMode)
Q_ENUMS(LineHeightMode)
Q_ENUMS(FontSizeMode)
+ Q_ENUMS(RenderType)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
Q_PROPERTY(int minimumPixelSize READ minimumPixelSize WRITE setMinimumPixelSize NOTIFY minimumPixelSizeChanged)
Q_PROPERTY(int minimumPointSize READ minimumPointSize WRITE setMinimumPointSize NOTIFY minimumPointSizeChanged)
Q_PROPERTY(FontSizeMode fontSizeMode READ fontSizeMode WRITE setFontSizeMode NOTIFY fontSizeModeChanged)
+ Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
public:
QQuickText(QQuickItem *parent=0);
Wrap = QTextOption::WrapAtWordBoundaryOrAnywhere
};
+ enum RenderType { QtRendering,
+ NativeRendering
+ };
+
enum LineHeightMode { ProportionalHeight, FixedHeight };
enum FontSizeMode { FixedSize = 0x0, HorizontalFit = 0x01, VerticalFit = 0x02,
QRectF clipRect() const;
Q_INVOKABLE void doLayout();
+ RenderType renderType() const;
+ void setRenderType(RenderType renderType);
+
Q_SIGNALS:
void textChanged(const QString &text);
void linkActivated(const QString &link);
void effectiveHorizontalAlignmentChanged();
void lineLaidOut(QQuickTextLine *line);
void baseUrlChanged();
+ void renderTypeChanged();
protected:
void mousePressEvent(QMouseEvent *event);
QQuickText::TextFormat format;
QQuickText::WrapMode wrapMode;
QQuickText::TextStyle style;
+ QQuickText::RenderType renderType;
UpdateType updateType;
bool maximumLineCountValid:1;
emit textFormatChanged(d->format);
}
+/*!
+ \qmlproperty enumeration QtQuick2::TextEdit::renderType
+
+ Override the default rendering type for this component.
+
+ Supported render types are:
+ \list
+ \li Text.QtRendering - the default
+ \li Text.NativeRendering
+ \endlist
+
+ Select Text.NativeRendering if you prefer text to look native on the target platform and do
+ not require advanced features such as transformation of the text. Using such features in
+ combination with the NativeRendering render type will lend poor and sometimes pixelated
+ results.
+*/
+QQuickTextEdit::RenderType QQuickTextEdit::renderType() const
+{
+ Q_D(const QQuickTextEdit);
+ return d->renderType;
+}
+
+void QQuickTextEdit::setRenderType(QQuickTextEdit::RenderType renderType)
+{
+ Q_D(QQuickTextEdit);
+ if (d->renderType == renderType)
+ return;
+
+ d->renderType = renderType;
+ emit renderTypeChanged();
+ d->updateDefaultTextOption();
+
+ if (isComponentComplete())
+ updateSize();
+}
+
QFont QQuickTextEdit::font() const
{
Q_D(const QQuickTextEdit);
node = static_cast<QQuickTextNode *>(oldNode);
}
+ node->setUseNativeRenderer(d->renderType == NativeRendering);
node->deleteContent();
node->setMatrix(QMatrix4x4());
QTextOption::WrapMode oldWrapMode = opt.wrapMode();
opt.setWrapMode(QTextOption::WrapMode(wrapMode));
- opt.setUseDesignMetrics(true);
+
+ bool oldUseDesignMetrics = opt.useDesignMetrics();
+ opt.setUseDesignMetrics(renderType != QQuickTextEdit::NativeRendering);
if (oldWrapMode != opt.wrapMode() || oldAlignment != opt.alignment()
- || oldTextDirection != opt.textDirection()) {
+ || oldTextDirection != opt.textDirection()
+ || oldUseDesignMetrics != opt.useDesignMetrics()) {
document->setDefaultTextOption(opt);
}
}
Q_ENUMS(TextFormat)
Q_ENUMS(WrapMode)
Q_ENUMS(SelectionMode)
+ Q_ENUMS(RenderType)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(bool canRedo READ canRedo NOTIFY canRedoChanged)
Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged)
Q_PROPERTY(QUrl baseUrl READ baseUrl WRITE setBaseUrl RESET resetBaseUrl NOTIFY baseUrlChanged)
+ Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
public:
QQuickTextEdit(QQuickItem *parent=0);
SelectWords
};
+ enum RenderType { QtRendering,
+ NativeRendering
+ };
+
QString text() const;
void setText(const QString &);
bool isInputMethodComposing() const;
+ RenderType renderType() const;
+ void setRenderType(RenderType renderType);
+
Q_INVOKABLE QString getText(int start, int end) const;
Q_INVOKABLE QString getFormattedText(int start, int end) const;
void effectiveHorizontalAlignmentChanged();
void baseUrlChanged();
void inputMethodHintsChanged();
+ void renderTypeChanged();
public Q_SLOTS:
void selectAll();
, lastSelectionStart(0), lastSelectionEnd(0), lineCount(0)
, hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop)
, format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap)
+ , renderType(QQuickTextEdit::QtRendering)
, contentDirection(Qt::LayoutDirectionAuto)
, mouseSelectionMode(QQuickTextEdit::SelectCharacters), inputMethodHints(Qt::ImhNone)
, updateType(UpdatePaintNode)
QQuickTextEdit::VAlignment vAlign;
QQuickTextEdit::TextFormat format;
QQuickTextEdit::WrapMode wrapMode;
+ QQuickTextEdit::RenderType renderType;
Qt::LayoutDirection contentDirection;
QQuickTextEdit::SelectionMode mouseSelectionMode;
Qt::InputMethodHints inputMethodHints;
d->internalSetText(s, -1, false);
}
+
+/*!
+ \qmlproperty enumeration QtQuick2::TextInput::renderType
+
+ Override the default rendering type for this component.
+
+ Supported render types are:
+ \list
+ \li Text.QtRendering - the default
+ \li Text.NativeRendering
+ \endlist
+
+ Select Text.NativeRendering if you prefer text to look native on the target platform and do
+ not require advanced features such as transformation of the text. Using such features in
+ combination with the NativeRendering render type will lend poor and sometimes pixelated
+ results.
+*/
+QQuickTextInput::RenderType QQuickTextInput::renderType() const
+{
+ Q_D(const QQuickTextInput);
+ return d->renderType;
+}
+
+void QQuickTextInput::setRenderType(QQuickTextInput::RenderType renderType)
+{
+ Q_D(QQuickTextInput);
+ if (d->renderType == renderType)
+ return;
+
+ d->renderType = renderType;
+ emit renderTypeChanged();
+
+ if (isComponentComplete())
+ d->updateLayout();
+}
+
/*!
\qmlproperty int QtQuick2::TextInput::length
}
}
} else {
+ node->setUseNativeRenderer(d->renderType == QQuickTextInput::NativeRendering);
node->deleteContent();
node->setMatrix(QMatrix4x4());
if (!qmlDisableDistanceField()) {
QTextOption option = m_textLayout.textOption();
- option.setUseDesignMetrics(true);
+ option.setUseDesignMetrics(renderType != QQuickTextInput::NativeRendering);
m_textLayout.setTextOption(option);
}
}
Q_ENUMS(EchoMode)
Q_ENUMS(SelectionMode)
Q_ENUMS(CursorPosition)
+ Q_ENUMS(RenderType)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(int length READ length NOTIFY textChanged)
Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged)
Q_PROPERTY(qreal contentWidth READ contentWidth NOTIFY contentSizeChanged)
Q_PROPERTY(qreal contentHeight READ contentHeight NOTIFY contentSizeChanged)
+ Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
public:
QQuickTextInput(QQuickItem * parent=0);
CursorOnCharacter
};
+ enum RenderType { QtRendering,
+ NativeRendering
+ };
//Auxilliary functions needed to control the TextInput from QML
Q_INVOKABLE void positionAt(QQmlV8Function *args) const;
Q_INVOKABLE void moveCursorSelection(int pos);
Q_INVOKABLE void moveCursorSelection(int pos, SelectionMode mode);
+ RenderType renderType() const;
+ void setRenderType(RenderType renderType);
+
QString text() const;
void setText(const QString &);
void effectiveHorizontalAlignmentChanged();
void contentSizeChanged();
void inputMethodHintsChanged();
+ void renderTypeChanged();
protected:
virtual void geometryChanged(const QRectF &newGeometry,
, vAlign(QQuickTextInput::AlignTop)
, wrapMode(QQuickTextInput::NoWrap)
, m_echoMode(QQuickTextInput::Normal)
+ , renderType(QQuickTextInput::QtRendering)
, updateType(UpdatePaintNode)
, mouseSelectionMode(QQuickTextInput::SelectCharacters)
, m_layoutDirection(Qt::LayoutDirectionAuto)
QQuickTextInput::VAlignment vAlign;
QQuickTextInput::WrapMode wrapMode;
QQuickTextInput::EchoMode m_echoMode;
+ QQuickTextInput::RenderType renderType;
UpdateType updateType;
QQuickTextInput::SelectionMode mouseSelectionMode;
Qt::LayoutDirection m_layoutDirection;
Creates an empty QQuickTextNode
*/
QQuickTextNode::QQuickTextNode(QSGContext *context, QQuickItem *ownerElement)
- : m_context(context), m_cursorNode(0), m_ownerElement(ownerElement)
+ : m_context(context), m_cursorNode(0), m_ownerElement(ownerElement), m_useNativeRenderer(false)
{
#if defined(QML_RUNTIME_TESTING)
description = QLatin1String("text");
QQuickText::TextStyle style, const QColor &styleColor,
QSGNode *parentNode)
{
- QSGGlyphNode *node = m_context->createGlyphNode();
+ QSGGlyphNode *node = m_useNativeRenderer
+ ? m_context->createNativeGlyphNode()
+ : m_context->createGlyphNode();
node->setOwnerElement(m_ownerElement);
node->setGlyphs(position + QPointF(0, glyphs.rawFont().ascent()), glyphs);
node->setStyle(style);
QSGNode *parentNode = 0);
void addImage(const QRectF &rect, const QImage &image);
+ bool useNativeRenderer() const { return m_useNativeRenderer; }
+ void setUseNativeRenderer(bool on) { m_useNativeRenderer = on; }
+
private:
void mergeFormats(QTextLayout *textLayout, QVarLengthArray<QTextLayout::FormatRange> *mergedFormats);
QSGSimpleRectNode *m_cursorNode;
QList<QSGTexture *> m_textures;
QQuickItem *m_ownerElement;
+ bool m_useNativeRenderer;
};
QT_END_NAMESPACE
}
/*!
+ Factory function for scene graph backends of the Text elements which supports native
+ text rendering. Used in special cases where native look and feel is a main objective.
+*/
+QSGGlyphNode *QSGContext::createNativeGlyphNode()
+{
+ return new QSGDefaultGlyphNode;
+}
+
+/*!
Factory function for scene graph backends of the Text elements;
*/
QSGGlyphNode *QSGContext::createGlyphNode()
Q_D(QSGContext);
if (d->distanceFieldDisabled) {
- return new QSGDefaultGlyphNode;
+ return createNativeGlyphNode();
} else {
QSGDistanceFieldGlyphNode *node = new QSGDistanceFieldGlyphNode(this);
node->setPreferredAntialiasingMode(d->distanceFieldAntialiasing);
virtual QSGRectangleNode *createRectangleNode();
virtual QSGImageNode *createImageNode();
virtual QSGGlyphNode *createGlyphNode();
+ virtual QSGGlyphNode *createNativeGlyphNode();
virtual QSGRenderer *createRenderer();
virtual QSGTexture *createTexture(const QImage &image = QImage()) const;
#include <qopenglshaderprogram.h>
#include <QtGui/private/qopengltextureglyphcache_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
#include <private/qfontengine_p.h>
#include <private/qopenglextensions_p.h>
virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
virtual char const *const *attributeNames() const;
+
+ virtual void activate();
+ virtual void deactivate();
+
private:
virtual void initialize();
virtual const char *vertexShader() const;
"uniform sampler2D texture; \n"
"uniform lowp vec4 color; \n"
"void main() { \n"
- " gl_FragColor = color * texture2D(texture, sampleCoord).a; \n"
+ " gl_FragColor = vec4(texture2D(texture, sampleCoord).rgb, 1.0); \n"
"}";
}
m_textureScale_id = program()->uniformLocation("textureScale");
}
+static inline qreal fontSmoothingGamma()
+{
+ static qreal fontSmoothingGamma = QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::FontSmoothingGamma).toReal();
+ return fontSmoothingGamma;
+}
+
+void QSGTextMaskMaterialData::activate()
+{
+ QSGMaterialShader::activate();
+ glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR);
+
+ // 0.25 was found to be acceptable error margin by experimentation. On Mac, the gamma is 2.0,
+ // but using sRGB looks okay.
+ if (qAbs(fontSmoothingGamma() - 2.2) < 0.25)
+ glEnable(GL_FRAMEBUFFER_SRGB);
+}
+
+void QSGTextMaskMaterialData::deactivate()
+{
+ QSGMaterialShader::deactivate();
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ if (qAbs(fontSmoothingGamma() - 2.2) < 0.25)
+ glDisable(GL_FRAMEBUFFER_SRGB);
+}
+
void QSGTextMaskMaterialData::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
{
Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect);
if (oldMaterial == 0 || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
- QVector4D color(material->color().redF(), material->color().greenF(),
- material->color().blueF(), material->color().alphaF());
+ QColor c = material->color();
+ QVector4D color(c.redF(), c.greenF(), c.blueF(), c.alphaF());
color *= state.opacity();
program()->setUniformValue(m_color_id, color);
+
+ if (oldMaterial == 0 || material->color() != oldMaterial->color()) {
+ state.context()->functions()->glBlendColor(c.redF(),
+ c.greenF(),
+ c.blueF(),
+ 1.0f);
+ }
}
bool updated = material->ensureUpToDate();
// Set the mag/min filters to be linear. We only need to do this when the texture
// has been recreated.
if (updated) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
}
{
Q_ASSERT(m_font.isValid());
- QFontEngineGlyphCache::Type type = QFontEngineGlyphCache::Raster_A8;
+ QFontEngineGlyphCache::Type type = QFontEngineGlyphCache::Raster_RGBMask;
setFlag(Blending, true);
QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());