Turn on HarfBuzz support for Mac/Cocoa
authorJiang Jiang <jiang.jiang@nokia.com>
Mon, 18 Apr 2011 15:08:30 +0000 (17:08 +0200)
committerJiang Jiang <jiang.jiang@nokia.com>
Fri, 29 Apr 2011 09:02:23 +0000 (11:02 +0200)
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
configure
src/gui/text/qtextengine.cpp
src/gui/text/text.pri

index 60e1ec1..b0cafbc 100755 (executable)
--- a/configure
+++ b/configure
@@ -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"
index 0e649f0..dab4bb7 100644 (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
index 2e0c6de..e5d57d0 100644 (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 {