Make HarBuzz-NG the default shaper on Mac

Since we dropped all platform-related shapers during the
QPA refactoring, thus making HarfBuzz the only shaper on all
platforms, we can not deal with AAT-capable fonts anymore.
HarBuzz-NG now supports it's own shaper backend infrastructure,
so the decision was to enable HB's CoreText shaper backend on Mac
and simply make HB-NG the default shaper there.

Task-number: QTBUG-36056

Change-Id: If22e24fd5cc00c25952934332a2f4123f38135a4
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
This commit is contained in:
Konstantin Ritt 2014-01-29 17:46:47 +02:00 committed by The Qt Project
parent 8c9a587ed3
commit 2d576f79f7
7 changed files with 57 additions and 8 deletions

6
configure vendored
View File

@ -5471,6 +5471,7 @@ fi
# harfbuzz support
[ "$XPLATFORM_MINGW" = "yes" ] && [ "$CFG_HARFBUZZ" = "auto" ] && CFG_HARFBUZZ=no
[ "$XPLATFORM_MAC" = "yes" ] && [ "$CFG_HARFBUZZ" = "auto" ] && CFG_HARFBUZZ=yes
if [ "$CFG_HARFBUZZ" = "auto" ]; then
if compileTest unix/harfbuzz "HarfBuzz"; then
CFG_HARFBUZZ=system
@ -5478,6 +5479,11 @@ if [ "$CFG_HARFBUZZ" = "auto" ]; then
CFG_HARFBUZZ=yes
fi
fi
if [ "$XPLATFORM_MAC" = "yes" -a "$CFG_HARFBUZZ" = "system" ]; then
echo
echo "WARNING: AAT is not supported with -system-harfbuzz on Mac OS X."
echo
fi
if ! compileTest unix/stl "STL" &&
[ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then

View File

@ -31,6 +31,9 @@
#include "hb-coretext.h"
#include "hb-face-private.hh"
#include <private/qfontengine_p.h>
#ifndef HB_DEBUG_CORETEXT
#define HB_DEBUG_CORETEXT (HB_DEBUG+0)
@ -61,10 +64,34 @@ release_data (void *info, const void *data, size_t size)
hb_coretext_shaper_face_data_t *
_hb_coretext_shaper_face_data_create (hb_face_t *face)
{
hb_blob_t *mort_blob = face->reference_table (HB_CORETEXT_TAG_MORT);
/* Umm, we just reference the table to check whether it exists.
* Maybe add better API for this? */
if (!hb_blob_get_length (mort_blob))
{
hb_blob_destroy (mort_blob);
mort_blob = face->reference_table (HB_CORETEXT_TAG_MORX);
if (!hb_blob_get_length (mort_blob))
{
hb_blob_destroy (mort_blob);
return NULL;
}
}
hb_blob_destroy (mort_blob);
hb_coretext_shaper_face_data_t *data = (hb_coretext_shaper_face_data_t *) calloc (1, sizeof (hb_coretext_shaper_face_data_t));
if (unlikely (!data))
return NULL;
QFontEngine *fe = (QFontEngine *) face->user_data;
if (fe->type () == QFontEngine::Mac)
{
data->cg_font = (CGFontRef) fe->userData ().value<void *> ();
if (likely (data->cg_font))
CFRetain (data->cg_font);
}
else
{
hb_blob_t *blob = hb_face_reference_blob (face);
unsigned int blob_length;
const char *blob_data = hb_blob_get_data (blob, &blob_length);
@ -74,6 +101,7 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face)
CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data);
data->cg_font = CGFontCreateWithDataProvider (provider);
CGDataProviderRelease (provider);
}
if (unlikely (!data->cg_font)) {
DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
@ -120,7 +148,7 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font)
hb_face_t *face = font->face;
hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
data->ct_font = CTFontCreateWithGraphicsFont (face_data->cg_font, font->y_scale, NULL, NULL);
data->ct_font = CTFontCreateWithGraphicsFont (face_data->cg_font, font->y_scale / 64, NULL, NULL);
if (unlikely (!data->ct_font)) {
DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed");
free (data);
@ -691,7 +719,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
* hb-uniscribe.cc for example. */
info->cluster = j;
info->mask = advance;
info->mask = advance * 64;
info->var1.u32 = 0;
info->var2.u32 = 0;
@ -747,9 +775,9 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
info->cluster = string_indices[j];
/* Currently, we do all x-positioning by setting the advance, we never use x-offset. */
info->mask = advance;
info->mask = advance * 64;
info->var1.u32 = 0;
info->var2.u32 = positions[j].y;
info->var2.u32 = positions[j].y * 64;
buffer->len++;
}

View File

@ -34,6 +34,10 @@
HB_BEGIN_DECLS
#define HB_CORETEXT_TAG_MORT HB_TAG('m','o','r','t')
#define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x')
CGFontRef
hb_coretext_face_get_cg_font (hb_face_t *face);

View File

@ -35,6 +35,11 @@
HB_SHAPER_IMPLEMENT (graphite2)
#endif
#ifdef HAVE_CORETEXT
/* Only picks up fonts that have a "mort" or "morx" table. */
HB_SHAPER_IMPLEMENT (coretext)
#endif
#ifdef HAVE_OT
HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
#endif
@ -48,9 +53,6 @@ HB_SHAPER_IMPLEMENT (icu_le)
#ifdef HAVE_UNISCRIBE
HB_SHAPER_IMPLEMENT (uniscribe)
#endif
#ifdef HAVE_CORETEXT
HB_SHAPER_IMPLEMENT (coretext)
#endif
#ifdef HAVE_FALLBACK
HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */

View File

@ -698,7 +698,7 @@ _hb_qt_font_create(QFontEngine *fe)
const int x_ppem = (fe->fontDef.pixelSize * fe->fontDef.stretch) / 100;
hb_font_set_funcs(font, hb_qt_get_font_funcs(), (void *)fe, NULL);
hb_font_set_scale(font, QFixed(x_ppem).value(), -QFixed(y_ppem).value());
hb_font_set_scale(font, QFixed(x_ppem).value(), QFixed(y_ppem).value());
hb_font_set_ppem(font, x_ppem, y_ppem);
return font;

View File

@ -1195,6 +1195,13 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
g.glyphs[i] |= (engineIdx << 24);
}
#ifdef Q_OS_MAC
if (actualFontEngine->fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
for (uint i = 0; i < num_glyphs; ++i)
g.advances[i] = g.advances[i].round();
}
#endif
glyphs_shaped += num_glyphs;
}

View File

@ -188,6 +188,8 @@ void QCoreTextFontEngine::init()
avgCharWidth = QFontEngine::averageCharWidth();
cache_cost = (CTFontGetAscent(ctfont) + CTFontGetDescent(ctfont)) * avgCharWidth.toInt() * 2000;
setUserData(QVariant::fromValue((void *)cgFont));
}
bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,