Use maximum ascent/descent/leading from fallback fonts in shaping
When shaping a QScriptItem with a multi font engine, currently we only take the ascent/descent/leading from the primary (first) font engine in that multi font engine, however, subsequent engines used during shaping may have larger ascent/descent/leading, disregarding them may cause clipping issues in some cases. It's fixed by checking each font engine used in the shaping process and take the maximum value instead of the first one. On ATSUI we merely make it compile. Task-number: QTBUG-16719 Reviewed-by: Eskil (cherry picked from commit c501403cb5a0c9ec21b00e0c2f640ae85566e0cf)
This commit is contained in:
parent
bbbfc9b0eb
commit
774527dd1e
@ -162,8 +162,10 @@ uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef font) const
|
|||||||
return engines.count() - 1;
|
return engines.count() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
|
bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
|
||||||
unsigned short *logClusters, const HB_CharAttributes *) const
|
int *nglyphs, QTextEngine::ShaperFlags flags,
|
||||||
|
unsigned short *logClusters, const HB_CharAttributes *,
|
||||||
|
QScriptItem *si) const
|
||||||
{
|
{
|
||||||
QCFType<CFStringRef> cfstring = CFStringCreateWithCharactersNoCopy(0,
|
QCFType<CFStringRef> cfstring = CFStringCreateWithCharactersNoCopy(0,
|
||||||
reinterpret_cast<const UniChar *>(str),
|
reinterpret_cast<const UniChar *>(str),
|
||||||
@ -254,7 +256,12 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
|
|||||||
if (!runAttribs)
|
if (!runAttribs)
|
||||||
runAttribs = attributeDict;
|
runAttribs = attributeDict;
|
||||||
CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttribs, NSFontAttributeName));
|
CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttribs, NSFontAttributeName));
|
||||||
const uint fontIndex = (fontIndexForFont(runFont) << 24);
|
uint fontIndex = fontIndexForFont(runFont);
|
||||||
|
const QFontEngine *engine = engineAt(fontIndex);
|
||||||
|
fontIndex <<= 24;
|
||||||
|
si->ascent = qMax(engine->ascent(), si->ascent);
|
||||||
|
si->descent = qMax(engine->descent(), si->descent);
|
||||||
|
si->leading = qMax(engine->leading(), si->leading);
|
||||||
//NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont));
|
//NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont));
|
||||||
if (endWithPDF)
|
if (endWithPDF)
|
||||||
glyphCount--;
|
glyphCount--;
|
||||||
|
@ -120,7 +120,8 @@ public:
|
|||||||
QTextEngine::ShaperFlags flags) const;
|
QTextEngine::ShaperFlags flags) const;
|
||||||
bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
|
bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
|
||||||
QTextEngine::ShaperFlags flags,
|
QTextEngine::ShaperFlags flags,
|
||||||
unsigned short *logClusters, const HB_CharAttributes *charAttributes) const;
|
unsigned short *logClusters, const HB_CharAttributes *charAttributes,
|
||||||
|
QScriptItem *si) const;
|
||||||
|
|
||||||
virtual const char *name() const { return "CoreText"; }
|
virtual const char *name() const { return "CoreText"; }
|
||||||
protected:
|
protected:
|
||||||
|
@ -377,7 +377,7 @@ bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
|
bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
|
||||||
unsigned short *logClusters, const HB_CharAttributes *charAttributes) const
|
unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const
|
||||||
{
|
{
|
||||||
if (*nglyphs < len) {
|
if (*nglyphs < len) {
|
||||||
*nglyphs = len;
|
*nglyphs = len;
|
||||||
|
@ -131,7 +131,7 @@ public:
|
|||||||
|
|
||||||
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
|
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
|
||||||
bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
|
bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
|
||||||
unsigned short *logClusters, const HB_CharAttributes *charAttributes) const;
|
unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const;
|
||||||
|
|
||||||
virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
|
virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
|
||||||
virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const;
|
virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const;
|
||||||
|
@ -1274,6 +1274,10 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
|
|||||||
actualFontEngine = static_cast<QFontEngineMulti *>(font)->engine(engineIdx);
|
actualFontEngine = static_cast<QFontEngineMulti *>(font)->engine(engineIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
|
||||||
|
si.descent = qMax(actualFontEngine->descent(), si.descent);
|
||||||
|
si.leading = qMax(actualFontEngine->leading(), si.leading);
|
||||||
|
|
||||||
shaper_item.font = actualFontEngine->harfbuzzFont();
|
shaper_item.font = actualFontEngine->harfbuzzFont();
|
||||||
shaper_item.face = actualFontEngine->harfbuzzFace();
|
shaper_item.face = actualFontEngine->harfbuzzFace();
|
||||||
|
|
||||||
|
@ -605,11 +605,11 @@ void QTextEngine::shapeTextMac(int item) const
|
|||||||
unsigned short *log_clusters = logClusters(&si);
|
unsigned short *log_clusters = logClusters(&si);
|
||||||
|
|
||||||
bool stringToCMapFailed = false;
|
bool stringToCMapFailed = false;
|
||||||
if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) {
|
if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes(), &si)) {
|
||||||
ensureSpace(num_glyphs);
|
ensureSpace(num_glyphs);
|
||||||
g = availableGlyphs(&si);
|
g = availableGlyphs(&si);
|
||||||
stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
|
stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
|
||||||
attributes());
|
attributes(), &si);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stringToCMapFailed) {
|
if (!stringToCMapFailed) {
|
||||||
|
Loading…
Reference in New Issue
Block a user