QTextOption: Add flag for showing default ignorable characters
The presence of the flag instructs the text shaping engine to not outright ignore normally non-printable code points, so that if the font has glyphs for them, they will be rendered. This is useful when editing plain text whose layout is affected by the presence of such characters (primarily BiDi control characters), and for layout debugging in general. [ChangeLog][QtGui][Text] Added QTextOption::ShowDefaultIgnorables flag. Change-Id: I610a30603f718254ab8e532083e65252351159f0 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
This commit is contained in:
parent
38bb72720a
commit
889bdf1de4
@ -1498,16 +1498,20 @@ void QTextEngine::shapeText(int item) const
|
||||
for (int i = 0; i < itemLength; ++i, ++glyph_pos) {
|
||||
log_clusters[i] = glyph_pos;
|
||||
initialGlyphs.attributes[glyph_pos].clusterStart = true;
|
||||
|
||||
bool is_print_char;
|
||||
if (QChar::isHighSurrogate(string[i])
|
||||
&& i + 1 < itemLength
|
||||
&& QChar::isLowSurrogate(string[i + 1])) {
|
||||
initialGlyphs.attributes[glyph_pos].dontPrint = !QChar::isPrint(QChar::surrogateToUcs4(string[i], string[i + 1]));
|
||||
is_print_char = QChar::isPrint(QChar::surrogateToUcs4(string[i], string[i + 1]));
|
||||
++i;
|
||||
log_clusters[i] = glyph_pos;
|
||||
|
||||
} else {
|
||||
initialGlyphs.attributes[glyph_pos].dontPrint = !QChar::isPrint(string[i]);
|
||||
is_print_char = QChar::isPrint(string[i]);
|
||||
}
|
||||
initialGlyphs.attributes[glyph_pos].dontPrint =
|
||||
!is_print_char && !(option.flags() & QTextOption::ShowDefaultIgnorables);
|
||||
|
||||
if (Q_UNLIKELY(!initialGlyphs.attributes[glyph_pos].dontPrint)) {
|
||||
QFontEngine *actualFontEngine = fontEngine;
|
||||
@ -1638,7 +1642,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si,
|
||||
uint buffer_flags = HB_BUFFER_FLAG_DEFAULT;
|
||||
// Symbol encoding used to encode various crap in the 32..255 character code range,
|
||||
// and thus might override U+00AD [SHY]; avoid hiding default ignorables
|
||||
if (Q_UNLIKELY(actualFontEngine->symbol))
|
||||
if (Q_UNLIKELY(actualFontEngine->symbol || (option.flags() & QTextOption::ShowDefaultIgnorables)))
|
||||
buffer_flags |= HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES;
|
||||
hb_buffer_set_flags(buffer, hb_buffer_flags_t(buffer_flags));
|
||||
|
||||
|
@ -268,6 +268,7 @@ QList<QTextOption::Tab> QTextOption::tabs() const
|
||||
shown differently to breaking spaces.
|
||||
\value ShowLineAndParagraphSeparators Visualize line and paragraph separators with appropriate symbol characters.
|
||||
\value [since 5.7] ShowDocumentTerminator Visualize the end of the document with a section sign.
|
||||
\value [since 6.9] ShowDefaultIgnorables Render normally non-visual characters if supported by font.
|
||||
\value AddSpaceForLineAndParagraphSeparators While determining the line-break positions take into account the
|
||||
space added for drawing a separator character.
|
||||
\value SuppressColors Suppress all color changes in the character formats (except the main selection).
|
||||
|
@ -73,6 +73,7 @@ public:
|
||||
AddSpaceForLineAndParagraphSeparators = 0x4,
|
||||
SuppressColors = 0x8,
|
||||
ShowDocumentTerminator = 0x10,
|
||||
ShowDefaultIgnorables = 0x20,
|
||||
IncludeTrailingSpaces = 0x80000000,
|
||||
};
|
||||
Q_DECLARE_FLAGS(Flags, Flag)
|
||||
|
@ -27,9 +27,13 @@ set_source_files_properties("../../../shared/resources/testfont.ttf"
|
||||
set_source_files_properties("../../../shared/resources/testfont_linemetrics.otf"
|
||||
PROPERTIES QT_RESOURCE_ALIAS "testfont_linemetrics.otf"
|
||||
)
|
||||
set_source_files_properties("../../../shared/resources/testfont_bidimarks.ttf"
|
||||
PROPERTIES QT_RESOURCE_ALIAS "testfont_bidimarks.ttf"
|
||||
)
|
||||
set(testfont_resource_files
|
||||
"../../../shared/resources/testfont.ttf"
|
||||
"../../../shared/resources/testfont_linemetrics.otf"
|
||||
"../../../shared/resources/testfont_bidimarks.ttf"
|
||||
"ucs4font.ttf"
|
||||
)
|
||||
|
||||
|
@ -37,6 +37,8 @@ private slots:
|
||||
void largeText_data();
|
||||
void largeText(); // QTBUG-123339
|
||||
void typoLineMetrics();
|
||||
void defaultIgnorableHorizontalAdvance_data();
|
||||
void defaultIgnorableHorizontalAdvance();
|
||||
};
|
||||
|
||||
void tst_QFontMetrics::same()
|
||||
@ -454,5 +456,60 @@ void tst_QFontMetrics::typoLineMetrics()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QFontMetrics::defaultIgnorableHorizontalAdvance_data()
|
||||
{
|
||||
QTest::addColumn<bool>("withShaping");
|
||||
|
||||
QTest::newRow("With Text Shaping") << true;
|
||||
QTest::newRow("Without Text Shaping") << false;
|
||||
}
|
||||
|
||||
void tst_QFontMetrics::defaultIgnorableHorizontalAdvance()
|
||||
{
|
||||
QFETCH(bool, withShaping);
|
||||
|
||||
// testfont_bidimarks.ttf is a version of testfont.ttf with additional
|
||||
// glyphs for U+200E (LRM) and U+200F (RLM)
|
||||
QString testFont = QFINDTESTDATA("fonts/testfont_bidimarks.ttf");
|
||||
QVERIFY(!testFont.isEmpty());
|
||||
|
||||
int id = QFontDatabase::addApplicationFont(testFont);
|
||||
QVERIFY(id >= 0);
|
||||
|
||||
auto cleanup = qScopeGuard([&id] {
|
||||
if (id >= 0)
|
||||
QFontDatabase::removeApplicationFont(id);
|
||||
});
|
||||
|
||||
QFont withoutSupport;
|
||||
QFont withSupport(QFontDatabase::applicationFontFamilies(id).at(0));
|
||||
|
||||
if (!withShaping) {
|
||||
withoutSupport.setStyleStrategy(QFont::PreferNoShaping);
|
||||
withSupport.setStyleStrategy(QFont::PreferNoShaping);
|
||||
}
|
||||
|
||||
QFontMetrics withoutSupportMetrics(withoutSupport);
|
||||
QFontMetrics withSupportMetrics(withSupport);
|
||||
|
||||
QTextOption opt;
|
||||
opt.setFlags(QTextOption::ShowDefaultIgnorables);
|
||||
|
||||
const QChar LRM = (ushort)0x200e;
|
||||
const QString str = QStringLiteral("[") + LRM + QStringLiteral("]");
|
||||
|
||||
int withoutSupportWithoutIgnorablesAdvance = withoutSupportMetrics.horizontalAdvance(str);
|
||||
int withoutSupportWithIgnorablesAdvance = withoutSupportMetrics.horizontalAdvance(str, opt);
|
||||
|
||||
QCOMPARE_GT(withoutSupportWithoutIgnorablesAdvance, 0);
|
||||
QCOMPARE_EQ(withoutSupportWithIgnorablesAdvance, withoutSupportWithoutIgnorablesAdvance);
|
||||
|
||||
int withSupportWithoutIgnorablesAdvance = withSupportMetrics.horizontalAdvance(str);
|
||||
int withSupportWithIgnorablesAdvance = withSupportMetrics.horizontalAdvance(str, opt);
|
||||
|
||||
QCOMPARE_GT(withSupportWithoutIgnorablesAdvance, 0);
|
||||
QCOMPARE_GT(withSupportWithIgnorablesAdvance, withSupportWithoutIgnorablesAdvance);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QFontMetrics)
|
||||
#include "tst_qfontmetrics.moc"
|
||||
|
BIN
tests/auto/shared/resources/testfont_bidimarks.ttf
Normal file
BIN
tests/auto/shared/resources/testfont_bidimarks.ttf
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user