summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-12-24 00:56:59 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-12-24 00:56:59 +0100
commitf0fbff4c905fd3e21d7aefedd45d98cc9dd54018 (patch)
treec61f47f858a9ac6183676bd7aee378a6a2b84a19
parentd776937df91e46536f404c6868d64016b6038d7b (diff)
parent0e1ce36ae67de940b2d499ec7f23e520dce0f112 (diff)
Merge remote-tracking branch 'origin/stable' into dev
-rwxr-xr-xconfigure9
-rw-r--r--dist/changes-5.2.04
-rw-r--r--examples/widgets/doc/src/classwizard.qdoc2
-rw-r--r--examples/widgets/doc/src/echoplugin.qdoc6
-rw-r--r--examples/xml/dombookmarks/doc/images/dombookmarks-example.png (renamed from doc/src/images/dombookmarks-example.png)bin19405 -> 19405 bytes
-rw-r--r--examples/xml/dombookmarks/doc/src/dombookmarks.qdoc (renamed from doc/src/examples/dombookmarks.qdoc)3
-rw-r--r--examples/xml/xmlstreamlint/doc/src/xmlstreamlint.qdoc (renamed from doc/src/examples/xmlstreamlint.qdoc)9
-rw-r--r--mkspecs/features/qt_app.prf2
-rw-r--r--mkspecs/features/wayland-scanner.prf66
-rw-r--r--qmake/Makefile.unix2
-rw-r--r--qmake/Makefile.win322
-rw-r--r--qmake/doc/src/qmake-manual.qdoc60
-rw-r--r--src/3rdparty/harfbuzz-ng/NEWS55
-rw-r--r--src/3rdparty/harfbuzz-ng/TODO8
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-blob.cc152
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh10
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc71
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer.cc446
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer.h16
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-common.cc161
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-common.h4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face-private.hh1
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face.cc172
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc10
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font-private.hh15
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font.cc517
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font.h132
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh10
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh136
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh95
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh442
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh229
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh403
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc58
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc10
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc21
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh40
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc358
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc35
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc73
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc29
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc156
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc315
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-private.hh3
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set-private.hh21
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set.cc244
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set.h2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc173
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape.cc56
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode.cc128
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode.h106
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-version.h4
-rw-r--r--src/3rdparty/harfbuzz.pri1
-rw-r--r--src/3rdparty/sqlite.pri1
-rw-r--r--src/corelib/Qt5CoreMacros.cmake1
-rw-r--r--src/corelib/doc/src/containers.qdoc8
-rw-r--r--src/corelib/global/qglobal.h13
-rw-r--r--src/corelib/global/qlogging.h49
-rw-r--r--src/corelib/kernel/qcorecmdlineargs_p.h4
-rw-r--r--src/corelib/kernel/qobject.cpp11
-rw-r--r--src/corelib/kernel/qobject_p.h8
-rw-r--r--src/corelib/plugin/qplugin.qdoc1
-rw-r--r--src/corelib/thread/qthread_win.cpp6
-rw-r--r--src/corelib/tools/qlocale_blackberry.cpp8
-rw-r--r--src/corelib/tools/qlocale_win.cpp12
-rw-r--r--src/corelib/tools/qstring.h20
-rw-r--r--src/gui/doc/src/dnd.qdoc4
-rw-r--r--src/gui/image/qimage.h3
-rw-r--r--src/gui/image/qimagewriter.cpp14
-rw-r--r--src/gui/opengl/qopenglversionfunctions.cpp2
-rw-r--r--src/gui/text/qharfbuzzng.cpp2
-rw-r--r--src/gui/text/qplatformfontdatabase.cpp44
-rw-r--r--src/gui/text/qtextengine.cpp4
-rw-r--r--src/plugins/bearer/connman/qconnmanengine.cpp45
-rw-r--r--src/plugins/generic/tslib/qtslib.cpp5
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoaclipboard.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm9
-rw-r--r--src/plugins/platforms/cocoa/qmacclipboard.h4
-rw-r--r--src/plugins/platforms/cocoa/qmacclipboard.mm20
-rw-r--r--src/plugins/platforms/cocoa/qmacmime.h14
-rw-r--r--src/plugins/platforms/cocoa/qmacmime.mm60
-rw-r--r--src/plugins/platforms/cocoa/qt_mac_p.h2
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm2
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm2
-rw-r--r--src/plugins/platforms/kms/qkmscursor.h4
-rw-r--r--src/plugins/platforms/kms/qkmsdevice.h2
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp5
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.h1
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp31
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp7
-rw-r--r--src/sql/kernel/qsqldriver.h1
-rw-r--r--src/sql/kernel/qsqlresult.cpp7
-rw-r--r--src/testlib/doc/qttestlib.qdocconf2
-rw-r--r--src/widgets/widgets/qgroupbox.cpp4
-rw-r--r--tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp5
-rw-r--r--tests/auto/corelib/tools/qdate/tst_qdate.cpp8
-rw-r--r--tests/auto/corelib/tools/qtime/tst_qtime.cpp16
-rw-r--r--tests/auto/sql/kernel/qsqlresult/qsqlresult.pro2
-rw-r--r--tests/auto/sql/kernel/qsqlresult/testsqldriver.h9
-rw-r--r--tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp20
-rw-r--r--tools/configure/Makefile.win322
122 files changed, 4346 insertions, 1316 deletions
diff --git a/configure b/configure
index 54b11cce70..7e5f74be8e 100755
--- a/configure
+++ b/configure
@@ -695,6 +695,7 @@ CFG_EVENTFD=auto
CFG_RPATH=yes
CFG_FRAMEWORK=auto
DEFINES=
+INCLUDES=
D_FLAGS=
I_FLAGS=
L_FLAGS=
@@ -1993,6 +1994,7 @@ while [ "$#" -gt 0 ]; do
D_FLAGS="$D_FLAGS -D\"$VAL\""
;;
add_ipath)
+ INCLUDES="$INCLUDES \"$VAL\""
I_FLAGS="$I_FLAGS -I\"${VAL}\""
;;
add_lpath)
@@ -5889,6 +5891,7 @@ fi
[ "$CFG_DIRECTWRITE" = "yes" ] && QT_CONFIG="$QT_CONFIG directwrite"
[ '!' -z "$DEFINES" ] && QMakeVar add DEFINES "$DEFINES"
+[ '!' -z "$INCLUDES" ] && QMakeVar add INCLUDEPATH "$INCLUDES"
[ '!' -z "$L_FLAGS" ] && QMakeVar add LIBS "$L_FLAGS"
if [ "$XPLATFORM_MAC" = "yes" ] && [ "$QT_CROSS_COMPILE" = "no" ]; then
@@ -5916,12 +5919,6 @@ if [ "$CFG_RPATH" = "yes" ]; then
QT_CONFIG="$QT_CONFIG rpath"
fi
-if [ '!' -z "$I_FLAGS" ]; then
- # add the user define include paths
- QMakeVar add QMAKE_CFLAGS "$I_FLAGS"
- QMakeVar add QMAKE_CXXFLAGS "$I_FLAGS"
-fi
-
if [ '!' -z "$W_FLAGS" ]; then
# add the user defined warning flags
QMakeVar add QMAKE_CFLAGS_WARN_ON "$W_FLAGS"
diff --git a/dist/changes-5.2.0 b/dist/changes-5.2.0
index 4dd1604fcc..0e3f18929a 100644
--- a/dist/changes-5.2.0
+++ b/dist/changes-5.2.0
@@ -314,6 +314,10 @@ QtGui
* When a QVariant holds a QPolygonF() then it will be correctly seen as
a null QVariant.
+ - QImage:
+ * Added three byte-ordered RGBA8888 format that simplifies interaction
+ with OpenGL and other technologies that internally using RGBA formats.
+
- [QTBUG-27349] Reintroduced command line argument for positioning
windows (-geometry on X11, -qwindowgeometry on other platforms)
diff --git a/examples/widgets/doc/src/classwizard.qdoc b/examples/widgets/doc/src/classwizard.qdoc
index 5a88076155..cc2c61f126 100644
--- a/examples/widgets/doc/src/classwizard.qdoc
+++ b/examples/widgets/doc/src/classwizard.qdoc
@@ -156,7 +156,7 @@
Then we create the child widgets, create \l{Registering and Using
Fields}{wizard fields} associated with them, and put them into
layouts. The \c className field is created with an asterisk (\c
- *) next to its name. This makes it a \l{mandatory field}, that
+ *) next to its name. This makes it a \l{mandatory fields}{mandatory field}, that
is, a field that must be filled before the user can press the
\uicontrol Next button (\uicontrol Continue on Mac OS X). The fields' values
can be accessed from any other page using QWizardPage::field(),
diff --git a/examples/widgets/doc/src/echoplugin.qdoc b/examples/widgets/doc/src/echoplugin.qdoc
index 9e2b0c35de..103a51cf93 100644
--- a/examples/widgets/doc/src/echoplugin.qdoc
+++ b/examples/widgets/doc/src/echoplugin.qdoc
@@ -194,10 +194,10 @@
\section1 Further reading and examples
- You can find an overview of the macros needed to create plugins
- \l{Macros for Defining Plugins}{here}.
+ The \l {qtplugin-defining-plugins}{Defining Plugins} page presents an overview of the macros needed to
+ create plugins.
- We give an example of a plugin that extend Qt in the \l{Style
+ We give an example of a plugin that extends Qt in the \l{Style
Plugin Example}{style plugin} example. The \l{Plug & Paint
Example}{plug and paint} example shows how to create static
plugins.
diff --git a/doc/src/images/dombookmarks-example.png b/examples/xml/dombookmarks/doc/images/dombookmarks-example.png
index abacacbbfc..abacacbbfc 100644
--- a/doc/src/images/dombookmarks-example.png
+++ b/examples/xml/dombookmarks/doc/images/dombookmarks-example.png
Binary files differ
diff --git a/doc/src/examples/dombookmarks.qdoc b/examples/xml/dombookmarks/doc/src/dombookmarks.qdoc
index 8b0191ed1d..f74856eb2c 100644
--- a/doc/src/examples/dombookmarks.qdoc
+++ b/examples/xml/dombookmarks/doc/src/dombookmarks.qdoc
@@ -26,8 +26,9 @@
****************************************************************************/
/*!
- \example xml/dombookmarks
+ \example dombookmarks
\title DOM Bookmarks Example
+ \ingroup xml-examples
The DOM Bookmarks example provides a reader for XML Bookmark Exchange Language (XBEL)
files that uses Qt's DOM-based XML API to read and parse the files. The SAX Bookmarks
diff --git a/doc/src/examples/xmlstreamlint.qdoc b/examples/xml/xmlstreamlint/doc/src/xmlstreamlint.qdoc
index 5ca5139781..376f074555 100644
--- a/doc/src/examples/xmlstreamlint.qdoc
+++ b/examples/xml/xmlstreamlint/doc/src/xmlstreamlint.qdoc
@@ -26,8 +26,9 @@
****************************************************************************/
/*!
- \example xml/xmlstreamlint
+ \example xmlstreamlint
\title XML Stream Lint Example
+ \ingroup xml-examples
The XML Stream Lint example provides a simple command line utility that
accepts a file name as its single argument and writes it to the standard
@@ -49,19 +50,19 @@
operates on the input file object; writing is handled by an instance of
QXmlStreamWriter operating on the output file object:
- \snippet examples/xml/xmlstreamlint/main.cpp 0
+ \snippet xmlstreamlint/main.cpp 0
The work of parsing and rewriting the XML is done in a while loop, and is
driven by input from the reader:
- \snippet examples/xml/xmlstreamlint/main.cpp 1
+ \snippet xmlstreamlint/main.cpp 1
If more input is available, the next token from the input file is read
and parsed. If an error occurred, information is written to the standard
error file via a stream, and the example exits by returning a non-zero
value from the main function.
- \snippet examples/xml/xmlstreamlint/main.cpp 2
+ \snippet xmlstreamlint/main.cpp 2
For valid input, the writer is fed the current token from the reader,
and this is written to the output file that was specified when it was
diff --git a/mkspecs/features/qt_app.prf b/mkspecs/features/qt_app.prf
index 8758f4a9a0..a4fcb7d484 100644
--- a/mkspecs/features/qt_app.prf
+++ b/mkspecs/features/qt_app.prf
@@ -25,7 +25,7 @@ host_build:force_bootstrap {
}
target.path = $$[QT_HOST_BINS]
} else {
- !build_pass:contains(QT_CONFIG, build_all): CONFIG += release
+ !build_pass:contains(QT_CONFIG, debug_and_release):contains(QT_CONFIG, build_all): CONFIG += release
target.path = $$[QT_INSTALL_BINS]
}
INSTALLS += target
diff --git a/mkspecs/features/wayland-scanner.prf b/mkspecs/features/wayland-scanner.prf
index b2eca41695..3a9d8cafbd 100644
--- a/mkspecs/features/wayland-scanner.prf
+++ b/mkspecs/features/wayland-scanner.prf
@@ -5,10 +5,52 @@
isEmpty(QMAKE_WAYLAND_SCANNER):error("QMAKE_WAYLAND_SCANNER not defined for this mkspec")
+defineReplace(waylandScannerHeaderFiles) {
+ side = $$1
+ path = $$2
+ isEqual(side, "server"): \
+ sources_list = $$WAYLANDSERVERSOURCES
+ else: \
+ sources_list = $$WAYLANDCLIENTSOURCES
+ wayland_header_files_for_side =
+ for(file, sources_list) {
+ basenameFile = $$basename(file)
+ basenameFile ~= s,\\.xml$,,
+ wayland_header_files_for_side += $$path/wayland-$$basenameFile-$$side-protocol$${first(QMAKE_EXT_H)}
+ isEqual(side, "server"): \
+ wayland_header_files_for_side += $$path/qwayland-server-$$basenameFile$${first(QMAKE_EXT_H)}
+ else: \
+ wayland_header_files_for_side += $$path/qwayland-$$basenameFile$${first(QMAKE_EXT_H)}
+ }
+ return($$wayland_header_files_for_side)
+}
+
+qt_install_headers {
+ header_dest = $$MODULE_BASE_OUTDIR/include/$$MODULE_INCNAME/$$VERSION/$$MODULE_INCNAME/private
+
+ header_files_client = $$waylandScannerHeaderFiles(client, $$header_dest)
+ !isEmpty(header_files_client) {
+ wayland_generated_client_headers.files = $$header_files_client
+ wayland_generated_client_headers.path = $$private_headers.path
+ INSTALLS += wayland_generated_client_headers
+ WAYLAND_CLIENT_HEADER_DEST = $$header_dest/
+ WAYLAND_CLIENT_INCLUDE_DIR = $$MODULE_INCNAME/private
+ }
+
+ header_files_server = $$waylandScannerHeaderFiles(server, $$header_dest)
+ !isEmpty(header_files_server) {
+ wayland_generated_server_headers.files = $$header_files_server
+ wayland_generated_server_headers.path = $$private_headers.path
+ INSTALLS += wayland_generated_server_headers
+ WAYLAND_SERVER_HEADER_DEST = $$header_dest/
+ WAYLAND_SERVER_INCLUDE_DIR = $$MODULE_INCNAME/private
+ }
+}
+
wayland_server_header.name = wayland ${QMAKE_FILE_BASE}
wayland_server_header.input = WAYLANDSERVERSOURCES
wayland_server_header.variable_out = HEADERS
-wayland_server_header.output = wayland-${QMAKE_FILE_BASE}-server-protocol$${first(QMAKE_EXT_H)}
+wayland_server_header.output = $${WAYLAND_SERVER_HEADER_DEST}wayland-${QMAKE_FILE_BASE}-server-protocol$${first(QMAKE_EXT_H)}
wayland_server_header.commands = $$QMAKE_WAYLAND_SCANNER server-header < ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT}
silent:wayland_server_header.commands = @echo Wayland server header ${QMAKE_FILE_IN} && $$wayland_server_header.commands
QMAKE_EXTRA_COMPILERS += wayland_server_header
@@ -16,7 +58,7 @@ QMAKE_EXTRA_COMPILERS += wayland_server_header
wayland_client_header.name = wayland ${QMAKE_FILE_BASE}
wayland_client_header.input = WAYLANDCLIENTSOURCES
wayland_client_header.variable_out = HEADERS
-wayland_client_header.output = wayland-${QMAKE_FILE_BASE}-client-protocol$${first(QMAKE_EXT_H)}
+wayland_client_header.output = $${WAYLAND_CLIENT_HEADER_DEST}wayland-${QMAKE_FILE_BASE}-client-protocol$${first(QMAKE_EXT_H)}
wayland_client_header.commands = $$QMAKE_WAYLAND_SCANNER client-header < ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT}
silent:wayland_client_header.commands = @echo Wayland client header ${QMAKE_FILE_IN} && $$wayland_client_header.commands
QMAKE_EXTRA_COMPILERS += wayland_client_header
@@ -34,35 +76,35 @@ qtPrepareTool(QMAKE_QTWAYLANDSCANNER, qtwaylandscanner)
qtwayland_client_header.name = qtwayland ${QMAKE_FILE_BASE}
qtwayland_client_header.input = WAYLANDCLIENTSOURCES
qtwayland_client_header.variable_out = HEADERS
-qtwayland_client_header.depends = wayland-${QMAKE_FILE_BASE}-client-protocol$${first(QMAKE_EXT_H)}
-qtwayland_client_header.output = qwayland-${QMAKE_FILE_BASE}$${first(QMAKE_EXT_H)}
-qtwayland_client_header.commands = $$QMAKE_QTWAYLANDSCANNER client-header ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT}
+qtwayland_client_header.depends = $${WAYLAND_CLIENT_HEADER_DEST}wayland-${QMAKE_FILE_BASE}-client-protocol$${first(QMAKE_EXT_H)}
+qtwayland_client_header.output = $${WAYLAND_CLIENT_HEADER_DEST}qwayland-${QMAKE_FILE_BASE}$${first(QMAKE_EXT_H)}
+qtwayland_client_header.commands = $$QMAKE_QTWAYLANDSCANNER client-header ${QMAKE_FILE_IN} $$WAYLAND_CLIENT_INCLUDE_DIR > ${QMAKE_FILE_OUT}
silent:qtwayland_client_header.commands = @echo QtWayland client header ${QMAKE_FILE_IN} && $$qtwayland_client_header.commands
QMAKE_EXTRA_COMPILERS += qtwayland_client_header
qtwayland_client_code.name = qtwayland ${QMAKE_FILE_BASE}
qtwayland_client_code.input = WAYLANDCLIENTSOURCES
qtwayland_client_code.variable_out = SOURCES
-qtwayland_client_code.depends = qwayland-${QMAKE_FILE_BASE}$${first(QMAKE_EXT_H)}
+qtwayland_client_code.depends = $${WAYLAND_CLIENT_HEADER_DEST}qwayland-${QMAKE_FILE_BASE}$${first(QMAKE_EXT_H)}
qtwayland_client_code.output = qwayland-${QMAKE_FILE_BASE}.cpp
-qtwayland_client_code.commands = $$QMAKE_QTWAYLANDSCANNER client-code ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT}
+qtwayland_client_code.commands = $$QMAKE_QTWAYLANDSCANNER client-code ${QMAKE_FILE_IN} $$WAYLAND_CLIENT_INCLUDE_DIR > ${QMAKE_FILE_OUT}
silent:qtwayland_client_code.commands = @echo QtWayland client code ${QMAKE_FILE_IN} && $$qtwayland_client_code.commands
QMAKE_EXTRA_COMPILERS += qtwayland_client_code
qtwayland_server_header.name = qtwayland ${QMAKE_FILE_BASE}
qtwayland_server_header.input = WAYLANDSERVERSOURCES
qtwayland_server_header.variable_out = HEADERS
-qtwayland_server_header.depends = wayland-${QMAKE_FILE_BASE}-server-protocol$${first(QMAKE_EXT_H)}
-qtwayland_server_header.output = qwayland-server-${QMAKE_FILE_BASE}$${first(QMAKE_EXT_H)}
-qtwayland_server_header.commands = $$QMAKE_QTWAYLANDSCANNER server-header ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT}
+qtwayland_server_header.depends = $${WAYLAND_SERVER_HEADER_DEST}wayland-${QMAKE_FILE_BASE}-server-protocol$${first(QMAKE_EXT_H)}
+qtwayland_server_header.output = $${WAYLAND_SERVER_HEADER_DEST}qwayland-server-${QMAKE_FILE_BASE}$${first(QMAKE_EXT_H)}
+qtwayland_server_header.commands = $$QMAKE_QTWAYLANDSCANNER server-header ${QMAKE_FILE_IN} $$WAYLAND_SERVER_INCLUDE_DIR > ${QMAKE_FILE_OUT}
silent:qtwayland_server_header.commands = @echo QtWayland server header ${QMAKE_FILE_IN} && $$qtwayland_server_header.commands
QMAKE_EXTRA_COMPILERS += qtwayland_server_header
qtwayland_server_code.name = qtwayland ${QMAKE_FILE_BASE}
qtwayland_server_code.input = WAYLANDSERVERSOURCES
qtwayland_server_code.variable_out = SOURCES
-qtwayland_server_code.depends = qwayland-server-${QMAKE_FILE_BASE}$${first(QMAKE_EXT_H)}
+qtwayland_server_code.depends = $${WAYLAND_SERVER_HEADER_DEST}qwayland-server-${QMAKE_FILE_BASE}$${first(QMAKE_EXT_H)}
qtwayland_server_code.output = qwayland-server-${QMAKE_FILE_BASE}.cpp
-qtwayland_server_code.commands = $$QMAKE_QTWAYLANDSCANNER server-code ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT}
+qtwayland_server_code.commands = $$QMAKE_QTWAYLANDSCANNER server-code ${QMAKE_FILE_IN} $$WAYLAND_SERVER_INCLUDE_DIR > ${QMAKE_FILE_OUT}
silent:qtwayland_server_code.commands = @echo QtWayland server code ${QMAKE_FILE_IN} && $$qtwayland_server_code.commands
QMAKE_EXTRA_COMPILERS += qtwayland_server_code
diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix
index 2c41bf5951..ef1c542f57 100644
--- a/qmake/Makefile.unix
+++ b/qmake/Makefile.unix
@@ -225,7 +225,7 @@ qsettings.o: $(SOURCE_PATH)/src/corelib/io/qsettings.cpp
qsystemerror.o: $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp
-qlibraryinfo.o: $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp
+qlibraryinfo.o: $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp $(BUILD_PATH)/src/corelib/global/qconfig.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp
qnumeric.o: $(SOURCE_PATH)/src/corelib/global/qnumeric.cpp
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32
index 0bc0093fd3..8ecb41b9c2 100644
--- a/qmake/Makefile.win32
+++ b/qmake/Makefile.win32
@@ -164,6 +164,8 @@ $(OBJS): qmake_pch.obj
$(QTOBJS): qmake_pch.obj
+qlibraryinfo.obj: $(BUILD_PATH)\src\corelib\global\qconfig.cpp
+
qmake_pch.obj:
$(CXX) $(CXXFLAGS_BARE) -c -Yc -Fpqmake_pch.pch -TP $(QMKSRC)\qmake_pch.h
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index 58e3ecec71..7ffdd9da0c 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -913,15 +913,34 @@
By default, support is disabled.
\endtable
- Since the \c debug option overrides the \c release option when both are
- defined in the \c CONFIG variable, it is necessary to use the
- \c debug_and_release option if you want to allow both debug and release
- versions of a project to be built. In such a case, the Makefile that
- qmake generates includes a rule that builds both
- versions, and this can be invoked in the following way:
+ When you use the \c debug_and_release option (which is the default under
+ Windows), the project will be processed three times: one time to produce
+ a "meta" Makefile, and two more times to produce a Makefile.Debug and a
+ Makefile.Release.
+
+ During the latter passes, \c build_pass and the respective \c debug or
+ \c release option is appended to \c CONFIG. This makes it possible to
+ perform build-specific tasks. For example:
+
+ \snippet code/doc_src_qmake-manual.pro 25
+
+ As an alternative to manually writing build type conditionals, some
+ variables offer build-specific variants, for example
+ \l{#QMAKE_LFLAGS_RELEASE}{QMAKE_LFLAGS_RELEASE} in addition to the general
+ \l{#QMAKE_LFLAGS}{QMAKE_LFLAGS}. These should be used when available.
+
+ The meta Makefile makes the sub-builds invokable via the \c debug and
+ \c release targets, and a combined build via the \c all target.
+ When the \c build_all \c CONFIG option is used, the combined build is
+ the default. Otherwise, the last specified \c CONFIG option from the set
+ (\c debug, \c release) determines the default. In this case, you can
+ explicitly invoke the \c all target to build both configurations at once:
\snippet code/doc_src_qmake-manual.pro 24
+ \note The details are slightly different when producing Visual Studio
+ and Xcode projects.
+
When linking a library, qmake relies on the
underlying platform to know what other libraries this library links
against. However, if linking statically, qmake
@@ -945,24 +964,6 @@
static library, while \c link_prl is required when \e {using} a
static library.
- On Windows (or if Qt is configured with \c{-debug-and-release}), add the
- \c build_all option to the \c CONFIG variable to build all build
- configurations by default.
-
- Additionally, adding \c debug_and_release to the \c CONFIG variable will
- cause both \c debug and \c release to be defined in the contents of
- \c CONFIG. When the project file is processed, the
- \l{Scopes}{scopes} that test for each value will be
- processed for \e both debug and release modes. The \c{build_pass} variable
- will be set for each of these modes, and you can test for this to perform
- build-specific tasks. For example:
-
- \snippet code/doc_src_qmake-manual.pro 25
-
- As a result, it may be useful to define mode-specific variables, such as
- \l{#QMAKE_LFLAGS_RELEASE}{QMAKE_LFLAGS_RELEASE}, instead of general
- variables, such as \l{#QMAKE_LFLAGS}{QMAKE_LFLAGS}, where possible.
-
The following options define the application or library type:
\table
@@ -971,9 +972,6 @@
library and header files. The proper include and library paths for the
Qt library will automatically be added to the project. This is defined
by default, and can be fine-tuned with the \c{\l{#qt}{QT}} variable.
- \row \li thread \li The target is a multi-threaded application or library. The
- proper defines and compiler flags will automatically be added to
- the project. This value is set by default.
\row \li x11 \li The target is a X11 application or library. The proper
include paths and libraries will automatically be added to the
project.
@@ -1002,8 +1000,6 @@
\row \li designer \li The target is a plugin for \QD.
\row \li no_lflags_merge \li Ensures that the list of libraries stored in the
\c LIBS variable is not reduced to a list of unique values before it is used.
- \row \li resources \li Configures qmake to run rcc on the content of \c RESOURCES
- if defined.
\endtable
These options define specific features on Windows only:
@@ -1019,8 +1015,6 @@
as part of a library project.
\row \li embed_manifest_exe \li Embeds a manifest file in the DLL created
as part of an application project.
- \row \li incremental \li Used to enable or disable incremental linking in Visual
- C++, depending on whether this feature is enabled or disabled by default.
\endtable
See \l{Platform Notes#Visual Studio Manifest Files}{Platform Notes}
@@ -1030,8 +1024,6 @@
\table
\header \li Option \li Description
- \row \li ppc \li Builds a PowerPC binary.
- \row \li x86 \li Builds an i386 compatible binary.
\row \li app_bundle \li Puts the executable into a bundle (this is the default).
\row \li lib_bundle \li Puts the library into a library bundle.
\endtable
@@ -4527,7 +4519,7 @@
Sometimes, it is necessary to build a project in both debug and release
modes. Although the \l{CONFIG} variable can hold both \c debug and \c release
- options, the \c debug option overrides the \c release option.
+ options, only the option that is specified last is applied.
\section2 Building in Both Modes
diff --git a/src/3rdparty/harfbuzz-ng/NEWS b/src/3rdparty/harfbuzz-ng/NEWS
index dc89614e07..0a2477268a 100644
--- a/src/3rdparty/harfbuzz-ng/NEWS
+++ b/src/3rdparty/harfbuzz-ng/NEWS
@@ -1,3 +1,58 @@
+Overview of changes leading to 0.9.25
+Wednesday, December 4, 2013
+=====================================
+
+- Myanmar shaper improvements.
+- Avoid font fallback in CoreText backend.
+- Additional OpenType language tag mappiongs.
+- More aggressive shape-plan caching.
+- Build with / require automake 1.13.
+- Build with libtool 2.4.2.418 alpha to support ppc64le.
+
+
+Overview of changes leading to 0.9.24
+Tuesday, November 13, 2013
+=====================================
+
+- Misc compiler warning fixes with clang.
+- No functional changes.
+
+
+Overview of changes leading to 0.9.23
+Monday, October 28, 2013
+=====================================
+
+- "Udupi HarfBuzz Hackfest", Paris, October 14..18 2013.
+- Fix (Chain)Context recursion with non-monotone lookup positions.
+- Misc Indic bug fixes.
+- New Javanese / Buginese shaping, similar to Windows 8.1.
+
+
+Overview of changes leading to 0.9.22
+Thursday, October 3, 2013
+=====================================
+
+- Fix use-after-end-of-scope in hb_language_from_string().
+- Fix hiding of default_ignorables if font doesn't have space glyph.
+- Protect against out-of-range lookup indices.
+
+- API Changes:
+
+ * Added hb_ot_layout_table_get_lookup_count()
+
+
+Overview of changes leading to 0.9.21
+Monday, September 16, 2013
+=====================================
+
+- Rename gobject-introspection library name from harfbuzz to HarfBuzz.
+- Remove (long disabled) hb-old and hb-icu-le test shapers.
+- Misc gtk-doc and gobject-introspection annotations.
+- Misc fixes.
+- API changes:
+
+ * Add HB_SET_VALUE_INVALID
+
Overview of changes leading to 0.9.20
Thursday, August 29, 2013
=====================================
diff --git a/src/3rdparty/harfbuzz-ng/TODO b/src/3rdparty/harfbuzz-ng/TODO
index 4808391b4e..e1aa39c4c0 100644
--- a/src/3rdparty/harfbuzz-ng/TODO
+++ b/src/3rdparty/harfbuzz-ng/TODO
@@ -12,6 +12,8 @@ General fixes:
- Warn at compile time (and runtime with HB_DEBUG?) if no Unicode / font
funcs found / set.
+- Do proper rounding when scaling from font space? May be a non-issue.
+
- Misc features:
* init/medi/fina/isol for non-cursive scripts
@@ -43,11 +45,9 @@ API additions
- Add sanitize API (and a cached version, that saves result on blob user-data)
-- Add glib GBoxedType stuff and introspection
-
- BCP 47 language handling / API (language_matches?)
-- Add hb_font_create_linear()?
+- Add hb_font_create_unscaled()?
- Add query / enumeration API for aalt-like features?
@@ -61,7 +61,7 @@ API additions
hb-view / hb-shape enhancements:
===============================
-- Add --width, --height, --auto-size, --align, etc?
+- Add --width, --height, --auto-size, --ink-box, --align, etc?
Tests to write:
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
index 9cc3bc5587..b5d64853ea 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
@@ -78,7 +78,7 @@ typedef int32_t hb_atomic_int_t;
#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
#else
-#if __ppc64__ || __x86_64__
+#if __ppc64__ || __x86_64__ || __arm64__
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
#else
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
index dfd134b776..d6acca0fca 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
@@ -29,7 +29,6 @@
#include "hb-private.hh"
-#include "hb-blob.h"
#include "hb-object-private.hh"
#ifdef HAVE_SYS_MMAN_H
@@ -76,6 +75,22 @@ _hb_blob_destroy_user_data (hb_blob_t *blob)
}
}
+/**
+ * hb_blob_create: (Xconstructor)
+ * @data: (array length=length) (closure user_data) (destroy destroy) (scope notified) (transfer none): Pointer to blob data.
+ * @length: Length of @data in bytes.
+ * @mode: Memory mode for @data.
+ * @user_data: Data parameter to pass to @destroy.
+ * @destroy: Callback to call when @data is not needed anymore.
+ *
+ * Creates a new "blob" object wrapping @data. The @mode parameter is used
+ * to negotiate ownership and lifecycle of @data.
+ *
+ * Return value: New blob, or the empty blob if something failed or if @length is
+ * zero. Destroy with hb_blob_destroy().
+ *
+ * Since: 1.0
+ **/
hb_blob_t *
hb_blob_create (const char *data,
unsigned int length,
@@ -109,6 +124,26 @@ hb_blob_create (const char *data,
return blob;
}
+/**
+ * hb_blob_create_sub_blob:
+ * @parent: Parent blob.
+ * @offset: Start offset of sub-blob within @parent, in bytes.
+ * @length: Length of sub-blob.
+ *
+ * Returns a blob that represents a range of bytes in @parent. The new
+ * blob is always created with %HB_MEMORY_MODE_READONLY, meaning that it
+ * will never modify data in the parent blob. The parent data is not
+ * expected to be modified, and will result in undefined behavior if it
+ * is.
+ *
+ * Makes @parent immutable.
+ *
+ * Return value: New blob, or the empty blob if something failed or if
+ * @length is zero or @offset is beyond the end of @parent's data. Destroy
+ * with hb_blob_destroy().
+ *
+ * Since: 1.0
+ **/
hb_blob_t *
hb_blob_create_sub_blob (hb_blob_t *parent,
unsigned int offset,
@@ -130,6 +165,17 @@ hb_blob_create_sub_blob (hb_blob_t *parent,
return blob;
}
+/**
+ * hb_blob_get_empty:
+ *
+ * Returns the singleton empty blob.
+ *
+ * See TODO:link object types for more information.
+ *
+ * Return value: (transfer full): the empty blob.
+ *
+ * Since: 1.0
+ **/
hb_blob_t *
hb_blob_get_empty (void)
{
@@ -149,12 +195,36 @@ hb_blob_get_empty (void)
return const_cast<hb_blob_t *> (&_hb_blob_nil);
}
+/**
+ * hb_blob_reference: (skip)
+ * @blob: a blob.
+ *
+ * Increases the reference count on @blob.
+ *
+ * See TODO:link object types for more information.
+ *
+ * Return value: @blob.
+ *
+ * Since: 1.0
+ **/
hb_blob_t *
hb_blob_reference (hb_blob_t *blob)
{
return hb_object_reference (blob);
}
+/**
+ * hb_blob_destroy: (skip)
+ * @blob: a blob.
+ *
+ * Descreases the reference count on @blob, and if it reaches zero, destroys
+ * @blob, freeing all memory, possibly calling the destroy-callback the blob
+ * was created for if it has not been called already.
+ *
+ * See TODO:link object types for more information.
+ *
+ * Since: 1.0
+ **/
void
hb_blob_destroy (hb_blob_t *blob)
{
@@ -165,6 +235,18 @@ hb_blob_destroy (hb_blob_t *blob)
free (blob);
}
+/**
+ * hb_blob_set_user_data: (skip)
+ * @blob: a blob.
+ * @key: key for data to set.
+ * @data: data to set.
+ * @destroy: callback to call when @data is not needed anymore.
+ * @replace: whether to replace an existing data with the same key.
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_blob_set_user_data (hb_blob_t *blob,
hb_user_data_key_t *key,
@@ -175,6 +257,17 @@ hb_blob_set_user_data (hb_blob_t *blob,
return hb_object_set_user_data (blob, key, data, destroy, replace);
}
+/**
+ * hb_blob_get_user_data: (skip)
+ * @blob: a blob.
+ * @key: key for data to get.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_blob_get_user_data (hb_blob_t *blob,
hb_user_data_key_t *key)
@@ -183,6 +276,14 @@ hb_blob_get_user_data (hb_blob_t *blob,
}
+/**
+ * hb_blob_make_immutable:
+ * @blob: a blob.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_blob_make_immutable (hb_blob_t *blob)
{
@@ -192,6 +293,16 @@ hb_blob_make_immutable (hb_blob_t *blob)
blob->immutable = true;
}
+/**
+ * hb_blob_is_immutable:
+ * @blob: a blob.
+ *
+ *
+ *
+ * Return value: TODO
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_blob_is_immutable (hb_blob_t *blob)
{
@@ -199,12 +310,33 @@ hb_blob_is_immutable (hb_blob_t *blob)
}
+/**
+ * hb_blob_get_length:
+ * @blob: a blob.
+ *
+ *
+ *
+ * Return value: the length of blob data in bytes.
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_blob_get_length (hb_blob_t *blob)
{
return blob->length;
}
+/**
+ * hb_blob_get_data:
+ * @blob: a blob.
+ * @length: (out):
+ *
+ *
+ *
+ * Returns: (transfer none) (array length=length):
+ *
+ * Since: 1.0
+ **/
const char *
hb_blob_get_data (hb_blob_t *blob, unsigned int *length)
{
@@ -214,6 +346,22 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length)
return blob->data;
}
+/**
+ * hb_blob_get_data_writable:
+ * @blob: a blob.
+ * @length: (out): output length of the writable data.
+ *
+ * Tries to make blob data writable (possibly copying it) and
+ * return pointer to data.
+ *
+ * Fails if blob has been made immutable, or if memory allocation
+ * fails.
+ *
+ * Returns: (transfer none) (array length=length): Writable blob data,
+ * or %NULL if failed.
+ *
+ * Since: 1.0
+ **/
char *
hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length)
{
@@ -324,5 +472,3 @@ _try_writable (hb_blob_t *blob)
return true;
}
-
-
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
index a8cf770244..3a2b9ab481 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
@@ -31,7 +31,6 @@
#define HB_BUFFER_PRIVATE_HH
#include "hb-private.hh"
-#include "hb-buffer.h"
#include "hb-object-private.hh"
#include "hb-unicode-private.hh"
@@ -103,6 +102,8 @@ struct hb_buffer_t {
inline unsigned int backtrack_len (void) const
{ return have_output? out_len : idx; }
+ inline unsigned int lookahead_len (void) const
+ { return len - idx; }
inline unsigned int next_serial (void) { return serial++; }
HB_INTERNAL void allocate_var (unsigned int byte_i, unsigned int count, const char *owner);
@@ -134,6 +135,7 @@ struct hb_buffer_t {
HB_INTERNAL void output_info (const hb_glyph_info_t &glyph_info);
/* Copies glyph at idx to output but doesn't advance idx */
HB_INTERNAL void copy_glyph (void);
+ HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
/* Copies glyph at idx to output and advance idx.
* If there's no output, just advance idx. */
inline void
@@ -178,11 +180,13 @@ struct hb_buffer_t {
HB_INTERNAL bool enlarge (unsigned int size);
inline bool ensure (unsigned int size)
- { return likely (size < allocated) ? true : enlarge (size); }
+ { return likely (!size || size < allocated) ? true : enlarge (size); }
HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
+ HB_INTERNAL bool shift_forward (unsigned int count);
- HB_INTERNAL void *get_scratch_buffer (unsigned int *size);
+ typedef long scratch_buffer_t;
+ HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size);
inline void clear_context (unsigned int side) { context_len[side] = 0; }
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
index eac69000dd..4541db23bd 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
@@ -33,12 +33,32 @@ static const char *serialize_formats[] = {
NULL
};
+/**
+ * hb_buffer_serialize_list_formats:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
const char **
hb_buffer_serialize_list_formats (void)
{
return serialize_formats;
}
+/**
+ * hb_buffer_serialize_format_from_string:
+ * @str:
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_buffer_serialize_format_t
hb_buffer_serialize_format_from_string (const char *str, int len)
{
@@ -46,6 +66,16 @@ hb_buffer_serialize_format_from_string (const char *str, int len)
return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x20202020);
}
+/**
+ * hb_buffer_serialize_format_to_string:
+ * @format:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
const char *
hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
{
@@ -116,9 +146,9 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
*p++ = '}';
- if (buf_size > (p - b))
+ unsigned int l = p - b;
+ if (buf_size > l)
{
- unsigned int l = p - b;
memcpy (buf, b, l);
buf += l;
buf_size -= l;
@@ -178,9 +208,9 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
}
- if (buf_size > (p - b))
+ unsigned int l = p - b;
+ if (buf_size > l)
{
- unsigned int l = p - b;
memcpy (buf, b, l);
buf += l;
buf_size -= l;
@@ -194,6 +224,24 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
}
/* Returns number of items, starting at start, that were serialized. */
+/**
+ * hb_buffer_serialize_glyphs:
+ * @buffer: a buffer.
+ * @start:
+ * @end:
+ * @buf: (array length=buf_size):
+ * @buf_size:
+ * @buf_consumed: (out):
+ * @font:
+ * @format:
+ * @flags:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
unsigned int start,
@@ -286,6 +334,21 @@ parse_int (const char *pp, const char *end, int32_t *pv)
#include "hb-buffer-deserialize-json.hh"
#include "hb-buffer-deserialize-text.hh"
+/**
+ * hb_buffer_deserialize_glyphs:
+ * @buffer: a buffer.
+ * @buf: (array length=buf_len):
+ * @buf_len:
+ * @end_ptr: (out):
+ * @font:
+ * @format:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
const char *buf,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
index 340bd5351b..d6c6fcb8e6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
@@ -139,7 +139,20 @@ hb_buffer_t::make_room_for (unsigned int num_in,
return true;
}
-void *
+bool
+hb_buffer_t::shift_forward (unsigned int count)
+{
+ assert (have_output);
+ if (unlikely (!ensure (len + count))) return false;
+
+ memmove (info + idx + count, info + idx, (len - idx) * sizeof (info[0]));
+ len += count;
+ idx += count;
+
+ return true;
+}
+
+hb_buffer_t::scratch_buffer_t *
hb_buffer_t::get_scratch_buffer (unsigned int *size)
{
have_output = false;
@@ -148,8 +161,9 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size)
out_len = 0;
out_info = info;
- *size = allocated * sizeof (pos[0]);
- return pos;
+ assert ((uintptr_t) pos % sizeof (scratch_buffer_t) == 0);
+ *size = allocated * sizeof (pos[0]) / sizeof (scratch_buffer_t);
+ return (scratch_buffer_t *) (void *) pos;
}
@@ -345,6 +359,44 @@ hb_buffer_t::copy_glyph (void)
out_len++;
}
+bool
+hb_buffer_t::move_to (unsigned int i)
+{
+ if (!have_output)
+ {
+ assert (i <= len);
+ idx = i;
+ return true;
+ }
+
+ assert (i <= out_len + (len - idx));
+
+ if (out_len < i)
+ {
+ unsigned int count = i - out_len;
+ if (unlikely (!make_room_for (count, count))) return false;
+
+ memmove (out_info + out_len, info + idx, count * sizeof (out_info[0]));
+ idx += count;
+ out_len += count;
+ }
+ else if (out_len > i)
+ {
+ /* Tricky part: rewinding... */
+ unsigned int count = out_len - i;
+
+ if (unlikely (idx < count && !shift_forward (count + 32))) return false;
+
+ assert (idx >= count);
+
+ idx -= count;
+ out_len -= count;
+ memmove (info + idx, out_info + out_len, count * sizeof (out_info[0]));
+ }
+
+ return true;
+}
+
void
hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
{
@@ -603,6 +655,15 @@ void hb_buffer_t::deallocate_var_all (void)
/* Public API */
+/**
+ * hb_buffer_create: (Xconstructor)
+ *
+ *
+ *
+ * Return value: (transfer full)
+ *
+ * Since: 1.0
+ **/
hb_buffer_t *
hb_buffer_create (void)
{
@@ -616,6 +677,15 @@ hb_buffer_create (void)
return buffer;
}
+/**
+ * hb_buffer_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_buffer_t *
hb_buffer_get_empty (void)
{
@@ -637,12 +707,30 @@ hb_buffer_get_empty (void)
return const_cast<hb_buffer_t *> (&_hb_buffer_nil);
}
+/**
+ * hb_buffer_reference: (skip)
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_buffer_t *
hb_buffer_reference (hb_buffer_t *buffer)
{
return hb_object_reference (buffer);
}
+/**
+ * hb_buffer_destroy: (skip)
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_destroy (hb_buffer_t *buffer)
{
@@ -656,6 +744,20 @@ hb_buffer_destroy (hb_buffer_t *buffer)
free (buffer);
}
+/**
+ * hb_buffer_set_user_data: (skip)
+ * @buffer: a buffer.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_buffer_set_user_data (hb_buffer_t *buffer,
hb_user_data_key_t *key,
@@ -666,6 +768,17 @@ hb_buffer_set_user_data (hb_buffer_t *buffer,
return hb_object_set_user_data (buffer, key, data, destroy, replace);
}
+/**
+ * hb_buffer_get_user_data: (skip)
+ * @buffer: a buffer.
+ * @key:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
void *
hb_buffer_get_user_data (hb_buffer_t *buffer,
hb_user_data_key_t *key)
@@ -674,6 +787,15 @@ hb_buffer_get_user_data (hb_buffer_t *buffer,
}
+/**
+ * hb_buffer_set_content_type:
+ * @buffer: a buffer.
+ * @content_type:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_content_type (hb_buffer_t *buffer,
hb_buffer_content_type_t content_type)
@@ -681,6 +803,16 @@ hb_buffer_set_content_type (hb_buffer_t *buffer,
buffer->content_type = content_type;
}
+/**
+ * hb_buffer_get_content_type:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_buffer_content_type_t
hb_buffer_get_content_type (hb_buffer_t *buffer)
{
@@ -688,28 +820,56 @@ hb_buffer_get_content_type (hb_buffer_t *buffer)
}
+/**
+ * hb_buffer_set_unicode_funcs:
+ * @buffer: a buffer.
+ * @unicode_funcs:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
- hb_unicode_funcs_t *unicode)
+ hb_unicode_funcs_t *unicode_funcs)
{
if (unlikely (hb_object_is_inert (buffer)))
return;
- if (!unicode)
- unicode = hb_unicode_funcs_get_default ();
+ if (!unicode_funcs)
+ unicode_funcs = hb_unicode_funcs_get_default ();
- hb_unicode_funcs_reference (unicode);
+ hb_unicode_funcs_reference (unicode_funcs);
hb_unicode_funcs_destroy (buffer->unicode);
- buffer->unicode = unicode;
+ buffer->unicode = unicode_funcs;
}
+/**
+ * hb_buffer_get_unicode_funcs:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_unicode_funcs_t *
hb_buffer_get_unicode_funcs (hb_buffer_t *buffer)
{
return buffer->unicode;
}
+/**
+ * hb_buffer_set_direction:
+ * @buffer: a buffer.
+ * @direction:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_direction (hb_buffer_t *buffer,
hb_direction_t direction)
@@ -721,12 +881,31 @@ hb_buffer_set_direction (hb_buffer_t *buffer,
buffer->props.direction = direction;
}
+/**
+ * hb_buffer_get_direction:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_direction_t
hb_buffer_get_direction (hb_buffer_t *buffer)
{
return buffer->props.direction;
}
+/**
+ * hb_buffer_set_script:
+ * @buffer: a buffer.
+ * @script:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_script (hb_buffer_t *buffer,
hb_script_t script)
@@ -737,12 +916,31 @@ hb_buffer_set_script (hb_buffer_t *buffer,
buffer->props.script = script;
}
+/**
+ * hb_buffer_get_script:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_script_t
hb_buffer_get_script (hb_buffer_t *buffer)
{
return buffer->props.script;
}
+/**
+ * hb_buffer_set_language:
+ * @buffer: a buffer.
+ * @language:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_language (hb_buffer_t *buffer,
hb_language_t language)
@@ -753,12 +951,31 @@ hb_buffer_set_language (hb_buffer_t *buffer,
buffer->props.language = language;
}
+/**
+ * hb_buffer_get_language:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_language_t
hb_buffer_get_language (hb_buffer_t *buffer)
{
return buffer->props.language;
}
+/**
+ * hb_buffer_set_segment_properties:
+ * @buffer: a buffer.
+ * @props:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_segment_properties (hb_buffer_t *buffer,
const hb_segment_properties_t *props)
@@ -769,6 +986,15 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer,
buffer->props = *props;
}
+/**
+ * hb_buffer_get_segment_properties:
+ * @buffer: a buffer.
+ * @props:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_get_segment_properties (hb_buffer_t *buffer,
hb_segment_properties_t *props)
@@ -777,6 +1003,15 @@ hb_buffer_get_segment_properties (hb_buffer_t *buffer,
}
+/**
+ * hb_buffer_set_flags:
+ * @buffer: a buffer.
+ * @flags:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_flags (hb_buffer_t *buffer,
hb_buffer_flags_t flags)
@@ -787,6 +1022,16 @@ hb_buffer_set_flags (hb_buffer_t *buffer,
buffer->flags = flags;
}
+/**
+ * hb_buffer_get_flags:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_buffer_flags_t
hb_buffer_get_flags (hb_buffer_t *buffer)
{
@@ -794,30 +1039,77 @@ hb_buffer_get_flags (hb_buffer_t *buffer)
}
+/**
+ * hb_buffer_reset:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_reset (hb_buffer_t *buffer)
{
buffer->reset ();
}
+/**
+ * hb_buffer_clear_contents:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_clear_contents (hb_buffer_t *buffer)
{
buffer->clear ();
}
+/**
+ * hb_buffer_pre_allocate:
+ * @buffer: a buffer.
+ * @size:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
{
return buffer->ensure (size);
}
+/**
+ * hb_buffer_allocation_successful:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_buffer_allocation_successful (hb_buffer_t *buffer)
{
return !buffer->in_error;
}
+/**
+ * hb_buffer_add:
+ * @buffer: a buffer.
+ * @codepoint:
+ * @cluster:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_add (hb_buffer_t *buffer,
hb_codepoint_t codepoint,
@@ -827,6 +1119,17 @@ hb_buffer_add (hb_buffer_t *buffer,
buffer->clear_context (1);
}
+/**
+ * hb_buffer_set_length:
+ * @buffer: a buffer.
+ * @length:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_buffer_set_length (hb_buffer_t *buffer,
unsigned int length)
@@ -847,19 +1150,43 @@ hb_buffer_set_length (hb_buffer_t *buffer,
buffer->len = length;
if (!length)
+ {
+ buffer->content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
buffer->clear_context (0);
+ }
buffer->clear_context (1);
return true;
}
+/**
+ * hb_buffer_get_length:
+ * @buffer: a buffer.
+ *
+ * Returns the number of items in the buffer.
+ *
+ * Return value: buffer length.
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_buffer_get_length (hb_buffer_t *buffer)
{
return buffer->len;
}
-/* Return value valid as long as buffer not modified */
+/**
+ * hb_buffer_get_glyph_infos:
+ * @buffer: a buffer.
+ * @length: (out): output array length.
+ *
+ * Returns buffer glyph information array. Returned pointer
+ * is valid as long as buffer contents are not modified.
+ *
+ * Return value: (transfer none) (array length=length): buffer glyph information array.
+ *
+ * Since: 1.0
+ **/
hb_glyph_info_t *
hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
unsigned int *length)
@@ -870,7 +1197,18 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
return (hb_glyph_info_t *) buffer->info;
}
-/* Return value valid as long as buffer not modified */
+/**
+ * hb_buffer_get_glyph_positions:
+ * @buffer: a buffer.
+ * @length: (out): output length.
+ *
+ * Returns buffer glyph position array. Returned pointer
+ * is valid as long as buffer contents are not modified.
+ *
+ * Return value: (transfer none) (array length=length): buffer glyph position array.
+ *
+ * Since: 1.0
+ **/
hb_glyph_position_t *
hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
unsigned int *length)
@@ -884,18 +1222,60 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
return (hb_glyph_position_t *) buffer->pos;
}
+/**
+ * hb_buffer_reverse:
+ * @buffer: a buffer.
+ *
+ * Reverses buffer contents.
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_reverse (hb_buffer_t *buffer)
{
buffer->reverse ();
}
+/**
+ * hb_buffer_reverse_clusters:
+ * @buffer: a buffer.
+ *
+ * Reverses buffer clusters. That is, the buffer contents are
+ * reversed, then each cluster (consecutive items having the
+ * same cluster number) are reversed again.
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_reverse_clusters (hb_buffer_t *buffer)
{
buffer->reverse_clusters ();
}
+/**
+ * hb_buffer_guess_segment_properties:
+ * @buffer: a buffer.
+ *
+ * Sets unset buffer segment properties based on buffer Unicode
+ * contents. If buffer is not empty, it must have content type
+ * %HB_BUFFER_CONTENT_TYPE_UNICODE.
+ *
+ * If buffer script is not set (ie. is %HB_SCRIPT_INVALID), it
+ * will be set to the Unicode script of the first character in
+ * the buffer that has a script other than %HB_SCRIPT_COMMON,
+ * %HB_SCRIPT_INHERITED, and %HB_SCRIPT_UNKNOWN.
+ *
+ * Next, if buffer direction is not set (ie. is %HB_DIRECTION_INVALID),
+ * it will be set to the natural horizontal direction of the
+ * buffer script as returned by hb_script_get_horizontal_direction().
+ *
+ * Finally, if buffer language is not set (ie. is %HB_LANGUAGE_INVALID),
+ * it will be set to the process's default language as returned by
+ * hb_language_get_default(). This may change in the future by
+ * taking buffer script into consideration when choosing a language.
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_guess_segment_properties (hb_buffer_t *buffer)
{
@@ -968,6 +1348,18 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
}
+/**
+ * hb_buffer_add_utf8:
+ * @buffer: a buffer.
+ * @text: (array length=text_length):
+ * @text_length:
+ * @item_offset:
+ * @item_length:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_add_utf8 (hb_buffer_t *buffer,
const char *text,
@@ -978,16 +1370,40 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer,
hb_buffer_add_utf (buffer, (const uint8_t *) text, text_length, item_offset, item_length);
}
+/**
+ * hb_buffer_add_utf16:
+ * @buffer: a buffer.
+ * @text: (array length=text_length):
+ * @text_length:
+ * @item_offset:
+ * @item_length:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_add_utf16 (hb_buffer_t *buffer,
const uint16_t *text,
int text_length,
unsigned int item_offset,
- int item_length)
+ int item_length)
{
hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length);
}
+/**
+ * hb_buffer_add_utf32:
+ * @buffer: a buffer.
+ * @text: (array length=text_length):
+ * @text_length:
+ * @item_offset:
+ * @item_length:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_add_utf32 (hb_buffer_t *buffer,
const uint32_t *text,
@@ -1054,6 +1470,14 @@ normalize_glyphs_cluster (hb_buffer_t *buffer,
}
}
+/**
+ * hb_buffer_normalize_glyphs:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
{
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
index 87c4ce58e8..3086851b01 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
@@ -172,10 +172,10 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
typedef enum { /*< flags >*/
- HB_BUFFER_FLAG_DEFAULT = 0x00000000,
- HB_BUFFER_FLAG_BOT = 0x00000001, /* Beginning-of-text */
- HB_BUFFER_FLAG_EOT = 0x00000002, /* End-of-text */
- HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004
+ HB_BUFFER_FLAG_DEFAULT = 0x00000000u,
+ HB_BUFFER_FLAG_BOT = 0x00000001u, /* Beginning-of-text */
+ HB_BUFFER_FLAG_EOT = 0x00000002u, /* End-of-text */
+ HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u
} hb_buffer_flags_t;
void
@@ -275,10 +275,10 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
*/
typedef enum { /*< flags >*/
- HB_BUFFER_SERIALIZE_FLAG_DEFAULT = 0x00000000,
- HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001,
- HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002,
- HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004
+ HB_BUFFER_SERIALIZE_FLAG_DEFAULT = 0x00000000u,
+ HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001u,
+ HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002u,
+ HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u
} hb_buffer_serialize_flags_t;
typedef enum {
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.cc b/src/3rdparty/harfbuzz-ng/src/hb-common.cc
index 7c6d26290d..0fd790bc04 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-common.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-common.cc
@@ -28,8 +28,6 @@
#include "hb-private.hh"
-#include "hb-version.h"
-
#include "hb-mutex-private.hh"
#include "hb-object-private.hh"
@@ -57,25 +55,45 @@ _hb_options_init (void)
/* hb_tag_t */
+/**
+ * hb_tag_from_string:
+ * @str: (array length=len):
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_tag_t
-hb_tag_from_string (const char *s, int len)
+hb_tag_from_string (const char *str, int len)
{
char tag[4];
unsigned int i;
- if (!s || !len || !*s)
+ if (!str || !len || !*str)
return HB_TAG_NONE;
if (len < 0 || len > 4)
len = 4;
- for (i = 0; i < (unsigned) len && s[i]; i++)
- tag[i] = s[i];
+ for (i = 0; i < (unsigned) len && str[i]; i++)
+ tag[i] = str[i];
for (; i < 4; i++)
tag[i] = ' ';
return HB_TAG_CHAR4 (tag);
}
+/**
+ * hb_tag_to_string:
+ * @tag:
+ * @buf: (array fixed-size=4):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_tag_to_string (hb_tag_t tag, char *buf)
{
@@ -95,6 +113,17 @@ const char direction_strings[][4] = {
"btt"
};
+/**
+ * hb_direction_from_string:
+ * @str: (array length=len):
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_direction_t
hb_direction_from_string (const char *str, int len)
{
@@ -112,6 +141,16 @@ hb_direction_from_string (const char *str, int len)
return HB_DIRECTION_INVALID;
}
+/**
+ * hb_direction_to_string:
+ * @direction:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
const char *
hb_direction_to_string (hb_direction_t direction)
{
@@ -187,7 +226,7 @@ struct hb_language_item_t {
return *this;
}
- void finish (void) { free (lang); }
+ void finish (void) { free ((void *) lang); }
};
@@ -237,14 +276,27 @@ retry:
}
+/**
+ * hb_language_from_string:
+ * @str: (array length=len):
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_language_t
hb_language_from_string (const char *str, int len)
{
+ char strbuf[64];
+
if (!str || !len || !*str)
return HB_LANGUAGE_INVALID;
- if (len >= 0) {
- char strbuf[64];
+ if (len >= 0)
+ {
len = MIN (len, (int) sizeof (strbuf) - 1);
str = (char *) memcpy (strbuf, str, len);
strbuf[len] = '\0';
@@ -255,6 +307,16 @@ hb_language_from_string (const char *str, int len)
return likely (item) ? item->lang : HB_LANGUAGE_INVALID;
}
+/**
+ * hb_language_to_string:
+ * @language:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
const char *
hb_language_to_string (hb_language_t language)
{
@@ -262,6 +324,15 @@ hb_language_to_string (hb_language_t language)
return language->s;
}
+/**
+ * hb_language_get_default:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_language_t
hb_language_get_default (void)
{
@@ -279,6 +350,16 @@ hb_language_get_default (void)
/* hb_script_t */
+/**
+ * hb_script_from_iso15924_tag:
+ * @tag:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_script_t
hb_script_from_iso15924_tag (hb_tag_t tag)
{
@@ -313,18 +394,49 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
return HB_SCRIPT_UNKNOWN;
}
+/**
+ * hb_script_from_string:
+ * @s: (array length=len):
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_script_t
hb_script_from_string (const char *s, int len)
{
return hb_script_from_iso15924_tag (hb_tag_from_string (s, len));
}
+/**
+ * hb_script_to_iso15924_tag:
+ * @script:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_tag_t
hb_script_to_iso15924_tag (hb_script_t script)
{
return (hb_tag_t) script;
}
+/**
+ * hb_script_get_horizontal_direction:
+ * @script:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_direction_t
hb_script_get_horizontal_direction (hb_script_t script)
{
@@ -409,6 +521,16 @@ hb_user_data_array_t::get (hb_user_data_key_t *key)
/* hb_version */
+/**
+ * hb_version:
+ * @major: (out): Library major version component.
+ * @minor: (out): Library minor version component.
+ * @micro: (out): Library micro version component.
+ *
+ * Returns library version as three integer components.
+ *
+ * Since: 1.0
+ **/
void
hb_version (unsigned int *major,
unsigned int *minor,
@@ -419,12 +541,33 @@ hb_version (unsigned int *major,
*micro = HB_VERSION_MICRO;
}
+/**
+ * hb_version_string:
+ *
+ * Returns library version as a string with three components.
+ *
+ * Return value: library version string.
+ *
+ * Since: 1.0
+ **/
const char *
hb_version_string (void)
{
return HB_VERSION_STRING;
}
+/**
+ * hb_version_check:
+ * @major:
+ * @minor:
+ * @micro:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_version_check (unsigned int major,
unsigned int minor,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.h b/src/3rdparty/harfbuzz-ng/src/hb-common.h
index 9079b2c046..e445504550 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-common.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-common.h
@@ -90,7 +90,7 @@ typedef union _hb_var_int_t {
typedef uint32_t hb_tag_t;
-#define HB_TAG(a,b,c,d) ((hb_tag_t)((((uint8_t)(a))<<24)|(((uint8_t)(b))<<16)|(((uint8_t)(c))<<8)|((uint8_t)(d))))
+#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4))))
#define HB_UNTAG(tag) ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag))
#define HB_TAG_NONE HB_TAG(0,0,0,0)
@@ -131,7 +131,7 @@ hb_direction_to_string (hb_direction_t direction);
/* hb_language_t */
-typedef struct hb_language_impl_t *hb_language_t;
+typedef const struct hb_language_impl_t *hb_language_t;
/* len=-1 means str is NUL-terminated */
hb_language_t
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh
index b33be0e5fc..6520d3dbdf 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh
@@ -31,7 +31,6 @@
#include "hb-private.hh"
-#include "hb-font.h"
#include "hb-object-private.hh"
#include "hb-shaper-private.hh"
#include "hb-shape-plan-private.hh"
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.cc b/src/3rdparty/harfbuzz-ng/src/hb-face.cc
index d8b9ed8c3f..71cf49a5bc 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-face.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face.cc
@@ -31,7 +31,6 @@
#include "hb-ot-layout-private.hh"
#include "hb-font-private.hh"
-#include "hb-blob.h"
#include "hb-open-file-private.hh"
#include "hb-ot-head-table.hh"
#include "hb-ot-maxp-table.hh"
@@ -68,6 +67,18 @@ const hb_face_t _hb_face_nil = {
};
+/**
+ * hb_face_create_for_tables:
+ * @reference_table_func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Return value: (transfer full)
+ *
+ * Since: 1.0
+ **/
hb_face_t *
hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
void *user_data,
@@ -137,6 +148,17 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
return blob;
}
+/**
+ * hb_face_create: (Xconstructor)
+ * @blob:
+ * @index:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_face_t *
hb_face_create (hb_blob_t *blob,
unsigned int index)
@@ -160,6 +182,15 @@ hb_face_create (hb_blob_t *blob,
return face;
}
+/**
+ * hb_face_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full)
+ *
+ * Since: 1.0
+ **/
hb_face_t *
hb_face_get_empty (void)
{
@@ -167,12 +198,30 @@ hb_face_get_empty (void)
}
+/**
+ * hb_face_reference: (skip)
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_face_t *
hb_face_reference (hb_face_t *face)
{
return hb_object_reference (face);
}
+/**
+ * hb_face_destroy: (skip)
+ * @face: a face.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_face_destroy (hb_face_t *face)
{
@@ -196,6 +245,20 @@ hb_face_destroy (hb_face_t *face)
free (face);
}
+/**
+ * hb_face_set_user_data: (skip)
+ * @face: a face.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_face_set_user_data (hb_face_t *face,
hb_user_data_key_t *key,
@@ -206,6 +269,17 @@ hb_face_set_user_data (hb_face_t *face,
return hb_object_set_user_data (face, key, data, destroy, replace);
}
+/**
+ * hb_face_get_user_data: (skip)
+ * @face: a face.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_face_get_user_data (hb_face_t *face,
hb_user_data_key_t *key)
@@ -213,6 +287,14 @@ hb_face_get_user_data (hb_face_t *face,
return hb_object_get_user_data (face, key);
}
+/**
+ * hb_face_make_immutable:
+ * @face: a face.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_face_make_immutable (hb_face_t *face)
{
@@ -222,6 +304,16 @@ hb_face_make_immutable (hb_face_t *face)
face->immutable = true;
}
+/**
+ * hb_face_is_immutable:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_face_is_immutable (hb_face_t *face)
{
@@ -229,6 +321,17 @@ hb_face_is_immutable (hb_face_t *face)
}
+/**
+ * hb_face_reference_table:
+ * @face: a face.
+ * @tag:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_blob_t *
hb_face_reference_table (hb_face_t *face,
hb_tag_t tag)
@@ -236,12 +339,31 @@ hb_face_reference_table (hb_face_t *face,
return face->reference_table (tag);
}
+/**
+ * hb_face_reference_blob:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_blob_t *
hb_face_reference_blob (hb_face_t *face)
{
return face->reference_table (HB_TAG_NONE);
}
+/**
+ * hb_face_set_index:
+ * @face: a face.
+ * @index:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_face_set_index (hb_face_t *face,
unsigned int index)
@@ -252,12 +374,31 @@ hb_face_set_index (hb_face_t *face,
face->index = index;
}
+/**
+ * hb_face_get_index:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_face_get_index (hb_face_t *face)
{
return face->index;
}
+/**
+ * hb_face_set_upem:
+ * @face: a face.
+ * @upem:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_face_set_upem (hb_face_t *face,
unsigned int upem)
@@ -268,6 +409,16 @@ hb_face_set_upem (hb_face_t *face,
face->upem = upem;
}
+/**
+ * hb_face_get_upem:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_face_get_upem (hb_face_t *face)
{
@@ -283,6 +434,15 @@ hb_face_t::load_upem (void) const
hb_blob_destroy (head_blob);
}
+/**
+ * hb_face_set_glyph_count:
+ * @face: a face.
+ * @glyph_count:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_face_set_glyph_count (hb_face_t *face,
unsigned int glyph_count)
@@ -293,6 +453,16 @@ hb_face_set_glyph_count (hb_face_t *face,
face->num_glyphs = glyph_count;
}
+/**
+ * hb_face_get_glyph_count:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_face_get_glyph_count (hb_face_t *face)
{
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
index 1a1fcfbda1..b894a4a47d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
@@ -95,6 +95,16 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
const hb_feature_t *features HB_UNUSED,
unsigned int num_features HB_UNUSED)
{
+ /* TODO
+ *
+ * - Apply fallback kern.
+ * - Handle Variation Selectors?
+ * - Apply normalization?
+ *
+ * This will make the fallback shaper into a dumb "TrueType"
+ * shaper which many people unfortunately still request.
+ */
+
hb_codepoint_t space;
font->get_glyph (' ', 0, &space);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
index 620d05e8f9..431d0477c2 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
@@ -31,7 +31,6 @@
#include "hb-private.hh"
-#include "hb-font.h"
#include "hb-object-private.hh"
#include "hb-face-private.hh"
#include "hb-shaper-private.hh"
@@ -118,12 +117,12 @@ struct hb_font_t {
/* Convert from parent-font user-space to our user-space */
inline hb_position_t parent_scale_x_distance (hb_position_t v) {
if (unlikely (parent && parent->x_scale != x_scale))
- return v * (int64_t) this->x_scale / this->parent->x_scale;
+ return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
return v;
}
inline hb_position_t parent_scale_y_distance (hb_position_t v) {
if (unlikely (parent && parent->y_scale != y_scale))
- return v * (int64_t) this->y_scale / this->parent->y_scale;
+ return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
return v;
}
inline hb_position_t parent_scale_x_position (hb_position_t v) {
@@ -193,10 +192,10 @@ struct hb_font_t {
klass->user_data.glyph_h_kerning);
}
- inline hb_position_t get_glyph_v_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
+ inline hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
{
return klass->get.glyph_v_kerning (this, user_data,
- left_glyph, right_glyph,
+ top_glyph, bottom_glyph,
klass->user_data.glyph_v_kerning);
}
@@ -397,11 +396,7 @@ struct hb_font_t {
}
private:
- inline hb_position_t em_scale (int16_t v, int scale)
- {
- unsigned int upem = face->get_upem ();
- return (v * (int64_t) scale + upem / 2) / upem;
- }
+ inline hb_position_t em_scale (int16_t v, int scale) { return (hb_position_t) (v * (int64_t) scale / face->get_upem ()); }
};
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-font.cc
index c2f6f6ddd5..fc4c8ebf07 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-font.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font.cc
@@ -31,7 +31,6 @@
#include "hb-ot-layout-private.hh"
#include "hb-font-private.hh"
-#include "hb-blob.h"
#include "hb-open-file-private.hh"
#include "hb-ot-head-table.hh"
#include "hb-ot-maxp-table.hh"
@@ -230,6 +229,15 @@ static const hb_font_funcs_t _hb_font_funcs_nil = {
};
+/**
+ * hb_font_funcs_create: (Xconstructor)
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_font_funcs_t *
hb_font_funcs_create (void)
{
@@ -243,18 +251,45 @@ hb_font_funcs_create (void)
return ffuncs;
}
+/**
+ * hb_font_funcs_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_font_funcs_t *
hb_font_funcs_get_empty (void)
{
return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil);
}
+/**
+ * hb_font_funcs_reference: (skip)
+ * @ffuncs: font functions.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_font_funcs_t *
hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
{
return hb_object_reference (ffuncs);
}
+/**
+ * hb_font_funcs_destroy: (skip)
+ * @ffuncs: font functions.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
{
@@ -268,6 +303,20 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
free (ffuncs);
}
+/**
+ * hb_font_funcs_set_user_data: (skip)
+ * @ffuncs: font functions.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
hb_user_data_key_t *key,
@@ -278,6 +327,17 @@ hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
}
+/**
+ * hb_font_funcs_get_user_data: (skip)
+ * @ffuncs: font functions.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
hb_user_data_key_t *key)
@@ -286,6 +346,14 @@ hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
}
+/**
+ * hb_font_funcs_make_immutable:
+ * @ffuncs: font functions.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
{
@@ -295,6 +363,16 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
ffuncs->immutable = true;
}
+/**
+ * hb_font_funcs_is_immutable:
+ * @ffuncs: font functions.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
{
@@ -336,6 +414,19 @@ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
/* Public getters */
+/**
+ * hb_font_get_glyph:
+ * @font: a font.
+ * @unicode:
+ * @variation_selector:
+ * @glyph: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph (hb_font_t *font,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
@@ -344,6 +435,17 @@ hb_font_get_glyph (hb_font_t *font,
return font->get_glyph (unicode, variation_selector, glyph);
}
+/**
+ * hb_font_get_glyph_h_advance:
+ * @font: a font.
+ * @glyph:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_position_t
hb_font_get_glyph_h_advance (hb_font_t *font,
hb_codepoint_t glyph)
@@ -351,6 +453,17 @@ hb_font_get_glyph_h_advance (hb_font_t *font,
return font->get_glyph_h_advance (glyph);
}
+/**
+ * hb_font_get_glyph_v_advance:
+ * @font: a font.
+ * @glyph:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_position_t
hb_font_get_glyph_v_advance (hb_font_t *font,
hb_codepoint_t glyph)
@@ -358,6 +471,19 @@ hb_font_get_glyph_v_advance (hb_font_t *font,
return font->get_glyph_v_advance (glyph);
}
+/**
+ * hb_font_get_glyph_h_origin:
+ * @font: a font.
+ * @glyph:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_h_origin (hb_font_t *font,
hb_codepoint_t glyph,
@@ -366,6 +492,19 @@ hb_font_get_glyph_h_origin (hb_font_t *font,
return font->get_glyph_h_origin (glyph, x, y);
}
+/**
+ * hb_font_get_glyph_v_origin:
+ * @font: a font.
+ * @glyph:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_v_origin (hb_font_t *font,
hb_codepoint_t glyph,
@@ -374,6 +513,18 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
return font->get_glyph_v_origin (glyph, x, y);
}
+/**
+ * hb_font_get_glyph_h_kerning:
+ * @font: a font.
+ * @left_glyph:
+ * @right_glyph:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
@@ -381,13 +532,37 @@ hb_font_get_glyph_h_kerning (hb_font_t *font,
return font->get_glyph_h_kerning (left_glyph, right_glyph);
}
+/**
+ * hb_font_get_glyph_v_kerning:
+ * @font: a font.
+ * @top_glyph:
+ * @bottom_glyph:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_position_t
hb_font_get_glyph_v_kerning (hb_font_t *font,
- hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
+ hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
{
- return font->get_glyph_v_kerning (left_glyph, right_glyph);
+ return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
}
+/**
+ * hb_font_get_glyph_extents:
+ * @font: a font.
+ * @glyph:
+ * @extents: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_extents (hb_font_t *font,
hb_codepoint_t glyph,
@@ -396,6 +571,20 @@ hb_font_get_glyph_extents (hb_font_t *font,
return font->get_glyph_extents (glyph, extents);
}
+/**
+ * hb_font_get_glyph_contour_point:
+ * @font: a font.
+ * @glyph:
+ * @point_index:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_contour_point (hb_font_t *font,
hb_codepoint_t glyph, unsigned int point_index,
@@ -404,6 +593,19 @@ hb_font_get_glyph_contour_point (hb_font_t *font,
return font->get_glyph_contour_point (glyph, point_index, x, y);
}
+/**
+ * hb_font_get_glyph_name:
+ * @font: a font.
+ * @glyph:
+ * @name: (array length=size):
+ * @size:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_name (hb_font_t *font,
hb_codepoint_t glyph,
@@ -412,6 +614,19 @@ hb_font_get_glyph_name (hb_font_t *font,
return font->get_glyph_name (glyph, name, size);
}
+/**
+ * hb_font_get_glyph_from_name:
+ * @font: a font.
+ * @name: (array length=len):
+ * @len:
+ * @glyph: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_from_name (hb_font_t *font,
const char *name, int len, /* -1 means nul-terminated */
@@ -423,6 +638,18 @@ hb_font_get_glyph_from_name (hb_font_t *font,
/* A bit higher-level, and with fallback */
+/**
+ * hb_font_get_glyph_advance_for_direction:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_get_glyph_advance_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
@@ -432,6 +659,18 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font,
return font->get_glyph_advance_for_direction (glyph, direction, x, y);
}
+/**
+ * hb_font_get_glyph_origin_for_direction:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_get_glyph_origin_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
@@ -441,6 +680,18 @@ hb_font_get_glyph_origin_for_direction (hb_font_t *font,
return font->get_glyph_origin_for_direction (glyph, direction, x, y);
}
+/**
+ * hb_font_add_glyph_origin_for_direction:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_add_glyph_origin_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
@@ -450,6 +701,18 @@ hb_font_add_glyph_origin_for_direction (hb_font_t *font,
return font->add_glyph_origin_for_direction (glyph, direction, x, y);
}
+/**
+ * hb_font_subtract_glyph_origin_for_direction:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
@@ -459,6 +722,19 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
}
+/**
+ * hb_font_get_glyph_kerning_for_direction:
+ * @font: a font.
+ * @first_glyph:
+ * @second_glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
@@ -468,6 +744,19 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
}
+/**
+ * hb_font_get_glyph_extents_for_origin:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @extents: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_extents_for_origin (hb_font_t *font,
hb_codepoint_t glyph,
@@ -477,6 +766,21 @@ hb_font_get_glyph_extents_for_origin (hb_font_t *font,
return font->get_glyph_extents_for_origin (glyph, direction, extents);
}
+/**
+ * hb_font_get_glyph_contour_point_for_origin:
+ * @font: a font.
+ * @glyph:
+ * @point_index:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
hb_codepoint_t glyph, unsigned int point_index,
@@ -487,6 +791,17 @@ hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
}
/* Generates gidDDD if glyph has no name. */
+/**
+ * hb_font_glyph_to_string:
+ * @font: a font.
+ * @glyph:
+ * @s: (array length=size):
+ * @size:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_glyph_to_string (hb_font_t *font,
hb_codepoint_t glyph,
@@ -496,6 +811,19 @@ hb_font_glyph_to_string (hb_font_t *font,
}
/* Parses gidDDD and uniUUUU strings automatically. */
+/**
+ * hb_font_glyph_from_string:
+ * @font: a font.
+ * @s: (array length=len):
+ * @len:
+ * @glyph: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_glyph_from_string (hb_font_t *font,
const char *s, int len, /* -1 means nul-terminated */
@@ -509,6 +837,16 @@ hb_font_glyph_from_string (hb_font_t *font,
* hb_font_t
*/
+/**
+ * hb_font_create: (Xconstructor)
+ * @face: a face.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_font_t *
hb_font_create (hb_face_t *face)
{
@@ -528,6 +866,16 @@ hb_font_create (hb_face_t *face)
return font;
}
+/**
+ * hb_font_create_sub_font:
+ * @parent: parent font.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_font_t *
hb_font_create_sub_font (hb_font_t *parent)
{
@@ -550,6 +898,15 @@ hb_font_create_sub_font (hb_font_t *parent)
return font;
}
+/**
+ * hb_font_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full)
+ *
+ * Since: 1.0
+ **/
hb_font_t *
hb_font_get_empty (void)
{
@@ -581,12 +938,30 @@ hb_font_get_empty (void)
return const_cast<hb_font_t *> (&_hb_font_nil);
}
+/**
+ * hb_font_reference: (skip)
+ * @font: a font.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_font_t *
hb_font_reference (hb_font_t *font)
{
return hb_object_reference (font);
}
+/**
+ * hb_font_destroy: (skip)
+ * @font: a font.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_destroy (hb_font_t *font)
{
@@ -606,6 +981,20 @@ hb_font_destroy (hb_font_t *font)
free (font);
}
+/**
+ * hb_font_set_user_data: (skip)
+ * @font: a font.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_set_user_data (hb_font_t *font,
hb_user_data_key_t *key,
@@ -616,6 +1005,17 @@ hb_font_set_user_data (hb_font_t *font,
return hb_object_set_user_data (font, key, data, destroy, replace);
}
+/**
+ * hb_font_get_user_data: (skip)
+ * @font: a font.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_font_get_user_data (hb_font_t *font,
hb_user_data_key_t *key)
@@ -623,6 +1023,14 @@ hb_font_get_user_data (hb_font_t *font,
return hb_object_get_user_data (font, key);
}
+/**
+ * hb_font_make_immutable:
+ * @font: a font.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_make_immutable (hb_font_t *font)
{
@@ -632,18 +1040,48 @@ hb_font_make_immutable (hb_font_t *font)
font->immutable = true;
}
+/**
+ * hb_font_is_immutable:
+ * @font: a font.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_is_immutable (hb_font_t *font)
{
return font->immutable;
}
+/**
+ * hb_font_get_parent:
+ * @font: a font.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
hb_font_t *
hb_font_get_parent (hb_font_t *font)
{
return font->parent;
}
+/**
+ * hb_font_get_face:
+ * @font: a font.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
hb_face_t *
hb_font_get_face (hb_font_t *font)
{
@@ -651,15 +1089,26 @@ hb_font_get_face (hb_font_t *font)
}
+/**
+ * hb_font_set_funcs:
+ * @font: a font.
+ * @klass: (closure font_data) (destroy destroy) (scope notified):
+ * @font_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_set_funcs (hb_font_t *font,
hb_font_funcs_t *klass,
- void *user_data,
+ void *font_data,
hb_destroy_func_t destroy)
{
if (font->immutable) {
if (destroy)
- destroy (user_data);
+ destroy (font_data);
return;
}
@@ -672,30 +1121,50 @@ hb_font_set_funcs (hb_font_t *font,
hb_font_funcs_reference (klass);
hb_font_funcs_destroy (font->klass);
font->klass = klass;
- font->user_data = user_data;
+ font->user_data = font_data;
font->destroy = destroy;
}
+/**
+ * hb_font_set_funcs_data:
+ * @font: a font.
+ * @font_data: (destroy destroy) (scope notified):
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_set_funcs_data (hb_font_t *font,
- void *user_data,
+ void *font_data,
hb_destroy_func_t destroy)
{
/* Destroy user_data? */
if (font->immutable) {
if (destroy)
- destroy (user_data);
+ destroy (font_data);
return;
}
if (font->destroy)
font->destroy (font->user_data);
- font->user_data = user_data;
+ font->user_data = font_data;
font->destroy = destroy;
}
+/**
+ * hb_font_set_scale:
+ * @font: a font.
+ * @x_scale:
+ * @y_scale:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_set_scale (hb_font_t *font,
int x_scale,
@@ -708,6 +1177,16 @@ hb_font_set_scale (hb_font_t *font,
font->y_scale = y_scale;
}
+/**
+ * hb_font_get_scale:
+ * @font: a font.
+ * @x_scale: (out):
+ * @y_scale: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_get_scale (hb_font_t *font,
int *x_scale,
@@ -717,6 +1196,16 @@ hb_font_get_scale (hb_font_t *font,
if (y_scale) *y_scale = font->y_scale;
}
+/**
+ * hb_font_set_ppem:
+ * @font: a font.
+ * @x_ppem:
+ * @y_ppem:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_set_ppem (hb_font_t *font,
unsigned int x_ppem,
@@ -729,6 +1218,16 @@ hb_font_set_ppem (hb_font_t *font,
font->y_ppem = y_ppem;
}
+/**
+ * hb_font_get_ppem:
+ * @font: a font.
+ * @x_ppem: (out):
+ * @y_ppem: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_get_ppem (hb_font_t *font,
unsigned int *x_ppem,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.h b/src/3rdparty/harfbuzz-ng/src/hb-font.h
index 3a0c001b98..7273db43ed 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-font.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font.h
@@ -139,54 +139,180 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *
/* func setters */
+/**
+ * hb_font_funcs_set_glyph_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
- hb_font_get_glyph_func_t glyph_func,
+ hb_font_get_glyph_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_font_funcs_set_glyph_h_advance_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_h_advance_func_t func,
void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_v_advance_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_v_advance_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_font_funcs_set_glyph_h_origin_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_h_origin_func_t func,
void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_v_origin_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_v_origin_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_font_funcs_set_glyph_h_kerning_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_h_kerning_func_t func,
void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_v_kerning_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_v_kerning_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_font_funcs_set_glyph_extents_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_extents_func_t func,
void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_contour_point_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_contour_point_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_font_funcs_set_glyph_name_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
- hb_font_get_glyph_name_func_t glyph_func,
+ hb_font_get_glyph_name_func_t func,
void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_from_name_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs,
- hb_font_get_glyph_from_name_func_t glyph_func,
+ hb_font_get_glyph_from_name_func_t func,
void *user_data, hb_destroy_func_t destroy);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
index ee3a21dc3b..437ecd57f8 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
@@ -31,8 +31,6 @@
#include "hb-private.hh"
-#include "hb-blob.h"
-
namespace OT {
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
index 3a9451295d..0285f0cf31 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
@@ -43,7 +43,7 @@ namespace OT {
struct head
{
- static const hb_tag_t Tag = HB_OT_TAG_head;
+ static const hb_tag_t tableTag = HB_OT_TAG_head;
inline unsigned int get_upem (void) const {
unsigned int upem = unitsPerEm;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
index 2b89c4e020..611de8a666 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
@@ -42,7 +42,7 @@ namespace OT {
struct hhea
{
- static const hb_tag_t Tag = HB_OT_TAG_hhea;
+ static const hb_tag_t tableTag = HB_OT_TAG_hhea;
inline bool sanitize (hb_sanitize_context_t *c) {
TRACE_SANITIZE (this);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
index b94337d0be..d107cf990a 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
@@ -50,7 +50,7 @@ struct LongHorMetric
struct hmtx
{
- static const hb_tag_t Tag = HB_OT_TAG_hmtx;
+ static const hb_tag_t tableTag = HB_OT_TAG_hmtx;
inline bool sanitize (hb_sanitize_context_t *c) {
TRACE_SANITIZE (this);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
index 2f6e80468e..02d0d0f87c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
@@ -39,6 +39,7 @@ namespace OT {
#define NOT_COVERED ((unsigned int) -1)
#define MAX_NESTING_LEVEL 8
+#define MAX_CONTEXT_LENGTH 64
@@ -376,7 +377,7 @@ struct FeatureParamsStylisticSet
return TRACE_RETURN (c->check_struct (this));
}
- USHORT minorVersion; /* (set to 0): This corresponds to a “minor”
+ USHORT version; /* (set to 0): This corresponds to a “minor”
* version number. Additional data may be
* added to the end of this Feature Parameters
* table in the future. */
@@ -399,6 +400,7 @@ struct FeatureParamsStylisticSet
DEFINE_SIZE_STATIC (4);
};
+/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */
struct FeatureParamsCharacterVariants
{
inline bool sanitize (hb_sanitize_context_t *c) {
@@ -1111,7 +1113,7 @@ struct Device
if (!pixels) return 0;
- return pixels * (int64_t) scale / ppem;
+ return (int) (pixels * (int64_t) scale / ppem);
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
index ff2d09c51f..389cbb9e39 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
@@ -324,7 +324,7 @@ struct MarkGlyphSets
struct GDEF
{
- static const hb_tag_t Tag = HB_OT_TAG_GDEF;
+ static const hb_tag_t tableTag = HB_OT_TAG_GDEF;
enum GlyphClasses {
UnclassifiedGlyph = 0,
@@ -383,12 +383,14 @@ struct GDEF
{
unsigned int klass = get_glyph_class (glyph);
+ ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs);
+ ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures);
+ ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks);
+
switch (klass) {
- default:
- case UnclassifiedGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED;
+ default: return 0;
case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
- case ComponentGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT;
case MarkGlyph:
klass = get_mark_attachment_type (glyph);
return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
index 2cf90b7b5f..5e4326ef0c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
@@ -390,6 +390,7 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde
unsigned int glyph_pos) const
{
TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index);
unsigned int mark_class = record.klass;
@@ -402,15 +403,15 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde
hb_position_t mark_x, mark_y, base_x, base_y;
- mark_anchor.get_anchor (c->font, c->buffer->cur().codepoint, &mark_x, &mark_y);
- glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, &base_x, &base_y);
+ mark_anchor.get_anchor (c->font, buffer->cur().codepoint, &mark_x, &mark_y);
+ glyph_anchor.get_anchor (c->font, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
- hb_glyph_position_t &o = c->buffer->cur_pos();
+ hb_glyph_position_t &o = buffer->cur_pos();
o.x_offset = base_x - mark_x;
o.y_offset = base_y - mark_y;
- o.attach_lookback() = c->buffer->idx - glyph_pos;
+ o.attach_lookback() = buffer->idx - glyph_pos;
- c->buffer->idx++;
+ buffer->idx++;
return TRACE_RETURN (true);
}
@@ -439,13 +440,14 @@ struct SinglePosFormat1
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
valueFormat.apply_value (c->font, c->direction, this,
- values, c->buffer->cur_pos());
+ values, buffer->cur_pos());
- c->buffer->idx++;
+ buffer->idx++;
return TRACE_RETURN (true);
}
@@ -484,16 +486,17 @@ struct SinglePosFormat2
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
if (likely (index >= valueCount)) return TRACE_RETURN (false);
valueFormat.apply_value (c->font, c->direction, this,
&values[index * valueFormat.get_len ()],
- c->buffer->cur_pos());
+ buffer->cur_pos());
- c->buffer->idx++;
+ buffer->idx++;
return TRACE_RETURN (true);
}
@@ -588,6 +591,7 @@ struct PairSet
unsigned int pos) const
{
TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
unsigned int len1 = valueFormats[0].get_len ();
unsigned int len2 = valueFormats[1].get_len ();
unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
@@ -597,15 +601,15 @@ struct PairSet
for (unsigned int i = 0; i < count; i++)
{
/* TODO bsearch */
- if (c->buffer->info[pos].codepoint == record->secondGlyph)
+ if (buffer->info[pos].codepoint == record->secondGlyph)
{
valueFormats[0].apply_value (c->font, c->direction, this,
- &record->values[0], c->buffer->cur_pos());
+ &record->values[0], buffer->cur_pos());
valueFormats[1].apply_value (c->font, c->direction, this,
- &record->values[len1], c->buffer->pos[pos]);
+ &record->values[len1], buffer->pos[pos]);
if (len2)
pos++;
- c->buffer->idx = pos;
+ buffer->idx = pos;
return TRACE_RETURN (true);
}
record = &StructAtOffset<PairValueRecord> (record, record_size);
@@ -659,10 +663,11 @@ struct PairPosFormat1
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ hb_buffer_t *buffer = c->buffer;
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
if (!skippy_iter.next ()) return TRACE_RETURN (false);
@@ -729,10 +734,11 @@ struct PairPosFormat2
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ hb_buffer_t *buffer = c->buffer;
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
if (!skippy_iter.next ()) return TRACE_RETURN (false);
@@ -741,19 +747,19 @@ struct PairPosFormat2
unsigned int len2 = valueFormat2.get_len ();
unsigned int record_len = len1 + len2;
- unsigned int klass1 = (this+classDef1).get_class (c->buffer->cur().codepoint);
- unsigned int klass2 = (this+classDef2).get_class (c->buffer->info[skippy_iter.idx].codepoint);
+ unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
+ unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_RETURN (false);
const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
valueFormat1.apply_value (c->font, c->direction, this,
- v, c->buffer->cur_pos());
+ v, buffer->cur_pos());
valueFormat2.apply_value (c->font, c->direction, this,
- v + len1, c->buffer->pos[skippy_iter.idx]);
+ v + len1, buffer->pos[skippy_iter.idx]);
- c->buffer->idx = skippy_iter.idx;
+ buffer->idx = skippy_iter.idx;
if (len2)
- c->buffer->idx++;
+ buffer->idx++;
return TRACE_RETURN (true);
}
@@ -875,29 +881,30 @@ struct CursivePosFormat1
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
/* We don't handle mark glyphs here. */
- if (c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK) return TRACE_RETURN (false);
+ if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN (false);
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
- const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (c->buffer->cur().codepoint)];
+ const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)];
if (!this_record.exitAnchor) return TRACE_RETURN (false);
if (!skippy_iter.next ()) return TRACE_RETURN (false);
- const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (c->buffer->info[skippy_iter.idx].codepoint)];
+ const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)];
if (!next_record.entryAnchor) return TRACE_RETURN (false);
- unsigned int i = c->buffer->idx;
+ unsigned int i = buffer->idx;
unsigned int j = skippy_iter.idx;
hb_position_t entry_x, entry_y, exit_x, exit_y;
- (this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepoint, &exit_x, &exit_y);
- (this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codepoint, &entry_x, &entry_y);
+ (this+this_record.exitAnchor).get_anchor (c->font, buffer->info[i].codepoint, &exit_x, &exit_y);
+ (this+next_record.entryAnchor).get_anchor (c->font, buffer->info[j].codepoint, &entry_x, &entry_y);
- hb_glyph_position_t *pos = c->buffer->pos;
+ hb_glyph_position_t *pos = buffer->pos;
hb_position_t d;
/* Main-direction adjustment */
@@ -950,7 +957,7 @@ struct CursivePosFormat1
pos[j].x_offset = exit_x - entry_x;
}
- c->buffer->idx = j;
+ buffer->idx = j;
return TRACE_RETURN (true);
}
@@ -1022,23 +1029,24 @@ struct MarkBasePosFormat1
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur().codepoint);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a non-mark glyph */
- hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1);
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
do {
if (!skippy_iter.prev ()) return TRACE_RETURN (false);
/* We only want to attach to the first of a MultipleSubst sequence. Reject others. */
- if (0 == get_lig_comp (c->buffer->info[skippy_iter.idx])) break;
+ if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) break;
skippy_iter.reject ();
} while (1);
- /* The following assertion is too strong, so we've disabled it. */
- if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/}
+ /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
+ if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ }
- unsigned int base_index = (this+baseCoverage).get_coverage (c->buffer->info[skippy_iter.idx].codepoint);
+ unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint);
if (base_index == NOT_COVERED) return TRACE_RETURN (false);
return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
@@ -1125,19 +1133,20 @@ struct MarkLigPosFormat1
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur().codepoint);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a non-mark glyph */
- hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1);
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
if (!skippy_iter.prev ()) return TRACE_RETURN (false);
- /* The following assertion is too strong, so we've disabled it. */
- if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE)) {/*return TRACE_RETURN (false);*/}
+ /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
+ if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ }
unsigned int j = skippy_iter.idx;
- unsigned int lig_index = (this+ligatureCoverage).get_coverage (c->buffer->info[j].codepoint);
+ unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint);
if (lig_index == NOT_COVERED) return TRACE_RETURN (false);
const LigatureArray& lig_array = this+ligatureArray;
@@ -1152,11 +1161,11 @@ struct MarkLigPosFormat1
* can directly use the component index. If not, we attach the mark
* glyph to the last component of the ligature. */
unsigned int comp_index;
- unsigned int lig_id = get_lig_id (c->buffer->info[j]);
- unsigned int mark_id = get_lig_id (c->buffer->cur());
- unsigned int mark_comp = get_lig_comp (c->buffer->cur());
+ unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]);
+ unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
if (lig_id && lig_id == mark_id && mark_comp > 0)
- comp_index = MIN (comp_count, get_lig_comp (c->buffer->cur())) - 1;
+ comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
else
comp_index = comp_count - 1;
@@ -1240,22 +1249,23 @@ struct MarkMarkPosFormat1
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- unsigned int mark1_index = (this+mark1Coverage).get_coverage (c->buffer->cur().codepoint);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint);
if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
- hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1);
skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
if (!skippy_iter.prev ()) return TRACE_RETURN (false);
- if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) { return TRACE_RETURN (false); }
+ if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return TRACE_RETURN (false); }
unsigned int j = skippy_iter.idx;
- unsigned int id1 = get_lig_id (c->buffer->cur());
- unsigned int id2 = get_lig_id (c->buffer->info[j]);
- unsigned int comp1 = get_lig_comp (c->buffer->cur());
- unsigned int comp2 = get_lig_comp (c->buffer->info[j]);
+ unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]);
+ unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur());
+ unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]);
if (likely (id1 == id2)) {
if (id1 == 0) /* Marks belonging to the same base. */
@@ -1273,7 +1283,7 @@ struct MarkMarkPosFormat1
return TRACE_RETURN (false);
good:
- unsigned int mark2_index = (this+mark2Coverage).get_coverage (c->buffer->info[j].codepoint);
+ unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint);
if (mark2_index == NOT_COVERED) return TRACE_RETURN (false);
return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
@@ -1434,12 +1444,6 @@ struct PosLookup : Lookup
return false;
}
- inline hb_is_inplace_context_t::return_t is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- return TRACE_RETURN (true);
- }
-
inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
@@ -1505,7 +1509,7 @@ typedef OffsetListOf<PosLookup> PosLookupList;
struct GPOS : GSUBGPOS
{
- static const hb_tag_t Tag = HB_OT_TAG_GPOS;
+ static const hb_tag_t tableTag = HB_OT_TAG_GPOS;
inline const PosLookup& get_lookup (unsigned int i) const
{ return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
@@ -1591,9 +1595,7 @@ GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
for (unsigned int i = 0; i < len; i++)
fix_mark_attachment (pos, i, direction);
- HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
- HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
- HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
+ _hb_buffer_deallocate_gsubgpos_vars (buffer);
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
index 6ab1a2b921..76b4f33c70 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
@@ -37,12 +37,6 @@ namespace OT {
struct SingleSubstFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -121,12 +115,6 @@ struct SingleSubstFormat1
struct SingleSubstFormat2
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -263,13 +251,6 @@ struct SingleSubst
struct Sequence
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- /* For len==0 we don't do anything, so it's harmless. */
- return TRACE_RETURN (substitute.len <= 1);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -291,8 +272,8 @@ struct Sequence
TRACE_APPLY (this);
if (unlikely (!substitute.len)) return TRACE_RETURN (false);
- unsigned int klass = c->buffer->cur().glyph_props() &
- HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
+ unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ?
+ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
unsigned int count = substitute.len;
if (count == 1) /* Special-case to make it in-place. */
{
@@ -301,7 +282,7 @@ struct Sequence
else
{
for (unsigned int i = 0; i < count; i++) {
- set_lig_props_for_component (c->buffer->cur(), i);
+ _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i);
c->output_glyph (substitute.array[i], klass);
}
c->buffer->skip_glyph ();
@@ -334,18 +315,6 @@ struct Sequence
struct MultipleSubstFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- /* Some tools generate MultipleSubst with each substitute having length 1!
- * So, check them. */
- unsigned int count = sequence.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+sequence[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -471,12 +440,6 @@ typedef ArrayOf<GlyphID> AlternateSet; /* Array of alternate GlyphIDs--in
struct AlternateSubstFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -663,27 +626,26 @@ struct Ligature
unsigned int count = component.len;
if (unlikely (count < 1)) return TRACE_RETURN (false);
- unsigned int end_offset = 0;
bool is_mark_ligature = false;
unsigned int total_component_count = 0;
+ unsigned int match_length = 0;
+ unsigned int match_positions[MAX_CONTEXT_LENGTH];
+
if (likely (!match_input (c, count,
&component[1],
match_glyph,
NULL,
- &end_offset,
+ &match_length,
+ match_positions,
&is_mark_ligature,
&total_component_count)))
return TRACE_RETURN (false);
- /* Deal, we are forming the ligature. */
- c->buffer->merge_clusters (c->buffer->idx, c->buffer->idx + end_offset);
-
ligate_input (c,
count,
- &component[1],
- match_glyph,
- NULL,
+ match_positions,
+ match_length,
ligGlyph,
is_mark_ligature,
total_component_count);
@@ -797,12 +759,6 @@ struct LigatureSet
struct LigatureSubstFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- return TRACE_RETURN (false);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -951,12 +907,6 @@ struct ExtensionSubst : Extension<ExtensionSubst>
struct ReverseChainSingleSubstFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -1038,7 +988,9 @@ struct ReverseChainSingleSubstFormat1
1))
{
c->replace_glyph_inplace (substitute[index]);
- c->buffer->idx--; /* Reverse! */
+ /* Note: We DON'T decrease buffer->idx. The main loop does it
+ * for us. This is useful for preventing surprises if someone
+ * calls us through a Context lookup. */
return TRACE_RETURN (true);
}
@@ -1194,13 +1146,6 @@ struct SubstLookup : Lookup
return lookup_type_is_reverse (type);
}
- inline hb_is_inplace_context_t::return_t is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- c->set_recurse_func (dispatch_recurse_func<hb_is_inplace_context_t>);
- return TRACE_RETURN (dispatch (c));
- }
-
inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -1351,7 +1296,7 @@ typedef OffsetListOf<SubstLookup> SubstLookupList;
struct GSUB : GSUBGPOS
{
- static const hb_tag_t Tag = HB_OT_TAG_GSUB;
+ static const hb_tag_t tableTag = HB_OT_TAG_GSUB;
inline const SubstLookup& get_lookup (unsigned int i) const
{ return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); }
@@ -1373,15 +1318,15 @@ struct GSUB : GSUBGPOS
void
GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer)
{
- HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
- HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
- HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
+ _hb_buffer_allocate_gsubgpos_vars (buffer);
const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef;
unsigned int count = buffer->len;
- for (unsigned int i = 0; i < count; i++) {
- buffer->info[i].lig_props() = buffer->info[i].syllable() = 0;
- buffer->info[i].glyph_props() = gdef.get_glyph_props (buffer->info[i].codepoint);
+ for (unsigned int i = 0; i < count; i++)
+ {
+ _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint));
+ _hb_glyph_info_clear_lig_props (&buffer->info[i]);
+ buffer->info[i].syllable() = 0;
}
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
index 316f506f0d..bdd773e36b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
@@ -43,56 +43,6 @@ namespace OT {
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
"");
-
-
-#ifndef HB_DEBUG_IS_INPLACE
-#define HB_DEBUG_IS_INPLACE (HB_DEBUG+0)
-#endif
-
-#define TRACE_IS_INPLACE(this) \
- hb_auto_trace_t<HB_DEBUG_IS_INPLACE, bool> trace \
- (&c->debug_depth, c->get_name (), this, HB_FUNC, \
- "");
-
-struct hb_is_inplace_context_t
-{
- inline const char *get_name (void) { return "IS_INPLACE"; }
- static const unsigned int max_debug_depth = HB_DEBUG_IS_INPLACE;
- typedef bool return_t;
- typedef return_t (*recurse_func_t) (hb_is_inplace_context_t *c, unsigned int lookup_index);
- template <typename T>
- inline return_t dispatch (const T &obj) { return obj.is_inplace (this); }
- static return_t default_return_value (void) { return true; }
- bool stop_sublookup_iteration (return_t r) const { return !r; }
-
- return_t recurse (unsigned int lookup_index)
- {
- if (unlikely (nesting_level_left == 0 || !recurse_func))
- return default_return_value ();
-
- nesting_level_left--;
- bool ret = recurse_func (this, lookup_index);
- nesting_level_left++;
- return ret;
- }
-
- hb_face_t *face;
- recurse_func_t recurse_func;
- unsigned int nesting_level_left;
- unsigned int debug_depth;
-
- hb_is_inplace_context_t (hb_face_t *face_,
- unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
- face (face_),
- recurse_func (NULL),
- nesting_level_left (nesting_level_left_),
- debug_depth (0) {}
-
- void set_recurse_func (recurse_func_t func) { recurse_func = func; }
-};
-
-
-
#ifndef HB_DEBUG_CLOSURE
#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
#endif
@@ -401,7 +351,7 @@ struct hb_apply_context_t
{
unsigned int property;
- property = info.glyph_props();
+ property = _hb_glyph_info_get_glyph_props (&info);
if (!c->match_properties (info.codepoint, property, lookup_props))
return SKIP_YES;
@@ -409,7 +359,7 @@ struct hb_apply_context_t
if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
(ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) &&
(ignore_zwj || !_hb_glyph_info_is_zwj (&info)) &&
- !is_a_ligature (info)))
+ !_hb_glyph_info_ligated (&info)))
return SKIP_MAYBE;
return SKIP_NO;
@@ -610,36 +560,47 @@ struct hb_apply_context_t
{
unsigned int property;
- property = info->glyph_props();
+ property = _hb_glyph_info_get_glyph_props (info);
return match_properties (info->codepoint, property, lookup_props);
}
- inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const
+ inline void _set_glyph_props (hb_codepoint_t glyph_index,
+ unsigned int class_guess = 0,
+ bool ligature = false) const
{
+ unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
+ HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
+ add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
+ if (ligature)
+ add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
if (likely (has_glyph_classes))
- buffer->cur().glyph_props() = gdef.get_glyph_props (glyph_index);
+ _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
else if (class_guess)
- buffer->cur().glyph_props() = class_guess;
+ _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess);
}
- inline void output_glyph (hb_codepoint_t glyph_index,
- unsigned int class_guess = 0) const
+ inline void replace_glyph (hb_codepoint_t glyph_index) const
{
- set_class (glyph_index, class_guess);
- buffer->output_glyph (glyph_index);
+ _set_glyph_props (glyph_index);
+ buffer->replace_glyph (glyph_index);
}
- inline void replace_glyph (hb_codepoint_t glyph_index,
- unsigned int class_guess = 0) const
+ inline void replace_glyph_inplace (hb_codepoint_t glyph_index) const
{
- set_class (glyph_index, class_guess);
+ _set_glyph_props (glyph_index);
+ buffer->cur().codepoint = glyph_index;
+ }
+ inline void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
+ unsigned int class_guess) const
+ {
+ _set_glyph_props (glyph_index, class_guess, true);
buffer->replace_glyph (glyph_index);
}
- inline void replace_glyph_inplace (hb_codepoint_t glyph_index,
- unsigned int class_guess = 0) const
+ inline void output_glyph (hb_codepoint_t glyph_index,
+ unsigned int class_guess) const
{
- set_class (glyph_index, class_guess);
- buffer->cur().codepoint = glyph_index;
+ _set_glyph_props (glyph_index, class_guess);
+ buffer->output_glyph (glyph_index);
}
};
@@ -752,13 +713,18 @@ static inline bool match_input (hb_apply_context_t *c,
const USHORT input[], /* Array of input values--start with second glyph */
match_func_t match_func,
const void *match_data,
- unsigned int *end_offset = NULL,
+ unsigned int *end_offset,
+ unsigned int match_positions[MAX_CONTEXT_LENGTH],
bool *p_is_mark_ligature = NULL,
unsigned int *p_total_component_count = NULL)
{
TRACE_APPLY (NULL);
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
+ if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false);
+
+ hb_buffer_t *buffer = c->buffer;
+
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, count - 1);
skippy_iter.set_match_func (match_func, match_data, input);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
@@ -780,20 +746,23 @@ static inline bool match_input (hb_apply_context_t *c,
* ligate with a conjunct...)
*/
- bool is_mark_ligature = !!(c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+ bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur());
unsigned int total_component_count = 0;
- total_component_count += get_lig_num_comps (c->buffer->cur());
+ total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
- unsigned int first_lig_id = get_lig_id (c->buffer->cur());
- unsigned int first_lig_comp = get_lig_comp (c->buffer->cur());
+ unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
+ match_positions[0] = buffer->idx;
for (unsigned int i = 1; i < count; i++)
{
if (!skippy_iter.next ()) return TRACE_RETURN (false);
- unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]);
- unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx]);
+ match_positions[i] = skippy_iter.idx;
+
+ unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]);
+ unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]);
if (first_lig_id && first_lig_comp) {
/* If first component was attached to a previous ligature component,
@@ -809,12 +778,11 @@ static inline bool match_input (hb_apply_context_t *c,
return TRACE_RETURN (false);
}
- is_mark_ligature = is_mark_ligature && (c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
- total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx]);
+ is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]);
+ total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]);
}
- if (end_offset)
- *end_offset = skippy_iter.idx - c->buffer->idx + 1;
+ *end_offset = skippy_iter.idx - buffer->idx + 1;
if (p_is_mark_ligature)
*p_is_mark_ligature = is_mark_ligature;
@@ -825,17 +793,18 @@ static inline bool match_input (hb_apply_context_t *c,
return TRACE_RETURN (true);
}
static inline void ligate_input (hb_apply_context_t *c,
- unsigned int count, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
- match_func_t match_func,
- const void *match_data,
+ unsigned int count, /* Including the first glyph */
+ unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */
+ unsigned int match_length,
hb_codepoint_t lig_glyph,
bool is_mark_ligature,
unsigned int total_component_count)
{
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
- skippy_iter.set_match_func (match_func, match_data, input);
- if (skippy_iter.has_no_chance ()) return;
+ TRACE_APPLY (NULL);
+
+ hb_buffer_t *buffer = c->buffer;
+
+ buffer->merge_clusters (buffer->idx, buffer->idx + match_length);
/*
* - If it *is* a mark ligature, we don't allocate a new ligature id, and leave
@@ -866,48 +835,49 @@ static inline void ligate_input (hb_apply_context_t *c,
*/
unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
- unsigned int lig_id = is_mark_ligature ? 0 : allocate_lig_id (c->buffer);
- unsigned int last_lig_id = get_lig_id (c->buffer->cur());
- unsigned int last_num_components = get_lig_num_comps (c->buffer->cur());
+ unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer);
+ unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
unsigned int components_so_far = last_num_components;
if (!is_mark_ligature)
{
- set_lig_props_for_ligature (c->buffer->cur(), lig_id, total_component_count);
- if (_hb_glyph_info_get_general_category (&c->buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
- _hb_glyph_info_set_general_category (&c->buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
+ _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count);
+ if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+ {
+ _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
+ _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0);
+ }
}
- c->replace_glyph (lig_glyph, klass);
+ c->replace_glyph_with_ligature (lig_glyph, klass);
for (unsigned int i = 1; i < count; i++)
{
- if (!skippy_iter.next ()) return;
-
- while (c->buffer->idx < skippy_iter.idx)
+ while (buffer->idx < match_positions[i])
{
if (!is_mark_ligature) {
unsigned int new_lig_comp = components_so_far - last_num_components +
- MIN (MAX (get_lig_comp (c->buffer->cur()), 1u), last_num_components);
- set_lig_props_for_mark (c->buffer->cur(), lig_id, new_lig_comp);
+ MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->cur()), 1u), last_num_components);
+ _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
}
- c->buffer->next_glyph ();
+ buffer->next_glyph ();
}
- last_lig_id = get_lig_id (c->buffer->cur());
- last_num_components = get_lig_num_comps (c->buffer->cur());
+ last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
components_so_far += last_num_components;
/* Skip the base glyph */
- c->buffer->idx++;
+ buffer->idx++;
}
if (!is_mark_ligature && last_lig_id) {
/* Re-adjust components for any marks following. */
- for (unsigned int i = c->buffer->idx; i < c->buffer->len; i++) {
- if (last_lig_id == get_lig_id (c->buffer->info[i])) {
+ for (unsigned int i = buffer->idx; i < buffer->len; i++) {
+ if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) {
unsigned int new_lig_comp = components_so_far - last_num_components +
- MIN (MAX (get_lig_comp (c->buffer->info[i]), 1u), last_num_components);
- set_lig_props_for_mark (c->buffer->info[i], lig_id, new_lig_comp);
+ MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->info[i]), 1u), last_num_components);
+ _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp);
} else
break;
}
@@ -982,99 +952,82 @@ static inline void recurse_lookups (context_t *c,
static inline bool apply_lookup (hb_apply_context_t *c,
unsigned int count, /* Including the first glyph */
- const USHORT input[], /* Array of input values--start with second glyph */
- match_func_t match_func,
- const void *match_data,
+ unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */
unsigned int lookupCount,
- const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */)
+ const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
+ unsigned int match_length)
{
TRACE_APPLY (NULL);
- unsigned int end = c->buffer->len;
- if (unlikely (count == 0 || c->buffer->idx + count > end))
- return TRACE_RETURN (false);
-
- /* TODO We don't support lookupRecord arrays that are not increasing:
- * Should be easy for in_place ones at least. */
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int end;
- /* Note: If sublookup is reverse, it will underflow after the first loop
- * and we jump out of it. Not entirely disastrous. So we don't check
- * for reverse lookup here.
- */
+ /* All positions are distance from beginning of *output* buffer.
+ * Adjust. */
+ {
+ unsigned int bl = buffer->backtrack_len ();
+ end = bl + match_length;
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
- skippy_iter.set_match_func (match_func, match_data, input);
- uint8_t syllable = c->buffer->cur().syllable();
+ int delta = bl - buffer->idx;
+ /* Convert positions to new indexing. */
+ for (unsigned int j = 0; j < count; j++)
+ match_positions[j] += delta;
+ }
- unsigned int i = 0;
- if (lookupCount && 0 == lookupRecord->sequenceIndex)
+ for (unsigned int i = 0; i < lookupCount; i++)
{
- unsigned int old_pos = c->buffer->idx;
+ unsigned int idx = lookupRecord[i].sequenceIndex;
+ if (idx >= count)
+ continue;
- /* Apply a lookup */
- bool done = c->recurse (lookupRecord->lookupListIndex);
+ buffer->move_to (match_positions[idx]);
- lookupRecord++;
- lookupCount--;
- i++;
+ unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len ();
+ if (!c->recurse (lookupRecord[i].lookupListIndex))
+ continue;
- if (!done)
- goto not_applied;
- else
- {
- if (c->table_index == 1)
- c->buffer->idx = old_pos + 1;
- /* Reinitialize iterator. */
- hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i);
- tmp.set_syllable (syllable);
- skippy_iter = tmp;
- }
- }
- else
- {
- not_applied:
- /* No lookup applied for this index */
- c->buffer->next_glyph ();
- i++;
- }
- while (i < count)
- {
- if (!skippy_iter.next ()) return TRACE_RETURN (true);
- while (c->buffer->idx < skippy_iter.idx)
- c->buffer->next_glyph ();
+ unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len ();
+ int delta = new_len - orig_len;
- if (lookupCount && i == lookupRecord->sequenceIndex)
- {
- unsigned int old_pos = c->buffer->idx;
+ if (!delta)
+ continue;
- /* Apply a lookup */
- bool done = c->recurse (lookupRecord->lookupListIndex);
+ /* Recursed lookup changed buffer len. Adjust. */
- lookupRecord++;
- lookupCount--;
- i++;
+ /* end can't go back past the current match position. */
+ end = MAX ((int) match_positions[idx] + 1, int (end) + delta);
- if (!done)
- goto not_applied2;
- else
- {
- if (c->table_index == 1)
- c->buffer->idx = old_pos + 1;
- /* Reinitialize iterator. */
- hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i);
- tmp.set_syllable (syllable);
- skippy_iter = tmp;
- }
+ unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */
+
+ if (delta > 0)
+ {
+ if (unlikely (delta + count > MAX_CONTEXT_LENGTH))
+ break;
}
else
{
- not_applied2:
- /* No lookup applied for this index */
- c->buffer->next_glyph ();
- i++;
+ /* NOTE: delta is negative. */
+ delta = MAX (delta, (int) next - (int) count);
+ next -= delta;
}
+
+ /* Shift! */
+ memmove (match_positions + next + delta, match_positions + next,
+ (count - next) * sizeof (match_positions[0]));
+ next += delta;
+ count += delta;
+
+ /* Fill in new entries. */
+ for (unsigned int j = idx + 1; j < next; j++)
+ match_positions[j] = match_positions[j - 1] + 1;
+
+ /* And fixup the rest. */
+ for (; next < count; next++)
+ match_positions[next] += delta;
}
+ buffer->move_to (end);
+
return TRACE_RETURN (true);
}
@@ -1146,28 +1099,20 @@ static inline bool context_apply_lookup (hb_apply_context_t *c,
const LookupRecord lookupRecord[],
ContextApplyLookupContext &lookup_context)
{
+ unsigned int match_length = 0;
+ unsigned int match_positions[MAX_CONTEXT_LENGTH];
return match_input (c,
inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data)
+ lookup_context.funcs.match, lookup_context.match_data,
+ &match_length, match_positions)
&& apply_lookup (c,
- inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data,
- lookupCount, lookupRecord);
+ inputCount, match_positions,
+ lookupCount, lookupRecord,
+ match_length);
}
struct Rule
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
- unsigned int count = lookupCount;
- for (unsigned int i = 0; i < count; i++)
- if (!c->recurse (lookupRecord[i].lookupListIndex))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE (this);
@@ -1227,16 +1172,6 @@ struct Rule
struct RuleSet
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- unsigned int num_rules = rule.len;
- for (unsigned int i = 0; i < num_rules; i++)
- if (!(this+rule[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE (this);
@@ -1293,16 +1228,6 @@ struct RuleSet
struct ContextFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- unsigned int count = ruleSet.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+ruleSet[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -1389,16 +1314,6 @@ struct ContextFormat1
struct ContextFormat2
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- unsigned int count = ruleSet.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+ruleSet[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -1494,17 +1409,6 @@ struct ContextFormat2
struct ContextFormat3
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
- unsigned int count = lookupCount;
- for (unsigned int i = 0; i < count; i++)
- if (!c->recurse (lookupRecord[i].lookupListIndex))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -1726,39 +1630,27 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
const LookupRecord lookupRecord[],
ChainContextApplyLookupContext &lookup_context)
{
- unsigned int lookahead_offset = 0;
+ unsigned int match_length = 0;
+ unsigned int match_positions[MAX_CONTEXT_LENGTH];
return match_input (c,
inputCount, input,
lookup_context.funcs.match, lookup_context.match_data[1],
- &lookahead_offset)
+ &match_length, match_positions)
&& match_backtrack (c,
backtrackCount, backtrack,
lookup_context.funcs.match, lookup_context.match_data[0])
&& match_lookahead (c,
lookaheadCount, lookahead,
lookup_context.funcs.match, lookup_context.match_data[2],
- lookahead_offset)
+ match_length)
&& apply_lookup (c,
- inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data[1],
- lookupCount, lookupRecord);
+ inputCount, match_positions,
+ lookupCount, lookupRecord,
+ match_length);
}
struct ChainRule
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
- const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
- const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
- unsigned int count = lookup.len;
- for (unsigned int i = 0; i < count; i++)
- if (!c->recurse (lookup.array[i].lookupListIndex))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE (this);
@@ -1844,16 +1736,6 @@ struct ChainRule
struct ChainRuleSet
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- unsigned int num_rules = rule.len;
- for (unsigned int i = 0; i < num_rules; i++)
- if (!(this+rule[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE (this);
@@ -1907,16 +1789,6 @@ struct ChainRuleSet
struct ChainContextFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- unsigned int count = ruleSet.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+ruleSet[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -2000,16 +1872,6 @@ struct ChainContextFormat1
struct ChainContextFormat2
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- unsigned int count = ruleSet.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+ruleSet[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -2134,20 +1996,6 @@ struct ChainContextFormat2
struct ChainContextFormat3
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
- const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
- const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
-
- unsigned int count = lookup.len;
- for (unsigned int i = 0; i < count; i++)
- if (!c->recurse (lookup.array[i].lookupListIndex))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh
new file mode 100644
index 0000000000..79eb859566
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh
@@ -0,0 +1,229 @@
+/*
+ * Copyright © 2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_JSTF_TABLE_HH
+#define HB_OT_LAYOUT_JSTF_TABLE_HH
+
+#include "hb-open-type-private.hh"
+#include "hb-ot-layout-gpos-table.hh"
+
+
+namespace OT {
+
+
+/*
+ * JstfModList -- Justification Modification List Tables
+ */
+
+typedef IndexArray JstfModList;
+
+
+/*
+ * JstfMax -- Justification Maximum Table
+ */
+
+typedef OffsetListOf<PosLookup> JstfMax;
+
+
+/*
+ * JstfPriority -- Justification Priority Table
+ */
+
+struct JstfPriority
+{
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) &&
+ shrinkageEnableGSUB.sanitize (c, this) &&
+ shrinkageDisableGSUB.sanitize (c, this) &&
+ shrinkageEnableGPOS.sanitize (c, this) &&
+ shrinkageDisableGPOS.sanitize (c, this) &&
+ shrinkageJstfMax.sanitize (c, this) &&
+ extensionEnableGSUB.sanitize (c, this) &&
+ extensionDisableGSUB.sanitize (c, this) &&
+ extensionEnableGPOS.sanitize (c, this) &&
+ extensionDisableGPOS.sanitize (c, this) &&
+ extensionJstfMax.sanitize (c, this));
+ }
+
+ protected:
+ OffsetTo<JstfModList>
+ shrinkageEnableGSUB; /* Offset to Shrinkage Enable GSUB
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfModList>
+ shrinkageDisableGSUB; /* Offset to Shrinkage Disable GSUB
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfModList>
+ shrinkageEnableGPOS; /* Offset to Shrinkage Enable GPOS
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfModList>
+ shrinkageDisableGPOS; /* Offset to Shrinkage Disable GPOS
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfMax>
+ shrinkageJstfMax; /* Offset to Shrinkage JstfMax table--
+ * from beginning of JstfPriority table
+ * --may be NULL */
+ OffsetTo<JstfModList>
+ extensionEnableGSUB; /* Offset to Extension Enable GSUB
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfModList>
+ extensionDisableGSUB; /* Offset to Extension Disable GSUB
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfModList>
+ extensionEnableGPOS; /* Offset to Extension Enable GPOS
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfModList>
+ extensionDisableGPOS; /* Offset to Extension Disable GPOS
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfMax>
+ extensionJstfMax; /* Offset to Extension JstfMax table--
+ * from beginning of JstfPriority table
+ * --may be NULL */
+
+ public:
+ DEFINE_SIZE_STATIC (20);
+};
+
+
+/*
+ * JstfLangSys -- Justification Language System Table
+ */
+
+struct JstfLangSys : OffsetListOf<JstfPriority>
+{
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<JstfLangSys>::sanitize_closure_t * = NULL) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (OffsetListOf<JstfPriority>::sanitize (c));
+ }
+};
+
+
+/*
+ * ExtenderGlyphs -- Extender Glyph Table
+ */
+
+typedef SortedArrayOf<GlyphID> ExtenderGlyphs;
+
+
+/*
+ * JstfScript -- The Justification Table
+ */
+
+struct JstfScript
+{
+ inline unsigned int get_lang_sys_count (void) const
+ { return langSys.len; }
+ inline const Tag& get_lang_sys_tag (unsigned int i) const
+ { return langSys.get_tag (i); }
+ inline unsigned int get_lang_sys_tags (unsigned int start_offset,
+ unsigned int *lang_sys_count /* IN/OUT */,
+ hb_tag_t *lang_sys_tags /* OUT */) const
+ { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
+ inline const JstfLangSys& get_lang_sys (unsigned int i) const
+ {
+ if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys ();
+ return this+langSys[i].offset;
+ }
+ inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
+ { return langSys.find_index (tag, index); }
+
+ inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
+ inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
+
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<JstfScript>::sanitize_closure_t * = NULL) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (extenderGlyphs.sanitize (c, this) &&
+ defaultLangSys.sanitize (c, this) &&
+ langSys.sanitize (c, this));
+ }
+
+ protected:
+ OffsetTo<ExtenderGlyphs>
+ extenderGlyphs; /* Offset to ExtenderGlyph table--from beginning
+ * of JstfScript table-may be NULL */
+ OffsetTo<JstfLangSys>
+ defaultLangSys; /* Offset to DefaultJstfLangSys table--from
+ * beginning of JstfScript table--may be Null */
+ RecordArrayOf<JstfLangSys>
+ langSys; /* Array of JstfLangSysRecords--listed
+ * alphabetically by LangSysTag */
+ public:
+ DEFINE_SIZE_ARRAY (6, langSys);
+};
+
+
+/*
+ * JSTF -- The Justification Table
+ */
+
+struct JSTF
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_JSTF;
+
+ inline unsigned int get_script_count (void) const
+ { return scriptList.len; }
+ inline const Tag& get_script_tag (unsigned int i) const
+ { return scriptList.get_tag (i); }
+ inline unsigned int get_script_tags (unsigned int start_offset,
+ unsigned int *script_count /* IN/OUT */,
+ hb_tag_t *script_tags /* OUT */) const
+ { return scriptList.get_tags (start_offset, script_count, script_tags); }
+ inline const JstfScript& get_script (unsigned int i) const
+ { return this+scriptList[i].offset; }
+ inline bool find_script_index (hb_tag_t tag, unsigned int *index) const
+ { return scriptList.find_index (tag, index); }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
+ scriptList.sanitize (c, this));
+ }
+
+ protected:
+ FixedVersion version; /* Version of the JSTF table--initially set
+ * to 0x00010000 */
+ RecordArrayOf<JstfScript>
+ scriptList; /* Array of JstfScripts--listed
+ * alphabetically by ScriptTag */
+ public:
+ DEFINE_SIZE_ARRAY (6, scriptList);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_JSTF_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
index c5ba8b4b4d..0a0a54b25d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
@@ -1,6 +1,6 @@
/*
* Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2012 Google, Inc.
+ * Copyright © 2012,2013 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -31,47 +31,184 @@
#include "hb-private.hh"
-#include "hb-ot-layout.h"
-
#include "hb-font-private.hh"
#include "hb-buffer-private.hh"
#include "hb-set-private.hh"
-/* buffer var allocations, used during the GSUB/GPOS processing */
-#define glyph_props() var1.u16[0] /* GDEF glyph properties */
-#define syllable() var1.u8[2] /* GSUB/GPOS shaping boundaries */
-#define lig_props() var1.u8[3] /* GSUB/GPOS ligature tracking */
+/*
+ * GDEF
+ */
+
+typedef enum
+{
+ /* The following three match LookupFlags::Ignore* numbers. */
+ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 0x02u,
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 0x04u,
+ HB_OT_LAYOUT_GLYPH_PROPS_MARK = 0x08u,
+
+ /* The following are used internally; not derived from GDEF. */
+ HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED = 0x10u,
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATED = 0x20u,
+
+ HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATED
+} hb_ot_layout_glyph_class_mask_t;
+
+
+/*
+ * GSUB/GPOS
+ */
+
+HB_INTERNAL hb_bool_t
+hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
+ unsigned int lookup_index,
+ const hb_codepoint_t *glyphs,
+ unsigned int glyphs_length,
+ hb_bool_t zero_context);
+
+
+/* Should be called before all the substitute_lookup's are done. */
+HB_INTERNAL void
+hb_ot_layout_substitute_start (hb_font_t *font,
+ hb_buffer_t *buffer);
+
+
+struct hb_ot_layout_lookup_accelerator_t;
+
+namespace OT {
+ struct hb_apply_context_t;
+ struct SubstLookup;
+}
+
+HB_INTERNAL void
+hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
+ const OT::SubstLookup &lookup,
+ const hb_ot_layout_lookup_accelerator_t &accel);
+
+
+/* Should be called after all the substitute_lookup's are done */
+HB_INTERNAL void
+hb_ot_layout_substitute_finish (hb_font_t *font,
+ hb_buffer_t *buffer);
+
+
+/* Should be called before all the position_lookup's are done. Resets positions to zero. */
+HB_INTERNAL void
+hb_ot_layout_position_start (hb_font_t *font,
+ hb_buffer_t *buffer);
+
+/* Should be called after all the position_lookup's are done */
+HB_INTERNAL void
+hb_ot_layout_position_finish (hb_font_t *font,
+ hb_buffer_t *buffer);
+
+
+
+/*
+ * hb_ot_layout_t
+ */
+
+namespace OT {
+ struct GDEF;
+ struct GSUB;
+ struct GPOS;
+}
+
+struct hb_ot_layout_lookup_accelerator_t
+{
+ template <typename TLookup>
+ inline void init (const TLookup &lookup)
+ {
+ digest.init ();
+ lookup.add_coverage (&digest);
+ }
+
+ template <typename TLookup>
+ inline void fini (const TLookup &lookup)
+ {
+ }
+
+ hb_set_digest_t digest;
+};
+
+struct hb_ot_layout_t
+{
+ hb_blob_t *gdef_blob;
+ hb_blob_t *gsub_blob;
+ hb_blob_t *gpos_blob;
+
+ const struct OT::GDEF *gdef;
+ const struct OT::GSUB *gsub;
+ const struct OT::GPOS *gpos;
+
+ unsigned int gsub_lookup_count;
+ unsigned int gpos_lookup_count;
+
+ hb_ot_layout_lookup_accelerator_t *gsub_accels;
+ hb_ot_layout_lookup_accelerator_t *gpos_accels;
+};
+
+
+HB_INTERNAL hb_ot_layout_t *
+_hb_ot_layout_create (hb_face_t *face);
+
+HB_INTERNAL void
+_hb_ot_layout_destroy (hb_ot_layout_t *layout);
+
+
+#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
+
+
+/*
+ * Buffer var routines.
+ */
/* buffer var allocations, used during the entire shaping process */
#define unicode_props0() var2.u8[0]
#define unicode_props1() var2.u8[1]
+/* buffer var allocations, used during the GSUB/GPOS processing */
+#define glyph_props() var1.u16[0] /* GDEF glyph properties */
+#define lig_props() var1.u8[2] /* GSUB/GPOS ligature tracking */
+#define syllable() var1.u8[3] /* GSUB/GPOS shaping boundaries */
+
+/* unicode_props */
+
+enum {
+ MASK0_ZWJ = 0x20u,
+ MASK0_ZWNJ = 0x40u,
+ MASK0_IGNORABLE = 0x80u,
+ MASK0_GEN_CAT = 0x1Fu
+};
inline void
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
{
+ /* XXX This shouldn't be inlined, or at least not while is_default_ignorable() is inline. */
info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
- (unicode->is_default_ignorable (info->codepoint) ? 0x80 : 0) |
- (info->codepoint == 0x200C ? 0x40 : 0) |
- (info->codepoint == 0x200D ? 0x20 : 0);
+ (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) |
+ (info->codepoint == 0x200C ? MASK0_ZWNJ : 0) |
+ (info->codepoint == 0x200D ? MASK0_ZWJ : 0);
info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
}
inline void
-_hb_glyph_info_set_general_category (hb_glyph_info_t *info, hb_unicode_general_category_t gen_cat)
+_hb_glyph_info_set_general_category (hb_glyph_info_t *info,
+ hb_unicode_general_category_t gen_cat)
{
- info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~0x1F);
+ info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_GEN_CAT);
}
inline hb_unicode_general_category_t
_hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
{
- return (hb_unicode_general_category_t) (info->unicode_props0() & 0x1F);
+ return (hb_unicode_general_category_t) (info->unicode_props0() & MASK0_GEN_CAT);
}
inline void
-_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, unsigned int modified_class)
+_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info,
+ unsigned int modified_class)
{
info->unicode_props1() = modified_class;
}
@@ -85,43 +222,28 @@ _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
inline hb_bool_t
_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
{
- return !!(info->unicode_props0() & 0x80);
+ return !!(info->unicode_props0() & MASK0_IGNORABLE);
}
inline hb_bool_t
_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
{
- return !!(info->unicode_props0() & 0x40);
+ return !!(info->unicode_props0() & MASK0_ZWNJ);
}
inline hb_bool_t
_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
{
- return !!(info->unicode_props0() & 0x20);
+ return !!(info->unicode_props0() & MASK0_ZWJ);
}
+inline void
+_hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
+{
+ info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ;
+}
-#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
-
-/*
- * GDEF
- */
-
-typedef enum {
- HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED = 1 << HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED,
- HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 1 << HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH,
- HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 1 << HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE,
- HB_OT_LAYOUT_GLYPH_PROPS_MARK = 1 << HB_OT_LAYOUT_GLYPH_CLASS_MARK,
- HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT = 1 << HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT
-} hb_ot_layout_glyph_class_mask_t;
-
-
-
-/*
- * GSUB/GPOS
- */
-
-/* lig_id / lig_comp
+/* lig_props: aka lig_id / lig_comp
*
* When a ligature is formed:
*
@@ -131,7 +253,9 @@ typedef enum {
* - The marks get lig_comp > 0, reflecting which component of the ligature
* they were applied to.
* - This is used in GPOS to attach marks to the right component of a ligature
- * in MarkLigPos.
+ * in MarkLigPos,
+ * - Note that when marks are ligated together, much of the above is skipped
+ * and the current lig_id reused.
*
* When a multiple-substitution is done:
*
@@ -141,156 +265,159 @@ typedef enum {
* multiple substitution in MarkBasePos.
*
* The numbers are also used in GPOS to do mark-to-mark positioning only
- * to marks that belong to the same component of a ligature in MarkMarPos.
+ * to marks that belong to the same component of the same ligature.
*/
+
+static inline void
+_hb_glyph_info_clear_lig_props (hb_glyph_info_t *info)
+{
+ info->lig_props() = 0;
+}
+
#define IS_LIG_BASE 0x10
+
static inline void
-set_lig_props_for_ligature (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_num_comps)
+_hb_glyph_info_set_lig_props_for_ligature (hb_glyph_info_t *info,
+ unsigned int lig_id,
+ unsigned int lig_num_comps)
{
- info.lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F);
+ info->lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F);
}
+
static inline void
-set_lig_props_for_mark (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_comp)
+_hb_glyph_info_set_lig_props_for_mark (hb_glyph_info_t *info,
+ unsigned int lig_id,
+ unsigned int lig_comp)
{
- info.lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
+ info->lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
}
+
static inline void
-set_lig_props_for_component (hb_glyph_info_t &info, unsigned int comp)
+_hb_glyph_info_set_lig_props_for_component (hb_glyph_info_t *info, unsigned int comp)
{
- set_lig_props_for_mark (info, 0, comp);
+ _hb_glyph_info_set_lig_props_for_mark (info, 0, comp);
}
static inline unsigned int
-get_lig_id (const hb_glyph_info_t &info)
+_hb_glyph_info_get_lig_id (const hb_glyph_info_t *info)
{
- return info.lig_props() >> 5;
+ return info->lig_props() >> 5;
}
+
static inline bool
-is_a_ligature (const hb_glyph_info_t &info)
+_hb_glyph_info_ligated_internal (const hb_glyph_info_t *info)
{
- return !!(info.lig_props() & IS_LIG_BASE);
+ return !!(info->lig_props() & IS_LIG_BASE);
}
+
static inline unsigned int
-get_lig_comp (const hb_glyph_info_t &info)
+_hb_glyph_info_get_lig_comp (const hb_glyph_info_t *info)
{
- if (is_a_ligature (info))
+ if (_hb_glyph_info_ligated_internal (info))
return 0;
else
- return info.lig_props() & 0x0F;
+ return info->lig_props() & 0x0F;
}
+
static inline unsigned int
-get_lig_num_comps (const hb_glyph_info_t &info)
+_hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info)
{
- if ((info.glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) && is_a_ligature (info))
- return info.lig_props() & 0x0F;
+ if ((info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) &&
+ _hb_glyph_info_ligated_internal (info))
+ return info->lig_props() & 0x0F;
else
return 1;
}
-static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
+static inline uint8_t
+_hb_allocate_lig_id (hb_buffer_t *buffer) {
uint8_t lig_id = buffer->next_serial () & 0x07;
if (unlikely (!lig_id))
- lig_id = allocate_lig_id (buffer); /* in case of overflow */
+ lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
return lig_id;
}
+/* glyph_props: */
-HB_INTERNAL hb_bool_t
-hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
- unsigned int lookup_index,
- const hb_codepoint_t *glyphs,
- unsigned int glyphs_length,
- hb_bool_t zero_context);
-
-
-/* Should be called before all the substitute_lookup's are done. */
-HB_INTERNAL void
-hb_ot_layout_substitute_start (hb_font_t *font,
- hb_buffer_t *buffer);
-
-
-struct hb_ot_layout_lookup_accelerator_t;
-
-namespace OT {
- struct hb_apply_context_t;
- struct SubstLookup;
+inline void
+_hb_glyph_info_set_glyph_props (hb_glyph_info_t *info, unsigned int props)
+{
+ info->glyph_props() = props;
}
-HB_INTERNAL void
-hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
- const OT::SubstLookup &lookup,
- const hb_ot_layout_lookup_accelerator_t &accel);
-
-
-/* Should be called after all the substitute_lookup's are done */
-HB_INTERNAL void
-hb_ot_layout_substitute_finish (hb_font_t *font,
- hb_buffer_t *buffer);
-
-
-/* Should be called before all the position_lookup's are done. Resets positions to zero. */
-HB_INTERNAL void
-hb_ot_layout_position_start (hb_font_t *font,
- hb_buffer_t *buffer);
-
-/* Should be called after all the position_lookup's are done */
-HB_INTERNAL void
-hb_ot_layout_position_finish (hb_font_t *font,
- hb_buffer_t *buffer);
-
-
-
-/*
- * hb_ot_layout_t
- */
-
-namespace OT {
- struct GDEF;
- struct GSUB;
- struct GPOS;
+inline unsigned int
+_hb_glyph_info_get_glyph_props (const hb_glyph_info_t *info)
+{
+ return info->glyph_props();
}
-struct hb_ot_layout_lookup_accelerator_t
+inline bool
+_hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info)
{
- template <typename TLookup>
- inline void init (const TLookup &lookup)
- {
- digest.init ();
- lookup.add_coverage (&digest);
- }
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
+}
- template <typename TLookup>
- inline void fini (const TLookup &lookup)
- {
- }
+inline bool
+_hb_glyph_info_is_ligature (const hb_glyph_info_t *info)
+{
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE);
+}
- hb_set_digest_t digest;
-};
+inline bool
+_hb_glyph_info_is_mark (const hb_glyph_info_t *info)
+{
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+}
-struct hb_ot_layout_t
+static inline bool
+_hb_glyph_info_substituted (const hb_glyph_info_t *info)
{
- hb_blob_t *gdef_blob;
- hb_blob_t *gsub_blob;
- hb_blob_t *gpos_blob;
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
+}
- const struct OT::GDEF *gdef;
- const struct OT::GSUB *gsub;
- const struct OT::GPOS *gpos;
+static inline bool
+_hb_glyph_info_ligated (const hb_glyph_info_t *info)
+{
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
+}
- unsigned int gsub_lookup_count;
- unsigned int gpos_lookup_count;
+/* Allocation / deallocation. */
- hb_ot_layout_lookup_accelerator_t *gsub_accels;
- hb_ot_layout_lookup_accelerator_t *gpos_accels;
-};
+inline void
+_hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer)
+{
+ HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0);
+ HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1);
+}
+inline void
+_hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer)
+{
+ HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1);
+}
-HB_INTERNAL hb_ot_layout_t *
-_hb_ot_layout_create (hb_face_t *face);
+inline void
+_hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer)
+{
+ HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
+ HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
+ HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
+}
-HB_INTERNAL void
-_hb_ot_layout_destroy (hb_ot_layout_t *layout);
+inline void
+_hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer)
+{
+ HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
+}
+/* Make sure no one directly touches our props... */
+#undef unicode_props0
+#undef unicode_props1
+#undef lig_props
+#undef glyph_props
#endif /* HB_OT_LAYOUT_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
index 520deff710..183726e63c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
@@ -33,6 +33,7 @@
#include "hb-ot-layout-gdef-table.hh"
#include "hb-ot-layout-gsub-table.hh"
#include "hb-ot-layout-gpos-table.hh"
+#include "hb-ot-layout-jstf-table.hh"
#include "hb-ot-map-private.hh"
@@ -413,6 +414,24 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face,
return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes);
}
+unsigned int
+hb_ot_layout_table_get_lookup_count (hb_face_t *face,
+ hb_tag_t table_tag)
+{
+ switch (table_tag)
+ {
+ case HB_OT_TAG_GSUB:
+ {
+ return hb_ot_layout_from_face (face)->gsub_lookup_count;
+ }
+ case HB_OT_TAG_GPOS:
+ {
+ return hb_ot_layout_from_face (face)->gpos_lookup_count;
+ }
+ }
+ return 0;
+}
+
static void
_hb_ot_layout_collect_lookups_lookups (hb_face_t *face,
hb_tag_t table_tag,
@@ -764,6 +783,7 @@ hb_ot_layout_get_size_params (hb_face_t *face,
struct GSUBProxy
{
static const unsigned int table_index = 0;
+ static const bool inplace = false;
typedef OT::SubstLookup Lookup;
GSUBProxy (hb_face_t *face) :
@@ -777,6 +797,7 @@ struct GSUBProxy
struct GPOSProxy
{
static const unsigned int table_index = 1;
+ static const bool inplace = true;
typedef OT::PosLookup Lookup;
GPOSProxy (hb_face_t *face) :
@@ -804,10 +825,9 @@ apply_string (OT::hb_apply_context_t *c,
const hb_ot_layout_lookup_accelerator_t &accel)
{
bool ret = false;
- OT::hb_is_inplace_context_t inplace_c (c->face);
- bool inplace = lookup.is_inplace (&inplace_c);
+ hb_buffer_t *buffer = c->buffer;
- if (unlikely (!c->buffer->len || !c->lookup_mask))
+ if (unlikely (!buffer->len || !c->lookup_mask))
return false;
c->set_lookup (lookup);
@@ -816,43 +836,43 @@ apply_string (OT::hb_apply_context_t *c,
{
/* in/out forward substitution/positioning */
if (Proxy::table_index == 0)
- c->buffer->clear_output ();
- c->buffer->idx = 0;
+ buffer->clear_output ();
+ buffer->idx = 0;
- while (c->buffer->idx < c->buffer->len)
+ while (buffer->idx < buffer->len)
{
- if (accel.digest.may_have (c->buffer->cur().codepoint) &&
- (c->buffer->cur().mask & c->lookup_mask) &&
+ if (accel.digest.may_have (buffer->cur().codepoint) &&
+ (buffer->cur().mask & c->lookup_mask) &&
apply_once (c, lookup))
ret = true;
else
- c->buffer->next_glyph ();
+ buffer->next_glyph ();
}
if (ret)
{
- if (!inplace)
- c->buffer->swap_buffers ();
+ if (!Proxy::inplace)
+ buffer->swap_buffers ();
else
- assert (!c->buffer->has_separate_output ());
+ assert (!buffer->has_separate_output ());
}
}
else
{
/* in-place backward substitution/positioning */
if (Proxy::table_index == 0)
- c->buffer->remove_output ();
- c->buffer->idx = c->buffer->len - 1;
+ buffer->remove_output ();
+ buffer->idx = buffer->len - 1;
do
{
- if (accel.digest.may_have (c->buffer->cur().codepoint) &&
- (c->buffer->cur().mask & c->lookup_mask) &&
+ if (accel.digest.may_have (buffer->cur().codepoint) &&
+ (buffer->cur().mask & c->lookup_mask) &&
apply_once (c, lookup))
ret = true;
- else
- c->buffer->idx--;
+ /* The reverse lookup doesn't "advance" cursor (for good reason). */
+ buffer->idx--;
}
- while ((int) c->buffer->idx >= 0);
+ while ((int) buffer->idx >= 0);
}
return ret;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
index 134f1a6c16..dfc7f2446f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
@@ -41,6 +41,7 @@ HB_BEGIN_DECLS
#define HB_OT_TAG_GDEF HB_TAG('G','D','E','F')
#define HB_OT_TAG_GSUB HB_TAG('G','S','U','B')
#define HB_OT_TAG_GPOS HB_TAG('G','P','O','S')
+#define HB_OT_TAG_JSTF HB_TAG('J','S','T','F')
/*
@@ -179,6 +180,11 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face,
unsigned int *lookup_count /* IN/OUT */,
unsigned int *lookup_indexes /* OUT */);
+unsigned int
+hb_ot_layout_table_get_lookup_count (hb_face_t *face,
+ hb_tag_t table_tag);
+
+
void
hb_ot_layout_collect_lookups (hb_face_t *face,
hb_tag_t table_tag,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
index 43856fa37e..559193c1ba 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
@@ -40,6 +40,9 @@ hb_ot_map_t::add_lookups (hb_face_t *face,
{
unsigned int lookup_indices[32];
unsigned int offset, len;
+ unsigned int table_lookup_count;
+
+ table_lookup_count = hb_ot_layout_table_get_lookup_count (face, table_tags[table_index]);
offset = 0;
do {
@@ -50,7 +53,10 @@ hb_ot_map_t::add_lookups (hb_face_t *face,
offset, &len,
lookup_indices);
- for (unsigned int i = 0; i < len; i++) {
+ for (unsigned int i = 0; i < len; i++)
+ {
+ if (lookup_indices[i] >= table_lookup_count)
+ continue;
hb_ot_map_t::lookup_map_t *lookup = lookups[table_index].push ();
if (unlikely (!lookup))
return;
@@ -175,7 +181,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
continue; /* Feature disabled, or not enough bits. */
- bool found = false;
+ hb_bool_t found = false;
unsigned int feature_index[2];
for (unsigned int table_index = 0; table_index < 2; table_index++)
found |= hb_ot_layout_language_find_feature (face,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
index 0ce3ebcc2a..e6d255579c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
@@ -41,7 +41,7 @@ namespace OT {
struct maxp
{
- static const hb_tag_t Tag = HB_OT_TAG_maxp;
+ static const hb_tag_t tableTag = HB_OT_TAG_maxp;
inline unsigned int get_num_glyphs (void) const {
return numGlyphs;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
index e36b0f7c97..07dc0565ca 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
@@ -74,7 +74,7 @@ struct NameRecord
struct name
{
- static const hb_tag_t Tag = HB_OT_TAG_name;
+ static const hb_tag_t tableTag = HB_OT_TAG_name;
inline unsigned int get_name (unsigned int platform_id,
unsigned int encoding_id,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
index a57e81a5ec..4f6c86e8ee 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
@@ -157,6 +157,11 @@ static const struct arabic_state_table_entry {
static void
+nuke_joiners (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+
+static void
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
@@ -176,6 +181,8 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
* TODO: Add test cases for these two.
*/
+ map->add_gsub_pause (nuke_joiners);
+
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
@@ -273,7 +280,8 @@ arabic_joining (hb_buffer_t *buffer)
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
if (entry->prev_action != NONE && prev != (unsigned int) -1)
- buffer->info[prev].arabic_shaping_action() = entry->prev_action;
+ for (; prev < i; prev++)
+ buffer->info[prev].arabic_shaping_action() = entry->prev_action;
buffer->info[i].arabic_shaping_action() = entry->curr_action;
@@ -314,6 +322,17 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan,
static void
+nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ if (_hb_glyph_info_is_zwj (&buffer->info[i]))
+ _hb_glyph_info_flip_joiners (&buffer->info[i]);
+}
+
+static void
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
index 39268b1453..3de5c203fa 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
@@ -43,23 +43,25 @@
* Not sure how to avoid duplication. */
enum indic_category_t {
OT_X = 0,
- OT_C,
- OT_V,
- OT_N,
- OT_H,
- OT_ZWNJ,
- OT_ZWJ,
- OT_M,
- OT_SM,
- OT_VD,
- OT_A,
- OT_NBSP,
- OT_DOTTEDCIRCLE, /* Not in the spec, but special in Uniscribe. /Very very/ special! */
- OT_RS, /* Register Shifter, used in Khmer OT spec */
- OT_Coeng,
- OT_Repha,
- OT_Ra, /* Not explicitly listed in the OT spec, but used in the grammar. */
- OT_CM
+ OT_C = 1,
+ OT_V = 2,
+ OT_N = 3,
+ OT_H = 4,
+ OT_ZWNJ = 5,
+ OT_ZWJ = 6,
+ OT_M = 7,
+ OT_SM = 8,
+ OT_VD = 9,
+ OT_A = 10,
+ OT_NBSP = 11,
+ OT_DOTTEDCIRCLE = 12,
+ OT_RS = 13, /* Register Shifter, used in Khmer OT spec. */
+ OT_Coeng = 14, /* Khmer-style Virama. */
+ OT_Repha = 15, /* Atomically-encoded logical or visual repha. */
+ OT_Ra = 16,
+ OT_CM = 17, /* Consonant-Medial. */
+ OT_Avag = 18, /* Avagraha. */
+ OT_CM2 = 31 /* Consonant-Medial, second slot. */
};
/* Visual positions in a syllable from left to right. */
@@ -93,7 +95,7 @@ enum indic_position_t {
enum indic_syllabic_category_t {
INDIC_SYLLABIC_CATEGORY_OTHER = OT_X,
- INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_X,
+ INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_Avag,
INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM,
INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C,
INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C,
@@ -101,7 +103,7 @@ enum indic_syllabic_category_t {
INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C,
INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_CM,
INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_NBSP,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_CM,
INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA = OT_Repha,
INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X,
INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
index d3c475b6ab..9edefe305d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
@@ -128,14 +128,6 @@ static const hb_codepoint_t ra_chars[] = {
0x179A, /* Khmer */ /* No Reph, Visual Repha */
};
-static inline indic_position_t
-consonant_position (hb_codepoint_t u)
-{
- if ((u & ~0x007F) == 0x1780)
- return POS_BELOW_C; /* In Khmer coeng model, post and below forms should not be reordered. */
- return POS_BASE_C; /* Will recategorize later based on font lookups. */
-}
-
static inline bool
is_ra (hb_codepoint_t u)
{
@@ -149,7 +141,7 @@ static inline bool
is_one_of (const hb_glyph_info_t &info, unsigned int flags)
{
/* If it ligated, all bets are off. */
- if (is_a_ligature (info)) return false;
+ if (_hb_glyph_info_ligated (&info)) return false;
return !!(FLAG (info.indic_category()) & flags);
}
@@ -160,12 +152,14 @@ is_joiner (const hb_glyph_info_t &info)
return is_one_of (info, JOINER_FLAGS);
}
+#define MEDIAL_FLAGS (FLAG (OT_CM) | FLAG (OT_CM2))
+
/* Note:
*
* We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
* cannot happen in a consonant syllable. The plus side however is, we can call the
* consonant syllable logic from the vowel syllable function and get it all right! */
-#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CM) | FLAG (OT_Ra) | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_DOTTEDCIRCLE))
+#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_DOTTEDCIRCLE))
static inline bool
is_consonant (const hb_glyph_info_t &info)
{
@@ -194,15 +188,15 @@ set_indic_properties (hb_glyph_info_t &info)
/* The spec says U+0952 is OT_A. However, testing shows that Uniscribe
- * treats U+0951..U+0952 all as OT_VD.
+ * treats U+0951..U+0954 all behave similarly.
* TESTS:
* U+092E,U+0947,U+0952
* U+092E,U+0952,U+0947
* U+092E,U+0947,U+0951
* U+092E,U+0951,U+0947
- * */
+ */
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x0951, 0x0954)))
- cat = OT_VD;
+ cat = OT_A;
if (unlikely (u == 0x17D1))
cat = OT_X;
@@ -220,7 +214,10 @@ set_indic_properties (hb_glyph_info_t &info)
else if (unlikely (u == 0x200C)) cat = OT_ZWNJ;
else if (unlikely (u == 0x200D)) cat = OT_ZWJ;
else if (unlikely (u == 0x25CC)) cat = OT_DOTTEDCIRCLE;
- else if (unlikely (u == 0x0A71)) cat = OT_SM; /* GURMUKHI ADDAK. More like consonant medial. like 0A75. */
+ else if (unlikely (u == 0x0A71)) cat = OT_SM; /* GURMUKHI ADDAK. Move it to the end. */
+ else if (unlikely (u == 0xA982)) cat = OT_SM; /* Javanese repha. */
+ else if (unlikely (u == 0xA9BE)) cat = OT_CM2; /* Javanese medial ya. */
+ else if (unlikely (u == 0xA9BD)) { cat = OT_M; pos = POS_POST_C; } /* Javanese vocalic r. */
if (cat == OT_Repha) {
/* There are two kinds of characters marked as Repha:
@@ -241,7 +238,7 @@ set_indic_properties (hb_glyph_info_t &info)
if ((FLAG (cat) & CONSONANT_FLAGS))
{
- pos = consonant_position (u);
+ pos = POS_BASE_C;
if (is_ra (u))
cat = OT_Ra;
}
@@ -249,7 +246,7 @@ set_indic_properties (hb_glyph_info_t &info)
{
pos = matra_position (u, pos);
}
- else if (cat == OT_SM || cat == OT_VD)
+ else if ((FLAG (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Avag))))
{
pos = POS_SMVD;
}
@@ -277,16 +274,16 @@ set_indic_properties (hb_glyph_info_t &info)
enum base_position_t {
BASE_POS_FIRST,
+ BASE_POS_LAST_SINHALA,
BASE_POS_LAST
};
enum reph_position_t {
- REPH_POS_DEFAULT = POS_BEFORE_POST,
-
REPH_POS_AFTER_MAIN = POS_AFTER_MAIN,
REPH_POS_BEFORE_SUB = POS_BEFORE_SUB,
REPH_POS_AFTER_SUB = POS_AFTER_SUB,
REPH_POS_BEFORE_POST = POS_BEFORE_POST,
- REPH_POS_AFTER_POST = POS_AFTER_POST
+ REPH_POS_AFTER_POST = POS_AFTER_POST,
+ REPH_POS_DONT_CARE = POS_RA_TO_BECOME_REPH
};
enum reph_mode_t {
REPH_MODE_IMPLICIT, /* Reph formed out of initial Ra,H sequence. */
@@ -294,6 +291,15 @@ enum reph_mode_t {
REPH_MODE_VIS_REPHA, /* Encoded Repha character, no reordering needed. */
REPH_MODE_LOG_REPHA /* Encoded Repha character, needs reordering. */
};
+enum blwf_mode_t {
+ BLWF_MODE_PRE_AND_POST, /* Below-forms feature applied to pre-base and post-base. */
+ BLWF_MODE_POST_ONLY /* Below-forms feature applied to post-base only. */
+};
+enum pref_len_t {
+ PREF_LEN_1 = 1,
+ PREF_LEN_2 = 2,
+ PREF_LEN_DONT_CARE = PREF_LEN_2
+};
struct indic_config_t
{
hb_script_t script;
@@ -302,24 +308,27 @@ struct indic_config_t
base_position_t base_pos;
reph_position_t reph_pos;
reph_mode_t reph_mode;
+ blwf_mode_t blwf_mode;
+ pref_len_t pref_len;
};
static const indic_config_t indic_configs[] =
{
/* Default. Should be first. */
- {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_DEFAULT, REPH_MODE_IMPLICIT},
- {HB_SCRIPT_DEVANAGARI,true, 0x094D,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT},
- {HB_SCRIPT_BENGALI, true, 0x09CD,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT},
- {HB_SCRIPT_GURMUKHI, true, 0x0A4D,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT},
- {HB_SCRIPT_GUJARATI, true, 0x0ACD,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT},
- {HB_SCRIPT_ORIYA, true, 0x0B4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT},
- {HB_SCRIPT_TAMIL, true, 0x0BCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT},
- {HB_SCRIPT_TELUGU, true, 0x0C4D,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT},
- {HB_SCRIPT_KANNADA, true, 0x0CCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT},
- {HB_SCRIPT_MALAYALAM, true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA},
- {HB_SCRIPT_SINHALA, false,0x0DCA,BASE_POS_FIRST,REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT},
- {HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DEFAULT, REPH_MODE_VIS_REPHA},
- {HB_SCRIPT_JAVANESE, false,0xA9C0,BASE_POS_LAST, REPH_POS_DEFAULT, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
+ {HB_SCRIPT_DEVANAGARI,true, 0x094D,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_BENGALI, true, 0x09CD,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_GURMUKHI, true, 0x0A4D,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_GUJARATI, true, 0x0ACD,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_ORIYA, true, 0x0B4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_TAMIL, true, 0x0BCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
+ {HB_SCRIPT_TELUGU, true, 0x0C4D,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2},
+ {HB_SCRIPT_KANNADA, true, 0x0CCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2},
+ {HB_SCRIPT_MALAYALAM, true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
+ {HB_SCRIPT_SINHALA, false,0x0DCA,BASE_POS_LAST_SINHALA,
+ REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
+ {HB_SCRIPT_JAVANESE, false,0xA9C0,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
};
@@ -346,15 +355,17 @@ indic_features[] =
{HB_TAG('r','k','r','f'), F_GLOBAL},
{HB_TAG('p','r','e','f'), F_NONE},
{HB_TAG('b','l','w','f'), F_NONE},
- {HB_TAG('h','a','l','f'), F_NONE},
{HB_TAG('a','b','v','f'), F_NONE},
+ {HB_TAG('h','a','l','f'), F_NONE},
{HB_TAG('p','s','t','f'), F_NONE},
- {HB_TAG('c','f','a','r'), F_NONE},
{HB_TAG('v','a','t','u'), F_GLOBAL},
{HB_TAG('c','j','c','t'), F_GLOBAL},
+ {HB_TAG('c','f','a','r'), F_NONE},
/*
* Other features.
* These features are applied all at once, after final_reordering.
+ * Default Bengali font in Windows for example has intermixed
+ * lookups for init,pres,abvs,blws features.
*/
{HB_TAG('i','n','i','t'), F_NONE},
{HB_TAG('p','r','e','s'), F_GLOBAL},
@@ -378,12 +389,12 @@ enum {
_RKRF,
PREF,
BLWF,
- HALF,
ABVF,
+ HALF,
PSTF,
- CFAR,
_VATU,
_CJCT,
+ CFAR,
INIT,
_PRES,
@@ -411,6 +422,10 @@ static void
final_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
+static void
+clear_syllables (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
static void
collect_features_indic (hb_ot_shape_planner_t *plan)
@@ -436,14 +451,26 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
for (; i < INDIC_NUM_FEATURES; i++) {
map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ);
}
+
+ map->add_global_bool_feature (HB_TAG('c','a','l','t'));
+ map->add_global_bool_feature (HB_TAG('c','l','i','g'));
+
+ map->add_gsub_pause (clear_syllables);
}
static void
override_features_indic (hb_ot_shape_planner_t *plan)
{
- /* Uniscribe does not apply 'kern'. */
+ /* Uniscribe does not apply 'kern' in Khmer. */
if (hb_options ().uniscribe_bug_compatible)
- plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
+ {
+ switch ((hb_tag_t) plan->props.script)
+ {
+ case HB_SCRIPT_KHMER:
+ plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
+ break;
+ }
+ }
plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
}
@@ -451,8 +478,9 @@ override_features_indic (hb_ot_shape_planner_t *plan)
struct would_substitute_feature_t
{
- inline void init (const hb_ot_map_t *map, hb_tag_t feature_tag)
+ inline void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
{
+ zero_context = zero_context_;
map->get_stage_lookups (0/*GSUB*/,
map->get_feature_stage (0/*GSUB*/, feature_tag),
&lookups, &count);
@@ -460,7 +488,6 @@ struct would_substitute_feature_t
inline bool would_substitute (const hb_codepoint_t *glyphs,
unsigned int glyphs_count,
- bool zero_context,
hb_face_t *face) const
{
for (unsigned int i = 0; i < count; i++)
@@ -472,6 +499,7 @@ struct would_substitute_feature_t
private:
const hb_ot_map_t::lookup_map_t *lookups;
unsigned int count;
+ bool zero_context;
};
struct indic_shape_plan_t
@@ -527,10 +555,13 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FF) != '2');
indic_plan->virama_glyph = (hb_codepoint_t) -1;
- indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'));
- indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'));
- indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'));
- indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'));
+ /* Use zero-context would_substitute() matching for new-spec of the main
+ * Indic scripts, but not for old-spec or scripts with one spec only. */
+ bool zero_context = indic_plan->config->has_old_spec || !indic_plan->is_old_spec;
+ indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'), zero_context);
+ indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), zero_context);
+ indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'), zero_context);
+ indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'), zero_context);
for (unsigned int i = 0; i < ARRAY_LENGTH (indic_plan->mask_array); i++)
indic_plan->mask_array[i] = (indic_features[i].flags & F_GLOBAL) ?
@@ -547,7 +578,8 @@ data_destroy_indic (void *data)
static indic_position_t
consonant_position_from_face (const indic_shape_plan_t *indic_plan,
- const hb_codepoint_t glyphs[2],
+ const hb_codepoint_t consonant,
+ const hb_codepoint_t virama,
hb_face_t *face)
{
/* For old-spec, the order of glyphs is Consonant,Virama,
@@ -560,16 +592,19 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan,
* 930,94D in 'blwf', not the expected 94D,930 (with new-spec
* table). As such, we simply match both sequences. Seems
* to work. */
- bool zero_context = indic_plan->is_old_spec ? false : true;
- hb_codepoint_t glyphs_r[2] = {glyphs[1], glyphs[0]};
- if (indic_plan->pref.would_substitute (glyphs , 2, zero_context, face) ||
- indic_plan->pref.would_substitute (glyphs_r, 2, zero_context, face))
- return POS_POST_C;
- if (indic_plan->blwf.would_substitute (glyphs , 2, zero_context, face) ||
- indic_plan->blwf.would_substitute (glyphs_r, 2, zero_context, face))
+ hb_codepoint_t glyphs[3] = {virama, consonant, virama};
+ if (indic_plan->blwf.would_substitute (glyphs , 2, face) ||
+ indic_plan->blwf.would_substitute (glyphs+1, 2, face))
return POS_BELOW_C;
- if (indic_plan->pstf.would_substitute (glyphs , 2, zero_context, face) ||
- indic_plan->pstf.would_substitute (glyphs_r, 2, zero_context, face))
+ if (indic_plan->pstf.would_substitute (glyphs , 2, face) ||
+ indic_plan->pstf.would_substitute (glyphs+1, 2, face))
+ return POS_POST_C;
+ unsigned int pref_len = indic_plan->config->pref_len;
+ if ((pref_len == PREF_LEN_2 &&
+ (indic_plan->pref.would_substitute (glyphs , 2, face) ||
+ indic_plan->pref.would_substitute (glyphs+1, 2, face)))
+ || (pref_len == PREF_LEN_1 &&
+ indic_plan->pref.would_substitute (glyphs+1, 1, face)))
return POS_POST_C;
return POS_BASE_C;
}
@@ -579,6 +614,7 @@ enum syllable_type_t {
consonant_syllable,
vowel_syllable,
standalone_cluster,
+ avagraha_cluster,
broken_cluster,
non_indic_cluster,
};
@@ -628,15 +664,18 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
{
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
- hb_codepoint_t glyphs[2];
- if (indic_plan->get_virama_glyph (font, &glyphs[0]))
+ if (indic_plan->config->base_pos != BASE_POS_LAST)
+ return;
+
+ hb_codepoint_t virama;
+ if (indic_plan->get_virama_glyph (font, &virama))
{
hb_face_t *face = font->face;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
if (buffer->info[i].indic_position() == POS_BASE_C) {
- glyphs[1] = buffer->info[i].codepoint;
- buffer->info[i].indic_position() = consonant_position_from_face (indic_plan, glyphs, face);
+ hb_codepoint_t consonant = buffer->info[i].codepoint;
+ buffer->info[i].indic_position() = consonant_position_from_face (indic_plan, consonant, virama, face);
}
}
}
@@ -677,7 +716,8 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* and has more than one consonant, Ra is excluded from candidates for
* base consonants. */
unsigned int limit = start;
- if (indic_plan->mask_array[RPHF] &&
+ if (indic_plan->config->reph_pos != REPH_POS_DONT_CARE &&
+ indic_plan->mask_array[RPHF] &&
start + 3 <= end &&
(
(indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
@@ -686,7 +726,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
{
/* See if it matches the 'rphf' feature. */
hb_codepoint_t glyphs[2] = {info[start].codepoint, info[start + 1].codepoint};
- if (indic_plan->rphf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), true, face))
+ if (indic_plan->rphf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face))
{
limit += 2;
while (limit < end && is_joiner (info[limit]))
@@ -758,9 +798,12 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
}
break;
- case BASE_POS_FIRST:
+ case BASE_POS_LAST_SINHALA:
{
- /* In scripts without half forms (eg. Khmer), the first consonant is always the base. */
+ /* Sinhala base positioning is slightly different from main Indic, in that:
+ * 1. It's ZWJ behavior is different,
+ * 2. We don't need to look into the font for consonant positions.
+ */
if (!has_reph)
base = limit;
@@ -768,7 +811,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Find the last base consonant that is not blocked by ZWJ. If there is
* a ZWJ right before a base consonant, that would request a subjoined form. */
for (unsigned int i = limit; i < end; i++)
- if (is_consonant (info[i]) && info[i].indic_position() == POS_BASE_C)
+ if (is_consonant (info[i]))
{
if (limit < i && info[i - 1].indic_category() == OT_ZWJ)
break;
@@ -778,7 +821,23 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Mark all subsequent consonants as below. */
for (unsigned int i = base + 1; i < end; i++)
- if (is_consonant (info[i]) && info[i].indic_position() == POS_BASE_C)
+ if (is_consonant (info[i]))
+ info[i].indic_position() = POS_BELOW_C;
+ }
+ break;
+
+ case BASE_POS_FIRST:
+ {
+ /* The first consonant is always the base. */
+
+ assert (indic_plan->config->reph_mode == REPH_MODE_VIS_REPHA);
+ assert (!has_reph);
+
+ base = start;
+
+ /* Mark all subsequent consonants as below. */
+ for (unsigned int i = base + 1; i < end; i++)
+ if (is_consonant (info[i]))
info[i].indic_position() = POS_BELOW_C;
}
break;
@@ -877,7 +936,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
indic_position_t last_pos = POS_START;
for (unsigned int i = start; i < end; i++)
{
- if ((FLAG (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | HALANT_OR_COENG_FLAGS)))
+ if ((FLAG (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS)))
{
info[i].indic_position() = last_pos;
if (unlikely (info[i].indic_category() == OT_H &&
@@ -903,33 +962,68 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
}
}
}
- /* Re-attach ZWJ, ZWNJ, and halant to next char, for after-base consonants. */
+ /* For post-base consonants let them own anything before them
+ * since the last consonant or matra. */
{
- unsigned int last_halant = end;
+ unsigned int last = base;
for (unsigned int i = base + 1; i < end; i++)
- if (is_halant_or_coeng (info[i]))
- last_halant = i;
- else if (is_consonant (info[i])) {
- for (unsigned int j = last_halant; j < i; j++)
- if (info[j].indic_position() != POS_SMVD)
+ if (is_consonant (info[i]))
+ {
+ for (unsigned int j = last + 1; j < i; j++)
+ if (info[j].indic_position() < POS_SMVD)
info[j].indic_position() = info[i].indic_position();
- }
+ last = i;
+ } else if (info[i].indic_category() == OT_M)
+ last = i;
}
+
{
- /* Things are out-of-control for post base positions, they may shuffle
- * around like crazy, so merge clusters. For pre-base stuff, we handle
- * cluster issues in final reordering. */
- buffer->merge_clusters (base, end);
+ /* Use syllable() for sort accounting temporarily. */
+ unsigned int syllable = info[start].syllable();
+ for (unsigned int i = start; i < end; i++)
+ info[i].syllable() = i - start;
+
/* Sit tight, rock 'n roll! */
hb_bubble_sort (info + start, end - start, compare_indic_order);
/* Find base again */
base = end;
for (unsigned int i = start; i < end; i++)
- if (info[i].indic_position() == POS_BASE_C) {
- base = i;
+ if (info[i].indic_position() == POS_BASE_C)
+ {
+ base = i;
break;
}
+ /* Things are out-of-control for post base positions, they may shuffle
+ * around like crazy. In old-spec mode, we move halants around, so in
+ * that case merge all clusters after base. Otherwise, check the sort
+ * order and merge as needed.
+ * For pre-base stuff, we handle cluster issues in final reordering. */
+ if (indic_plan->is_old_spec || end - base > 127)
+ buffer->merge_clusters (base, end);
+ else
+ {
+ /* Note! syllable() is a one-byte field. */
+ for (unsigned int i = base; i < end; i++)
+ if (info[i].syllable() != 255)
+ {
+ unsigned int max = i;
+ unsigned int j = start + info[i].syllable();
+ while (j != i)
+ {
+ max = MAX (max, j);
+ unsigned int next = start + info[j].syllable();
+ info[j].syllable() = 255; /* So we don't process j later again. */
+ j = next;
+ }
+ if (i != max)
+ buffer->merge_clusters (i, max + 1);
+ }
+ }
+
+ /* Put syllable back in. */
+ for (unsigned int i = start; i < end; i++)
+ info[i].syllable() = syllable;
}
/* Setup masks now */
@@ -943,6 +1037,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Pre-base */
mask = indic_plan->mask_array[HALF];
+ if (!indic_plan->is_old_spec &&
+ indic_plan->config->blwf_mode == BLWF_MODE_PRE_AND_POST)
+ mask |= indic_plan->mask_array[BLWF];
for (unsigned int i = start; i < base; i++)
info[i].mask |= mask;
/* Base */
@@ -987,15 +1084,19 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
}
}
- if (indic_plan->mask_array[PREF] && base + 2 < end)
+ unsigned int pref_len = indic_plan->config->pref_len;
+ if (indic_plan->mask_array[PREF] && base + pref_len < end)
{
+ assert (1 <= pref_len && pref_len <= 2);
/* Find a Halant,Ra sequence and mark it for pre-base reordering processing. */
- for (unsigned int i = base + 1; i + 1 < end; i++) {
- hb_codepoint_t glyphs[2] = {info[i].codepoint, info[i + 1].codepoint};
- if (indic_plan->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), true, face))
+ for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) {
+ hb_codepoint_t glyphs[2];
+ for (unsigned int j = 0; j < pref_len; j++)
+ glyphs[j] = info[i + j].codepoint;
+ if (indic_plan->pref.would_substitute (glyphs, pref_len, face))
{
- info[i++].mask |= indic_plan->mask_array[PREF];
- info[i++].mask |= indic_plan->mask_array[PREF];
+ for (unsigned int j = 0; j < pref_len; j++)
+ info[i++].mask |= indic_plan->mask_array[PREF];
/* Mark the subsequent stuff with 'cfar'. Used in Khmer.
* Read the feature spec.
@@ -1003,8 +1104,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* U+1784,U+17D2,U+179A,U+17D2,U+1782
* U+1784,U+17D2,U+1782,U+17D2,U+179A
*/
- for (; i < end; i++)
- info[i].mask |= indic_plan->mask_array[CFAR];
+ if (indic_plan->mask_array[CFAR])
+ for (; i < end; i++)
+ info[i].mask |= indic_plan->mask_array[CFAR];
break;
}
@@ -1075,6 +1177,16 @@ initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
}
static void
+initial_reordering_avagraha_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_face_t *face HB_UNUSED,
+ hb_buffer_t *buffer HB_UNUSED,
+ unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
+{
+ /* Nothing to do right now. If we ever switch to using the output
+ * buffer in the reordering process, we'd need to next_glyph() here. */
+}
+
+static void
initial_reordering_non_indic_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_face_t *face HB_UNUSED,
hb_buffer_t *buffer HB_UNUSED,
@@ -1096,6 +1208,7 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
case vowel_syllable: initial_reordering_vowel_syllable (plan, face, buffer, start, end); return;
case standalone_cluster: initial_reordering_standalone_cluster (plan, face, buffer, start, end); return;
+ case avagraha_cluster: initial_reordering_avagraha_cluster (plan, face, buffer, start, end); return;
case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
case non_indic_cluster: initial_reordering_non_indic_cluster (plan, face, buffer, start, end); return;
}
@@ -1265,9 +1378,9 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
info[new_pos] = tmp;
if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */
base--;
+ buffer->merge_clusters (new_pos, MIN (end, base + 1));
new_pos--;
}
- buffer->merge_clusters (new_pos, MIN (end, base + 1));
} else {
for (unsigned int i = start; i < base; i++)
if (info[i].indic_position () == POS_PRE_M) {
@@ -1287,17 +1400,24 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* before post-base consonant forms, and after post-base consonant forms.
*/
- /* If there's anything after the Ra that has the REPH pos, it ought to be halant.
- * Which means that the font has failed to ligate the Reph. In which case, we
- * shouldn't move. */
+ /* Two cases:
+ *
+ * - If repha is encoded as a sequence of characters (Ra,H or Ra,H,ZWJ), then
+ * we should only move it if the sequence ligated to the repha form.
+ *
+ * - If repha is encoded separately and in the logical position, we should only
+ * move it if it did NOT ligate. If it ligated, it's probably the font trying
+ * to make it work without the reordering.
+ */
if (start + 1 < end &&
info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
- info[start + 1].indic_position() != POS_RA_TO_BECOME_REPH)
+ ((info[start].indic_category() == OT_Repha) ^
+ _hb_glyph_info_ligated (&info[start])))
{
unsigned int new_reph_pos;
reph_position_t reph_pos = indic_plan->config->reph_pos;
- /* XXX Figure out old behavior too */
+ assert (reph_pos != REPH_POS_DONT_CARE);
/* 1. If reph should be positioned after post-base consonant forms,
* proceed to step 5.
@@ -1339,7 +1459,6 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (reph_pos == REPH_POS_AFTER_MAIN)
{
new_reph_pos = base;
- /* XXX Skip potential pre-base reordering Ra. */
while (new_reph_pos + 1 < end && info[new_reph_pos + 1].indic_position() <= POS_AFTER_MAIN)
new_reph_pos++;
if (new_reph_pos < end)
@@ -1412,8 +1531,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
reph_move:
{
- /* Yay, one big cluster! Merge before moving. */
- buffer->merge_clusters (start, end);
+ buffer->merge_clusters (start, new_reph_pos + 1);
/* Move */
hb_glyph_info_t reph = info[start];
@@ -1433,6 +1551,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (indic_plan->mask_array[PREF] && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */
{
+ unsigned int pref_len = indic_plan->config->pref_len;
for (unsigned int i = base + 1; i < end; i++)
if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
{
@@ -1440,7 +1559,13 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* of the <pref> feature. (Note that a font may shape a Ra consonant with
* the feature generally but block it in certain contexts.)
*/
- if (i + 1 == end || (info[i + 1].mask & indic_plan->mask_array[PREF]) == 0)
+ /* Note: We just check that something got substituted. We don't check that
+ * the <pref> feature actually did it...
+ *
+ * If pref len is longer than one, then only reorder if it ligated. If
+ * pref len is one, only reorder if it didn't ligate with other things. */
+ if (_hb_glyph_info_substituted (&info[i]) &&
+ ((pref_len == 1) ^ _hb_glyph_info_ligated (&info[i])))
{
/*
* 2. Try to find a target position the same way as for pre-base matra.
@@ -1461,7 +1586,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
!(is_one_of (info[new_pos - 1], FLAG(OT_M) | HALANT_OR_COENG_FLAGS)))
new_pos--;
- /* In Khmer coeng model, a V,Ra can go *after* matras. If it goes after a
+ /* In Khmer coeng model, a H,Ra can go *after* matras. If it goes after a
* split matra, it should be reordered to *before* the left part of such matra. */
if (new_pos > start && info[new_pos - 1].indic_category() == OT_M)
{
@@ -1511,11 +1636,20 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
*/
if (hb_options ().uniscribe_bug_compatible)
{
- /* Uniscribe merges the entire cluster.
- * This means, half forms are submerged into the main consonants cluster.
- * This is unnecessary, and makes cursor positioning harder, but that's what
- * Uniscribe does. */
- buffer->merge_clusters (start, end);
+ switch ((hb_tag_t) plan->props.script)
+ {
+ case HB_SCRIPT_TAMIL:
+ case HB_SCRIPT_SINHALA:
+ break;
+
+ default:
+ /* Uniscribe merges the entire cluster... Except for Tamil & Sinhala.
+ * This means, half forms are submerged into the main consonants cluster.
+ * This is unnecessary, and makes cursor positioning harder, but that's what
+ * Uniscribe does. */
+ buffer->merge_clusters (start, end);
+ break;
+ }
}
}
@@ -1539,15 +1673,23 @@ final_reordering (const hb_ot_shape_plan_t *plan,
}
final_reordering_syllable (plan, buffer, last, count);
- /* Zero syllables now... */
- for (unsigned int i = 0; i < count; i++)
- info[i].syllable() = 0;
-
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
}
+static void
+clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ info[i].syllable() = 0;
+}
+
+
static hb_ot_shape_normalization_mode_t
normalization_preference_indic (const hb_segment_properties_t *props HB_UNUSED)
{
@@ -1627,7 +1769,7 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
if (hb_options ().uniscribe_bug_compatible ||
(c->font->get_glyph (ab, 0, &glyph) &&
- indic_plan->pstf.would_substitute (&glyph, 1, true, c->font->face)))
+ indic_plan->pstf.would_substitute (&glyph, 1, c->font->face)))
{
/* Ok, safe to use Uniscribe-style decomposition. */
*a = 0x0DD9;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
index 29f29bb556..25ba7264ca 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
@@ -60,6 +60,16 @@ other_features[] =
HB_TAG('p','s','t','s'),
/* Positioning features, though we don't care about the types. */
HB_TAG('d','i','s','t'),
+ /* Pre-release version of Windows 8 Myanmar font had abvm,blwm
+ * features. The released Windows 8 version of the font (as well
+ * as the released spec) used 'mark' instead. The Windows 8
+ * shaper however didn't apply 'mark' but did apply 'mkmk'.
+ * Perhaps it applied abvm/blwm. This was fixed in a Windows 8
+ * update, so now it applies mark/mkmk. We are guessing that
+ * it still applies abvm/blwm too.
+ */
+ HB_TAG('a','b','v','m'),
+ HB_TAG('b','l','w','m'),
};
static void
@@ -109,6 +119,7 @@ override_features_myanmar (hb_ot_shape_planner_t *plan)
enum syllable_type_t {
consonant_syllable,
+ punctuation_cluster,
broken_cluster,
non_myanmar_cluster,
};
@@ -133,7 +144,8 @@ enum myanmar_category_t {
OT_VBlw = 27,
OT_VPre = 28,
OT_VPst = 29,
- OT_VS = 30 /* Variation selectors */
+ OT_VS = 30, /* Variation selectors */
+ OT_P = 31 /* Punctuation */
};
@@ -141,7 +153,7 @@ static inline bool
is_one_of (const hb_glyph_info_t &info, unsigned int flags)
{
/* If it ligated, all bets are off. */
- if (is_a_ligature (info)) return false;
+ if (_hb_glyph_info_ligated (&info)) return false;
return !!(FLAG (info.myanmar_category()) & flags);
}
@@ -176,6 +188,10 @@ set_myanmar_properties (hb_glyph_info_t &info)
switch (u)
{
+ case 0x104E:
+ cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */
+ break;
+
case 0x002D: case 0x00A0: case 0x00D7: case 0x2012:
case 0x2013: case 0x2014: case 0x2015: case 0x2022:
case 0x25CC: case 0x25FB: case 0x25FC: case 0x25FD:
@@ -233,6 +249,10 @@ set_myanmar_properties (hb_glyph_info_t &info)
case 0x108F: case 0x109A: case 0x109B: case 0x109C:
cat = (indic_category_t) OT_SM;
break;
+
+ case 0x104A: case 0x104B:
+ cat = (indic_category_t) OT_P;
+ break;
}
if (cat == OT_M)
@@ -396,6 +416,16 @@ initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
}
static void
+initial_reordering_punctuation_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_face_t *face HB_UNUSED,
+ hb_buffer_t *buffer HB_UNUSED,
+ unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
+{
+ /* Nothing to do right now. If we ever switch to using the output
+ * buffer in the reordering process, we'd need to next_glyph() here. */
+}
+
+static void
initial_reordering_non_myanmar_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_face_t *face HB_UNUSED,
hb_buffer_t *buffer HB_UNUSED,
@@ -415,6 +445,7 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
switch (syllable_type) {
case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
+ case punctuation_cluster: initial_reordering_punctuation_cluster (plan, face, buffer, start, end); return;
case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
case non_myanmar_cluster: initial_reordering_non_myanmar_cluster (plan, face, buffer, start, end); return;
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
index a099e05d74..ac0072ba56 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
@@ -279,9 +279,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
/* Unicode-3.0 additions */
case HB_SCRIPT_SINHALA:
- /* Unicode-4.1 additions */
- case HB_SCRIPT_BUGINESE:
-
/* Unicode-5.0 additions */
case HB_SCRIPT_BALINESE:
@@ -336,6 +333,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
return &_hb_ot_complex_shaper_default;
/* Unicode-4.1 additions */
+ case HB_SCRIPT_BUGINESE:
case HB_SCRIPT_NEW_TAI_LUE:
/* Unicode-5.1 additions */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc
index 9c0c303e3d..da687ed646 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc
@@ -266,7 +266,7 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
switch (syllable_type) {
case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
- case non_sea_cluster: initial_reordering_non_sea_cluster (plan, face, buffer, start, end); return;
+ case non_sea_cluster: initial_reordering_non_sea_cluster (plan, face, buffer, start, end); return;
}
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
index 284d030d5f..449b64e5ca 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
@@ -260,7 +260,13 @@ position_mark (const hb_ot_shape_plan_t *plan,
case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT:
case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW:
- pos.y_offset += base_extents.y_bearing + base_extents.height - mark_extents.y_bearing;
+ pos.y_offset = base_extents.y_bearing + base_extents.height - mark_extents.y_bearing;
+ /* Never shift up "below" marks. */
+ if ((y_gap > 0) == (pos.y_offset > 0))
+ {
+ base_extents.height -= pos.y_offset;
+ pos.y_offset = 0;
+ }
base_extents.height += mark_extents.height;
break;
@@ -274,7 +280,15 @@ position_mark (const hb_ot_shape_plan_t *plan,
case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE:
case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT:
- pos.y_offset += base_extents.y_bearing - (mark_extents.y_bearing + mark_extents.height);
+ pos.y_offset = base_extents.y_bearing - (mark_extents.y_bearing + mark_extents.height);
+ /* Don't shift down "above" marks too much. */
+ if ((y_gap > 0) != (pos.y_offset > 0))
+ {
+ unsigned int correction = -pos.y_offset / 2;
+ base_extents.y_bearing += correction;
+ base_extents.height -= correction;
+ pos.y_offset += correction;
+ }
base_extents.y_bearing -= mark_extents.height;
base_extents.height += mark_extents.height;
break;
@@ -300,8 +314,8 @@ position_around_base (const hb_ot_shape_plan_t *plan,
base_extents.x_bearing += buffer->pos[base].x_offset;
base_extents.y_bearing += buffer->pos[base].y_offset;
- unsigned int lig_id = get_lig_id (buffer->info[base]);
- unsigned int num_lig_components = get_lig_num_comps (buffer->info[base]);
+ unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[base]);
+ unsigned int num_lig_components = _hb_glyph_info_get_lig_num_comps (&buffer->info[base]);
hb_position_t x_offset = 0, y_offset = 0;
if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
@@ -317,8 +331,8 @@ position_around_base (const hb_ot_shape_plan_t *plan,
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]))
{
if (num_lig_components > 1) {
- unsigned int this_lig_id = get_lig_id (buffer->info[i]);
- unsigned int this_lig_component = get_lig_comp (buffer->info[i]) - 1;
+ unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[i]);
+ unsigned int this_lig_component = _hb_glyph_info_get_lig_comp (&buffer->info[i]) - 1;
/* Conditions for attaching to the last component. */
if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_components)
this_lig_component = num_lig_components - 1;
@@ -416,41 +430,52 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
- unsigned int count = buffer->len;
hb_mask_t kern_mask = plan->map.get_1_mask (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
+ if (!kern_mask) return;
+
+ unsigned int count = buffer->len;
OT::hb_apply_context_t c (1, font, buffer);
c.set_lookup_mask (kern_mask);
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
- for (buffer->idx = 0; buffer->idx < count;)
+ hb_glyph_info_t *info = buffer->info;
+ hb_glyph_position_t *pos = buffer->pos;
+
+ for (unsigned int idx = 0; idx < count;)
{
- OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, buffer->idx, 1);
+ OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, idx, 1);
if (!skippy_iter.next ())
{
- buffer->idx++;
+ idx++;
continue;
}
- hb_position_t x_kern, y_kern, kern1, kern2;
- font->get_glyph_kerning_for_direction (buffer->info[buffer->idx].codepoint,
- buffer->info[skippy_iter.idx].codepoint,
+ hb_position_t x_kern, y_kern;
+ font->get_glyph_kerning_for_direction (info[idx].codepoint,
+ info[skippy_iter.idx].codepoint,
buffer->props.direction,
&x_kern, &y_kern);
- kern1 = x_kern >> 1;
- kern2 = x_kern - kern1;
- buffer->pos[buffer->idx].x_advance += kern1;
- buffer->pos[skippy_iter.idx].x_advance += kern2;
- buffer->pos[skippy_iter.idx].x_offset += kern2;
+ if (x_kern)
+ {
+ hb_position_t kern1 = x_kern >> 1;
+ hb_position_t kern2 = x_kern - kern1;
+ pos[idx].x_advance += kern1;
+ pos[skippy_iter.idx].x_advance += kern2;
+ pos[skippy_iter.idx].x_offset += kern2;
+ }
- kern1 = y_kern >> 1;
- kern2 = y_kern - kern1;
- buffer->pos[buffer->idx].y_advance += kern1;
- buffer->pos[skippy_iter.idx].y_advance += kern2;
- buffer->pos[skippy_iter.idx].y_offset += kern2;
+ if (y_kern)
+ {
+ hb_position_t kern1 = y_kern >> 1;
+ hb_position_t kern2 = y_kern - kern1;
+ pos[idx].y_advance += kern1;
+ pos[skippy_iter.idx].y_advance += kern2;
+ pos[skippy_iter.idx].y_offset += kern2;
+ }
- buffer->idx = skippy_iter.idx;
+ idx = skippy_iter.idx;
}
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
index 085d48511d..fb8048caa2 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
@@ -29,8 +29,6 @@
#include "hb-private.hh"
-#include "hb-font.h"
-#include "hb-buffer.h"
/* buffer var allocations, used during the normalization process */
#define glyph_index() var1.u32
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
index 3fee809cf9..6531e1b215 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
@@ -132,17 +132,19 @@ static inline unsigned int
decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint_t ab)
{
hb_codepoint_t a, b, a_glyph, b_glyph;
+ hb_buffer_t * const buffer = c->buffer;
+ hb_font_t * const font = c->font;
if (!c->decompose (c, ab, &a, &b) ||
- (b && !c->font->get_glyph (b, 0, &b_glyph)))
+ (b && !font->get_glyph (b, 0, &b_glyph)))
return 0;
- bool has_a = c->font->get_glyph (a, 0, &a_glyph);
+ bool has_a = font->get_glyph (a, 0, &a_glyph);
if (shortest && has_a) {
/* Output a and b */
- output_char (c->buffer, a, a_glyph);
+ output_char (buffer, a, a_glyph);
if (likely (b)) {
- output_char (c->buffer, b, b_glyph);
+ output_char (buffer, b, b_glyph);
return 2;
}
return 1;
@@ -151,16 +153,16 @@ decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint
unsigned int ret;
if ((ret = decompose (c, shortest, a))) {
if (b) {
- output_char (c->buffer, b, b_glyph);
+ output_char (buffer, b, b_glyph);
return ret + 1;
}
return ret;
}
if (has_a) {
- output_char (c->buffer, a, a_glyph);
+ output_char (buffer, a, a_glyph);
if (likely (b)) {
- output_char (c->buffer, b, b_glyph);
+ output_char (buffer, b, b_glyph);
return 2;
}
return 1;
@@ -214,34 +216,35 @@ static inline void
handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end)
{
hb_buffer_t * const buffer = c->buffer;
+ hb_font_t * const font = c->font;
for (; buffer->idx < end - 1;) {
if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) {
/* The next two lines are some ugly lines... But work. */
- if (c->font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
+ if (font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
{
buffer->replace_glyphs (2, 1, &buffer->cur().codepoint);
}
else
{
/* Just pass on the two characters separately, let GSUB do its magic. */
- set_glyph (buffer->cur(), c->font);
+ set_glyph (buffer->cur(), font);
buffer->next_glyph ();
- set_glyph (buffer->cur(), c->font);
+ set_glyph (buffer->cur(), font);
buffer->next_glyph ();
}
/* Skip any further variation selectors. */
while (buffer->idx < end && unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint)))
{
- set_glyph (buffer->cur(), c->font);
+ set_glyph (buffer->cur(), font);
buffer->next_glyph ();
}
} else {
- set_glyph (buffer->cur(), c->font);
+ set_glyph (buffer->cur(), font);
buffer->next_glyph ();
}
}
if (likely (buffer->idx < end)) {
- set_glyph (buffer->cur(), c->font);
+ set_glyph (buffer->cur(), font);
buffer->next_glyph ();
}
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
index 817147199f..cbfab5b40c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
@@ -66,7 +66,7 @@ struct hb_ot_shape_planner_t
hb_ot_map_builder_t map;
hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) :
- face (master_plan->face),
+ face (master_plan->face_unsafe),
props (master_plan->props),
shaper (NULL),
map (face, &props) {}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
index c23240c80c..63c36f936f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
@@ -290,16 +290,18 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c)
if (HB_DIRECTION_IS_FORWARD (c->target_direction))
return;
- hb_unicode_funcs_t *unicode = c->buffer->unicode;
+ hb_buffer_t *buffer = c->buffer;
+ hb_unicode_funcs_t *unicode = buffer->unicode;
hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m'));
- unsigned int count = c->buffer->len;
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++) {
- hb_codepoint_t codepoint = unicode->mirroring (c->buffer->info[i].codepoint);
- if (likely (codepoint == c->buffer->info[i].codepoint))
- c->buffer->info[i].mask |= rtlm_mask;
+ hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint);
+ if (likely (codepoint == info[i].codepoint))
+ info[i].mask |= rtlm_mask;
else
- c->buffer->info[i].codepoint = codepoint;
+ info[i].codepoint = codepoint;
}
}
@@ -307,12 +309,13 @@ static inline void
hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
{
hb_ot_map_t *map = &c->plan->map;
+ hb_buffer_t *buffer = c->buffer;
hb_mask_t global_mask = map->get_global_mask ();
- c->buffer->reset_masks (global_mask);
+ buffer->reset_masks (global_mask);
if (c->plan->shaper->setup_masks)
- c->plan->shaper->setup_masks (c->plan, c->buffer, c->font);
+ c->plan->shaper->setup_masks (c->plan, buffer, c->font);
for (unsigned int i = 0; i < c->num_user_features; i++)
{
@@ -320,7 +323,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
unsigned int shift;
hb_mask_t mask = map->get_mask (feature->tag, &shift);
- c->buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
+ buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
}
}
}
@@ -338,46 +341,53 @@ static inline void
hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
{
unsigned int count = c->buffer->len;
+ hb_glyph_info_t *info = c->buffer->info;
for (unsigned int i = 0; i < count; i++)
- c->buffer->info[i].glyph_props() = _hb_glyph_info_get_general_category (&c->buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ?
- HB_OT_LAYOUT_GLYPH_PROPS_MARK :
- HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
+ _hb_glyph_info_set_glyph_props (&info[i],
+ _hb_glyph_info_get_general_category (&info[i])
+ == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ?
+ HB_OT_LAYOUT_GLYPH_PROPS_MARK :
+ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
}
static inline void
hb_ot_substitute_default (hb_ot_shape_context_t *c)
{
+ hb_buffer_t *buffer = c->buffer;
+
if (c->plan->shaper->preprocess_text)
- c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font);
+ c->plan->shaper->preprocess_text (c->plan, buffer, c->font);
hb_ot_mirror_chars (c);
- HB_BUFFER_ALLOCATE_VAR (c->buffer, glyph_index);
+ HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);
- _hb_ot_shape_normalize (c->plan, c->buffer, c->font);
+ _hb_ot_shape_normalize (c->plan, buffer, c->font);
hb_ot_shape_setup_masks (c);
/* This is unfortunate to go here, but necessary... */
if (!hb_ot_layout_has_positioning (c->face))
- _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, c->buffer);
+ _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer);
- hb_ot_map_glyphs_fast (c->buffer);
+ hb_ot_map_glyphs_fast (buffer);
- HB_BUFFER_DEALLOCATE_VAR (c->buffer, glyph_index);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index);
}
static inline void
hb_ot_substitute_complex (hb_ot_shape_context_t *c)
{
- hb_ot_layout_substitute_start (c->font, c->buffer);
+ hb_buffer_t *buffer = c->buffer;
+
+ hb_ot_layout_substitute_start (c->font, buffer);
if (!hb_ot_layout_has_glyph_classes (c->face))
hb_synthesize_glyph_classes (c);
- c->plan->substitute (c->font, c->buffer);
+ c->plan->substitute (c->font, buffer);
- hb_ot_layout_substitute_finish (c->font, c->buffer);
+ hb_ot_layout_substitute_finish (c->font, buffer);
return;
}
@@ -408,7 +418,7 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
- if ((buffer->info[i].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
+ if (_hb_glyph_info_is_mark (&buffer->info[i]))
{
buffer->pos[i].x_advance = 0;
buffer->pos[i].y_advance = 0;
@@ -418,21 +428,29 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer)
static inline void
hb_ot_position_default (hb_ot_shape_context_t *c)
{
- hb_ot_layout_position_start (c->font, c->buffer);
-
+ hb_direction_t direction = c->buffer->props.direction;
unsigned int count = c->buffer->len;
+ hb_glyph_info_t *info = c->buffer->info;
+ hb_glyph_position_t *pos = c->buffer->pos;
for (unsigned int i = 0; i < count; i++)
{
- c->font->get_glyph_advance_for_direction (c->buffer->info[i].codepoint,
- c->buffer->props.direction,
- &c->buffer->pos[i].x_advance,
- &c->buffer->pos[i].y_advance);
- c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
- c->buffer->props.direction,
- &c->buffer->pos[i].x_offset,
- &c->buffer->pos[i].y_offset);
+ c->font->get_glyph_advance_for_direction (info[i].codepoint,
+ direction,
+ &pos[i].x_advance,
+ &pos[i].y_advance);
+ c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
+ direction,
+ &pos[i].x_offset,
+ &pos[i].y_offset);
}
+}
+
+static inline bool
+hb_ot_position_complex (hb_ot_shape_context_t *c)
+{
+ bool ret = false;
+ unsigned int count = c->buffer->len;
switch (c->plan->shaper->zero_width_marks)
{
@@ -452,32 +470,28 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
break;
}
-}
-
-static inline bool
-hb_ot_position_complex (hb_ot_shape_context_t *c)
-{
- bool ret = false;
- unsigned int count = c->buffer->len;
if (hb_ot_layout_has_positioning (c->face))
{
+ hb_glyph_info_t *info = c->buffer->info;
+ hb_glyph_position_t *pos = c->buffer->pos;
+
/* Change glyph origin to what GPOS expects, apply GPOS, change it back. */
for (unsigned int i = 0; i < count; i++) {
- c->font->add_glyph_origin_for_direction (c->buffer->info[i].codepoint,
+ c->font->add_glyph_origin_for_direction (info[i].codepoint,
HB_DIRECTION_LTR,
- &c->buffer->pos[i].x_offset,
- &c->buffer->pos[i].y_offset);
+ &pos[i].x_offset,
+ &pos[i].y_offset);
}
c->plan->position (c->font, c->buffer);
for (unsigned int i = 0; i < count; i++) {
- c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
+ c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
HB_DIRECTION_LTR,
- &c->buffer->pos[i].x_offset,
- &c->buffer->pos[i].y_offset);
+ &pos[i].x_offset,
+ &pos[i].y_offset);
}
ret = true;
@@ -500,18 +514,20 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
break;
}
- hb_ot_layout_position_finish (c->font, c->buffer);
-
return ret;
}
static inline void
hb_ot_position (hb_ot_shape_context_t *c)
{
+ hb_ot_layout_position_start (c->font, c->buffer);
+
hb_ot_position_default (c);
hb_bool_t fallback = !hb_ot_position_complex (c);
+ hb_ot_layout_position_finish (c->font, c->buffer);
+
if (fallback && c->plan->shaper->fallback_position)
_hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
@@ -533,22 +549,42 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)
return;
- hb_codepoint_t space = 0;
+ hb_codepoint_t space;
+ enum {
+ SPACE_DONT_KNOW,
+ SPACE_AVAILABLE,
+ SPACE_UNAVAILABLE
+ } space_status = SPACE_DONT_KNOW;
unsigned int count = c->buffer->len;
+ hb_glyph_info_t *info = c->buffer->info;
+ hb_glyph_position_t *pos = c->buffer->pos;
+ unsigned int j = 0;
for (unsigned int i = 0; i < count; i++)
- if (unlikely (!is_a_ligature (c->buffer->info[i]) &&
- _hb_glyph_info_is_default_ignorable (&c->buffer->info[i])))
+ {
+ if (unlikely (!_hb_glyph_info_ligated (&info[i]) &&
+ _hb_glyph_info_is_default_ignorable (&info[i])))
{
- if (!space) {
- /* We assume that the space glyph is not gid0. */
- if (unlikely (!c->font->get_glyph (' ', 0, &space)) || !space)
- return; /* No point! */
+ if (space_status == SPACE_DONT_KNOW)
+ space_status = c->font->get_glyph (' ', 0, &space) ? SPACE_AVAILABLE : SPACE_UNAVAILABLE;
+
+ if (space_status == SPACE_AVAILABLE)
+ {
+ info[i].codepoint = space;
+ pos[i].x_advance = 0;
+ pos[i].y_advance = 0;
}
- c->buffer->info[i].codepoint = space;
- c->buffer->pos[i].x_advance = 0;
- c->buffer->pos[i].y_advance = 0;
+ else
+ continue; /* Delete it. */
}
+ if (j != i)
+ {
+ info[j] = info[i];
+ pos[j] = pos[i];
+ }
+ j++;
+ }
+ c->buffer->len = j;
}
@@ -562,8 +598,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
/* Save the original direction, we use it later. */
c->target_direction = c->buffer->props.direction;
- HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props0);
- HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props1);
+ _hb_buffer_allocate_unicode_vars (c->buffer);
c->buffer->clear_output ();
@@ -578,8 +613,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
hb_ot_hide_default_ignorables (c);
- HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props1);
- HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props0);
+ _hb_buffer_deallocate_unicode_vars (c->buffer);
c->buffer->props.direction = c->target_direction;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
index 91ebec76ee..5594ef5074 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
@@ -27,7 +27,6 @@
*/
#include "hb-private.hh"
-#include "hb-ot.h"
#include <string.h>
@@ -167,9 +166,12 @@ typedef struct {
*
* Generated by intersecting the OpenType language tag list from
* Draft OpenType 1.5 spec, with with the ISO 639-3 codes from
- * 2008/08/04, matching on name, and finally adjusted manually.
+ * 2008-08-04, matching on name, and finally adjusted manually.
*
- * Updated on 2012/12/07 with more research into remaining codes.
+ * Updated on 2012-12-07 with more research into remaining codes.
+ *
+ * Updated on 2013-11-23 based on usage in SIL and Microsoft fonts,
+ * the new proposal from Microsoft, and latest ISO 639-3 names.
*
* Some items still missing. Those are commented out at the end.
* Keep sorted for bsearch.
@@ -179,57 +181,90 @@ static const LangTag ot_languages[] = {
{"aa", HB_TAG('A','F','R',' ')}, /* Afar */
{"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */
{"abq", HB_TAG('A','B','A',' ')}, /* Abaza */
+ {"ach", HB_TAG('A','C','H',' ')}, /* Acoli */
{"ada", HB_TAG('D','N','G',' ')}, /* Dangme */
{"ady", HB_TAG('A','D','Y',' ')}, /* Adyghe */
{"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */
{"aii", HB_TAG('S','W','A',' ')}, /* Swadaya Aramaic */
+ {"aio", HB_TAG('A','I','O',' ')}, /* Aiton */
{"aiw", HB_TAG('A','R','I',' ')}, /* Aari */
+ {"ak", HB_TAG('T','W','I',' ')}, /* Akan [macrolanguage] */
{"alt", HB_TAG('A','L','T',' ')}, /* [Southern] Altai */
{"am", HB_TAG('A','M','H',' ')}, /* Amharic */
{"amf", HB_TAG('H','B','N',' ')}, /* Hammer-Banna */
- {"ar", HB_TAG('A','R','A',' ')}, /* Arabic */
+ {"an", HB_TAG('A','R','G',' ')}, /* Aragonese */
+ {"ang", HB_TAG('A','N','G',' ')}, /* Old English (ca. 450-1100) */
+ {"ar", HB_TAG('A','R','A',' ')}, /* Arabic [macrolanguage] */
+ {"arb", HB_TAG('A','R','A',' ')}, /* Standard Arabic */
{"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */
+ {"ary", HB_TAG('M','O','R',' ')}, /* Moroccan Arabic */
{"as", HB_TAG('A','S','M',' ')}, /* Assamese */
+ {"ast", HB_TAG('A','S','T',' ')}, /* Asturian/Asturleonese/Bable/Leonese */
{"ath", HB_TAG('A','T','H',' ')}, /* Athapaskan [family] */
{"atv", HB_TAG('A','L','T',' ')}, /* [Northern] Altai */
{"av", HB_TAG('A','V','R',' ')}, /* Avaric */
{"awa", HB_TAG('A','W','A',' ')}, /* Awadhi */
- {"ay", HB_TAG('A','Y','M',' ')}, /* Aymara */
- {"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani */
+ {"ay", HB_TAG('A','Y','M',' ')}, /* Aymara [macrolanguage] */
+ {"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani [macrolanguage] */
+ {"azb", HB_TAG('A','Z','B',' ')}, /* South Azerbaijani */
+ {"azj", HB_TAG('A','Z','E',' ')}, /* North Azerbaijani */
{"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */
{"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */
- {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi */
- {"bci", HB_TAG('B','A','U',' ')}, /* Baule */
+ {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi [macrolangauge] */
+ {"ban", HB_TAG('B','A','N',' ')}, /* Balinese */
+ {"bar", HB_TAG('B','A','R',' ')}, /* Bavarian */
+ {"bbc", HB_TAG('B','B','C',' ')}, /* Batak Toba */
+ {"bci", HB_TAG('B','A','U',' ')}, /* Baoulé */
+ {"bcl", HB_TAG('B','I','K',' ')}, /* Central Bikol */
{"bcq", HB_TAG('B','C','H',' ')}, /* Bench */
- {"be", HB_TAG('B','E','L',' ')}, /* Belarussian */
+ {"be", HB_TAG('B','E','L',' ')}, /* Belarusian */
{"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */
{"ber", HB_TAG('B','E','R',' ')}, /* Berber [family] */
{"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */
{"bft", HB_TAG('B','L','T',' ')}, /* Balti */
{"bfy", HB_TAG('B','A','G',' ')}, /* Baghelkhandi */
{"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */
+ {"bgc", HB_TAG('B','G','C',' ')}, /* Haryanvi */
+ {"bgq", HB_TAG('B','G','Q',' ')}, /* Bagri */
{"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */
+ {"bhk", HB_TAG('B','I','K',' ')}, /* Albay Bicolano (retired code) */
{"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */
- {"bik", HB_TAG('B','I','K',' ')}, /* Bikol */
+ {"bi", HB_TAG('B','I','S',' ')}, /* Bislama */
+ {"bik", HB_TAG('B','I','K',' ')}, /* Bikol [macrolanguage] */
{"bin", HB_TAG('E','D','O',' ')}, /* Bini */
+ {"bjj", HB_TAG('B','J','J',' ')}, /* Kanauji */
{"bjt", HB_TAG('B','L','N',' ')}, /* Balanta-Ganja */
{"bla", HB_TAG('B','K','F',' ')}, /* Blackfoot */
{"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe */
+ {"blk", HB_TAG('B','L','K',' ')}, /* Pa'O/Pa'o Karen */
+ {"bln", HB_TAG('B','I','K',' ')}, /* Southern Catanduanes Bikol */
{"bm", HB_TAG('B','M','B',' ')}, /* Bambara */
{"bn", HB_TAG('B','E','N',' ')}, /* Bengali */
{"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */
+ {"bpy", HB_TAG('B','P','Y',' ')}, /* Bishnupriya */
+ {"bqi", HB_TAG('L','R','C',' ')}, /* Bakhtiari */
{"br", HB_TAG('B','R','E',' ')}, /* Breton */
{"bra", HB_TAG('B','R','I',' ')}, /* Braj Bhasha */
{"brh", HB_TAG('B','R','H',' ')}, /* Brahui */
+ {"brx", HB_TAG('B','R','X',' ')}, /* Bodo (India) */
{"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */
{"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) */
+ {"bto", HB_TAG('B','I','K',' ')}, /* Rinconada Bikol */
+ {"bts", HB_TAG('B','T','S',' ')}, /* Batak Simalungun */
+ {"bug", HB_TAG('B','U','G',' ')}, /* Buginese */
{"bxr", HB_TAG('R','B','U',' ')}, /* Russian Buriat */
{"byn", HB_TAG('B','I','L',' ')}, /* Bilen */
{"ca", HB_TAG('C','A','T',' ')}, /* Catalan */
+ {"cbk", HB_TAG('C','B','K',' ')}, /* Chavacano */
{"ce", HB_TAG('C','H','E',' ')}, /* Chechen */
{"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */
+ {"cgg", HB_TAG('C','G','G',' ')}, /* Chiga */
+ {"ch", HB_TAG('C','H','A',' ')}, /* Chamorro */
+ {"cho", HB_TAG('C','H','O',' ')}, /* Choctaw */
{"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
{"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */
+ {"chy", HB_TAG('C','H','Y',' ')}, /* Cheyenne */
+ {"ckb", HB_TAG('K','U','R',' ')}, /* Central Kurdish (Sorani) */
{"ckt", HB_TAG('C','H','K',' ')}, /* Chukchi */
{"cop", HB_TAG('C','O','P',' ')}, /* Coptic */
{"cr", HB_TAG('C','R','E',' ')}, /* Cree */
@@ -239,6 +274,9 @@ static const LangTag ot_languages[] = {
{"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */
{"crx", HB_TAG('C','R','R',' ')}, /* Carrier */
{"cs", HB_TAG('C','S','Y',' ')}, /* Czech */
+ {"csb", HB_TAG('C','S','B',' ')}, /* Kashubian */
+ {"ctg", HB_TAG('C','T','G',' ')}, /* Chittagonian */
+ {"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol */
{"cu", HB_TAG('C','S','L',' ')}, /* Church Slavic */
{"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */
{"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */
@@ -247,34 +285,42 @@ static const LangTag ot_languages[] = {
{"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) */
{"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */
{"de", HB_TAG('D','E','U',' ')}, /* German */
- {"din", HB_TAG('D','N','K',' ')}, /* Dinka */
- {"dje", HB_TAG('D','J','R',' ')}, /* Djerma */
+ {"dgo", HB_TAG('D','G','O',' ')}, /* Dogri */
+ {"dhd", HB_TAG('M','A','W',' ')}, /* Dhundari */
+ {"din", HB_TAG('D','N','K',' ')}, /* Dinka [macrolanguage] */
+ {"diq", HB_TAG('D','I','Q',' ')}, /* Dimli */
+ {"dje", HB_TAG('D','J','R',' ')}, /* Zarma */
{"dng", HB_TAG('D','U','N',' ')}, /* Dungan */
- {"doi", HB_TAG('D','G','R',' ')}, /* Dogri */
+ {"doi", HB_TAG('D','G','R',' ')}, /* Dogri [macrolanguage] */
{"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */
- {"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi */
+ {"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi/Divehi/Maldivian */
{"dyu", HB_TAG('J','U','L',' ')}, /* Jula */
{"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */
{"ee", HB_TAG('E','W','E',' ')}, /* Ewe */
{"efi", HB_TAG('E','F','I',' ')}, /* Efik */
+ {"ekk", HB_TAG('E','T','I',' ')}, /* Standard Estonian */
{"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) */
+ {"emk", HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan */
{"en", HB_TAG('E','N','G',' ')}, /* English */
{"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */
{"eot", HB_TAG('B','T','I',' ')}, /* Beti (Côte d'Ivoire) */
{"es", HB_TAG('E','S','P',' ')}, /* Spanish */
- {"et", HB_TAG('E','T','I',' ')}, /* Estonian */
+ {"et", HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */
{"eu", HB_TAG('E','U','Q',' ')}, /* Basque */
{"eve", HB_TAG('E','V','N',' ')}, /* Even */
{"evn", HB_TAG('E','V','K',' ')}, /* Evenki */
- {"fa", HB_TAG('F','A','R',' ')}, /* Persian */
- {"ff", HB_TAG('F','U','L',' ')}, /* Fulah */
+ {"fa", HB_TAG('F','A','R',' ')}, /* Persian [macrolanguage] */
+ {"ff", HB_TAG('F','U','L',' ')}, /* Fulah [macrolanguage] */
{"fi", HB_TAG('F','I','N',' ')}, /* Finnish */
{"fil", HB_TAG('P','I','L',' ')}, /* Filipino */
{"fj", HB_TAG('F','J','I',' ')}, /* Fijian */
{"fo", HB_TAG('F','O','S',' ')}, /* Faroese */
{"fon", HB_TAG('F','O','N',' ')}, /* Fon */
{"fr", HB_TAG('F','R','A',' ')}, /* French */
+ {"frc", HB_TAG('F','R','C',' ')}, /* Cajun French */
+ {"frp", HB_TAG('F','R','P',' ')}, /* Arpitan/Francoprovençal */
{"fur", HB_TAG('F','R','L',' ')}, /* Friulian */
+ {"fuv", HB_TAG('F','U','V',' ')}, /* Nigerian Fulfulde */
{"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian */
{"ga", HB_TAG('I','R','I',' ')}, /* Irish */
{"gaa", HB_TAG('G','A','D',' ')}, /* Ga */
@@ -282,113 +328,167 @@ static const LangTag ot_languages[] = {
{"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */
{"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */
{"gez", HB_TAG('G','E','Z',' ')}, /* Ge'ez */
+ {"ggo", HB_TAG('G','O','N',' ')}, /* Southern Gondi */
{"gl", HB_TAG('G','A','L',' ')}, /* Galician */
{"gld", HB_TAG('N','A','N',' ')}, /* Nanai */
- {"gn", HB_TAG('G','U','A',' ')}, /* Guarani */
- {"gon", HB_TAG('G','O','N',' ')}, /* Gondi */
+ {"glk", HB_TAG('G','L','K',' ')}, /* Gilaki */
+ {"gn", HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */
+ {"gno", HB_TAG('G','O','N',' ')}, /* Northern Gondi */
+ {"gog", HB_TAG('G','O','G',' ')}, /* Gogo */
+ {"gon", HB_TAG('G','O','N',' ')}, /* Gondi [macrolanguage] */
{"grt", HB_TAG('G','R','O',' ')}, /* Garo */
{"gru", HB_TAG('S','O','G',' ')}, /* Sodo Gurage */
{"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */
+ {"guc", HB_TAG('G','U','C',' ')}, /* Wayuu */
{"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */
- {"gv", HB_TAG('M','N','X',' ')}, /* Manx Gaelic */
+/*{"guk", HB_TAG('G','U','K',' ')},*/ /* Gumuz (in SIL fonts) */
+ {"guz", HB_TAG('G','U','Z',' ')}, /* Ekegusii/Gusii */
+ {"gv", HB_TAG('M','N','X',' ')}, /* Manx */
{"ha", HB_TAG('H','A','U',' ')}, /* Hausa */
{"har", HB_TAG('H','R','I',' ')}, /* Harari */
- {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiin */
+ {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiian */
+ {"hay", HB_TAG('H','A','Y',' ')}, /* Haya */
+ {"haz", HB_TAG('H','A','Z',' ')}, /* Hazaragi */
{"he", HB_TAG('I','W','R',' ')}, /* Hebrew */
+ {"hz", HB_TAG('H','E','R',' ')}, /* Herero */
{"hi", HB_TAG('H','I','N',' ')}, /* Hindi */
{"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */
{"hnd", HB_TAG('H','N','D',' ')}, /* [Southern] Hindko */
{"hne", HB_TAG('C','H','H',' ')}, /* Chattisgarhi */
{"hno", HB_TAG('H','N','D',' ')}, /* [Northern] Hindko */
+ {"ho", HB_TAG('H','M','O',' ')}, /* Hiri Motu */
{"hoc", HB_TAG('H','O',' ',' ')}, /* Ho */
{"hoj", HB_TAG('H','A','R',' ')}, /* Harauti */
{"hr", HB_TAG('H','R','V',' ')}, /* Croatian */
{"hsb", HB_TAG('U','S','B',' ')}, /* Upper Sorbian */
- {"ht", HB_TAG('H','A','I',' ')}, /* Haitian */
+ {"ht", HB_TAG('H','A','I',' ')}, /* Haitian/Haitian Creole */
{"hu", HB_TAG('H','U','N',' ')}, /* Hungarian */
{"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */
+ {"hz", HB_TAG('H','E','R',' ')}, /* Herero */
+ {"ia", HB_TAG('I','N','A',' ')}, /* Interlingua (International Auxiliary Language Association) */
+ {"ibb", HB_TAG('I','B','B',' ')}, /* Ibibio */
{"id", HB_TAG('I','N','D',' ')}, /* Indonesian */
+ {"ie", HB_TAG('I','L','E',' ')}, /* Interlingue/Occidental */
{"ig", HB_TAG('I','B','O',' ')}, /* Igbo */
{"igb", HB_TAG('E','B','I',' ')}, /* Ebira */
+ {"ijc", HB_TAG('I','J','O',' ')}, /* Izon */
{"ijo", HB_TAG('I','J','O',' ')}, /* Ijo [family] */
+ {"ik", HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] */
{"ilo", HB_TAG('I','L','O',' ')}, /* Ilokano */
{"inh", HB_TAG('I','N','G',' ')}, /* Ingush */
+ {"io", HB_TAG('I','D','O',' ')}, /* Ido */
{"is", HB_TAG('I','S','L',' ')}, /* Icelandic */
{"it", HB_TAG('I','T','A',' ')}, /* Italian */
- {"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut */
+ {"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut [macrolanguage] */
{"ja", HB_TAG('J','A','N',' ')}, /* Japanese */
+ {"jam", HB_TAG('J','A','M',' ')}, /* Jamaican Creole English */
+ {"jbo", HB_TAG('J','B','O',' ')}, /* Lojban */
{"jv", HB_TAG('J','A','V',' ')}, /* Javanese */
{"ka", HB_TAG('K','A','T',' ')}, /* Georgian */
{"kaa", HB_TAG('K','R','K',' ')}, /* Karakalpak */
+ {"kab", HB_TAG('K','A','B',' ')}, /* Kabyle */
{"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */
{"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */
{"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */
+ {"kde", HB_TAG('K','D','E',' ')}, /* Makonde */
{"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */
{"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */
{"kex", HB_TAG('K','K','N',' ')}, /* Kokni */
{"kfr", HB_TAG('K','A','C',' ')}, /* Kachchi */
{"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */
+ {"kg", HB_TAG('K','O','N',' ')}, /* Kongo [macrolanguage] */
{"kha", HB_TAG('K','S','I',' ')}, /* Khasi */
- {"khb", HB_TAG('X','B','D',' ')}, /* Tai Lue */
+ {"khb", HB_TAG('X','B','D',' ')}, /* Lü */
+ {"kht", HB_TAG('K','H','N',' ')}, /* Khamti (Microsoft fonts) */
+/*{"kht", HB_TAG('K','H','T',' ')},*/ /* Khamti (OpenType spec and SIL fonts) */
{"khw", HB_TAG('K','H','W',' ')}, /* Khowar */
- {"ki", HB_TAG('K','I','K',' ')}, /* Kikuyu */
+ {"ki", HB_TAG('K','I','K',' ')}, /* Gikuyu/Kikuyu */
+ {"kj", HB_TAG('K','U','A',' ')}, /* Kuanyama/Kwanyama */
{"kjh", HB_TAG('K','H','A',' ')}, /* Khakass */
+ {"kjp", HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen */
{"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */
{"kl", HB_TAG('G','R','N',' ')}, /* Kalaallisut */
{"kln", HB_TAG('K','A','L',' ')}, /* Kalenjin */
{"km", HB_TAG('K','H','M',' ')}, /* Central Khmer */
- {"kmb", HB_TAG('M','B','N',' ')}, /* [North] Mbundu */
+ {"kmb", HB_TAG('M','B','N',' ')}, /* Kimbundu */
{"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */
{"kn", HB_TAG('K','A','N',' ')}, /* Kannada */
+ {"knn", HB_TAG('K','O','K',' ')}, /* Konkani */
{"ko", HB_TAG('K','O','R',' ')}, /* Korean */
{"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */
- {"kok", HB_TAG('K','O','K',' ')}, /* Konkani */
- {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle */
+ {"kok", HB_TAG('K','O','K',' ')}, /* Konkani [macrolanguage] */
+ {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle [macrolanguage] */
{"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */
{"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */
{"kqy", HB_TAG('K','R','T',' ')}, /* Koorete */
- {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri */
+ {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri [macrolanguage] */
{"kri", HB_TAG('K','R','I',' ')}, /* Krio */
{"krl", HB_TAG('K','R','L',' ')}, /* Karelian */
{"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */
{"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */
- {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish */
+ {"ksh", HB_TAG('K','S','H',' ')}, /* Kölsch */
+/*{"ksw", HB_TAG('K','R','N',' ')},*/ /* S'gaw Karen (Microsoft fonts?) */
+ {"ksw", HB_TAG('K','S','W',' ')}, /* S'gaw Karen (OpenType spec and SIL fonts) */
+ {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish [macrolanguage] */
{"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */
+ {"kv", HB_TAG('K','O','M',' ')}, /* Komi [macrolanguage] */
{"kvd", HB_TAG('K','U','I',' ')}, /* Kui (Indonesia) */
+ {"kw", HB_TAG('C','O','R',' ')}, /* Cornish */
{"kxc", HB_TAG('K','M','S',' ')}, /* Komso */
{"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */
- {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz */
+ {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz/Kyrgyz */
+ {"kyu", HB_TAG('K','Y','U',' ')}, /* Western Kayah */
{"la", HB_TAG('L','A','T',' ')}, /* Latin */
{"lad", HB_TAG('J','U','D',' ')}, /* Ladino */
{"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */
{"lbe", HB_TAG('L','A','K',' ')}, /* Lak */
{"lbj", HB_TAG('L','D','K',' ')}, /* Ladakhi */
{"lez", HB_TAG('L','E','Z',' ')}, /* Lezgi */
- {"lg", HB_TAG('L','U','G',' ')}, /* Luganda */
+ {"lg", HB_TAG('L','U','G',' ')}, /* Ganda */
+ {"li", HB_TAG('L','I','M',' ')}, /* Limburgan/Limburger/Limburgish */
{"lif", HB_TAG('L','M','B',' ')}, /* Limbu */
+ {"lij", HB_TAG('L','I','J',' ')}, /* Ligurian */
+ {"lis", HB_TAG('L','I','S',' ')}, /* Lisu */
+ {"ljp", HB_TAG('L','J','P',' ')}, /* Lampung Api */
+ {"lki", HB_TAG('L','K','I',' ')}, /* Laki */
{"lld", HB_TAG('L','A','D',' ')}, /* Ladin */
{"lmn", HB_TAG('L','A','M',' ')}, /* Lambani */
+ {"lmo", HB_TAG('L','M','O',' ')}, /* Lombard */
{"ln", HB_TAG('L','I','N',' ')}, /* Lingala */
{"lo", HB_TAG('L','A','O',' ')}, /* Lao */
+ {"lrc", HB_TAG('L','R','C',' ')}, /* Northern Luri */
{"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */
{"lu", HB_TAG('L','U','B',' ')}, /* Luba-Katanga */
{"lua", HB_TAG('L','U','B',' ')}, /* Luba-Kasai */
{"luo", HB_TAG('L','U','O',' ')}, /* Luo (Kenya and Tanzania) */
{"lus", HB_TAG('M','I','Z',' ')}, /* Mizo */
- {"luy", HB_TAG('L','U','H',' ')}, /* Luhya [macrolanguage] */
+ {"luy", HB_TAG('L','U','H',' ')}, /* Luyia/Oluluyia [macrolanguage] */
+ {"luz", HB_TAG('L','R','C',' ')}, /* Southern Luri */
{"lv", HB_TAG('L','V','I',' ')}, /* Latvian */
{"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */
+ {"mad", HB_TAG('M','A','D',' ')}, /* Madurese */
+ {"mag", HB_TAG('M','A','G',' ')}, /* Magahi */
{"mai", HB_TAG('M','T','H',' ')}, /* Maithili */
+ {"mak", HB_TAG('M','K','R',' ')}, /* Makasar */
+ {"man", HB_TAG('M','N','K',' ')}, /* Manding/Mandingo [macrolanguage] */
{"mdc", HB_TAG('M','L','E',' ')}, /* Male (Papua New Guinea) */
{"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */
+ {"mdr", HB_TAG('M','D','R',' ')}, /* Mandar */
{"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */
{"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */
- {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy */
+ {"mer", HB_TAG('M','E','R',' ')}, /* Meru */
+ {"mfe", HB_TAG('M','F','E',' ')}, /* Morisyen */
+ {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy [macrolanguage] */
+ {"mh", HB_TAG('M','A','H',' ')}, /* Marshallese */
{"mhr", HB_TAG('L','M','A',' ')}, /* Low Mari */
{"mi", HB_TAG('M','R','I',' ')}, /* Maori */
+ {"min", HB_TAG('M','I','N',' ')}, /* Minangkabau */
{"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */
+ {"mku", HB_TAG('M','N','K',' ')}, /* Konyanka Maninka */
+ {"mkw", HB_TAG('M','K','W',' ')}, /* Kituba (Congo) */
{"ml", HB_TAG('M','L','R',' ')}, /* Malayalam */
- {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian */
+ {"mlq", HB_TAG('M','N','K',' ')}, /* Western Maninkakan */
+ {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian [macrolanguage] */
{"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */
{"mni", HB_TAG('M','N','I',' ')}, /* Manipuri */
{"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */
@@ -396,72 +496,119 @@ static const LangTag ot_languages[] = {
{"mnw", HB_TAG('M','O','N',' ')}, /* Mon */
{"mo", HB_TAG('M','O','L',' ')}, /* Moldavian */
{"moh", HB_TAG('M','O','H',' ')}, /* Mohawk */
+ {"mos", HB_TAG('M','O','S',' ')}, /* Mossi */
{"mpe", HB_TAG('M','A','J',' ')}, /* Majang */
{"mr", HB_TAG('M','A','R',' ')}, /* Marathi */
{"mrj", HB_TAG('H','M','A',' ')}, /* High Mari */
- {"ms", HB_TAG('M','L','Y',' ')}, /* Malay */
+ {"ms", HB_TAG('M','L','Y',' ')}, /* Malay [macrolanguage] */
+ {"msc", HB_TAG('M','N','K',' ')}, /* Sankaran Maninka */
{"mt", HB_TAG('M','T','S',' ')}, /* Maltese */
- {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari */
+ {"mtr", HB_TAG('M','A','W',' ')}, /* Mewari */
+ {"mus", HB_TAG('M','U','S',' ')}, /* Creek */
+ {"mve", HB_TAG('M','A','W',' ')}, /* Marwari (Pakistan) */
+ {"mwk", HB_TAG('M','N','K',' ')}, /* Kita Maninkakan */
+ {"mwl", HB_TAG('M','W','L',' ')}, /* Mirandese */
+ {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari [macrolanguage] */
+ {"mww", HB_TAG('M','W','W',' ')}, /* Hmong Daw */
{"my", HB_TAG('B','R','M',' ')}, /* Burmese */
{"mym", HB_TAG('M','E','N',' ')}, /* Me'en */
+ {"myq", HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) */
{"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */
+ {"mzn", HB_TAG('M','Z','N',' ')}, /* Mazanderani */
+ {"na", HB_TAG('N','A','U',' ')}, /* Nauru */
{"nag", HB_TAG('N','A','G',' ')}, /* Naga-Assamese */
+ {"nah", HB_TAG('N','A','H',' ')}, /* Nahuatl [family] */
+ {"nap", HB_TAG('N','A','P',' ')}, /* Neapolitan */
{"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål */
{"nco", HB_TAG('S','I','B',' ')}, /* Sibe */
{"nd", HB_TAG('N','D','B',' ')}, /* [North] Ndebele */
+ {"ndc", HB_TAG('N','D','C',' ')}, /* Ndau */
+ {"nds", HB_TAG('N','D','S',' ')}, /* Low German/Low Saxon */
{"ne", HB_TAG('N','E','P',' ')}, /* Nepali */
{"new", HB_TAG('N','E','W',' ')}, /* Newari */
{"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */
+ {"nga", HB_TAG('N','G','A',' ')}, /* Ngabaka */
{"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */
{"niu", HB_TAG('N','I','U',' ')}, /* Niuean */
{"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */
{"nl", HB_TAG('N','L','D',' ')}, /* Dutch */
{"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk */
- {"no", HB_TAG('N','O','R',' ')}, /* Norwegian (deprecated) */
- {"nod", HB_TAG('N','T','A',' ')}, /* Northern Tai */
+ {"no", HB_TAG('N','O','R',' ')}, /* Norwegian [macrolanguage] */
+ {"nod", HB_TAG('N','T','A',' ')}, /* Northern Thai */
+ {"noe", HB_TAG('N','O','E',' ')}, /* Nimadi */
{"nog", HB_TAG('N','O','G',' ')}, /* Nogai */
+ {"nov", HB_TAG('N','O','V',' ')}, /* Novial */
{"nqo", HB_TAG('N','K','O',' ')}, /* N'Ko */
{"nr", HB_TAG('N','D','B',' ')}, /* [South] Ndebele */
{"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */
{"nso", HB_TAG('S','O','T',' ')}, /* [Northern] Sotho */
- {"ny", HB_TAG('C','H','I',' ')}, /* Nyanja */
- {"nyn", HB_TAG('N','K','L',' ')}, /* Nkole */
+ {"ny", HB_TAG('C','H','I',' ')}, /* Chewa/Chichwa/Nyanja */
+ {"nym", HB_TAG('N','Y','M',' ')}, /* Nyamwezi */
+ {"nyn", HB_TAG('N','K','L',' ')}, /* Nyankole */
{"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */
- {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa */
+ {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] */
{"ojs", HB_TAG('O','C','R',' ')}, /* Oji-Cree */
- {"om", HB_TAG('O','R','O',' ')}, /* Oromo */
+ {"om", HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */
{"or", HB_TAG('O','R','I',' ')}, /* Oriya */
{"os", HB_TAG('O','S','S',' ')}, /* Ossetian */
{"pa", HB_TAG('P','A','N',' ')}, /* Panjabi */
+ {"pag", HB_TAG('P','A','G',' ')}, /* Pangasinan */
+ {"pam", HB_TAG('P','A','M',' ')}, /* Kapampangan/Pampanga */
+ {"pap", HB_TAG('P','A','P',' ')}, /* Papiamento */
+ {"pcc", HB_TAG('P','C','C',' ')}, /* Bouyei */
+ {"pcd", HB_TAG('P','C','D',' ')}, /* Picard */
{"pce", HB_TAG('P','L','G',' ')}, /* [Ruching] Palaung */
+ {"pdc", HB_TAG('P','D','C',' ')}, /* Pennsylvania German */
+ {"pes", HB_TAG('F','A','R',' ')}, /* Iranian Persian */
+ {"phk", HB_TAG('P','H','K',' ')}, /* Phake */
{"pi", HB_TAG('P','A','L',' ')}, /* Pali */
+ {"pih", HB_TAG('P','I','H',' ')}, /* Pitcairn-Norfolk */
{"pl", HB_TAG('P','L','K',' ')}, /* Polish */
{"pll", HB_TAG('P','L','G',' ')}, /* [Shwe] Palaung */
{"plp", HB_TAG('P','A','P',' ')}, /* Palpa */
- {"prs", HB_TAG('D','R','I',' ')}, /* Dari */
- {"ps", HB_TAG('P','A','S',' ')}, /* Pushto */
+ {"pms", HB_TAG('P','M','S',' ')}, /* Piemontese */
+ {"pnb", HB_TAG('P','N','B',' ')}, /* Western Panjabi */
+ {"prs", HB_TAG('D','R','I',' ')}, /* Afghan Persian/Dari */
+ {"ps", HB_TAG('P','A','S',' ')}, /* Pashto/Pushto [macrolanguage] */
{"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */
- {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani */
- {"rbb", HB_TAG('P','L','G',' ')}, /* [Rumai] Palaung */
+ {"pwo", HB_TAG('P','W','O',' ')}, /* Pwo Western Karen */
+ {"qu", HB_TAG('Q','U','Z',' ')}, /* Quechua [macrolanguage] */
+ {"quc", HB_TAG('Q','U','C',' ')}, /* K'iche'/Quiché */
+ {"quz", HB_TAG('Q','U','Z',' ')}, /* Cusco Quechua */
+ {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani [macrolanguage] */
+ {"rbb", HB_TAG('P','L','G',' ')}, /* Rumai Palaung */
+ {"rej", HB_TAG('R','E','J',' ')}, /* Rejang */
{"ria", HB_TAG('R','I','A',' ')}, /* Riang (India) */
{"ril", HB_TAG('R','I','A',' ')}, /* Riang (Myanmar) */
- {"rki", HB_TAG('A','R','K',' ')}, /* Arakanese */
- {"rm", HB_TAG('R','M','S',' ')}, /* Rhaeto-Romanic */
+ {"rki", HB_TAG('A','R','K',' ')}, /* Rakhine */
+ {"rm", HB_TAG('R','M','S',' ')}, /* Romansh */
+ {"rmy", HB_TAG('R','M','Y',' ')}, /* Vlax Romani */
+ {"rn", HB_TAG('R','U','N',' ')}, /* Rundi */
{"ro", HB_TAG('R','O','M',' ')}, /* Romanian */
- {"rom", HB_TAG('R','O','Y',' ')}, /* Romany */
+ {"rom", HB_TAG('R','O','Y',' ')}, /* Romany [macrolanguage] */
{"ru", HB_TAG('R','U','S',' ')}, /* Russian */
{"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */
- {"rw", HB_TAG('R','U','A',' ')}, /* Ruanda */
+ {"rup", HB_TAG('R','U','P',' ')}, /* Aromanian/Arumanian/Macedo-Romanian */
+ {"rw", HB_TAG('R','U','A',' ')}, /* Kinyarwanda */
+ {"rwr", HB_TAG('M','A','W',' ')}, /* Marwari (India) */
{"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */
{"sah", HB_TAG('Y','A','K',' ')}, /* Yakut */
+ {"sas", HB_TAG('S','A','S',' ')}, /* Sasak */
{"sat", HB_TAG('S','A','T',' ')}, /* Santali */
{"sck", HB_TAG('S','A','D',' ')}, /* Sadri */
+ {"sc", HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */
+ {"scn", HB_TAG('S','C','N',' ')}, /* Sicilian */
+ {"sco", HB_TAG('S','C','O',' ')}, /* Scots */
{"scs", HB_TAG('S','L','A',' ')}, /* [North] Slavey */
{"sd", HB_TAG('S','N','D',' ')}, /* Sindhi */
{"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */
{"seh", HB_TAG('S','N','A',' ')}, /* Sena */
{"sel", HB_TAG('S','E','L',' ')}, /* Selkup */
{"sg", HB_TAG('S','G','O',' ')}, /* Sango */
+ {"sga", HB_TAG('S','G','A',' ')}, /* Old Irish (to 900) */
+ {"sgs", HB_TAG('S','G','S',' ')}, /* Samogitian */
+ {"sgw", HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage */
+/*{"sgw", HB_TAG('S','G','W',' ')},*/ /* Sebat Bet Gurage (in SIL fonts) */
{"shn", HB_TAG('S','H','N',' ')}, /* Shan */
{"si", HB_TAG('S','N','H',' ')}, /* Sinhala */
{"sid", HB_TAG('S','I','D',' ')}, /* Sidamo */
@@ -474,60 +621,98 @@ static const LangTag ot_languages[] = {
{"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */
{"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */
{"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */
+ {"sn", HB_TAG('S','N','A',' ')}, /* Shona */
{"snk", HB_TAG('S','N','K',' ')}, /* Soninke */
{"so", HB_TAG('S','M','L',' ')}, /* Somali */
- {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian */
+ {"sop", HB_TAG('S','O','P',' ')}, /* Songe */
+ {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian [macrolanguage] */
{"sr", HB_TAG('S','R','B',' ')}, /* Serbian */
{"srr", HB_TAG('S','R','R',' ')}, /* Serer */
- {"ss", HB_TAG('S','W','Z',' ')}, /* Swazi */
+ {"ss", HB_TAG('S','W','Z',' ')}, /* Swati */
{"st", HB_TAG('S','O','T',' ')}, /* [Southern] Sotho */
+ {"stq", HB_TAG('S','T','Q',' ')}, /* Saterfriesisch */
+ {"stv", HB_TAG('S','I','G',' ')}, /* Silt'e */
+ {"su", HB_TAG('S','U','N',' ')}, /* Sundanese */
+ {"suk", HB_TAG('S','U','K',' ')}, /* Sukama */
{"suq", HB_TAG('S','U','R',' ')}, /* Suri */
{"sv", HB_TAG('S','V','E',' ')}, /* Swedish */
{"sva", HB_TAG('S','V','A',' ')}, /* Svan */
- {"sw", HB_TAG('S','W','K',' ')}, /* Swahili */
+ {"sw", HB_TAG('S','W','K',' ')}, /* Swahili [macrolanguage] */
{"swb", HB_TAG('C','M','R',' ')}, /* Comorian */
- {"syr", HB_TAG('S','Y','R',' ')}, /* Syriac */
+ {"swh", HB_TAG('S','W','K',' ')}, /* Kiswahili/Swahili */
+ {"swv", HB_TAG('M','A','W',' ')}, /* Shekhawati */
+ {"sxu", HB_TAG('S','X','U',' ')}, /* Upper Saxon */
+ {"syl", HB_TAG('S','Y','L',' ')}, /* Sylheti */
+ {"syr", HB_TAG('S','Y','R',' ')}, /* Syriac [macrolanguage] */
+ {"szl", HB_TAG('S','Z','L',' ')}, /* Silesian */
{"ta", HB_TAG('T','A','M',' ')}, /* Tamil */
{"tab", HB_TAG('T','A','B',' ')}, /* Tabasaran */
{"tcy", HB_TAG('T','U','L',' ')}, /* Tulu */
+ {"tdd", HB_TAG('T','D','D',' ')}, /* Tai Nüa */
{"te", HB_TAG('T','E','L',' ')}, /* Telugu */
{"tem", HB_TAG('T','M','N',' ')}, /* Temne */
+ {"tet", HB_TAG('T','E','T',' ')}, /* Tetum */
{"tg", HB_TAG('T','A','J',' ')}, /* Tajik */
{"th", HB_TAG('T','H','A',' ')}, /* Thai */
{"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */
{"tig", HB_TAG('T','G','R',' ')}, /* Tigre */
+ {"tiv", HB_TAG('T','I','V',' ')}, /* Tiv */
{"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */
+ {"tl", HB_TAG('T','G','L',' ')}, /* Tagalog */
+ {"tmh", HB_TAG('t','m','h',' ')}, /* Tamashek [macrolanguage] */
{"tn", HB_TAG('T','N','A',' ')}, /* Tswana */
{"to", HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) */
+ {"tpi", HB_TAG('T','P','I',' ')}, /* Tok Pisin */
{"tr", HB_TAG('T','R','K',' ')}, /* Turkish */
{"tru", HB_TAG('T','U','A',' ')}, /* Turoyo Aramaic */
{"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */
{"tt", HB_TAG('T','A','T',' ')}, /* Tatar */
+ {"tum", HB_TAG('T','U','M',' ')}, /* Tumbuka */
{"tw", HB_TAG('T','W','I',' ')}, /* Twi */
{"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */
{"tyv", HB_TAG('T','U','V',' ')}, /* Tuvin */
+ {"tyz", HB_TAG('T','Y','Z',' ')}, /* Tày */
+ {"tzm", HB_TAG('T','Z','M',' ')}, /* Central Atlas Tamazight */
{"udm", HB_TAG('U','D','M',' ')}, /* Udmurt */
{"ug", HB_TAG('U','Y','G',' ')}, /* Uighur */
{"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */
- {"umb", HB_TAG('M','B','N',' ')}, /* [South] Mbundu */
+ {"umb", HB_TAG('U','M','B',' ')}, /* Umbundu */
{"unr", HB_TAG('M','U','N',' ')}, /* Mundari */
{"ur", HB_TAG('U','R','D',' ')}, /* Urdu */
- {"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek */
+ {"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek [macrolanguage] */
+ {"uzn", HB_TAG('U','Z','B',' ')}, /* Northern Uzbek */
+ {"uzs", HB_TAG('U','Z','B',' ')}, /* Southern Uzbek */
{"ve", HB_TAG('V','E','N',' ')}, /* Venda */
+ {"vec", HB_TAG('V','E','C',' ')}, /* Venetian */
+ {"vls", HB_TAG('F','L','E',' ')}, /* Vlaams */
{"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */
- {"vmw", HB_TAG('M','A','K',' ')}, /* Makua */
+ {"vmw", HB_TAG('M','A','K',' ')}, /* Makhuwa */
+ {"vo", HB_TAG('V','O','L',' ')}, /* Volapük */
+ {"vro", HB_TAG('V','R','O',' ')}, /* Võro */
+ {"wa", HB_TAG('W','L','N',' ')}, /* Walloon */
+ {"war", HB_TAG('W','A','R',' ')}, /* Waray (Philippines) */
{"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */
{"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */
+ {"wle", HB_TAG('S','I','G',' ')}, /* Wolane */
+ {"wry", HB_TAG('M','A','W',' ')}, /* Merwari */
+ {"wtm", HB_TAG('W','T','M',' ')}, /* Mewati */
{"wo", HB_TAG('W','L','F',' ')}, /* Wolof */
{"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */
{"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */
+ {"xog", HB_TAG('X','O','G',' ')}, /* Soga */
{"xom", HB_TAG('K','M','O',' ')}, /* Komo (Sudan) */
{"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */
- {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish */
+ {"xst", HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) */
+ {"xwo", HB_TAG('T','O','D',' ')}, /* Written Oirat (Todo) */
+ {"yao", HB_TAG('Y','A','O',' ')}, /* Yao */
+ {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */
{"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */
{"yso", HB_TAG('N','I','S',' ')}, /* Nisi (China) */
+ {"za", HB_TAG('Z','H','A',' ')}, /* Chuang/Zhuang [macrolanguage] */
+ {"zea", HB_TAG('Z','E','A',' ')}, /* Zeeuws */
{"zne", HB_TAG('Z','N','D',' ')}, /* Zande */
- {"zu", HB_TAG('Z','U','L',' ')} /* Zulu */
+ {"zu", HB_TAG('Z','U','L',' ')}, /* Zulu */
+ {"zum", HB_TAG('L','R','C',' ')} /* Kumzari */
/* The corresponding languages IDs for the following IDs are unclear,
* overlap, or are architecturally weird. Needs more research. */
@@ -536,13 +721,13 @@ static const LangTag ot_languages[] = {
/*{"gsw?/gsw-FR?", HB_TAG('A','L','S',' ')},*/ /* Alsatian */
/*{"krc", HB_TAG('B','A','L',' ')},*/ /* Balkar */
/*{"??", HB_TAG('B','C','R',' ')},*/ /* Bible Cree */
-/*{"sgw?", HB_TAG('C','H','G',' ')},*/ /* Chaha Gurage */
+/*{"zh?", HB_TAG('C','H','N',' ')},*/ /* Chinese (seen in Microsoft fonts) */
/*{"acf/gcf?", HB_TAG('F','A','N',' ')},*/ /* French Antillean */
-/*{"vls/nl-be", HB_TAG('F','L','E',' ')},*/ /* Flemish */
/*{"enf?/yrk?", HB_TAG('F','N','E',' ')},*/ /* Forest Nenets */
/*{"fuf?", HB_TAG('F','T','A',' ')},*/ /* Futa */
/*{"ar-Syrc?", HB_TAG('G','A','R',' ')},*/ /* Garshuni */
/*{"cfm/rnl?", HB_TAG('H','A','L',' ')},*/ /* Halam */
+/*{"fonipa", HB_TAG('I','P','P','H')},*/ /* Phonetic transcription—IPA conventions */
/*{"ga-Latg?/Latg?", HB_TAG('I','R','T',' ')},*/ /* Irish Traditional */
/*{"krc", HB_TAG('K','A','R',' ')},*/ /* Karachay */
/*{"alw?/ktb?", HB_TAG('K','E','B',' ')},*/ /* Kebena */
@@ -559,8 +744,6 @@ static const LangTag ot_languages[] = {
/*{"??", HB_TAG('L','C','R',' ')},*/ /* L-Cree */
/*{"??", HB_TAG('M','A','L',' ')},*/ /* Malayalam Traditional */
/*{"mnk?/mlq?/...", HB_TAG('M','L','N',' ')},*/ /* Malinke */
-/*{"man?/myq?/mku?/msc?/...", HB_TAG('M','N','K',' ')},*/ /* Maninka */
-/*{"??", HB_TAG('M','O','R',' ')},*/ /* Moroccan */
/*{"??", HB_TAG('N','C','R',' ')},*/ /* N-Cree */
/*{"??", HB_TAG('N','H','C',' ')},*/ /* Norway House Cree */
/*{"jpa?/sam?", HB_TAG('P','A','A',' ')},*/ /* Palestinian Aramaic */
@@ -569,14 +752,12 @@ static const LangTag ot_languages[] = {
/*{"??", HB_TAG('R','C','R',' ')},*/ /* R-Cree */
/*{"chp?", HB_TAG('S','A','Y',' ')},*/ /* Sayisi */
/*{"xan?", HB_TAG('S','E','K',' ')},*/ /* Sekota */
-/*{"stv/wle?/xst?", HB_TAG('S','I','G',' ')},*/ /* Silte Gurage */
/*{"ngo?", HB_TAG('S','X','T',' ')},*/ /* Sutu */
/*{"??", HB_TAG('T','C','R',' ')},*/ /* TH-Cree */
/*{"tnz?/tog?/toi?", HB_TAG('T','N','G',' ')},*/ /* Tonga */
/*{"enh?/yrk?", HB_TAG('T','N','E',' ')},*/ /* Tundra Nenets */
-/*{"??", HB_TAG('T','O','D',' ')},*/ /* Todo */
/*{"??", HB_TAG('W','C','R',' ')},*/ /* West-Cree */
-/*{"??", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */
+/*{"cre?", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */
/*{"??", HB_TAG('Y','I','C',' ')},*/ /* Yi Classic */
/*{"ii?/Yiii?", HB_TAG('Y','I','M',' ')},*/ /* Yi Modern */
/*{"??", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-private.hh
index 4152e27552..4b72260ed5 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-private.hh
@@ -79,6 +79,9 @@ static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
template <typename Type>
static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
+static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
+{ return (a + (b - 1)) / b; }
+
#undef ARRAY_LENGTH
template <typename Type, unsigned int n>
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
index adfa88f18e..705f554ce6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
@@ -28,7 +28,6 @@
#define HB_SET_PRIVATE_HH
#include "hb-private.hh"
-#include "hb-set.h"
#include "hb-object-private.hh"
@@ -171,7 +170,7 @@ struct hb_set_t
inline void add (hb_codepoint_t g)
{
if (unlikely (in_error)) return;
- if (unlikely (g == SENTINEL)) return;
+ if (unlikely (g == INVALID)) return;
if (unlikely (g > MAX_G)) return;
elt (g) |= mask (g);
}
@@ -256,19 +255,22 @@ struct hb_set_t
}
inline bool next (hb_codepoint_t *codepoint) const
{
- if (unlikely (*codepoint == SENTINEL)) {
+ if (unlikely (*codepoint == INVALID)) {
hb_codepoint_t i = get_min ();
- if (i != SENTINEL) {
+ if (i != INVALID) {
*codepoint = i;
return true;
- } else
+ } else {
+ *codepoint = INVALID;
return false;
+ }
}
for (hb_codepoint_t i = *codepoint + 1; i < MAX_G + 1; i++)
if (has (i)) {
*codepoint = i;
return true;
}
+ *codepoint = INVALID;
return false;
}
inline bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const
@@ -277,7 +279,10 @@ struct hb_set_t
i = *last;
if (!next (&i))
+ {
+ *last = *first = INVALID;
return false;
+ }
*last = *first = i;
while (next (&i) && i == *last + 1)
@@ -300,7 +305,7 @@ struct hb_set_t
for (unsigned int j = 0; j < BITS; j++)
if (elts[i] & (1 << j))
return i * BITS + j;
- return SENTINEL;
+ return INVALID;
}
inline hb_codepoint_t get_max (void) const
{
@@ -309,7 +314,7 @@ struct hb_set_t
for (unsigned int j = BITS; j; j--)
if (elts[i - 1] & (1 << (j - 1)))
return (i - 1) * BITS + (j - 1);
- return SENTINEL;
+ return INVALID;
}
typedef uint32_t elt_t;
@@ -318,7 +323,7 @@ struct hb_set_t
static const unsigned int BITS = (1 << SHIFT);
static const unsigned int MASK = BITS - 1;
static const unsigned int ELTS = (MAX_G + 1 + (BITS - 1)) / BITS;
- static const hb_codepoint_t SENTINEL = (hb_codepoint_t) -1;
+ static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID;
elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.cc b/src/3rdparty/harfbuzz-ng/src/hb-set.cc
index 3c9573fbce..59a0af46ed 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-set.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set.cc
@@ -30,6 +30,13 @@
/* Public API */
+/**
+ * hb_set_create: (Xconstructor)
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_set_t *
hb_set_create (void)
{
@@ -43,6 +50,13 @@ hb_set_create (void)
return set;
}
+/**
+ * hb_set_get_empty:
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_set_t *
hb_set_get_empty (void)
{
@@ -56,12 +70,26 @@ hb_set_get_empty (void)
return const_cast<hb_set_t *> (&_hb_set_nil);
}
+/**
+ * hb_set_reference: (skip)
+ * @set: a set.
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_set_t *
hb_set_reference (hb_set_t *set)
{
return hb_object_reference (set);
}
+/**
+ * hb_set_destroy: (skip)
+ * @set: a set.
+ *
+ * Since: 1.0
+ **/
void
hb_set_destroy (hb_set_t *set)
{
@@ -72,6 +100,18 @@ hb_set_destroy (hb_set_t *set)
free (set);
}
+/**
+ * hb_set_set_user_data: (skip)
+ * @set: a set.
+ * @key:
+ * @data:
+ * @destroy (closure data):
+ * @replace:
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_set_user_data (hb_set_t *set,
hb_user_data_key_t *key,
@@ -82,6 +122,15 @@ hb_set_set_user_data (hb_set_t *set,
return hb_object_set_user_data (set, key, data, destroy, replace);
}
+/**
+ * hb_set_get_user_data: (skip)
+ * @set: a set.
+ * @key:
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_set_get_user_data (hb_set_t *set,
hb_user_data_key_t *key)
@@ -90,24 +139,63 @@ hb_set_get_user_data (hb_set_t *set,
}
+/**
+ * hb_set_allocation_successful:
+ * @set: a set.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_allocation_successful (const hb_set_t *set HB_UNUSED)
{
return !set->in_error;
}
+/**
+ * hb_set_clear:
+ * @set: a set.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_clear (hb_set_t *set)
{
set->clear ();
}
+/**
+ * hb_set_is_empty:
+ * @set: a set.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_is_empty (const hb_set_t *set)
{
return set->is_empty ();
}
+/**
+ * hb_set_has:
+ * @set: a set.
+ * @codepoint:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_has (const hb_set_t *set,
hb_codepoint_t codepoint)
@@ -115,6 +203,15 @@ hb_set_has (const hb_set_t *set,
return set->has (codepoint);
}
+/**
+ * hb_set_add:
+ * @set: a set.
+ * @codepoint:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_add (hb_set_t *set,
hb_codepoint_t codepoint)
@@ -122,6 +219,16 @@ hb_set_add (hb_set_t *set,
set->add (codepoint);
}
+/**
+ * hb_set_add_range:
+ * @set: a set.
+ * @first:
+ * @last:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_add_range (hb_set_t *set,
hb_codepoint_t first,
@@ -130,6 +237,15 @@ hb_set_add_range (hb_set_t *set,
set->add_range (first, last);
}
+/**
+ * hb_set_del:
+ * @set: a set.
+ * @codepoint:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_del (hb_set_t *set,
hb_codepoint_t codepoint)
@@ -137,6 +253,16 @@ hb_set_del (hb_set_t *set,
set->del (codepoint);
}
+/**
+ * hb_set_del_range:
+ * @set: a set.
+ * @first:
+ * @last:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_del_range (hb_set_t *set,
hb_codepoint_t first,
@@ -145,6 +271,17 @@ hb_set_del_range (hb_set_t *set,
set->del_range (first, last);
}
+/**
+ * hb_set_is_equal:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_is_equal (const hb_set_t *set,
const hb_set_t *other)
@@ -152,6 +289,15 @@ hb_set_is_equal (const hb_set_t *set,
return set->is_equal (other);
}
+/**
+ * hb_set_set:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_set (hb_set_t *set,
const hb_set_t *other)
@@ -159,6 +305,15 @@ hb_set_set (hb_set_t *set,
set->set (other);
}
+/**
+ * hb_set_union:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_union (hb_set_t *set,
const hb_set_t *other)
@@ -166,6 +321,15 @@ hb_set_union (hb_set_t *set,
set->union_ (other);
}
+/**
+ * hb_set_intersect:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_intersect (hb_set_t *set,
const hb_set_t *other)
@@ -173,6 +337,15 @@ hb_set_intersect (hb_set_t *set,
set->intersect (other);
}
+/**
+ * hb_set_subtract:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_subtract (hb_set_t *set,
const hb_set_t *other)
@@ -180,6 +353,15 @@ hb_set_subtract (hb_set_t *set,
set->subtract (other);
}
+/**
+ * hb_set_symmetric_difference:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_symmetric_difference (hb_set_t *set,
const hb_set_t *other)
@@ -187,30 +369,79 @@ hb_set_symmetric_difference (hb_set_t *set,
set->symmetric_difference (other);
}
+/**
+ * hb_set_invert:
+ * @set: a set.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_invert (hb_set_t *set)
{
set->invert ();
}
+/**
+ * hb_set_get_population:
+ * @set: a set.
+ *
+ * Returns the number of numbers in the set.
+ *
+ * Return value: set population.
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_set_get_population (const hb_set_t *set)
{
return set->get_population ();
}
+/**
+ * hb_set_get_min:
+ * @set: a set.
+ *
+ * Finds the minimum number in the set.
+ *
+ * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty.
+ *
+ * Since: 1.0
+ **/
hb_codepoint_t
hb_set_get_min (const hb_set_t *set)
{
return set->get_min ();
}
+/**
+ * hb_set_get_max:
+ * @set: a set.
+ *
+ * Finds the maximum number in the set.
+ *
+ * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty.
+ *
+ * Since: 1.0
+ **/
hb_codepoint_t
hb_set_get_max (const hb_set_t *set)
{
return set->get_max ();
}
+/**
+ * hb_set_next:
+ * @set: a set.
+ * @codepoint: (inout):
+ *
+ *
+ *
+ * Return value: whether there was a next value.
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_next (const hb_set_t *set,
hb_codepoint_t *codepoint)
@@ -218,6 +449,19 @@ hb_set_next (const hb_set_t *set,
return set->next (codepoint);
}
+/**
+ * hb_set_next_range:
+ * @set: a set.
+ * @first: (out): output first codepoint in the range.
+ * @last: (inout): input current last and output last codepoint in the range.
+ *
+ * Gets the next consecutive range of numbers in @set that
+ * are greater than current value of @last.
+ *
+ * Return value: whether there was a next range.
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_next_range (const hb_set_t *set,
hb_codepoint_t *first,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.h b/src/3rdparty/harfbuzz-ng/src/hb-set.h
index 291e24974e..bafdae9633 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-set.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set.h
@@ -36,6 +36,8 @@
HB_BEGIN_DECLS
+#define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1)
+
typedef struct hb_set_t hb_set_t;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh
index dd014e38d0..607da5e779 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh
@@ -28,7 +28,6 @@
#define HB_SHAPE_PLAN_PRIVATE_HH
#include "hb-private.hh"
-#include "hb-shape-plan.h"
#include "hb-object-private.hh"
#include "hb-shaper-private.hh"
@@ -39,12 +38,15 @@ struct hb_shape_plan_t
ASSERT_POD ();
hb_bool_t default_shaper_list;
- hb_face_t *face;
+ hb_face_t *face_unsafe; /* We don't carry a reference to face. */
hb_segment_properties_t props;
hb_shape_func_t *shaper_func;
const char *shaper_name;
+ hb_feature_t *user_features;
+ unsigned int num_user_features;
+
struct hb_shaper_data_t shaper_data;
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
index a6d2d26210..e354f29176 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
@@ -46,7 +46,7 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
#define HB_SHAPER_PLAN(shaper) \
HB_STMT_START { \
- if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face)) { \
+ if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) { \
HB_SHAPER_DATA (shaper, shape_plan) = \
HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \
shape_plan->shaper_func = _hb_##shaper##_shape; \
@@ -83,6 +83,20 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
* hb_shape_plan_t
*/
+/**
+ * hb_shape_plan_create: (Xconstructor)
+ * @face:
+ * @props:
+ * @user_features: (array length=num_user_features):
+ * @num_user_features:
+ * @shaper_list: (array zero-terminated=1):
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_shape_plan_t *
hb_shape_plan_create (hb_face_t *face,
const hb_segment_properties_t *props,
@@ -93,24 +107,42 @@ hb_shape_plan_create (hb_face_t *face,
assert (props->direction != HB_DIRECTION_INVALID);
hb_shape_plan_t *shape_plan;
+ hb_feature_t *features = NULL;
if (unlikely (!face))
face = hb_face_get_empty ();
if (unlikely (!props || hb_object_is_inert (face)))
return hb_shape_plan_get_empty ();
- if (!(shape_plan = hb_object_create<hb_shape_plan_t> ()))
+ if (num_user_features && !(features = (hb_feature_t *) malloc (num_user_features * sizeof (hb_feature_t))))
return hb_shape_plan_get_empty ();
+ if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) {
+ free (features);
+ return hb_shape_plan_get_empty ();
+ }
hb_face_make_immutable (face);
shape_plan->default_shaper_list = shaper_list == NULL;
- shape_plan->face = hb_face_reference (face);
+ shape_plan->face_unsafe = face;
shape_plan->props = *props;
+ shape_plan->num_user_features = num_user_features;
+ shape_plan->user_features = features;
+ if (num_user_features)
+ memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list);
return shape_plan;
}
+/**
+ * hb_shape_plan_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_shape_plan_t *
hb_shape_plan_get_empty (void)
{
@@ -124,6 +156,9 @@ hb_shape_plan_get_empty (void)
NULL, /* shaper_func */
NULL, /* shaper_name */
+ NULL, /* user_features */
+ 0, /* num_user_featurs */
+
{
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
#include "hb-shaper-list.hh"
@@ -134,12 +169,30 @@ hb_shape_plan_get_empty (void)
return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil);
}
+/**
+ * hb_shape_plan_reference: (skip)
+ * @shape_plan: a shape plan.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_shape_plan_t *
hb_shape_plan_reference (hb_shape_plan_t *shape_plan)
{
return hb_object_reference (shape_plan);
}
+/**
+ * hb_shape_plan_destroy: (skip)
+ * @shape_plan: a shape plan.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
{
@@ -149,11 +202,25 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
- hb_face_destroy (shape_plan->face);
+ free (shape_plan->user_features);
free (shape_plan);
}
+/**
+ * hb_shape_plan_set_user_data: (skip)
+ * @shape_plan: a shape plan.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
hb_user_data_key_t *key,
@@ -164,6 +231,17 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
return hb_object_set_user_data (shape_plan, key, data, destroy, replace);
}
+/**
+ * hb_shape_plan_get_user_data: (skip)
+ * @shape_plan: a shape plan.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
hb_user_data_key_t *key)
@@ -172,6 +250,20 @@ hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
}
+/**
+ * hb_shape_plan_execute:
+ * @shape_plan: a shape plan.
+ * @font: a font.
+ * @buffer: a buffer.
+ * @features: (array length=num_features):
+ * @num_features:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
hb_font_t *font,
@@ -184,7 +276,7 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
hb_object_is_inert (buffer)))
return false;
- assert (shape_plan->face == font->face);
+ assert (shape_plan->face_unsafe == font->face);
assert (hb_segment_properties_equal (&shape_plan->props, &buffer->props));
#define HB_SHAPER_EXECUTE(shaper) \
@@ -221,23 +313,69 @@ hb_shape_plan_hash (const hb_shape_plan_t *shape_plan)
}
#endif
-/* TODO no user-feature caching for now. */
+/* User-feature caching is currently somewhat dumb:
+ * it only finds matches where the feature array is identical,
+ * not cases where the feature lists would be compatible for plan purposes
+ * but have different ranges, for example.
+ */
struct hb_shape_plan_proposal_t
{
const hb_segment_properties_t props;
const char * const *shaper_list;
+ const hb_feature_t *user_features;
+ unsigned int num_user_features;
hb_shape_func_t *shaper_func;
};
+static inline hb_bool_t
+hb_shape_plan_user_features_match (const hb_shape_plan_t *shape_plan,
+ const hb_shape_plan_proposal_t *proposal)
+{
+ if (proposal->num_user_features != shape_plan->num_user_features) return false;
+ for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++)
+ if (proposal->user_features[i].tag != shape_plan->user_features[i].tag ||
+ proposal->user_features[i].value != shape_plan->user_features[i].value ||
+ proposal->user_features[i].start != shape_plan->user_features[i].start ||
+ proposal->user_features[i].end != shape_plan->user_features[i].end) return false;
+ return true;
+}
+
static hb_bool_t
hb_shape_plan_matches (const hb_shape_plan_t *shape_plan,
const hb_shape_plan_proposal_t *proposal)
{
return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
+ hb_shape_plan_user_features_match (shape_plan, proposal) &&
((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
(shape_plan->shaper_func == proposal->shaper_func));
}
+static inline hb_bool_t
+hb_non_global_user_features_present (const hb_feature_t *user_features,
+ unsigned int num_user_features)
+{
+ while (num_user_features)
+ if (user_features->start != 0 || user_features->end != (unsigned int) -1)
+ return true;
+ else
+ num_user_features--, user_features++;
+ return false;
+}
+
+/**
+ * hb_shape_plan_create_cached:
+ * @face:
+ * @props:
+ * @user_features: (array length=num_user_features):
+ * @num_user_features:
+ * @shaper_list: (array zero-terminated=1):
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_shape_plan_t *
hb_shape_plan_create_cached (hb_face_t *face,
const hb_segment_properties_t *props,
@@ -245,12 +383,11 @@ hb_shape_plan_create_cached (hb_face_t *face,
unsigned int num_user_features,
const char * const *shaper_list)
{
- if (num_user_features)
- return hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
-
hb_shape_plan_proposal_t proposal = {
*props,
shaper_list,
+ user_features,
+ num_user_features,
NULL
};
@@ -288,6 +425,11 @@ retry:
hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
+ /* Don't add the plan to the cache if there were user features with non-global ranges */
+
+ if (hb_non_global_user_features_present (user_features, num_user_features))
+ return shape_plan;
+
hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t));
if (unlikely (!node))
return shape_plan;
@@ -301,12 +443,19 @@ retry:
goto retry;
}
- /* Release our reference on face. */
- hb_face_destroy (face);
-
return hb_shape_plan_reference (shape_plan);
}
+/**
+ * hb_shape_plan_get_shaper:
+ * @shape_plan: a shape plan.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
const char *
hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
{
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
index 80d8c1306b..c1b752405e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
@@ -153,6 +153,18 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
*pp == end;
}
+/**
+ * hb_feature_from_string:
+ * @str: (array length=len):
+ * @len:
+ * @feature: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_feature_from_string (const char *str, int len,
hb_feature_t *feature)
@@ -163,6 +175,16 @@ hb_feature_from_string (const char *str, int len,
return parse_one_feature (&str, str + len, feature);
}
+/**
+ * hb_feature_to_string:
+ * @feature:
+ * @buf: (array length=size):
+ * @size:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_feature_to_string (hb_feature_t *feature,
char *buf, unsigned int size)
@@ -209,6 +231,15 @@ void free_static_shaper_list (void)
free (static_shaper_list);
}
+/**
+ * hb_shape_list_shapers:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
const char **
hb_shape_list_shapers (void)
{
@@ -244,6 +275,20 @@ retry:
}
+/**
+ * hb_shape_full:
+ * @font: a font.
+ * @buffer: a buffer.
+ * @features: (array length=num_features):
+ * @num_features:
+ * @shaper_list: (array zero-terminated=1):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_shape_full (hb_font_t *font,
hb_buffer_t *buffer,
@@ -265,6 +310,17 @@ hb_shape_full (hb_font_t *font,
return res;
}
+/**
+ * hb_shape:
+ * @font: a font.
+ * @buffer: a buffer.
+ * @features: (array length=num_features):
+ * @num_features:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_shape (hb_font_t *font,
hb_buffer_t *buffer,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
index dd4d00138e..779d8ae229 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
@@ -32,8 +32,6 @@
#define HB_UNICODE_PRIVATE_HH
#include "hb-private.hh"
-
-#include "hb-unicode.h"
#include "hb-object-private.hh"
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
index b7e098737c..5b44913bd3 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
@@ -150,6 +150,16 @@ hb_unicode_funcs_get_default (void)
#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS.")
#endif
+/**
+ * hb_unicode_funcs_create: (Xconstructor)
+ * @parent: (allow-none):
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_unicode_funcs_t *
hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
{
@@ -187,18 +197,45 @@ const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
}
};
+/**
+ * hb_unicode_funcs_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_unicode_funcs_t *
hb_unicode_funcs_get_empty (void)
{
return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil);
}
+/**
+ * hb_unicode_funcs_reference: (skip)
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_unicode_funcs_t *
hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
{
return hb_object_reference (ufuncs);
}
+/**
+ * hb_unicode_funcs_destroy: (skip)
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
{
@@ -214,6 +251,20 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
free (ufuncs);
}
+/**
+ * hb_unicode_funcs_set_user_data: (skip)
+ * @ufuncs: Unicode functions.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
hb_user_data_key_t *key,
@@ -224,6 +275,17 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
}
+/**
+ * hb_unicode_funcs_get_user_data: (skip)
+ * @ufuncs: Unicode functions.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
hb_user_data_key_t *key)
@@ -232,6 +294,14 @@ hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
}
+/**
+ * hb_unicode_funcs_make_immutable:
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
{
@@ -241,12 +311,32 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
ufuncs->immutable = true;
}
+/**
+ * hb_unicode_funcs_is_immutable:
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
{
return ufuncs->immutable;
}
+/**
+ * hb_unicode_funcs_get_parent:
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_unicode_funcs_t *
hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
{
@@ -294,6 +384,19 @@ hb_unicode_##name (hb_unicode_funcs_t *ufuncs, \
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
#undef HB_UNICODE_FUNC_IMPLEMENT
+/**
+ * hb_unicode_compose:
+ * @ufuncs: Unicode functions.
+ * @a:
+ * @b:
+ * @ab: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t a,
@@ -303,6 +406,19 @@ hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
return ufuncs->compose (a, b, ab);
}
+/**
+ * hb_unicode_decompose:
+ * @ufuncs: Unicode functions.
+ * @ab:
+ * @a: (out):
+ * @b: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t ab,
@@ -312,6 +428,18 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
return ufuncs->decompose (ab, a, b);
}
+/**
+ * hb_unicode_decompose_compatibility:
+ * @ufuncs: Unicode functions.
+ * @u:
+ * @decomposed: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t u,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.h b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h
index 2e10d98a3b..1c4e097b92 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h
@@ -248,7 +248,7 @@ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_decompose_compatibility_func_t:
- * @ufuncs: Unicode function structure
+ * @ufuncs: a Unicode function structure
* @u: codepoint to decompose
* @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
* @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
@@ -274,44 +274,132 @@ typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_
/* setters */
+/**
+ * hb_unicode_funcs_set_combining_class_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_combining_class_func_t combining_class_func,
+ hb_unicode_combining_class_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_eastasian_width_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_eastasian_width_func_t eastasian_width_func,
+ hb_unicode_eastasian_width_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_general_category_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_general_category_func_t general_category_func,
+ hb_unicode_general_category_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_mirroring_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_mirroring_func_t mirroring_func,
+ hb_unicode_mirroring_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_script_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_script_func_t script_func,
+ hb_unicode_script_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_compose_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_compose_func_t compose_func,
+ hb_unicode_compose_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_decompose_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_decompose_func_t decompose_func,
+ hb_unicode_decompose_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_decompose_compatibility_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_decompose_compatibility_func_t decompose_compatibility_func,
+ hb_unicode_decompose_compatibility_func_t func,
void *user_data, hb_destroy_func_t destroy);
/* accessors */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h
index dc07ef794a..790e0ecbae 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-version.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h
@@ -38,9 +38,9 @@ HB_BEGIN_DECLS
#define HB_VERSION_MAJOR 0
#define HB_VERSION_MINOR 9
-#define HB_VERSION_MICRO 20
+#define HB_VERSION_MICRO 25
-#define HB_VERSION_STRING "0.9.20"
+#define HB_VERSION_STRING "0.9.25"
#define HB_VERSION_CHECK(major,minor,micro) \
((major)*10000+(minor)*100+(micro) >= \
diff --git a/src/3rdparty/harfbuzz.pri b/src/3rdparty/harfbuzz.pri
index bc8d49c625..0d55867c74 100644
--- a/src/3rdparty/harfbuzz.pri
+++ b/src/3rdparty/harfbuzz.pri
@@ -79,6 +79,7 @@ contains(QT_CONFIG, harfbuzz) {
$$QT_HARFBUZZ_DIR/src/hb-ot-layout-gpos-table.hh \
$$QT_HARFBUZZ_DIR/src/hb-ot-layout-gsubgpos-private.hh \
$$QT_HARFBUZZ_DIR/src/hb-ot-layout-gsub-table.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-layout-jstf-table.hh \
$$QT_HARFBUZZ_DIR/src/hb-ot-layout-private.hh \
$$QT_HARFBUZZ_DIR/src/hb-ot-map-private.hh \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-arabic-fallback.hh \
diff --git a/src/3rdparty/sqlite.pri b/src/3rdparty/sqlite.pri
index 072502c8e9..0c9d179660 100644
--- a/src/3rdparty/sqlite.pri
+++ b/src/3rdparty/sqlite.pri
@@ -3,6 +3,7 @@ DEFINES += SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQ
!contains(CONFIG, largefile):DEFINES += SQLITE_DISABLE_LFS
contains(QT_CONFIG, posix_fallocate):DEFINES += HAVE_POSIX_FALLOCATE=1
winrt: DEFINES += SQLITE_OS_WINRT
+qnx: DEFINES += _QNX_SOURCE
INCLUDEPATH += $$PWD/sqlite
SOURCES += $$PWD/sqlite/sqlite3.c
diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake
index dca257f080..88710bc55e 100644
--- a/src/corelib/Qt5CoreMacros.cmake
+++ b/src/corelib/Qt5CoreMacros.cmake
@@ -110,6 +110,7 @@ macro(QT5_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target)
string (REPLACE ";" "\n" _moc_parameters "${_moc_parameters}")
if(moc_target)
+ set(_moc_parameters_file ${_moc_parameters_file}$<$<BOOL:$<CONFIGURATION>>:_$<CONFIGURATION>>)
set(targetincludes "$<TARGET_PROPERTY:${moc_target},INCLUDE_DIRECTORIES>")
set(targetdefines "$<TARGET_PROPERTY:${moc_target},COMPILE_DEFINITIONS>")
diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc
index fa26409d83..6017269272 100644
--- a/src/corelib/doc/src/containers.qdoc
+++ b/src/corelib/doc/src/containers.qdoc
@@ -578,9 +578,11 @@
\snippet code/doc_src_containers.cpp 18
With QMap and QHash, \c foreach accesses the value component of
- the (key, value) pairs. If you want to iterate over both the keys
- and the values, you can use iterators (which are fastest), or you
- can write code like this:
+ the (key, value) pairs automatically, so you should not call
+ values() on the container (it would generate an unnecessary copy,
+ see below). If you want to iterate over both the keys and the
+ values, you can use iterators (which are faster), or you can
+ obtain the keys, and use them to get the values too:
\snippet code/doc_src_containers.cpp 19
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 18e9ecae85..f5f144fe6b 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -467,6 +467,19 @@ typedef qptrdiff qintptr;
# define QT_FASTCALL
#endif
+// enable gcc warnings for printf-style functions
+#if defined(Q_CC_GNU) && !defined(__INSURE__)
+# if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
+# define Q_ATTRIBUTE_FORMAT_PRINTF(A, B) \
+ __attribute__((format(gnu_printf, (A), (B))))
+# else
+# define Q_ATTRIBUTE_FORMAT_PRINTF(A, B) \
+ __attribute__((format(printf, (A), (B))))
+# endif
+#else
+# define Q_ATTRIBUTE_FORMAT_PRINTF(A, B)
+#endif
+
//defines the type for the WNDPROC on windows
//the alignment needs to be forced for sse2 to not crash with mingw
#if defined(Q_OS_WIN)
diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h
index 2b798f9ea0..5ae1fb3205 100644
--- a/src/corelib/global/qlogging.h
+++ b/src/corelib/global/qlogging.h
@@ -92,55 +92,16 @@ public:
Q_DECL_CONSTEXPR QMessageLogger(const char *file, int line, const char *function, const char *category)
: context(file, line, function, category) {}
- void debug(const char *msg, ...) const
-#if defined(Q_CC_GNU) && !defined(__INSURE__)
-# if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
- __attribute__ ((format (gnu_printf, 2, 3)))
-# else
- __attribute__ ((format (printf, 2, 3)))
-# endif
-#endif
- ;
- void noDebug(const char *, ...) const
-#if defined(Q_CC_GNU) && !defined(__INSURE__)
-# if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
- __attribute__ ((format (gnu_printf, 2, 3)))
-# else
- __attribute__ ((format (printf, 2, 3)))
-# endif
-#endif
+ void debug(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
+ void noDebug(const char *, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3)
{}
- void warning(const char *msg, ...) const
-#if defined(Q_CC_GNU) && !defined(__INSURE__)
-# if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
- __attribute__ ((format (gnu_printf, 2, 3)))
-# else
- __attribute__ ((format (printf, 2, 3)))
-# endif
-#endif
- ;
- void critical(const char *msg, ...) const
-#if defined(Q_CC_GNU) && !defined(__INSURE__)
-# if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
- __attribute__ ((format (gnu_printf, 2, 3)))
-# else
- __attribute__ ((format (printf, 2, 3)))
-# endif
-#endif
- ;
+ void warning(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
+ void critical(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
#ifndef Q_CC_MSVC
Q_NORETURN
#endif
- void fatal(const char *msg, ...) const Q_DECL_NOTHROW
-#if defined(Q_CC_GNU) && !defined(__INSURE__)
-# if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
- __attribute__ ((format (gnu_printf, 2, 3)))
-# else
- __attribute__ ((format (printf, 2, 3)))
-# endif
-#endif
- ;
+ void fatal(const char *msg, ...) const Q_DECL_NOTHROW Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
#ifndef QT_NO_DEBUG_STREAM
QDebug debug() const;
diff --git a/src/corelib/kernel/qcorecmdlineargs_p.h b/src/corelib/kernel/qcorecmdlineargs_p.h
index d1cfa2dfa9..bbbee7df25 100644
--- a/src/corelib/kernel/qcorecmdlineargs_p.h
+++ b/src/corelib/kernel/qcorecmdlineargs_p.h
@@ -101,8 +101,8 @@ static QVector<Char*> qWinCmdLine(Char *cmdParam, int length, int &argc)
}
}
if (*p == '\\') { // escape char?
- // testing by looking at argc, argv shows that it only escapes quotes and backslashes
- if (p < p_end && (*(p+1) == Char('\"') || *(p+1) == Char('\\')))
+ // testing by looking at argc, argv shows that it only escapes quotes
+ if (p < p_end && (*(p+1) == Char('\"')))
p++;
} else {
if (!quote && (*p == Char('\"'))) {
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 8e0dc4dede..a027f82f82 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -908,10 +908,13 @@ QObject::~QObject()
}
if (d->declarativeData) {
- if (QAbstractDeclarativeData::destroyed)
- QAbstractDeclarativeData::destroyed(d->declarativeData, this);
- if (QAbstractDeclarativeData::destroyed_qml1)
- QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
+ if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
+ if (QAbstractDeclarativeData::destroyed_qml1)
+ QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
+ } else {
+ if (QAbstractDeclarativeData::destroyed)
+ QAbstractDeclarativeData::destroyed(d->declarativeData, this);
+ }
}
// set ref to zero to indicate that this object has been deleted
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index cd2d592cec..011e140e3b 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -97,6 +97,14 @@ public:
static bool (*isSignalConnected)(QAbstractDeclarativeData *, const QObject *, int);
};
+// This is an implementation of QAbstractDeclarativeData that is identical with
+// the implementation in QtDeclarative and QtQml for the first bit
+struct QAbstractDeclarativeDataImpl : public QAbstractDeclarativeData
+{
+ quint32 ownedByQml1:1;
+ quint32 unused: 31;
+};
+
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
{
Q_DECLARE_PUBLIC(QObject)
diff --git a/src/corelib/plugin/qplugin.qdoc b/src/corelib/plugin/qplugin.qdoc
index 0a94077d95..b72516eae5 100644
--- a/src/corelib/plugin/qplugin.qdoc
+++ b/src/corelib/plugin/qplugin.qdoc
@@ -28,6 +28,7 @@
/*!
\headerfile <QtPlugin>
\title Defining Plugins
+ \target qtplugin-defining-plugins
\ingroup plugins
\brief The <QtPlugin> header file defines macros for defining plugins.
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index 903e72c151..28e13910d9 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -258,7 +258,11 @@ DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID)
qt_adopted_thread_watcher_mutex.unlock();
DWORD ret = WAIT_TIMEOUT;
- int loops = (handlesCopy.count() / MAXIMUM_WAIT_OBJECTS) + 1, offset, count;
+ int count;
+ int offset;
+ int loops = handlesCopy.size() / MAXIMUM_WAIT_OBJECTS;
+ if (handlesCopy.size() % MAXIMUM_WAIT_OBJECTS)
+ ++loops;
if (loops == 1) {
// no need to loop, no timeout
offset = 0;
diff --git a/src/corelib/tools/qlocale_blackberry.cpp b/src/corelib/tools/qlocale_blackberry.cpp
index c2c3476b0a..0165780634 100644
--- a/src/corelib/tools/qlocale_blackberry.cpp
+++ b/src/corelib/tools/qlocale_blackberry.cpp
@@ -193,15 +193,15 @@ QByteArray QBBSystemLocaleData::readPpsValue(const char *ppsObject, int ppsFd)
// Using QVarLengthArray means the first try (of size == 512) uses a buffer on the stack - no allocation necessary.
// Hopefully that covers most use cases.
int bytes;
- QVarLengthArray<char, 512> buffer;
+ QVarLengthArray<char, 512> buffer(512);
for (;;) {
errno = 0;
- bytes = qt_safe_read(ppsFd, buffer.data(), buffer.capacity() - 1);
- const bool bufferIsTooSmall = (bytes == -1 && errno == EMSGSIZE && buffer.capacity() < MAX_PPS_SIZE);
+ bytes = qt_safe_read(ppsFd, buffer.data(), buffer.size() - 1);
+ const bool bufferIsTooSmall = (bytes == -1 && errno == EMSGSIZE && buffer.size() < MAX_PPS_SIZE);
if (!bufferIsTooSmall)
break;
- buffer.resize(qMin(buffer.capacity()*2, MAX_PPS_SIZE));
+ buffer.resize(qMin(buffer.size()*2, MAX_PPS_SIZE));
}
// This method is called in the ctor(), so do not use qWarning to log warnings
diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp
index bbc208e673..885c77c46d 100644
--- a/src/corelib/tools/qlocale_win.cpp
+++ b/src/corelib/tools/qlocale_win.cpp
@@ -102,6 +102,9 @@ static QString winIso3116CtryName(LPWSTR id = LOCALE_NAME_USER_DEFAULT);
#ifndef LOCALE_SNATIVECOUNTRYNAME
# define LOCALE_SNATIVECOUNTRYNAME 0x00000008
#endif
+#ifndef LOCALE_SSHORTTIME
+# define LOCALE_SSHORTTIME 0x00000079
+#endif
struct QSystemLocalePrivate
{
@@ -327,7 +330,9 @@ QVariant QSystemLocalePrivate::timeFormat(QLocale::FormatType type)
{
switch (type) {
case QLocale::ShortFormat:
- return winToQtFormat(getLocaleInfo(LOCALE_STIMEFORMAT)); //###
+ if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7)
+ return winToQtFormat(getLocaleInfo(LOCALE_SSHORTTIME));
+ // fall through
case QLocale::LongFormat:
return winToQtFormat(getLocaleInfo(LOCALE_STIMEFORMAT));
case QLocale::NarrowFormat:
@@ -410,7 +415,7 @@ QVariant QSystemLocalePrivate::toString(const QDate &date, QLocale::FormatType t
return QString();
}
-QVariant QSystemLocalePrivate::toString(const QTime &time, QLocale::FormatType)
+QVariant QSystemLocalePrivate::toString(const QTime &time, QLocale::FormatType type)
{
SYSTEMTIME st;
memset(&st, 0, sizeof(SYSTEMTIME));
@@ -420,6 +425,9 @@ QVariant QSystemLocalePrivate::toString(const QTime &time, QLocale::FormatType)
st.wMilliseconds = 0;
DWORD flags = 0;
+ // keep the same conditional as timeFormat() above
+ if (type == QLocale::ShortFormat && QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7)
+ flags = TIME_NOSECONDS;
wchar_t buf[255];
if (getTimeFormat(flags, &st, NULL, buf, 255)) {
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 460afb00f4..01ddf669f5 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -302,24 +302,8 @@ public:
const QString &a4, const QString &a5, const QString &a6,
const QString &a7, const QString &a8, const QString &a9) const Q_REQUIRED_RESULT;
- QString &vsprintf(const char *format, va_list ap)
-#if defined(Q_CC_GNU) && !defined(__INSURE__)
-# if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
- __attribute__ ((format (gnu_printf, 2, 0)))
-# else
- __attribute__ ((format (printf, 2, 0)))
-# endif
-#endif
- ;
- QString &sprintf(const char *format, ...)
-#if defined(Q_CC_GNU) && !defined(__INSURE__)
-# if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
- __attribute__ ((format (gnu_printf, 2, 3)))
-# else
- __attribute__ ((format (printf, 2, 3)))
-# endif
-#endif
- ;
+ QString &vsprintf(const char *format, va_list ap) Q_ATTRIBUTE_FORMAT_PRINTF(2, 0);
+ QString &sprintf(const char *format, ...) Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
int indexOf(QChar c, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int indexOf(const QString &s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
diff --git a/src/gui/doc/src/dnd.qdoc b/src/gui/doc/src/dnd.qdoc
index 1c6ca9c81c..9f7fdc7fbf 100644
--- a/src/gui/doc/src/dnd.qdoc
+++ b/src/gui/doc/src/dnd.qdoc
@@ -80,8 +80,8 @@
The rest of the document focuses mainly on how to implement drag and drop
in C++. For using drag and drop inside a Qt Quick scene, please read the
- documentation for the Qt Quick \l{Drag}, \l{DragEvent} and \l{DropArea} items.
- There is also an example \l{quick/draganddrop}{available}.
+ documentation for the Qt Quick \l{Drag}, \l{DragEvent}, and \l{DropArea} items,
+ as well as the \l {Qt Quick Examples - Drag and Drop}{Qt Quick Drag and Drop} examples.
\section1 Dragging
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 02f0c18243..bc7f3729ad 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -327,6 +327,7 @@ inline void QImage::setPixel(const QPoint &pt, uint index_or_rgb) { setPixel(pt.
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(Q_CC_MSVC)
+# pragma warning(push)
# pragma warning(disable: 4996)
#endif
@@ -403,7 +404,7 @@ inline void QImage::setText(const char* key, const char* lang, const QString &s)
#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)
# pragma GCC diagnostic pop
#elif defined(Q_CC_MSVC)
-# pragma warning(default: 4996)
+# pragma warning(pop)
#endif
inline int QImage::numColors() const
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index 8dd5fdd111..c12dbb6544 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -279,7 +279,7 @@ QImageWriterPrivate::QImageWriterPrivate(QImageWriter *qq)
compression = 0;
gamma = 0.0;
imageWriterError = QImageWriter::UnknownError;
- errorString = QT_TRANSLATE_NOOP(QImageWriter, QLatin1String("Unknown error"));
+ errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Unknown error"));
q = qq;
}
@@ -288,22 +288,19 @@ bool QImageWriterPrivate::canWriteHelper()
{
if (!device) {
imageWriterError = QImageWriter::DeviceError;
- errorString = QT_TRANSLATE_NOOP(QImageWriter,
- QLatin1String("Device is not set"));
+ errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Device is not set"));
return false;
}
if (!device->isOpen())
device->open(QIODevice::WriteOnly);
if (!device->isWritable()) {
imageWriterError = QImageWriter::DeviceError;
- errorString = QT_TRANSLATE_NOOP(QImageWriter,
- QLatin1String("Device not writable"));
+ errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Device not writable"));
return false;
}
if (!handler && (handler = createWriteHandlerHelper(device, format)) == 0) {
imageWriterError = QImageWriter::UnsupportedFormatError;
- errorString = QT_TRANSLATE_NOOP(QImageWriter,
- QLatin1String("Unsupported image format"));
+ errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Unsupported image format"));
return false;
}
return true;
@@ -670,8 +667,7 @@ bool QImageWriter::supportsOption(QImageIOHandler::ImageOption option) const
{
if (!d->handler && (d->handler = createWriteHandlerHelper(d->device, d->format)) == 0) {
d->imageWriterError = QImageWriter::UnsupportedFormatError;
- d->errorString = QT_TRANSLATE_NOOP(QImageWriter,
- QLatin1String("Unsupported image format"));
+ d->errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Unsupported image format"));
return false;
}
diff --git a/src/gui/opengl/qopenglversionfunctions.cpp b/src/gui/opengl/qopenglversionfunctions.cpp
index 0b1b6834e3..428f6e8a8b 100644
--- a/src/gui/opengl/qopenglversionfunctions.cpp
+++ b/src/gui/opengl/qopenglversionfunctions.cpp
@@ -198,6 +198,8 @@ bool QAbstractOpenGLFunctions::initializeOpenGLFunctions()
return true;
}
+/*! \internal
+ */
bool QAbstractOpenGLFunctions::isInitialized() const
{
Q_D(const QAbstractOpenGLFunctions);
diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp
index 08072b1cf3..b4ab5856df 100644
--- a/src/gui/text/qharfbuzzng.cpp
+++ b/src/gui/text/qharfbuzzng.cpp
@@ -581,7 +581,7 @@ static hb_user_data_key_t _useDesignMetricsKey;
void hb_qt_font_set_use_design_metrics(hb_font_t *font, uint value)
{
- hb_font_set_user_data(font, &_useDesignMetricsKey, (void *)value, NULL, true);
+ hb_font_set_user_data(font, &_useDesignMetricsKey, (void *)quintptr(value), NULL, true);
}
uint hb_qt_font_get_use_design_metrics(hb_font_t *font)
diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp
index 7076fba41b..37610a9099 100644
--- a/src/gui/text/qplatformfontdatabase.cpp
+++ b/src/gui/text/qplatformfontdatabase.cpp
@@ -459,10 +459,20 @@ static const ushort requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] =
};
enum {
+ Latin1CsbBit = 0,
+ CentralEuropeCsbBit = 1,
+ TurkishCsbBit = 4,
+ BalticCsbBit = 7,
+ CyrillicCsbBit = 2,
+ GreekCsbBit = 3,
+ HebrewCsbBit = 5,
+ ArabicCsbBit = 6,
+ VietnameseCsbBit = 8,
SimplifiedChineseCsbBit = 18,
TraditionalChineseCsbBit = 20,
JapaneseCsbBit = 17,
- KoreanCsbBit = 21
+ KoreanCsbBit = 19,
+ KoreanJohabCsbBit = 21
};
/*!
@@ -492,6 +502,36 @@ QSupportedWritingSystems QPlatformFontDatabase::writingSystemsFromTrueTypeBits(q
}
}
}
+ if (codePageRange[0] & ((1 << Latin1CsbBit) | (1 << CentralEuropeCsbBit) | (1 << TurkishCsbBit) | (1 << BalticCsbBit))) {
+ writingSystems.setSupported(QFontDatabase::Latin);
+ hasScript = true;
+ //qDebug("font %s supports Latin", familyName.latin1());
+ }
+ if (codePageRange[0] & (1 << CyrillicCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::Cyrillic);
+ hasScript = true;
+ //qDebug("font %s supports Cyrillic", familyName.latin1());
+ }
+ if (codePageRange[0] & (1 << GreekCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::Greek);
+ hasScript = true;
+ //qDebug("font %s supports Greek", familyName.latin1());
+ }
+ if (codePageRange[0] & (1 << HebrewCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::Hebrew);
+ hasScript = true;
+ //qDebug("font %s supports Hebrew", familyName.latin1());
+ }
+ if (codePageRange[0] & (1 << ArabicCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::Arabic);
+ hasScript = true;
+ //qDebug("font %s supports Arabic", familyName.latin1());
+ }
+ if (codePageRange[0] & (1 << VietnameseCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::Vietnamese);
+ hasScript = true;
+ //qDebug("font %s supports Vietnamese", familyName.latin1());
+ }
if (codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
writingSystems.setSupported(QFontDatabase::SimplifiedChinese);
hasScript = true;
@@ -507,7 +547,7 @@ QSupportedWritingSystems QPlatformFontDatabase::writingSystemsFromTrueTypeBits(q
hasScript = true;
//qDebug("font %s supports Japanese", familyName.latin1());
}
- if (codePageRange[0] & (1 << KoreanCsbBit)) {
+ if (codePageRange[0] & ((1 << KoreanCsbBit) | (1 << KoreanJohabCsbBit))) {
writingSystems.setSupported(QFontDatabase::Korean);
hasScript = true;
//qDebug("font %s supports Korean", familyName.latin1());
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 08b0491ddc..4e1c8c4c4a 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1098,7 +1098,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
hb_buffer_set_segment_properties(buffer, &props);
hb_buffer_guess_segment_properties(buffer);
- uint buffer_flags = HB_BUFFER_FLAG_DEFAULT;
+ uint buffer_flags = 0; // HB_BUFFER_FLAG_DEFAULT
// Symbol encoding used to encode various crap in the 32..255 character code range,
// and thus might override U+00AD [SHY]; avoid hiding default ignorables
if (actualFontEngine->symbol)
@@ -1124,7 +1124,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
hb_qt_font_set_use_design_metrics(hb_font, option.useDesignMetrics() ? uint(QFontEngine::DesignMetrics) : 0); // ###
const hb_feature_t features[1] = {
- { HB_TAG('k','e','r','n'), !!kerningEnabled, 0, -1 }
+ { HB_TAG('k','e','r','n'), !!kerningEnabled, 0, uint(-1) }
};
const int num_features = 1;
shapedOk = hb_shape_full(hb_font, buffer, features, num_features, 0);
diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp
index e85949afb6..6ea34b17f5 100644
--- a/src/plugins/bearer/connman/qconnmanengine.cpp
+++ b/src/plugins/bearer/connman/qconnmanengine.cpp
@@ -150,20 +150,7 @@ void QConnmanEngine::connectToId(const QString &id)
if(!serv.isValid()) {
emit connectionError(id, QBearerEngineImpl::InterfaceLookupError);
} else {
- if(serv.getType() != "cellular") {
-
- serv.connect();
- } else {
- QOfonoManagerInterface ofonoManager(0);
- QString modemPath = ofonoManager.currentModem().path();
- QOfonoDataConnectionManagerInterface dc(modemPath,0);
- foreach (const QDBusObjectPath &dcPath,dc.getPrimaryContexts()) {
- if(dcPath.path().contains(servicePath.section("_",-1))) {
- QOfonoConnectionContextInterface primaryContext(dcPath.path(),0);
- primaryContext.setActive(true);
- }
- }
- }
+ serv.connect();
}
}
@@ -175,19 +162,7 @@ void QConnmanEngine::disconnectFromId(const QString &id)
if(!serv.isValid()) {
emit connectionError(id, DisconnectionError);
} else {
- if(serv.getType() != "cellular") {
- serv.disconnect();
- } else {
- QOfonoManagerInterface ofonoManager(0);
- QString modemPath = ofonoManager.currentModem().path();
- QOfonoDataConnectionManagerInterface dc(modemPath,0);
- foreach (const QDBusObjectPath &dcPath,dc.getPrimaryContexts()) {
- if(dcPath.path().contains(servicePath.section("_",-1))) {
- QOfonoConnectionContextInterface primaryContext(dcPath.path(),0);
- primaryContext.setActive(false);
- }
- }
- }
+ serv.disconnect();
}
}
@@ -292,7 +267,8 @@ QNetworkConfigurationManager::Capabilities QConnmanEngine::capabilities() const
{
return QNetworkConfigurationManager::ForcedRoaming |
QNetworkConfigurationManager::DataStatistics |
- QNetworkConfigurationManager::CanStartAndStopInterfaces;
+ QNetworkConfigurationManager::CanStartAndStopInterfaces |
+ QNetworkConfigurationManager::NetworkSessionRequired;
}
QNetworkSessionPrivate *QConnmanEngine::createSessionBackend()
@@ -374,7 +350,7 @@ void QConnmanEngine::configurationChange(const QString &id)
QMutexLocker locker(&mutex);
if (accessPointConfigurations.contains(id)) {
-
+ bool changed = false;
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
QString servicePath = serviceFromId(id);
@@ -392,17 +368,21 @@ void QConnmanEngine::configurationChange(const QString &id)
if (ptr->name != networkName) {
ptr->name = networkName;
+ changed = true;
}
if (ptr->state != curState) {
ptr->state = curState;
+ changed = true;
}
ptr->mutex.unlock();
- locker.unlock();
- emit configurationChanged(ptr);
- locker.relock();
+ if (changed) {
+ locker.unlock();
+ emit configurationChanged(ptr);
+ locker.relock();
+ }
}
locker.unlock();
@@ -515,6 +495,7 @@ void QConnmanEngine::removeConfiguration(const QString &id)
serviceNetworks.removeOne(service);
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(id);
+ foundConfigurations.removeOne(ptr.data());
locker.unlock();
emit configurationRemoved(ptr);
locker.relock();
diff --git a/src/plugins/generic/tslib/qtslib.cpp b/src/plugins/generic/tslib/qtslib.cpp
index 6986fd5dfa..773939b485 100644
--- a/src/plugins/generic/tslib/qtslib.cpp
+++ b/src/plugins/generic/tslib/qtslib.cpp
@@ -64,7 +64,10 @@ QTsLibMouseHandler::QTsLibMouseHandler(const QString &key,
qDebug() << "QTsLibMouseHandler" << key << specification;
setObjectName(QLatin1String("TSLib Mouse Handler"));
- QByteArray device = "/dev/input/event1";
+ QByteArray device = qgetenv("TSLIB_TSDEVICE");
+ if (device.isEmpty())
+ device = QByteArrayLiteral("/dev/input/event1");
+
if (specification.startsWith("/dev/"))
device = specification.toLocal8Bit();
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index 8e20a96a48..66c7727f15 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -240,7 +240,10 @@
// misc
- (BOOL)accessibilityIsIgnored {
- return QCocoaAccessible::shouldBeIgnored(QAccessible::accessibleInterface(axid));
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
+ if (!iface || !iface->isValid())
+ return true;
+ return QCocoaAccessible::shouldBeIgnored(iface);
}
- (id)accessibilityHitTest:(NSPoint)point {
diff --git a/src/plugins/platforms/cocoa/qcocoaclipboard.mm b/src/plugins/platforms/cocoa/qcocoaclipboard.mm
index daeebcb078..a49ff902a5 100644
--- a/src/plugins/platforms/cocoa/qcocoaclipboard.mm
+++ b/src/plugins/platforms/cocoa/qcocoaclipboard.mm
@@ -46,8 +46,8 @@
QT_BEGIN_NAMESPACE
QCocoaClipboard::QCocoaClipboard()
- :m_clipboard(new QMacPasteboard(kPasteboardClipboard, QMacPasteboardMime::MIME_CLIP))
- ,m_find(new QMacPasteboard(kPasteboardFind, QMacPasteboardMime::MIME_CLIP))
+ :m_clipboard(new QMacPasteboard(kPasteboardClipboard, QMacInternalPasteboardMime::MIME_CLIP))
+ ,m_find(new QMacPasteboard(kPasteboardFind, QMacInternalPasteboardMime::MIME_CLIP))
{
}
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm
index a22830f64e..5d7f53ee5d 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.mm
+++ b/src/plugins/platforms/cocoa/qcocoadrag.mm
@@ -131,7 +131,7 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
NSImage *nsimage = qt_mac_create_nsimage(pm);
- QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacPasteboardMime::MIME_DND);
+ QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacInternalPasteboardMime::MIME_DND);
m_drag->mimeData()->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy"));
dragBoard.setMimeData(m_drag->mimeData());
@@ -181,7 +181,7 @@ QStringList QCocoaDropData::formats_sys() const
qDebug("DnD: Cannot get PasteBoard!");
return formats;
}
- formats = QMacPasteboard(board, QMacPasteboardMime::MIME_DND).formats();
+ formats = QMacPasteboard(board, QMacInternalPasteboardMime::MIME_DND).formats();
return formats;
}
@@ -193,7 +193,7 @@ QVariant QCocoaDropData::retrieveData_sys(const QString &mimeType, QVariant::Typ
qDebug("DnD: Cannot get PasteBoard!");
return data;
}
- data = QMacPasteboard(board, QMacPasteboardMime::MIME_DND).retrieveData(mimeType, type);
+ data = QMacPasteboard(board, QMacInternalPasteboardMime::MIME_DND).retrieveData(mimeType, type);
CFRelease(board);
return data;
}
@@ -206,7 +206,7 @@ bool QCocoaDropData::hasFormat_sys(const QString &mimeType) const
qDebug("DnD: Cannot get PasteBoard!");
return has;
}
- has = QMacPasteboard(board, QMacPasteboardMime::MIME_DND).hasFormat(mimeType);
+ has = QMacPasteboard(board, QMacInternalPasteboardMime::MIME_DND).hasFormat(mimeType);
CFRelease(board);
return has;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 0af635be6f..5f01274d98 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -268,7 +268,7 @@ QCocoaIntegration::QCocoaIntegration()
updateScreens();
- QMacPasteboardMime::initializeMimeTypes();
+ QMacInternalPasteboardMime::initializeMimeTypes();
}
QCocoaIntegration::~QCocoaIntegration()
@@ -288,7 +288,7 @@ QCocoaIntegration::~QCocoaIntegration()
// Deleting the clipboard integration flushes promised pastes using
// the mime converters - the ordering here is important.
delete mCocoaClipboard;
- QMacPasteboardMime::destroyMimeTypes();
+ QMacInternalPasteboardMime::destroyMimeTypes();
// Delete screens in reverse order to avoid crash in case of multiple screens
while (!mScreens.isEmpty()) {
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index 972c171f69..795d1a8149 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -207,12 +207,12 @@ void *QCocoaNativeInterface::nsOpenGLContextForContext(QOpenGLContext* context)
void QCocoaNativeInterface::addToMimeList(void *macPasteboardMime)
{
- qt_mac_addToGlobalMimeList(reinterpret_cast<QMacPasteboardMime *>(macPasteboardMime));
+ qt_mac_addToGlobalMimeList(reinterpret_cast<QMacInternalPasteboardMime *>(macPasteboardMime));
}
void QCocoaNativeInterface::removeFromMimeList(void *macPasteboardMime)
{
- qt_mac_removeFromGlobalMimeList(reinterpret_cast<QMacPasteboardMime *>(macPasteboardMime));
+ qt_mac_removeFromGlobalMimeList(reinterpret_cast<QMacInternalPasteboardMime *>(macPasteboardMime));
}
void QCocoaNativeInterface::registerDraggedTypes(const QStringList &types)
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index a2ef43db67..ad11a525ad 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -942,10 +942,11 @@ void QCocoaWindow::setNSWindow(NSWindow *window)
[window setReleasedWhenClosed : NO];
- [[NSNotificationCenter defaultCenter] addObserver:m_contentView
- selector:@selector(windowNotification:)
- name:nil // Get all notifications
- object:m_nsWindow];
+ if (m_qtView)
+ [[NSNotificationCenter defaultCenter] addObserver:m_qtView
+ selector:@selector(windowNotification:)
+ name:nil // Get all notifications
+ object:m_nsWindow];
[m_contentView setPostsFrameChangedNotifications: NO];
[window setContentView:m_contentView];
diff --git a/src/plugins/platforms/cocoa/qmacclipboard.h b/src/plugins/platforms/cocoa/qmacclipboard.h
index 4eeeecc0c0..d8e588e36b 100644
--- a/src/plugins/platforms/cocoa/qmacclipboard.h
+++ b/src/plugins/platforms/cocoa/qmacclipboard.h
@@ -55,9 +55,9 @@ class QMacPasteboard
{
struct Promise {
Promise() : itemId(0), convertor(0) { }
- Promise(int itemId, QMacPasteboardMime *c, QString m, QVariant d, int o=0) : itemId(itemId), offset(o), convertor(c), mime(m), data(d) { }
+ Promise(int itemId, QMacInternalPasteboardMime *c, QString m, QVariant d, int o=0) : itemId(itemId), offset(o), convertor(c), mime(m), data(d) { }
int itemId, offset;
- QMacPasteboardMime *convertor;
+ QMacInternalPasteboardMime *convertor;
QString mime;
QVariant data;
};
diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm
index b5c50d676f..9ccf41fbf4 100644
--- a/src/plugins/platforms/cocoa/qmacclipboard.mm
+++ b/src/plugins/platforms/cocoa/qmacclipboard.mm
@@ -68,7 +68,7 @@ QT_BEGIN_NAMESPACE
QMacPasteboard::QMacPasteboard(PasteboardRef p, uchar mt)
{
mac_mime_source = false;
- mime_type = mt ? mt : uchar(QMacPasteboardMime::MIME_ALL);
+ mime_type = mt ? mt : uchar(QMacInternalPasteboardMime::MIME_ALL);
paste = p;
CFRetain(paste);
}
@@ -76,7 +76,7 @@ QMacPasteboard::QMacPasteboard(PasteboardRef p, uchar mt)
QMacPasteboard::QMacPasteboard(uchar mt)
{
mac_mime_source = false;
- mime_type = mt ? mt : uchar(QMacPasteboardMime::MIME_ALL);
+ mime_type = mt ? mt : uchar(QMacInternalPasteboardMime::MIME_ALL);
paste = 0;
OSStatus err = PasteboardCreate(0, &paste);
if (err == noErr) {
@@ -89,7 +89,7 @@ QMacPasteboard::QMacPasteboard(uchar mt)
QMacPasteboard::QMacPasteboard(CFStringRef name, uchar mt)
{
mac_mime_source = false;
- mime_type = mt ? mt : uchar(QMacPasteboardMime::MIME_ALL);
+ mime_type = mt ? mt : uchar(QMacInternalPasteboardMime::MIME_ALL);
paste = 0;
OSStatus err = PasteboardCreate(name, &paste);
if (err == noErr) {
@@ -287,7 +287,7 @@ QMacPasteboard::setMimeData(QMimeData *mime_src)
delete mime;
mime = mime_src;
- QList<QMacPasteboardMime*> availableConverters = QMacPasteboardMime::all(mime_type);
+ QList<QMacInternalPasteboardMime*> availableConverters = QMacInternalPasteboardMime::all(mime_type);
if (mime != 0) {
clear_helper();
QStringList formats = mime_src->formats();
@@ -304,8 +304,8 @@ QMacPasteboard::setMimeData(QMimeData *mime_src)
}
for (int f = 0; f < formats.size(); ++f) {
QString mimeType = formats.at(f);
- for (QList<QMacPasteboardMime *>::Iterator it = availableConverters.begin(); it != availableConverters.end(); ++it) {
- QMacPasteboardMime *c = (*it);
+ for (QList<QMacInternalPasteboardMime *>::Iterator it = availableConverters.begin(); it != availableConverters.end(); ++it) {
+ QMacInternalPasteboardMime *c = (*it);
QString flavor(c->flavorFor(mimeType));
if (!flavor.isEmpty()) {
QVariant mimeData = static_cast<QMacMimeData*>(mime_src)->variantData(mimeType);
@@ -358,7 +358,7 @@ QMacPasteboard::formats() const
#ifdef DEBUG_PASTEBOARD
qDebug(" -%s", qPrintable(QString(flavor)));
#endif
- QString mimeType = QMacPasteboardMime::flavorToMime(mime_type, flavor);
+ QString mimeType = QMacInternalPasteboardMime::flavorToMime(mime_type, flavor);
if (!mimeType.isEmpty() && !ret.contains(mimeType)) {
#ifdef DEBUG_PASTEBOARD
qDebug(" -<%d> %s [%s]", ret.size(), qPrintable(mimeType), qPrintable(QString(flavor)));
@@ -401,7 +401,7 @@ QMacPasteboard::hasFormat(const QString &format) const
#ifdef DEBUG_PASTEBOARD
qDebug(" -%s [0x%x]", qPrintable(QString(flavor)), mime_type);
#endif
- QString mimeType = QMacPasteboardMime::flavorToMime(mime_type, flavor);
+ QString mimeType = QMacInternalPasteboardMime::flavorToMime(mime_type, flavor);
#ifdef DEBUG_PASTEBOARD
if (!mimeType.isEmpty())
qDebug(" - %s", qPrintable(mimeType));
@@ -428,9 +428,9 @@ QMacPasteboard::retrieveData(const QString &format, QVariant::Type) const
#ifdef DEBUG_PASTEBOARD
qDebug("Pasteboard: retrieveData [%s]", qPrintable(format));
#endif
- const QList<QMacPasteboardMime *> mimes = QMacPasteboardMime::all(mime_type);
+ const QList<QMacInternalPasteboardMime *> mimes = QMacInternalPasteboardMime::all(mime_type);
for (int mime = 0; mime < mimes.size(); ++mime) {
- QMacPasteboardMime *c = mimes.at(mime);
+ QMacInternalPasteboardMime *c = mimes.at(mime);
QString c_flavor = c->flavorFor(format);
if (!c_flavor.isEmpty()) {
// Handle text/plain a little differently. Try handling Unicode first.
diff --git a/src/plugins/platforms/cocoa/qmacmime.h b/src/plugins/platforms/cocoa/qmacmime.h
index d9ef63ae48..0802987fab 100644
--- a/src/plugins/platforms/cocoa/qmacmime.h
+++ b/src/plugins/platforms/cocoa/qmacmime.h
@@ -49,7 +49,7 @@
QT_BEGIN_NAMESPACE
// Duplicate of QMacPasteboardMime in QtMacExtras. Keep in sync!
-class QMacPasteboardMime {
+class QMacInternalPasteboardMime {
char type;
public:
enum QMacPasteboardMimeType { MIME_DND=0x01,
@@ -58,14 +58,14 @@ public:
MIME_QT3_CONVERTOR=0x08,
MIME_ALL=MIME_DND|MIME_CLIP
};
- explicit QMacPasteboardMime(char);
- virtual ~QMacPasteboardMime();
+ explicit QMacInternalPasteboardMime(char);
+ virtual ~QMacInternalPasteboardMime();
static void initializeMimeTypes();
static void destroyMimeTypes();
- static QList<QMacPasteboardMime*> all(uchar);
- static QMacPasteboardMime *convertor(uchar, const QString &mime, QString flav);
+ static QList<QMacInternalPasteboardMime*> all(uchar);
+ static QMacInternalPasteboardMime *convertor(uchar, const QString &mime, QString flav);
static QString flavorToMime(uchar, QString flav);
virtual QString convertorName() = 0;
@@ -78,8 +78,8 @@ public:
virtual int count(QMimeData *mimeData);
};
-void qt_mac_addToGlobalMimeList(QMacPasteboardMime *macMime);
-void qt_mac_removeFromGlobalMimeList(QMacPasteboardMime *macMime);
+void qt_mac_addToGlobalMimeList(QMacInternalPasteboardMime *macMime);
+void qt_mac_removeFromGlobalMimeList(QMacInternalPasteboardMime *macMime);
void qt_mac_registerDraggedTypes(const QStringList &types);
const QStringList& qt_mac_enabledDraggedTypes();
diff --git a/src/plugins/platforms/cocoa/qmacmime.mm b/src/plugins/platforms/cocoa/qmacmime.mm
index b4634c8ad8..89d1b5f681 100644
--- a/src/plugins/platforms/cocoa/qmacmime.mm
+++ b/src/plugins/platforms/cocoa/qmacmime.mm
@@ -62,11 +62,11 @@ QT_BEGIN_NAMESPACE
extern CGImageRef qt_mac_createCGImageFromQImage(const QImage &img, const QImage **imagePtr = 0); // qpaintengine_mac.cpp
-typedef QList<QMacPasteboardMime*> MimeList;
+typedef QList<QMacInternalPasteboardMime*> MimeList;
Q_GLOBAL_STATIC(MimeList, globalMimeList)
Q_GLOBAL_STATIC(QStringList, globalDraggedTypesList)
-void qt_mac_addToGlobalMimeList(QMacPasteboardMime *macMime)
+void qt_mac_addToGlobalMimeList(QMacInternalPasteboardMime *macMime)
{
// globalMimeList is in decreasing priority order. Recently added
// converters take prioity over previously added converters: prepend
@@ -74,7 +74,7 @@ void qt_mac_addToGlobalMimeList(QMacPasteboardMime *macMime)
globalMimeList()->prepend(macMime);
}
-void qt_mac_removeFromGlobalMimeList(QMacPasteboardMime *macMime)
+void qt_mac_removeFromGlobalMimeList(QMacInternalPasteboardMime *macMime)
{
if (!QGuiApplication::closingDown())
globalMimeList()->removeAll(macMime);
@@ -166,7 +166,7 @@ CFStringRef qt_mac_mime_typeUTI = CFSTR("com.pasteboard.trolltech.marker");
Constructs a new conversion object of type \a t, adding it to the
globally accessed list of available convertors.
*/
-QMacPasteboardMime::QMacPasteboardMime(char t) : type(t)
+QMacInternalPasteboardMime::QMacInternalPasteboardMime(char t) : type(t)
{
qt_mac_addToGlobalMimeList(this);
}
@@ -175,7 +175,7 @@ QMacPasteboardMime::QMacPasteboardMime(char t) : type(t)
Destroys a conversion object, removing it from the global
list of available convertors.
*/
-QMacPasteboardMime::~QMacPasteboardMime()
+QMacInternalPasteboardMime::~QMacInternalPasteboardMime()
{
qt_mac_removeFromGlobalMimeList(this);
}
@@ -183,17 +183,17 @@ QMacPasteboardMime::~QMacPasteboardMime()
/*!
Returns the item count for the given \a mimeData
*/
-int QMacPasteboardMime::count(QMimeData *mimeData)
+int QMacInternalPasteboardMime::count(QMimeData *mimeData)
{
Q_UNUSED(mimeData);
return 1;
}
-class QMacPasteboardMimeAny : public QMacPasteboardMime {
+class QMacPasteboardMimeAny : public QMacInternalPasteboardMime {
private:
public:
- QMacPasteboardMimeAny() : QMacPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) {
+ QMacPasteboardMimeAny() : QMacInternalPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) {
}
~QMacPasteboardMimeAny() {
}
@@ -255,11 +255,11 @@ QList<QByteArray> QMacPasteboardMimeAny::convertFromMime(const QString &mime, QV
return ret;
}
-class QMacPasteboardMimeTypeName : public QMacPasteboardMime {
+class QMacPasteboardMimeTypeName : public QMacInternalPasteboardMime {
private:
public:
- QMacPasteboardMimeTypeName() : QMacPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) {
+ QMacPasteboardMimeTypeName() : QMacInternalPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) {
}
~QMacPasteboardMimeTypeName() {
}
@@ -307,9 +307,9 @@ QList<QByteArray> QMacPasteboardMimeTypeName::convertFromMime(const QString &, Q
return ret;
}
-class QMacPasteboardMimePlainText : public QMacPasteboardMime {
+class QMacPasteboardMimePlainText : public QMacInternalPasteboardMime {
public:
- QMacPasteboardMimePlainText() : QMacPasteboardMime(MIME_ALL) { }
+ QMacPasteboardMimePlainText() : QMacInternalPasteboardMime(MIME_ALL) { }
QString convertorName();
QString flavorFor(const QString &mime);
@@ -369,9 +369,9 @@ QList<QByteArray> QMacPasteboardMimePlainText::convertFromMime(const QString &,
return ret;
}
-class QMacPasteboardMimeUnicodeText : public QMacPasteboardMime {
+class QMacPasteboardMimeUnicodeText : public QMacInternalPasteboardMime {
public:
- QMacPasteboardMimeUnicodeText() : QMacPasteboardMime(MIME_ALL) { }
+ QMacPasteboardMimeUnicodeText() : QMacInternalPasteboardMime(MIME_ALL) { }
QString convertorName();
QString flavorFor(const QString &mime);
@@ -449,9 +449,9 @@ QList<QByteArray> QMacPasteboardMimeUnicodeText::convertFromMime(const QString &
return ret;
}
-class QMacPasteboardMimeHTMLText : public QMacPasteboardMime {
+class QMacPasteboardMimeHTMLText : public QMacInternalPasteboardMime {
public:
- QMacPasteboardMimeHTMLText() : QMacPasteboardMime(MIME_ALL) { }
+ QMacPasteboardMimeHTMLText() : QMacInternalPasteboardMime(MIME_ALL) { }
QString convertorName();
QString flavorFor(const QString &mime);
@@ -503,9 +503,9 @@ QList<QByteArray> QMacPasteboardMimeHTMLText::convertFromMime(const QString &mim
return ret;
}
-class QMacPasteboardMimeTiff : public QMacPasteboardMime {
+class QMacPasteboardMimeTiff : public QMacInternalPasteboardMime {
public:
- QMacPasteboardMimeTiff() : QMacPasteboardMime(MIME_ALL) { }
+ QMacPasteboardMimeTiff() : QMacInternalPasteboardMime(MIME_ALL) { }
QString convertorName();
QString flavorFor(const QString &mime);
@@ -595,9 +595,9 @@ QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, Q
}
-class QMacPasteboardMimeFileUri : public QMacPasteboardMime {
+class QMacPasteboardMimeFileUri : public QMacInternalPasteboardMime {
public:
- QMacPasteboardMimeFileUri() : QMacPasteboardMime(MIME_ALL) { }
+ QMacPasteboardMimeFileUri() : QMacInternalPasteboardMime(MIME_ALL) { }
QString convertorName();
QString flavorFor(const QString &mime);
@@ -673,9 +673,9 @@ int QMacPasteboardMimeFileUri::count(QMimeData *mimeData)
return mimeData->urls().count();
}
-class QMacPasteboardMimeUrl : public QMacPasteboardMime {
+class QMacPasteboardMimeUrl : public QMacInternalPasteboardMime {
public:
- QMacPasteboardMimeUrl() : QMacPasteboardMime(MIME_ALL) { }
+ QMacPasteboardMimeUrl() : QMacInternalPasteboardMime(MIME_ALL) { }
QString convertorName();
QString flavorFor(const QString &mime);
@@ -747,10 +747,10 @@ QList<QByteArray> QMacPasteboardMimeUrl::convertFromMime(const QString &mime, QV
return ret;
}
-class QMacPasteboardMimeVCard : public QMacPasteboardMime
+class QMacPasteboardMimeVCard : public QMacInternalPasteboardMime
{
public:
- QMacPasteboardMimeVCard() : QMacPasteboardMime(MIME_ALL){ }
+ QMacPasteboardMimeVCard() : QMacInternalPasteboardMime(MIME_ALL){ }
QString convertorName();
QString flavorFor(const QString &mime);
@@ -808,7 +808,7 @@ QList<QByteArray> QMacPasteboardMimeVCard::convertFromMime(const QString &mime,
This is an internal function.
*/
-void QMacPasteboardMime::initializeMimeTypes()
+void QMacInternalPasteboardMime::initializeMimeTypes()
{
if (globalMimeList()->isEmpty()) {
// Create QMacPasteboardMimeAny first to put it at the end of globalMimeList
@@ -830,7 +830,7 @@ void QMacPasteboardMime::initializeMimeTypes()
/*!
\internal
*/
-void QMacPasteboardMime::destroyMimeTypes()
+void QMacInternalPasteboardMime::destroyMimeTypes()
{
MimeList *mimes = globalMimeList();
while (!mimes->isEmpty())
@@ -842,8 +842,8 @@ void QMacPasteboardMime::destroyMimeTypes()
between the \a mime and \a flav formats. Returns 0 if no such convertor
exists.
*/
-QMacPasteboardMime*
-QMacPasteboardMime::convertor(uchar t, const QString &mime, QString flav)
+QMacInternalPasteboardMime*
+QMacInternalPasteboardMime::convertor(uchar t, const QString &mime, QString flav)
{
MimeList *mimes = globalMimeList();
for (MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) {
@@ -868,7 +868,7 @@ QMacPasteboardMime::convertor(uchar t, const QString &mime, QString flav)
/*!
Returns a MIME type of type \a t for \a flav, or 0 if none exists.
*/
-QString QMacPasteboardMime::flavorToMime(uchar t, QString flav)
+QString QMacInternalPasteboardMime::flavorToMime(uchar t, QString flav)
{
MimeList *mimes = globalMimeList();
for (MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) {
@@ -891,7 +891,7 @@ QString QMacPasteboardMime::flavorToMime(uchar t, QString flav)
/*!
Returns a list of all currently defined QMacPasteboardMime objects of type \a t.
*/
-QList<QMacPasteboardMime*> QMacPasteboardMime::all(uchar t)
+QList<QMacInternalPasteboardMime*> QMacInternalPasteboardMime::all(uchar t)
{
MimeList ret;
MimeList *mimes = globalMimeList();
diff --git a/src/plugins/platforms/cocoa/qt_mac_p.h b/src/plugins/platforms/cocoa/qt_mac_p.h
index 808ca9194b..581157c2e1 100644
--- a/src/plugins/platforms/cocoa/qt_mac_p.h
+++ b/src/plugins/platforms/cocoa/qt_mac_p.h
@@ -178,7 +178,7 @@ public:
}
};
-class QMacPasteboardMime;
+class QMacInternalPasteboardMime;
class QMimeData;
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index ea6a0bd4a6..39a22f367e 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -150,7 +150,7 @@
m_keyboardEndRect = [self getKeyboardRect:notification];
if (!m_duration) {
m_duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
- m_curve = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16;
+ m_curve = UIViewAnimationCurve([notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16);
}
m_context->scrollRootView();
}
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index 5c8f67bda2..660da6397f 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -110,6 +110,8 @@ bool QIOSIntegration::hasCapability(Capability cap) const
return true;
case MultipleWindows:
return true;
+ case WindowManagement:
+ return false;
case ApplicationState:
return true;
default:
diff --git a/src/plugins/platforms/kms/qkmscursor.h b/src/plugins/platforms/kms/qkmscursor.h
index ee65b01e36..91ac10aae5 100644
--- a/src/plugins/platforms/kms/qkmscursor.h
+++ b/src/plugins/platforms/kms/qkmscursor.h
@@ -47,8 +47,8 @@
QT_BEGIN_NAMESPACE
class QKmsScreen;
-class gbm_device;
-class gbm_bo;
+struct gbm_device;
+struct gbm_bo;
class QKmsCursor : public QPlatformCursor
{
diff --git a/src/plugins/platforms/kms/qkmsdevice.h b/src/plugins/platforms/kms/qkmsdevice.h
index 33bb4e814e..906e00aa13 100644
--- a/src/plugins/platforms/kms/qkmsdevice.h
+++ b/src/plugins/platforms/kms/qkmsdevice.h
@@ -53,7 +53,7 @@ extern "C" {
QT_BEGIN_NAMESPACE
-class gbm_device;
+struct gbm_device;
class QKmsIntegration;
class QKmsDevice : public QObject
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
index 977df8abd0..53f48d5480 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
@@ -57,7 +57,6 @@ QLinuxFbIntegration::QLinuxFbIntegration(const QStringList &paramList)
: m_fontDb(new QGenericUnixFontDatabase())
{
m_primaryScreen = new QLinuxFbScreen(paramList);
- screenAdded(m_primaryScreen);
}
QLinuxFbIntegration::~QLinuxFbIntegration()
@@ -67,7 +66,9 @@ QLinuxFbIntegration::~QLinuxFbIntegration()
void QLinuxFbIntegration::initialize()
{
- if (!m_primaryScreen->initialize())
+ if (m_primaryScreen->initialize())
+ screenAdded(m_primaryScreen);
+ else
qWarning("linuxfb: Failed to initialize screen");
}
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
index a213f83c6f..965a6e4642 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
@@ -70,6 +70,7 @@ public:
private:
QLinuxFbScreen *m_primaryScreen;
QPlatformFontDatabase *m_fontDb;
+
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index ee539e9aed..9f8c93cce1 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -323,6 +323,26 @@ void QQnxWindow::setBufferSize(const QSize &size)
}
}
+ // Set the transparency. According to QNX technical support, setting the window
+ // transparency property should always be done *after* creating the window
+ // buffers in order to guarantee the property is paid attention to.
+ if (window()->requestedFormat().alphaBufferSize() == 0) {
+ // To avoid overhead in the composition manager, disable blending
+ // when the underlying window buffer doesn't have an alpha channel.
+ val[0] = SCREEN_TRANSPARENCY_NONE;
+ } else {
+ // Normal alpha blending. This doesn't commit us to translucency; the
+ // normal backfill during the painting will contain a fully opaque
+ // alpha channel unless the user explicitly intervenes to make something
+ // transparent.
+ val[0] = SCREEN_TRANSPARENCY_SOURCE_OVER;
+ }
+
+ errno = 0;
+ result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val);
+ if (result != 0)
+ qFatal("QQnxWindow: failed to set window transparency, errno=%d", errno);
+
// Cache new buffer size
m_bufferSize = nonEmptySize;
resetBuffers();
@@ -551,17 +571,6 @@ void QQnxWindow::initWindow()
if (result != 0)
qFatal("QQnxWindow: failed to set window alpha mode, errno=%d", errno);
- // Blend the window with Source Over Porter-Duff behavior onto whatever's
- // behind it.
- //
- // If the desired use-case is opaque, the Widget painting framework will
- // already fill in the alpha channel with full opacity.
- errno = 0;
- val = SCREEN_TRANSPARENCY_SOURCE_OVER;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window transparency, errno=%d", errno);
-
// Set the window swap interval
errno = 0;
val = 1;
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index e19e8d350f..2b6a6255b8 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -627,7 +627,6 @@ static inline QFontDatabase::WritingSystem writingSystemFromCharSet(uchar charSe
case EASTEUROPE_CHARSET:
case BALTIC_CHARSET:
case TURKISH_CHARSET:
- case OEM_CHARSET:
return QFontDatabase::Latin;
case GREEK_CHARSET:
return QFontDatabase::Greek;
@@ -652,8 +651,6 @@ static inline QFontDatabase::WritingSystem writingSystemFromCharSet(uchar charSe
return QFontDatabase::Vietnamese;
case SYMBOL_CHARSET:
return QFontDatabase::Symbol;
- // ### case MAC_CHARSET:
- // ### case DEFAULT_CHARSET:
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
index 8d14adf828..51f79736f2 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
@@ -81,7 +81,6 @@ static inline QFontDatabase::WritingSystem writingSystemFromCharSet(uchar charSe
case EASTEUROPE_CHARSET:
case BALTIC_CHARSET:
case TURKISH_CHARSET:
- case OEM_CHARSET:
return QFontDatabase::Latin;
case GREEK_CHARSET:
return QFontDatabase::Greek;
@@ -106,8 +105,6 @@ static inline QFontDatabase::WritingSystem writingSystemFromCharSet(uchar charSe
return QFontDatabase::Vietnamese;
case SYMBOL_CHARSET:
return QFontDatabase::Symbol;
- // ### case MAC_CHARSET:
- // ### case DEFAULT_CHARSET:
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 2743ef029d..1baea6faff 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -743,8 +743,11 @@ bool QWindowsKeyMapper::translateKeyEvent(QWindow *widget, HWND hwnd,
return true;
}
- // Add this key to the keymap if it is not present yet.
- updateKeyMap(msg);
+ // WM_CHAR messages already contain the character in question so there is
+ // no need to fiddle with our key map. In any other case add this key to the
+ // keymap if it is not present yet.
+ if (msg.message != WM_CHAR)
+ updateKeyMap(msg);
MSG peekedMsg;
// consume dead chars?(for example, typing '`','a' resulting in a-accent).
diff --git a/src/sql/kernel/qsqldriver.h b/src/sql/kernel/qsqldriver.h
index 017ffd4e4a..f93a03063b 100644
--- a/src/sql/kernel/qsqldriver.h
+++ b/src/sql/kernel/qsqldriver.h
@@ -62,6 +62,7 @@ class QVariant;
class Q_SQL_EXPORT QSqlDriver : public QObject
{
friend class QSqlDatabase;
+ friend class QSqlResultPrivate;
Q_OBJECT
Q_DECLARE_PRIVATE(QSqlDriver)
diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp
index 953e2ca66e..31b05ab9e9 100644
--- a/src/sql/kernel/qsqlresult.cpp
+++ b/src/sql/kernel/qsqlresult.cpp
@@ -51,6 +51,7 @@
#include "qsqldriver.h"
#include "qpointer.h"
#include "qsqlresult_p.h"
+#include "private/qsqldriver_p.h"
#include <QDebug>
QT_BEGIN_NAMESPACE
@@ -89,6 +90,7 @@ QString QSqlResultPrivate::positionalToNamedBinding(const QString &query) const
result.reserve(n * 5 / 4);
QChar closingQuote;
int count = 0;
+ bool ignoreBraces = (sqldriver->d_func()->dbmsType == QSqlDriverPrivate::PostgreSQL);
for (int i = 0; i < n; ++i) {
QChar ch = query.at(i);
@@ -110,7 +112,7 @@ QString QSqlResultPrivate::positionalToNamedBinding(const QString &query) const
} else {
if (ch == QLatin1Char('\'') || ch == QLatin1Char('"') || ch == QLatin1Char('`'))
closingQuote = ch;
- else if (ch == QLatin1Char('['))
+ else if (!ignoreBraces && ch == QLatin1Char('['))
closingQuote = QLatin1Char(']');
result += ch;
}
@@ -129,6 +131,7 @@ QString QSqlResultPrivate::namedToPositionalBinding(const QString &query)
QChar closingQuote;
int count = 0;
int i = 0;
+ bool ignoreBraces = (sqldriver->d_func()->dbmsType == QSqlDriverPrivate::PostgreSQL);
while (i < n) {
QChar ch = query.at(i);
@@ -160,7 +163,7 @@ QString QSqlResultPrivate::namedToPositionalBinding(const QString &query)
} else {
if (ch == QLatin1Char('\'') || ch == QLatin1Char('"') || ch == QLatin1Char('`'))
closingQuote = ch;
- else if (ch == QLatin1Char('['))
+ else if (!ignoreBraces && ch == QLatin1Char('['))
closingQuote = QLatin1Char(']');
result += ch;
++i;
diff --git a/src/testlib/doc/qttestlib.qdocconf b/src/testlib/doc/qttestlib.qdocconf
index 426236c339..250d237f12 100644
--- a/src/testlib/doc/qttestlib.qdocconf
+++ b/src/testlib/doc/qttestlib.qdocconf
@@ -27,7 +27,7 @@ qhp.QtTestLib.subprojects.classes.sortPages = true
tagfile = ../../../doc/qttestlib/qttestlib.tags
-depends += qtcore qtdoc qtwidgets qtgui
+depends += qtcore qtdoc qtwidgets qtgui qtquick
headerdirs += ..
diff --git a/src/widgets/widgets/qgroupbox.cpp b/src/widgets/widgets/qgroupbox.cpp
index 14d434ec28..168f0bbd67 100644
--- a/src/widgets/widgets/qgroupbox.cpp
+++ b/src/widgets/widgets/qgroupbox.cpp
@@ -645,8 +645,8 @@ void QGroupBox::setChecked(bool b)
#ifndef QT_NO_ACCESSIBILITY
QAccessible::State st;
st.checked = true;
- QAccessibleStateChangeEvent *ev = new QAccessibleStateChangeEvent(this, st);
- QAccessible::updateAccessibility(ev);
+ QAccessibleStateChangeEvent e(this, st);
+ QAccessible::updateAccessibility(&e);
#endif
emit toggled(b);
}
diff --git a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
index cbbb30a598..ce30710f7f 100644
--- a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
+++ b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
@@ -572,15 +572,16 @@ void tst_QCommandLineParser::testQuoteEscaping()
QProcess process;
process.start("testhelper/qcommandlineparser_test_helper", QStringList() <<
QString::number(QCommandLineParser::ParseAsCompactedShortOptions) <<
- "-DKEY1=\"VALUE1\"" << "-DKEY2=\\\"VALUE2\\\"" <<
+ "\\\\server\\path" <<
+ "-DKEY1=\"VALUE1\""
"-DQTBUG-15379=C:\\path\\'file.ext" <<
"-DQTBUG-30628=C:\\temp\\'file'.ext");
QVERIFY(process.waitForFinished(5000));
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
QString output = process.readAll();
QVERIFY2(!output.contains("ERROR"), qPrintable(output));
+ QVERIFY2(output.contains("\\\\server\\path"), qPrintable(output));
QVERIFY2(output.contains("KEY1=\"VALUE1\""), qPrintable(output));
- QVERIFY2(output.contains("KEY2=\\\"VALUE2\\\""), qPrintable(output));
QVERIFY2(output.contains("QTBUG-15379=C:\\path\\'file.ext"), qPrintable(output));
QVERIFY2(output.contains("QTBUG-30628=C:\\temp\\'file'.ext"), qPrintable(output));
#endif // !QT_NO_PROCESS
diff --git a/tests/auto/corelib/tools/qdate/tst_qdate.cpp b/tests/auto/corelib/tools/qdate/tst_qdate.cpp
index 728a4244a1..b91de092e8 100644
--- a/tests/auto/corelib/tools/qdate/tst_qdate.cpp
+++ b/tests/auto/corelib/tools/qdate/tst_qdate.cpp
@@ -1137,10 +1137,14 @@ void tst_QDate::toStringDateFormat()
QFETCH(QString, expectedStr);
QCOMPARE(date.toString(Qt::SystemLocaleShortDate), QLocale::system().toString(date, QLocale::ShortFormat));
- QCOMPARE(date.toString(Qt::LocaleDate), QLocale().toString(date, QLocale::ShortFormat));
+ QCOMPARE(date.toString(Qt::DefaultLocaleShortDate), QLocale().toString(date, QLocale::ShortFormat));
+ QCOMPARE(date.toString(Qt::SystemLocaleLongDate), QLocale::system().toString(date, QLocale::LongFormat));
+ QCOMPARE(date.toString(Qt::DefaultLocaleLongDate), QLocale().toString(date, QLocale::LongFormat));
QLocale::setDefault(QLocale::German);
QCOMPARE(date.toString(Qt::SystemLocaleShortDate), QLocale::system().toString(date, QLocale::ShortFormat));
- QCOMPARE(date.toString(Qt::LocaleDate), QLocale().toString(date, QLocale::ShortFormat));
+ QCOMPARE(date.toString(Qt::DefaultLocaleShortDate), QLocale().toString(date, QLocale::ShortFormat));
+ QCOMPARE(date.toString(Qt::SystemLocaleLongDate), QLocale::system().toString(date, QLocale::LongFormat));
+ QCOMPARE(date.toString(Qt::DefaultLocaleLongDate), QLocale().toString(date, QLocale::LongFormat));
QCOMPARE(date.toString(format), expectedStr);
}
diff --git a/tests/auto/corelib/tools/qtime/tst_qtime.cpp b/tests/auto/corelib/tools/qtime/tst_qtime.cpp
index 0563111abb..4bd29da056 100644
--- a/tests/auto/corelib/tools/qtime/tst_qtime.cpp
+++ b/tests/auto/corelib/tools/qtime/tst_qtime.cpp
@@ -723,15 +723,23 @@ void tst_QTime::toStringFormat()
void tst_QTime::toStringLocale()
{
QTime time(18, 30);
- QCOMPARE(time.toString(Qt::SystemLocaleDate),
+ QCOMPARE(time.toString(Qt::SystemLocaleShortDate),
QLocale::system().toString(time, QLocale::ShortFormat));
- QCOMPARE(time.toString(Qt::LocaleDate),
+ QCOMPARE(time.toString(Qt::DefaultLocaleShortDate),
QLocale().toString(time, QLocale::ShortFormat));
+ QCOMPARE(time.toString(Qt::SystemLocaleLongDate),
+ QLocale::system().toString(time, QLocale::LongFormat));
+ QCOMPARE(time.toString(Qt::DefaultLocaleLongDate),
+ QLocale().toString(time, QLocale::LongFormat));
QLocale::setDefault(QLocale::German);
- QCOMPARE(time.toString(Qt::SystemLocaleDate),
+ QCOMPARE(time.toString(Qt::SystemLocaleShortDate),
QLocale::system().toString(time, QLocale::ShortFormat));
- QCOMPARE(time.toString(Qt::LocaleDate),
+ QCOMPARE(time.toString(Qt::DefaultLocaleShortDate),
QLocale().toString(time, QLocale::ShortFormat));
+ QCOMPARE(time.toString(Qt::SystemLocaleLongDate),
+ QLocale::system().toString(time, QLocale::LongFormat));
+ QCOMPARE(time.toString(Qt::DefaultLocaleLongDate),
+ QLocale().toString(time, QLocale::LongFormat));
}
void tst_QTime::msecsSinceStartOfDay_data()
diff --git a/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro b/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro
index ef6c7a7e09..114327effb 100644
--- a/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro
+++ b/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro
@@ -1,7 +1,7 @@
TARGET = tst_qsqlresult
CONFIG += testcase
-QT = core sql testlib
+QT = core core-private sql sql-private testlib
SOURCES += tst_qsqlresult.cpp
HEADERS += testsqldriver.h
diff --git a/tests/auto/sql/kernel/qsqlresult/testsqldriver.h b/tests/auto/sql/kernel/qsqlresult/testsqldriver.h
index 9d435a0f7c..eda0658b41 100644
--- a/tests/auto/sql/kernel/qsqlresult/testsqldriver.h
+++ b/tests/auto/sql/kernel/qsqlresult/testsqldriver.h
@@ -45,6 +45,7 @@
#include <QtSql/QSqlResult>
#include <QtSql/QSqlDriver>
#include <QtSql/QSqlRecord>
+#include <private/qsqldriver_p.h>
class TestSqlDriverResult : public QSqlResult
{
@@ -77,6 +78,8 @@ protected:
class TestSqlDriver : public QSqlDriver
{
+ Q_DECLARE_PRIVATE(QSqlDriver)
+
public:
TestSqlDriver() {}
~TestSqlDriver() {}
@@ -96,6 +99,12 @@ public:
int /* port */, const QString & /* options */)
{ return false; }
void close() {}
+ QSqlDriverPrivate::DBMSType dbmsType() const
+ {
+ Q_D(const QSqlDriver);
+ return d->dbmsType;
+ }
+
QSqlResult *createResult() const { return new TestSqlDriverResult(this); }
};
diff --git a/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp b/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp
index ba6b4d1fbf..2462fab879 100644
--- a/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp
+++ b/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp
@@ -79,18 +79,30 @@ void tst_QSqlResult::parseOfBoundValues()
QVERIFY(result.savePrepare("SELECT :1 AS ':2'"));
QCOMPARE(result.boundValues().count(), 1);
QVERIFY(result.savePrepare("SELECT :1 AS [:2]"));
- QCOMPARE(result.boundValues().count(), 1);
+ if (testDriver.dbmsType() == QSqlDriverPrivate::PostgreSQL)
+ QCOMPARE(result.boundValues().count(), 2);
+ else
+ QCOMPARE(result.boundValues().count(), 1);
QVERIFY(result.savePrepare("SELECT :1 AS [:2]]]"));
- QCOMPARE(result.boundValues().count(), 1);
+ if (testDriver.dbmsType() == QSqlDriverPrivate::PostgreSQL)
+ QCOMPARE(result.boundValues().count(), 2);
+ else
+ QCOMPARE(result.boundValues().count(), 1);
QVERIFY(result.savePrepare("SELECT :1 AS [:2]]]]]"));
- QCOMPARE(result.boundValues().count(), 1);
+ if (testDriver.dbmsType() == QSqlDriverPrivate::PostgreSQL)
+ QCOMPARE(result.boundValues().count(), 2);
+ else
+ QCOMPARE(result.boundValues().count(), 1);
QVERIFY(result.savePrepare("SELECT ? AS \"?\""));
QCOMPARE(result.boundValues().count(), 1);
QVERIFY(result.savePrepare("SELECT ? AS '?'"));
QCOMPARE(result.boundValues().count(), 1);
QVERIFY(result.savePrepare("SELECT ? AS [?]"));
- QCOMPARE(result.boundValues().count(), 1);
+ if (testDriver.dbmsType() == QSqlDriverPrivate::PostgreSQL)
+ QCOMPARE(result.boundValues().count(), 2);
+ else
+ QCOMPARE(result.boundValues().count(), 1);
QVERIFY(result.savePrepare("SELECT ? AS \"'?\""));
QCOMPARE(result.boundValues().count(), 1);
diff --git a/tools/configure/Makefile.win32 b/tools/configure/Makefile.win32
index 272b86c2d4..ff38ddcc76 100644
--- a/tools/configure/Makefile.win32
+++ b/tools/configure/Makefile.win32
@@ -85,6 +85,8 @@ clean:
$(PCH): $(CONFSRC)\configure_pch.h
$(CXX) -c -Yc $(CXXFLAGS_BARE) -Fp$@ -Foconfigure_pch.obj -TP $**
+$(OBJECTS): $(PCH)
+
main.obj: $(CONFSRC)\main.cpp $(CONFSRC)\configureapp.h $(PCH)
configureapp.obj: $(CONFSRC)\configureapp.cpp $(CONFSRC)\configureapp.h $(CONFSRC)\environment.h $(CONFSRC)\tools.h $(PCH)
environment.obj: $(CONFSRC)\environment.cpp $(CONFSRC)\environment.h $(PCH)