Turn on HarfBuzz support for Mac/Cocoa

It's possible to enable HarfBuzz text layout on Mac by either:

- Set QT_ENABLE_HARFBUZZ environment variable when running a Qt
  app.

- configure with -harfbuzz to build Qt, then HarfBuzz support
  will be turned on by default.

HarfBuzz will only be used when the font explicitly requested
is supported by HarfBuzz (aka. TrueType/OpenType font), other
fonts (AAT fonts) will still be handled by Core Text.

Using HarfBuzz for text layout will hopefully solve most tricky
complex text shaping bugs on Mac.

Task-number: QTBUG-17728
Reviewed-by: Eskil
This commit is contained in:
Jiang Jiang 2011-04-18 17:08:30 +02:00
parent 0f7cba14f6
commit a7b6f4c8a5
3 changed files with 51 additions and 2 deletions

16
configure vendored
View File

@ -804,6 +804,7 @@ CFG_MAC_XARCH=auto
CFG_MAC_CARBON=no
CFG_MAC_COCOA=yes
COMMANDLINE_MAC_CARBON=no
CFG_MAC_HARFBUZZ=no
CFG_SXE=no
CFG_PREFIX_INSTALL=yes
CFG_SDK=
@ -1041,7 +1042,7 @@ while [ "$#" -gt 0 ]; do
VAL=no
;;
#Qt style yes options
-incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles|-icu)
-incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-harfbuzz|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles|-icu)
VAR=`echo $1 | sed "s,^-\(.*\),\1,"`
VAL=yes
;;
@ -1499,6 +1500,13 @@ while [ "$#" -gt 0 ]; do
UNKNOWN_OPT=yes
fi
;;
harfbuzz)
if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_MAC_CARBON" != "yes" ] && [ "$VAL" = "yes" ]; then
CFG_MAC_HARFBUZZ="$VAL"
else
UNKNOWN_OPT=yes
fi
;;
framework)
if [ "$PLATFORM_MAC" = "yes" ] || [ "$PLATFORM_QPA" = "yes" ]; then
@ -4257,6 +4265,11 @@ Qt/Mac only:
-sdk <sdk> ......... Build Qt using Apple provided SDK <sdk>. This option requires gcc 4.
To use a different SDK with gcc 3.3, set the SDKROOT environment variable.
-harfbuzz .......... Use HarfBuzz to do text layout instead of Core Text when possible.
It is only available to Cocoa builds.
* -no-harfbuzz ....... Disable HarfBuzz on Mac. It can still be enabled by setting
QT_ENABLE_HARFBUZZ environment variable.
EOF
fi
@ -7251,6 +7264,7 @@ fi
[ "$CFG_NAS" = "system" ] && QT_CONFIG="$QT_CONFIG nas"
[ "$CFG_OPENSSL" = "yes" ] && QT_CONFIG="$QT_CONFIG openssl"
[ "$CFG_OPENSSL" = "linked" ] && QT_CONFIG="$QT_CONFIG openssl-linked"
[ "$CFG_MAC_HARFBUZZ" = "yes" ] && QT_CONFIG="$QT_CONFIG harfbuzz"
if [ "$PLATFORM_X11" = "yes" ]; then
[ "$CFG_SM" = "yes" ] && QT_CONFIG="$QT_CONFIG x11sm"

View File

@ -856,6 +856,21 @@ void QTextEngine::shapeLine(const QScriptLine &line)
}
}
#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
static bool enableHarfBuzz()
{
static enum { Yes, No, Unknown } status = Unknown;
if (status == Unknown) {
QByteArray v = qgetenv("QT_ENABLE_HARFBUZZ");
bool value = !v.isEmpty() && v != "0" && v != "false";
if (value) status = Yes;
else status = No;
}
return status == Yes;
}
#endif
void QTextEngine::shapeText(int item) const
{
Q_ASSERT(item < layoutData->items.size());
@ -865,7 +880,24 @@ void QTextEngine::shapeText(int item) const
return;
#if defined(Q_WS_MAC)
shapeTextMac(item);
#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
if (enableHarfBuzz()) {
#endif
QFontEngine *actualFontEngine = fontEngine(si, &si.ascent, &si.descent, &si.leading);
if (actualFontEngine->type() == QFontEngine::Multi)
actualFontEngine = static_cast<QFontEngineMulti *>(actualFontEngine)->engine(0);
HB_Face face = actualFontEngine->harfbuzzFace();
HB_Script script = (HB_Script) si.analysis.script;
if (face->supported_scripts[script])
shapeTextWithHarfbuzz(item);
else
shapeTextMac(item);
#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
} else {
shapeTextMac(item);
}
#endif
#elif defined(Q_WS_WINCE)
shapeTextWithCE(item);
#else

View File

@ -114,6 +114,9 @@ unix:x11 {
OBJECTIVE_SOURCES += \
text/qfontengine_coretext.mm \
text/qfontengine_mac.mm
contains(QT_CONFIG, harfbuzz) {
DEFINES += QT_ENABLE_HARFBUZZ_FOR_MAC
}
}
embedded {