It is annoying that HB maintains binary compatibility but does not
really care about source compatibility.
Change-Id: Ife7b011919f28527b77858ad8398fe723c65b1b3
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
(same thing for center- and delimiter-aligned tabs)
The width of the inline object wasn't taken into account, the code in
QTextEngine::calculateTabWidth only looked at glyph widths.
Change-Id: I303a6561c67870ff2094a685698e642fc1b53b12
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
In positionInLigature() we were mixing indexes into the script item with
indexes into the entire string. The getClusterLength() function would expect
an attributes array for the current script item and it thus needs to be
adjusted by si->position. In addition, when looking for the next grapheme
boundary, we were comparing pos (which indexed the string) with end (which
indexed the script item). This has also now been fixed by adjusting for
si->position as well.
Task-number: QTBUG-30123
Change-Id: Id02e2eddcc5b7888eacb34bd1e39cc6911880ca1
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Change check of QAtomicInt::load with the preferred ref() deref() pattern.
Change-Id: I12d2e24812259c16623c8a59cac30cafa4b05565
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Make sure we deallocate the scaled rawfont, when it is not used due
to a cached engine being used instead.
This fixes a major memory leak in Qt WebKit when using Small Caps in the
complex font path. The complex font path is always used for small caps
since Qt 5.1.
Task-number: QTBUG-33576
Change-Id: I500db9ae6f6576734f1a972387a1a488218a9db6
Reviewed-by: pierre.rossi@digia.com
Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
This was broken in 7ac6ce21 which removed some unused functions;
but MSVC2008 in debug mode requires this particular operator overload.
I'm re-adding it in an appropriate #ifdef so it doesn't cause "unused"
warnings in other platforms/compilers.
Task-number: QTBUG-33473
Change-Id: I6dfba0fa5f835e848e8a1e4213efb030fb5def3d
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Some features are of limited usefulness for now (same as with HB-old):
* mixed scripts cases aren't handled correctly due to an outdated
script and bidi itemization implementation;
* language-by-script detection: the only fallback to locale's LANG is used
Some features are missing entirely (in compare to HB-old):
* justification points support: not implemented in HarfBuzz-NG
Task-number: QTBUG-18980
Task-number: QTBUG-14590
Task-number: QTBUG-16128
Change-Id: Ic98a10054be5fac55224ef31c7261168c0bf8739
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Use Q_UNREACHABLE() instead of silly return to catch shaping errors,
which are fatal ones in fact, since the application would assert/crash
some later due to a hard dependency on the shaping result.
Change-Id: Ie58a2f2686a795f6178a588de6f2a2e37e1ed13c
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Move (sub-)item boundaries calculation (aka fallback font items)
outside to be shared with HarfBuzz-NG based shaping a bit later.
This implementation might silently break words or even graphemes
so it needs to be reworked anyways; keeping it in a single place
would make futher work some cheaper.
Change-Id: Id9ca82b40e90b07ca29363fd43247c5fa9897eff
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Added Q_DECL_UNUSED for the function used in Q_ASSERT; removed the
functions that really weren't used and added the #ifdef for the
function that was only used under #ifdef.
qmetaobjectbuilder.cpp(93): warning #177: function "priv" was declared but never referenced
qobject.cpp(2349): warning #177: function "check_and_warn_compat" was declared but never referenced
qpathsimplifier.cpp(141): error #177: function "<unnamed>::Rational::isValid" was declared but never referenced
qtextengine.cpp(2584): error #177: function "<unnamed>::QScriptItemComparator::operator()(const QScriptItem &, const QScriptItem &)" was declared but never referenced
Change-Id: I89a140d59211f10ecd88d751f0bcc0ea2fedff7f
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Check if the sequence is really a mnemonic and emulate grapheme cluster if so,
rather than blindly reset the next character's attributes.
This covers cases like "& ", "&<U+034F>", etc.
Change-Id: Ibb063a2d258aff6455b9bb41bbe1a58a5036d0d6
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
* Move non-specific code to shapeText();
* Make shapeTextWithHarfbuzz() re-use variables obtained in shapeText();
* Make shapeTextWithHarfbuzz() return amount of shaped glyphs
instead of nothing. Right now, this is not about error reporting,
since failed shaping causes assertion/crash in most cases.
Change-Id: I2e0c91b9e5de8b19e0bc22ca60add1b1fc6ebdb0
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Also move stringToGlyphs() helper closer to shapeTextWithHarfbuzz(),
where it is only used.
As of now, Harfbuzz-old dependency in QTextEngine can be disabled
by simply if-defing a single piece of code.
Change-Id: Ic6f7d9b64bf9201d7540c58db46e20f28de8120d
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
1. when there were some engines with ref > 1 in the cache, prior to calling
QFontDatabase::{add,remove}ApplicationFont()/removeAllApplicationFonts()
(QFontCache::clear() has never decreased engine's cache_count);
2. when the QFontEngineData's engine is not in cache i.e. the Box or Test font engine
(~QFontEngineData() didn't free engines it keeps).
Instead of using the font engine's (external) "cache_count" counter,
QFontCache now references a given font engine every time it is inserted to
the cache and dereferences exactly that number of times in clear().
Change-Id: I87677ebd24c1f4a81a53526f2e726e596b043c61
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
As of now, we'll have everything related to the additional formats handling
just in a single place. Make specialData private to prevent accessing it
from outside. This helped in tracking-down several related issues:
- in format(const QScriptItem *), the resolvedFormatIndices can not be empty
at that point, so the code path is dead;
- in resolveAdditionalFormats(), testing if formats has not been indexed yet
is not needed since they are indexed just in the setter;
- in useRawFont mode, hasFormats() didn't check if QTextEngine really
has some formats, which potentially leads to formatting artifacts.
Change-Id: Id4b912888fd5a1fa83f01007170134b6386e2879
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
The capitalization settings is attempted read via specialData->addFormats,
but the QTextCharFormat there is reset when added, and should instead be
accessed through specialData->addFormatIndices.
Change-Id: I190c419f07c3f7e803ca1d44059e8f538216b9ab
Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
This is still the same trivial implementation with the only difference in that
that it properly handles surrogate pairs and combining marks.
This temporarily makes QTextEngine::itemize() insignificatly slower due to
using intermediate buffer, until refactoring is done.
Change-Id: I7987d6306b0b5cdb21b837968e292dd70abfe223
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Avoid using script_to_hbscript() in generateScriptItems()'s loop.
This is absolutely unnecessary due to hbscript_to_script(script_to_hbscript(..))
in QTextEngine::itemize().
Change-Id: I44e710d010f8e57043a6c74dd80f3164e95e18e6
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This affects HB_Font and HB_Face.
As of now, the Hurfbuzz API usage is concentrated in qfontengine(|_ft).cpp
and qtextengine.cpp, thus it is a lot easier to switch to Hurfbuzz-NG.
Change-Id: Ie06959efd5d6080fe44c407d9f5de0a07dd1c210
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Josh Faust <jfaust@suitabletech.com>
With trailing spaces in some cases, we would not get the
"no justification at end of paragraph" special case, and continue
in the code, getting the unexpected case where line_length becomes
< 0 which would lead to memory corruption because we were writing
outside our buffers. I added an assert to catch this type of bug
earlier, and I added the trailing spaces to the test for the end
of the paragraph.
The test case added is one example which would crash.
Task-number: QTBUG-27354
Change-Id: Id720a6fa55dbc709ce04dd5321e55687bf960d75
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
...and remove the outdated QUnicodeTables::Script enum.
QFontEngineData now has one extra slot that never used
(engines[QChar::Script_Inherited]). engines[QChar::Script_Unknown],
if accessed, would be set with a Box engine instance, and could be used
as a minor optimization some time later.
In order to preserve the existing behavior, we map all scripts up to Latin to Common.
Change-Id: Ide4182a0f8447b4bf25713ecc3fe8097b8fed040
Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
There are a lot of hacks here and there in Qt trying to align the
text in a correct way which caused regressions to appear once
the default coordinate system changed. We need to remove these
hacks to get a more consistent and maintainable base. This also
fixes the regression introduced by changing the aliased coordinate
system.
Task-number: QTBUG-27667
Change-Id: I620db2ca23b7ff6c912f3a51e86e7e36bbef81f0
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
This reverts commit 101d04681f.
That change seems to have introduced a few regressions, and
Creator hits an assertion that it introduced because it assumes
the additionalFormats consists of well-formed ranges
(QTCREATORBUG-7995).
Change-Id: Ic4ae761e6e7f6df8a6b5ca565ceb250647420c15
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
This is useful when the additional formats are used on a
text layout using a raw font. It can also come in handy for
input methods operating on a QTextDocument.
We now consider all format range edges to generate the
associated items. The capitalization can be overridden via
the additionnal formats mechanism.
Adds an autotest that checks that this works with font capitalization.
Change-Id: I782d2c48d05b0dfbad480a9ca77198465292b358
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
qUpperBound was replaced by std::upper_bound.
Unfortunately the STL of MSVC 2008 enforces
the definition of the operator in both
directions.
Change-Id: I3e0f775c23e43332d106e0847d3611e488da6c06
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Change copyrights and license headers from Nokia to Digia
Change-Id: If1cc974286d29fd01ec6c19dd4719a67f4c3f00e
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Sergio Ahumada <sergio.ahumada@digia.com>
Introduce QCharAttributes and use it instead of HB_CharAttributes everywhere in Qt
(in Harfbuzz, the HB_CharAttributes is only used in the text segmentation algorithm
which has been moved from HB to Qt (well, most of it)).
Rename some members to better reflect their meaning,
remember to keep HB_CharAttributes in sync with QCharAttributes.
Also replace HB_ScriptItem with a (temporary) QUnicodeTools::ScriptItem struct
that will be replaced with a more efficient/friendly solution a bit later.
The soft hyphen and the mandatory break detection has been factored out
of the default text breaking algorithm to a higher level in order to refactor
the QCharAttributes bitfields and to optimize the implementation for the common case.
Change-Id: Ieb365623ae954430f1c8b2dfcd65c82973143eec
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Replace them with std::upper_bound; this allows for deprecation of
qUpperBound.
Change-Id: Idef01d2228b9a70eee3d52931d7aedb5bb6ba902
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
That can be reproduced in Qt Creator when deleting code.
Task-number: QTBUG-27140
Change-Id: Ida7177612653f10e5d866bf9a422c71c632f4eb3
Reviewed-by: Simon Hausmann <simon.hausmann@nokia.com>
When QTextLayout is used in a QTextDocument, many code paths use
special caches and thus greatly outperform the raw QTextLayout version
that operates directly on a QString.
This patch brings some of these optimizations also to the raw version.
We now also use a QFormatCollection in such cases and enable the
functionality of QTextEngine::indexAdditionalFormats() and
QTextEngine::resolveAdditionalFormats(). Thanks to that, we can greatly
speed up QTextEngine::format(), which now uses an amort O(1) hash table
lookup instead of a O(N) linear search.
The added benchmark shows a gain in the order of one magnitude:
./tst_bench_QText formattedLayout:long-many
before applying the patch:
378.19 msecs per iteration (total: 37,820, iterations: 100)
after applying the patch:
25.80 msecs per iteration (total: 2,580, iterations: 100)
Note: This change is source-incompatible for applications using the private
QTextEngine API.
Task-number: QTBUG-8389
Change-Id: Ifcf7a8902a394428979ea06a6d955f886ee739c7
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Before, setBoundary was O(N), now it is O(log N) assuming the boundaries
are added in order. (splitItem might still be linear because of the call
to QVector::insert)
This speeds up a lot QTextEngine::addRequiredBoundaries when there is a
lot of addFormats. (For example if there is a very long line with syntax
highlighting)
Task-number: QTBUG-8389
Change-Id: I10c9fca72343f46db24b1d4f519f7747188d4009
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Don't call the linear QTextEngine::format in the loop.
Instead, keep track of the current formats by indexing their start and end position.
Task-number: QTBUG-8389
Change-Id: I89c18b804111edfab6254442cbee33da39d1a273
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
These flags are specific to font engine(s) and has nothing
to do with the text engine or the text layout.
Change-Id: I4bb793c3c634b3cf0ae0a8a8c23b946fad5874b6
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Just like for the QChar::ByteOrderMark, `ch == QChar::SoftHyphen`
is much more readable than `ch == 0x00ad // (soft-hyphen)`, etc.
Change-Id: I9c85f14cfd979037d35103c3259a435fd729b869
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
We only want to change the capitalization if the QScriptAnalysis flag
was Lowercase, Uppercase or SmallCaps.
Task-number: QTBUG-17485
Change-Id: Icbecb09b06a9153866ae81d592b3f6779c2dafb5
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>
If the used font engine is of type QFontEngine::Multi, then we already have
both the "font engine runs" and the stripped glyph indicies for the kerning
-> just call the actual font engine's doKerning() method.
If the font engine is not of type QFontEngine::Multi, then we could safely
avoid the glyph indicies extra manipulations.
Change-Id: Ia8899e6d7beecfd391b050683ac41c21465336e4
Reviewed-by: Jiang Jiang <jiang.jiang@nokia.com>
XLFD fonts are no longer supported in Qt 5.
Change-Id: I83400dab417c933d5cd956c0d168c45b9d79dab7
Reviewed-by: Casper van Donderen <casper.vandonderen@nokia.com>
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
The length we cast is from int QTextEngine::length() so it's safe
to do so.
Change-Id: I60fdbcb5a96c99b767093102a30e97951ef5b6ea
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>